reduce number of binder calls from mediaserver

Reduce the number of audio port, audio patch and
IO config changed binder calls from mediaserver to
client processes:
- Do not call IO config changed callback if selected
device is the same as previously selected one on a given
audio flinger playback or capture thread.
- Do not call the audio port or audo patch list update
callback on a client if this client as no listener registered.

Bug: 22045560.

Change-Id: If780e105404de79b7cb5c80c27b793ceb6b1c423
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index c5f4fb7..fbe4f18 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -166,6 +166,17 @@
     }
 }
 
+void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
+{
+    Mutex::Autolock _l(mNotificationClientsLock);
+
+    uid_t uid = IPCThreadState::self()->getCallingUid();
+    if (mNotificationClients.indexOfKey(uid) < 0) {
+        return;
+    }
+    mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled);
+}
+
 // removeNotificationClient() is called when the client process dies.
 void AudioPolicyService::removeNotificationClient(uid_t uid)
 {
@@ -246,7 +257,8 @@
 AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
                                                      const sp<IAudioPolicyServiceClient>& client,
                                                      uid_t uid)
-    : mService(service), mUid(uid), mAudioPolicyServiceClient(client)
+    : mService(service), mUid(uid), mAudioPolicyServiceClient(client),
+      mAudioPortCallbacksEnabled(false)
 {
 }
 
@@ -265,14 +277,14 @@
 
 void AudioPolicyService::NotificationClient::onAudioPortListUpdate()
 {
-    if (mAudioPolicyServiceClient != 0) {
+    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
         mAudioPolicyServiceClient->onAudioPortListUpdate();
     }
 }
 
 void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
 {
-    if (mAudioPolicyServiceClient != 0) {
+    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
         mAudioPolicyServiceClient->onAudioPatchListUpdate();
     }
 }
@@ -285,6 +297,12 @@
     }
 }
 
+void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
+{
+    mAudioPortCallbacksEnabled = enabled;
+}
+
+
 void AudioPolicyService::binderDied(const wp<IBinder>& who) {
     ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
             IPCThreadState::self()->getCallingPid());