AudioFlinger: send audio source to audio effects

Added support for EFFECT_CMD_SET_AUDIO_SOURCE audio effect
command to inform preprocessings of current audio source
selection for capture.

Change-Id: Ib2418a9aa8114e8457fe828ecd43b230ed86cdd6
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 14f74b5..c27b4a2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1141,7 +1141,7 @@
         mChannelCount(0),
         mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
         mParamStatus(NO_ERROR),
-        mStandby(false), mDevice(device), mId(id),
+        mStandby(false), mDevice(device), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
         // mName will be set by concrete (non-virtual) subclass
         mDeathRecipient(new PMDeathRecipient(this))
 {
@@ -6591,6 +6591,15 @@
             newDevice |= value;
             mDevice = newDevice;    // since mDevice is read by other threads, only write to it once
         }
+        if (param.getInt(String8(AudioParameter::keyInputSource), value) == NO_ERROR &&
+                mAudioSource != (audio_source_t)value) {
+            // forward device change to effects that have requested to be
+            // aware of attached audio device.
+            for (size_t i = 0; i < mEffectChains.size(); i++) {
+                mEffectChains[i]->setAudioSource_l((audio_source_t)value);
+            }
+            mAudioSource = (audio_source_t)value;
+        }
         if (status == NO_ERROR) {
             status = mInput->stream->common.set_parameters(&mInput->stream->common, keyValuePair.string());
             if (status == INVALID_OPERATION) {
@@ -7737,6 +7746,7 @@
 
             effect->setDevice(mDevice);
             effect->setMode(mAudioFlinger->getMode());
+            effect->setAudioSource(mAudioSource);
         }
         // create effect handle and connect it to effect module
         handle = new EffectHandle(effect, client, effectClient, priority);
@@ -7814,6 +7824,7 @@
 
     effect->setDevice(mDevice);
     effect->setMode(mAudioFlinger->getMode());
+    effect->setAudioSource(mAudioSource);
     return NO_ERROR;
 }
 
@@ -8712,6 +8723,22 @@
     return status;
 }
 
+status_t AudioFlinger::EffectModule::setAudioSource(audio_source_t source)
+{
+    Mutex::Autolock _l(mLock);
+    status_t status = NO_ERROR;
+    if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_SOURCE_MASK) == EFFECT_FLAG_AUDIO_SOURCE_IND) {
+        uint32_t size = 0;
+        status = (*mEffectInterface)->command(mEffectInterface,
+                                              EFFECT_CMD_SET_AUDIO_SOURCE,
+                                              sizeof(audio_source_t),
+                                              &source,
+                                              &size,
+                                              NULL);
+    }
+    return status;
+}
+
 void AudioFlinger::EffectModule::setSuspended(bool suspended)
 {
     Mutex::Autolock _l(mLock);
@@ -9387,6 +9414,15 @@
     }
 }
 
+// setAudioSource_l() must be called with PlaybackThread::mLock held
+void AudioFlinger::EffectChain::setAudioSource_l(audio_source_t source)
+{
+    size_t size = mEffects.size();
+    for (size_t i = 0; i < size; i++) {
+        mEffects[i]->setAudioSource(source);
+    }
+}
+
 // setVolume_l() must be called with PlaybackThread::mLock held
 bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right)
 {