audio: several fixes in audio routing callbacks

- audio policy:
Force device change to ensure new audio patch creation
upon first track activity on a given output.
Fix function device_distinguishes_on_address() which could mistake
some output device with remote submix input device.

- audio flinger:
Reduce number of binder calls upon new client registration by only
sending ioConfigChanged() callbacks to newly registered client.
Fix first patch after output thread creation not triggering an
ioConfigChanged() callback.

-audio system:
Force client registration upon routing callback installation to force
new ioConfigChanged() callback from audio flinger.

Bug: 22381136.

Change-Id: Ieb0d9f92f563a40552eb31bc0499c8ac65f78ce4
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 52fce34..8f1e050 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1252,11 +1252,9 @@
     if (client == 0) {
         return;
     }
-    bool clientAdded = false;
+    pid_t pid = IPCThreadState::self()->getCallingPid();
     {
         Mutex::Autolock _cl(mClientLock);
-
-        pid_t pid = IPCThreadState::self()->getCallingPid();
         if (mNotificationClients.indexOfKey(pid) < 0) {
             sp<NotificationClient> notificationClient = new NotificationClient(this,
                                                                                 client,
@@ -1267,22 +1265,19 @@
 
             sp<IBinder> binder = IInterface::asBinder(client);
             binder->linkToDeath(notificationClient);
-            clientAdded = true;
         }
     }
 
     // mClientLock should not be held here because ThreadBase::sendIoConfigEvent() will lock the
     // ThreadBase mutex and the locking order is ThreadBase::mLock then AudioFlinger::mClientLock.
-    if (clientAdded) {
-        // the config change is always sent from playback or record threads to avoid deadlock
-        // with AudioSystem::gLock
-        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-            mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED);
-        }
+    // the config change is always sent from playback or record threads to avoid deadlock
+    // with AudioSystem::gLock
+    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+        mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED, pid);
+    }
 
-        for (size_t i = 0; i < mRecordThreads.size(); i++) {
-            mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED);
-        }
+    for (size_t i = 0; i < mRecordThreads.size(); i++) {
+        mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED, pid);
     }
 }
 
@@ -1316,12 +1311,15 @@
 }
 
 void AudioFlinger::ioConfigChanged(audio_io_config_event event,
-                                   const sp<AudioIoDescriptor>& ioDesc)
+                                   const sp<AudioIoDescriptor>& ioDesc,
+                                   pid_t pid)
 {
     Mutex::Autolock _l(mClientLock);
     size_t size = mNotificationClients.size();
     for (size_t i = 0; i < size; i++) {
-        mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioDesc);
+        if ((pid == 0) || (mNotificationClients.keyAt(i) == pid)) {
+            mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioDesc);
+        }
     }
 }
 
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index d087ced..4f7e27d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -559,7 +559,8 @@
               float streamVolume_l(audio_stream_type_t stream) const
                                 { return mStreamTypes[stream].volume; }
               void ioConfigChanged(audio_io_config_event event,
-                                   const sp<AudioIoDescriptor>& ioDesc);
+                                   const sp<AudioIoDescriptor>& ioDesc,
+                                   pid_t pid = 0);
 
               // Allocate an audio_io_handle_t, session ID, effect ID, or audio_module_handle_t.
               // They all share the same ID space, but the namespaces are actually independent
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d3ea9d8..0880c5d 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -532,7 +532,8 @@
         // RecordThread::readInputParameters_l()
         //FIXME: mStandby should be true here. Is this some kind of hack?
         mStandby(false), mOutDevice(outDevice), mInDevice(inDevice),
-        mPrevInDevice(AUDIO_DEVICE_NONE), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
+        mPrevOutDevice(AUDIO_DEVICE_NONE), 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)
@@ -627,16 +628,16 @@
     return status;
 }
 
-void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event)
+void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid)
 {
     Mutex::Autolock _l(mLock);
-    sendIoConfigEvent_l(event);
+    sendIoConfigEvent_l(event, pid);
 }
 
 // sendIoConfigEvent_l() must be called with ThreadBase::mLock held
-void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event)
+void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid)
 {
-    sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event);
+    sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid);
     sendConfigEvent_l(configEvent);
 }
 
@@ -706,7 +707,7 @@
         } break;
         case CFG_EVENT_IO: {
             IoConfigEventData *data = (IoConfigEventData *)event->mData.get();
-            ioConfigChanged(data->mEvent);
+            ioConfigChanged(data->mEvent, data->mPid);
         } break;
         case CFG_EVENT_SET_PARAMETER: {
             SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get();
@@ -1999,7 +2000,7 @@
     return out_s8;
 }
 
-void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event) {
+void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {
     sp<AudioIoDescriptor> desc = new AudioIoDescriptor();
     ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event);
 
@@ -2021,7 +2022,7 @@
     default:
         break;
     }
-    mAudioFlinger->ioConfigChanged(event, desc);
+    mAudioFlinger->ioConfigChanged(event, desc, pid);
 }
 
 void AudioFlinger::PlaybackThread::writeCallback()
@@ -3133,7 +3134,10 @@
     for (size_t i = 0; i < mEffectChains.size(); i++) {
         mEffectChains[i]->setDevice_l(type);
     }
-    bool configChanged = mOutDevice != type;
+
+    // mPrevOutDevice is the latest device set by createAudioPatch_l(). It is not set when
+    // the thread is created so that the first patch creation triggers an ioConfigChanged callback
+    bool configChanged = mPrevOutDevice != type;
     mOutDevice = type;
     mPatch = *patch;
 
@@ -3163,6 +3167,7 @@
         *handle = AUDIO_PATCH_HANDLE_NONE;
     }
     if (configChanged) {
+        mPrevOutDevice = type;
         sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
     }
     return status;
@@ -6868,7 +6873,7 @@
     return out_s8;
 }
 
-void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event) {
+void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {
     sp<AudioIoDescriptor> desc = new AudioIoDescriptor();
 
     desc->mIoHandle = mId;
@@ -6888,7 +6893,7 @@
     default:
         break;
     }
-    mAudioFlinger->ioConfigChanged(event, desc);
+    mAudioFlinger->ioConfigChanged(event, desc, pid);
 }
 
 void AudioFlinger::RecordThread::readInputParameters_l()
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 0783371..46ac300 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -104,21 +104,22 @@
 
     class IoConfigEventData : public ConfigEventData {
     public:
-        IoConfigEventData(audio_io_config_event event) :
-            mEvent(event) {}
+        IoConfigEventData(audio_io_config_event event, pid_t pid) :
+            mEvent(event), mPid(pid) {}
 
         virtual  void dump(char *buffer, size_t size) {
             snprintf(buffer, size, "IO event: event %d\n", mEvent);
         }
 
         const audio_io_config_event mEvent;
+        const pid_t                 mPid;
     };
 
     class IoConfigEvent : public ConfigEvent {
     public:
-        IoConfigEvent(audio_io_config_event event) :
+        IoConfigEvent(audio_io_config_event event, pid_t pid) :
             ConfigEvent(CFG_EVENT_IO) {
-            mData = new IoConfigEventData(event);
+            mData = new IoConfigEventData(event, pid);
         }
         virtual ~IoConfigEvent() {}
     };
@@ -255,13 +256,13 @@
                                                     status_t& status) = 0;
     virtual     status_t    setParameters(const String8& keyValuePairs);
     virtual     String8     getParameters(const String8& keys) = 0;
-    virtual     void        ioConfigChanged(audio_io_config_event event) = 0;
+    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0) = 0;
                 // sendConfigEvent_l() must be called with ThreadBase::mLock held
                 // Can temporarily release the lock if waiting for a reply from
                 // processConfigEvents_l().
                 status_t    sendConfigEvent_l(sp<ConfigEvent>& event);
-                void        sendIoConfigEvent(audio_io_config_event event);
-                void        sendIoConfigEvent_l(audio_io_config_event event);
+                void        sendIoConfigEvent(audio_io_config_event event, pid_t pid = 0);
+                void        sendIoConfigEvent_l(audio_io_config_event event, pid_t pid = 0);
                 void        sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio);
                 void        sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio);
                 status_t    sendSetParameterConfigEvent_l(const String8& keyValuePair);
@@ -436,6 +437,7 @@
                 bool                    mStandby;     // Whether thread is currently in standby.
                 audio_devices_t         mOutDevice;   // output device
                 audio_devices_t         mInDevice;    // input device
+                audio_devices_t         mPrevOutDevice;   // previous output device
                 audio_devices_t         mPrevInDevice;    // previous input device
                 struct audio_patch      mPatch;
                 audio_source_t          mAudioSource;
@@ -572,7 +574,7 @@
                                 { return android_atomic_acquire_load(&mSuspended) > 0; }
 
     virtual     String8     getParameters(const String8& keys);
-    virtual     void        ioConfigChanged(audio_io_config_event event);
+    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);
                 status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
                 // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency.
                 // Consider also removing and passing an explicit mMainBuffer initialization
@@ -1254,7 +1256,7 @@
                                                status_t& status);
     virtual void        cacheParameters_l() {}
     virtual String8     getParameters(const String8& keys);
-    virtual void        ioConfigChanged(audio_io_config_event event);
+    virtual void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);
     virtual status_t    createAudioPatch_l(const struct audio_patch *patch,
                                            audio_patch_handle_t *handle);
     virtual status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);