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/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 410fff5..c8f9be0 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -530,7 +530,7 @@
         // RecordThread::readInputParameters_l()
         //FIXME: mStandby should be true here. Is this some kind of hack?
         mStandby(false), mOutDevice(outDevice), mInDevice(inDevice),
-        mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
+        mPrevInDevice(AUDIO_DEVICE_NONE), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
         // mName will be set by concrete (non-virtual) subclass
         mDeathRecipient(new PMDeathRecipient(this)),
         mSystemReady(systemReady)
@@ -3131,6 +3131,7 @@
     for (size_t i = 0; i < mEffectChains.size(); i++) {
         mEffectChains[i]->setDevice_l(type);
     }
+    bool configChanged = mOutDevice != type;
     mOutDevice = type;
     mPatch = *patch;
 
@@ -3159,7 +3160,9 @@
                 param.toString().string());
         *handle = AUDIO_PATCH_HANDLE_NONE;
     }
-    sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
+    if (configChanged) {
+        sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
+    }
     return status;
 }
 
@@ -6796,6 +6799,9 @@
             status = BAD_VALUE;
         } else {
             mInDevice = value;
+            if (value != AUDIO_DEVICE_NONE) {
+                mPrevInDevice = value;
+            }
             // disable AEC and NS if the device is a BT SCO headset supporting those
             // pre processings
             if (mTracks.size() > 0) {
@@ -7079,7 +7085,10 @@
         *handle = AUDIO_PATCH_HANDLE_NONE;
     }
 
-    sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
+    if (mInDevice != mPrevInDevice) {
+        sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
+        mPrevInDevice = mInDevice;
+    }
 
     return status;
 }