audio policy: pass session ID to capture activity methods

Indicate the audio session ID when calling getInput(),
startInput(), stopInput(), releaseInput().

Bug: 12378680.
Change-Id: I763793752f93e2f4e1445a5ab217c895af011038
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0ef5bb8..2e2f533 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -5649,7 +5649,7 @@
         status_t status = NO_ERROR;
         if (recordTrack->isExternalTrack()) {
             mLock.unlock();
-            status = AudioSystem::startInput(mId);
+            status = AudioSystem::startInput(mId, (audio_session_t)recordTrack->sessionId());
             mLock.lock();
             // FIXME should verify that recordTrack is still in mActiveTracks
             if (status != NO_ERROR) {
@@ -5684,7 +5684,7 @@
 
 startError:
     if (recordTrack->isExternalTrack()) {
-        AudioSystem::stopInput(mId);
+        AudioSystem::stopInput(mId, (audio_session_t)recordTrack->sessionId());
     }
     recordTrack->clearSyncStartEvent();
     // FIXME I wonder why we do not reset the state here?
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index e81697f..48093da 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -2050,7 +2050,7 @@
     if (thread != 0) {
         RecordThread *recordThread = (RecordThread *)thread.get();
         if (recordThread->stop(this) && isExternalTrack()) {
-            AudioSystem::stopInput(recordThread->id());
+            AudioSystem::stopInput(recordThread->id(), (audio_session_t)mSessionId);
         }
     }
 }
@@ -2064,9 +2064,9 @@
         if (thread != 0) {
             if (isExternalTrack()) {
                 if (mState == ACTIVE || mState == RESUMING) {
-                    AudioSystem::stopInput(thread->id());
+                    AudioSystem::stopInput(thread->id(), (audio_session_t)mSessionId);
                 }
-                AudioSystem::releaseInput(thread->id());
+                AudioSystem::releaseInput(thread->id(), (audio_session_t)mSessionId);
             }
             Mutex::Autolock _l(thread->mLock);
             RecordThread *recordThread = (RecordThread *) thread.get();
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 749350a..50ee803 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -112,14 +112,17 @@
                                     uint32_t samplingRate,
                                     audio_format_t format,
                                     audio_channel_mask_t channelMask,
-                                    audio_in_acoustics_t acoustics,
+                                    audio_session_t session,
                                     audio_input_flags_t flags) = 0;
     // indicates to the audio policy manager that the input starts being used.
-    virtual status_t startInput(audio_io_handle_t input) = 0;
+    virtual status_t startInput(audio_io_handle_t input,
+                                audio_session_t session) = 0;
     // indicates to the audio policy manager that the input stops being used.
-    virtual status_t stopInput(audio_io_handle_t input) = 0;
+    virtual status_t stopInput(audio_io_handle_t input,
+                               audio_session_t session) = 0;
     // releases the input.
-    virtual void releaseInput(audio_io_handle_t input) = 0;
+    virtual void releaseInput(audio_io_handle_t input,
+                              audio_session_t session) = 0;
 
     //
     // volume control functions
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
index 4a55bec..75745b3 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
@@ -232,8 +232,8 @@
     Mutex::Autolock _l(mLock);
     // the audio_in_acoustics_t parameter is ignored by get_input()
     audio_io_handle_t input = mAudioPolicyManager->getInput(inputSource, samplingRate,
-                                                   format, channelMask, (audio_in_acoustics_t) 0,
-                                                   flags);
+                                                   format, channelMask,
+                                                   (audio_session_t)audioSession, flags);
 
     if (input == 0) {
         return input;
@@ -248,33 +248,36 @@
     return input;
 }
 
-status_t AudioPolicyService::startInput(audio_io_handle_t input)
+status_t AudioPolicyService::startInput(audio_io_handle_t input,
+                                        audio_session_t session)
 {
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     Mutex::Autolock _l(mLock);
 
-    return mAudioPolicyManager->startInput(input);
+    return mAudioPolicyManager->startInput(input, session);
 }
 
-status_t AudioPolicyService::stopInput(audio_io_handle_t input)
+status_t AudioPolicyService::stopInput(audio_io_handle_t input,
+                                       audio_session_t session)
 {
     if (mAudioPolicyManager == NULL) {
         return NO_INIT;
     }
     Mutex::Autolock _l(mLock);
 
-    return mAudioPolicyManager->stopInput(input);
+    return mAudioPolicyManager->stopInput(input, session);
 }
 
-void AudioPolicyService::releaseInput(audio_io_handle_t input)
+void AudioPolicyService::releaseInput(audio_io_handle_t input,
+                                      audio_session_t session)
 {
     if (mAudioPolicyManager == NULL) {
         return;
     }
     Mutex::Autolock _l(mLock);
-    mAudioPolicyManager->releaseInput(input);
+    mAudioPolicyManager->releaseInput(input, session);
 
     // release audio processors from the input
     status_t status = mAudioPolicyEffects->releaseInputEffects(input);
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index 5ef02e5..aa46ace 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -235,7 +235,8 @@
     return input;
 }
 
-status_t AudioPolicyService::startInput(audio_io_handle_t input)
+status_t AudioPolicyService::startInput(audio_io_handle_t input,
+                                        audio_session_t session __unused)
 {
     if (mpAudioPolicy == NULL) {
         return NO_INIT;
@@ -245,7 +246,8 @@
     return mpAudioPolicy->start_input(mpAudioPolicy, input);
 }
 
-status_t AudioPolicyService::stopInput(audio_io_handle_t input)
+status_t AudioPolicyService::stopInput(audio_io_handle_t input,
+                                       audio_session_t session __unused)
 {
     if (mpAudioPolicy == NULL) {
         return NO_INIT;
@@ -255,7 +257,8 @@
     return mpAudioPolicy->stop_input(mpAudioPolicy, input);
 }
 
-void AudioPolicyService::releaseInput(audio_io_handle_t input)
+void AudioPolicyService::releaseInput(audio_io_handle_t input,
+                                      audio_session_t session __unused)
 {
     if (mpAudioPolicy == NULL) {
         return;
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 7fd9b3a..37f8513 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -1062,12 +1062,12 @@
                                     uint32_t samplingRate,
                                     audio_format_t format,
                                     audio_channel_mask_t channelMask,
-                                    audio_in_acoustics_t acoustics,
+                                    audio_session_t session,
                                     audio_input_flags_t flags)
 {
-    ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x, "
+    ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, session %d, "
           "flags %#x",
-          inputSource, samplingRate, format, channelMask, acoustics, flags);
+          inputSource, samplingRate, format, channelMask, session, flags);
 
     audio_devices_t device = getDeviceForInputSource(inputSource);
 
@@ -1142,13 +1142,15 @@
     inputDesc->mFormat = format;
     inputDesc->mChannelMask = channelMask;
     inputDesc->mDevice = device;
+    inputDesc->mSessions.add(session);
 
     addInput(input, inputDesc);
     mpClientInterface->onAudioPortListUpdate();
     return input;
 }
 
-status_t AudioPolicyManager::startInput(audio_io_handle_t input)
+status_t AudioPolicyManager::startInput(audio_io_handle_t input,
+                                        audio_session_t session)
 {
     ALOGV("startInput() input %d", input);
     ssize_t index = mInputs.indexOfKey(input);
@@ -1158,6 +1160,12 @@
     }
     sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
 
+    index = inputDesc->mSessions.indexOf(session);
+    if (index < 0) {
+        ALOGW("startInput() unknown session %d on input %d", session, input);
+        return BAD_VALUE;
+    }
+
     // virtual input devices are compatible with other input devices
     if (!isVirtualInputDevice(inputDesc->mDevice)) {
 
@@ -1170,8 +1178,8 @@
             sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
             if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
                 ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
-                stopInput(activeInput);
-                releaseInput(activeInput);
+                stopInput(activeInput, activeDesc->mSessions.itemAt(0));
+                releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
             } else {
                 ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
                 return INVALID_OPERATION;
@@ -1196,7 +1204,8 @@
     return NO_ERROR;
 }
 
-status_t AudioPolicyManager::stopInput(audio_io_handle_t input)
+status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
+                                       audio_session_t session)
 {
     ALOGV("stopInput() input %d", input);
     ssize_t index = mInputs.indexOfKey(input);
@@ -1206,6 +1215,12 @@
     }
     sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
 
+    index = inputDesc->mSessions.indexOf(session);
+    if (index < 0) {
+        ALOGW("stopInput() unknown session %d on input %d", session, input);
+        return BAD_VALUE;
+    }
+
     if (inputDesc->mRefCount == 0) {
         ALOGW("stopInput() input %d already stopped", input);
         return INVALID_OPERATION;
@@ -1225,7 +1240,8 @@
     return NO_ERROR;
 }
 
-void AudioPolicyManager::releaseInput(audio_io_handle_t input)
+void AudioPolicyManager::releaseInput(audio_io_handle_t input,
+                                      audio_session_t session)
 {
     ALOGV("releaseInput() %d", input);
     ssize_t index = mInputs.indexOfKey(input);
@@ -1235,6 +1251,13 @@
     }
     sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
     ALOG_ASSERT(inputDesc != 0);
+
+    index = inputDesc->mSessions.indexOf(session);
+    if (index < 0) {
+        ALOGW("releaseInput() unknown session %d on input %d", session, input);
+        return;
+    }
+    inputDesc->mSessions.remove(session);
     if (inputDesc->mOpenRefCount == 0) {
         ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount);
         return;
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index cb4b056..ec94144 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -107,15 +107,18 @@
                                             uint32_t samplingRate,
                                             audio_format_t format,
                                             audio_channel_mask_t channelMask,
-                                            audio_in_acoustics_t acoustics,
+                                            audio_session_t session,
                                             audio_input_flags_t flags);
 
         // indicates to the audio policy manager that the input starts being used.
-        virtual status_t startInput(audio_io_handle_t input);
+        virtual status_t startInput(audio_io_handle_t input,
+                                    audio_session_t session);
 
         // indicates to the audio policy manager that the input stops being used.
-        virtual status_t stopInput(audio_io_handle_t input);
-        virtual void releaseInput(audio_io_handle_t input);
+        virtual status_t stopInput(audio_io_handle_t input,
+                                   audio_session_t session);
+        virtual void releaseInput(audio_io_handle_t input,
+                                  audio_session_t session);
         virtual void closeAllInputs();
         virtual void initStreamVolume(audio_stream_type_t stream,
                                                     int indexMin,
@@ -485,6 +488,7 @@
             uint32_t mOpenRefCount;
             audio_source_t mInputSource;                // input source selected by application (mediarecorder.h)
             const sp<IOProfile> mProfile;                  // I/O profile this output derives from
+            SortedVector<audio_session_t> mSessions;  // audio sessions attached to this input
 
             virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
                                    const struct audio_port_config *srcConfig = NULL) const;
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index 3769aab..97236e3 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -91,9 +91,12 @@
                                     audio_channel_mask_t channelMask,
                                     int audioSession,
                                     audio_input_flags_t flags);
-    virtual status_t startInput(audio_io_handle_t input);
-    virtual status_t stopInput(audio_io_handle_t input);
-    virtual void releaseInput(audio_io_handle_t input);
+    virtual status_t startInput(audio_io_handle_t input,
+                                audio_session_t session);
+    virtual status_t stopInput(audio_io_handle_t input,
+                               audio_session_t session);
+    virtual void releaseInput(audio_io_handle_t input,
+                              audio_session_t session);
     virtual status_t initStreamVolume(audio_stream_type_t stream,
                                       int indexMin,
                                       int indexMax);