audio policy: add routing update client interface

Added IAudioPolicyServiceClient client binder interface
for client process to receive notifications from AudioPolicyService
when audio ports are added/removed or audio patches created/released.

The audio patches owned by a given client are automatically released when
this client binder dies.

Bug: 14815883.

Change-Id: I6013f6aec03b50565cffb1ad2cd1f0f8852032c5
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 845ee20..eafb3ad 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -45,6 +45,7 @@
 audio_channel_mask_t AudioSystem::gPrevInChannelMask;
 size_t AudioSystem::gInBuffSize = 0;    // zero indicates cache is invalid
 
+sp<AudioSystem::AudioPortCallback> AudioSystem::gAudioPortCallback;
 
 // establish binder interface to AudioFlinger service
 const sp<IAudioFlinger>& AudioSystem::get_audio_flinger()
@@ -528,6 +529,7 @@
     gAudioErrorCallback = cb;
 }
 
+
 bool AudioSystem::routedToA2dpOutput(audio_stream_type_t streamType)
 {
     switch (streamType) {
@@ -566,6 +568,7 @@
         }
         binder->linkToDeath(gAudioPolicyServiceClient);
         gAudioPolicyService = interface_cast<IAudioPolicyService>(binder);
+        gAudioPolicyService->registerClient(gAudioPolicyServiceClient);
         gLock.unlock();
     } else {
         gLock.unlock();
@@ -880,14 +883,39 @@
     return aps->setAudioPortConfig(config);
 }
 
+void AudioSystem::setAudioPortCallback(sp<AudioPortCallback> callBack)
+{
+    Mutex::Autolock _l(gLock);
+    gAudioPortCallback = callBack;
+}
+
 // ---------------------------------------------------------------------------
 
 void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
 {
-    Mutex::Autolock _l(AudioSystem::gLock);
+    Mutex::Autolock _l(gLock);
+    if (gAudioPortCallback != 0) {
+        gAudioPortCallback->onServiceDied();
+    }
     AudioSystem::gAudioPolicyService.clear();
 
     ALOGW("AudioPolicyService server died!");
 }
 
+void AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate()
+{
+    Mutex::Autolock _l(gLock);
+    if (gAudioPortCallback != 0) {
+        gAudioPortCallback->onAudioPortListUpdate();
+    }
+}
+
+void AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate()
+{
+    Mutex::Autolock _l(gLock);
+    if (gAudioPortCallback != 0) {
+        gAudioPortCallback->onAudioPatchListUpdate();
+    }
+}
+
 }; // namespace android