audio policy: concurrent capture

Implement concurrent capture in audio policy manager:
- Attach AudioRecord client to already opened input when possible
instead of systematically opening a new input for each client.
- Always allow inputs to start even in case of concurrency.
- Clients are selectively silenced based on their app state by audio
policy service.
- In case of concurrency on a given input stream, device and source is
chosen based app states and source priority.

Bug: 111438757
Test: Manual capture tests with solotester and Camera, Assistant and Duo
Test: CTS tests for AudioRecord

Change-Id: I302710ff545f67361d9aca89e81de40771ce7fb0
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 45d3a06..e70e567 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7367,8 +7367,7 @@
         status_t status = NO_ERROR;
         if (recordTrack->isExternalTrack()) {
             mLock.unlock();
-            bool silenced;
-            status = AudioSystem::startInput(recordTrack->portId(), &silenced);
+            status = AudioSystem::startInput(recordTrack->portId());
             mLock.lock();
             if (recordTrack->isInvalid()) {
                 recordTrack->clearSyncStartEvent();
@@ -7396,7 +7395,6 @@
                 recordTrack->clearSyncStartEvent();
                 return status;
             }
-            recordTrack->setSilenced(silenced);
         }
         // Catch up with current buffer indices if thread is already running.
         // This is what makes a new client discard all buffered data.  If the track's mRsmpInFront
@@ -8346,11 +8344,10 @@
         return BAD_VALUE;
     }
 
-    bool silenced = false;
     if (isOutput()) {
         ret = AudioSystem::startOutput(portId);
     } else {
-        ret = AudioSystem::startInput(portId, &silenced);
+        ret = AudioSystem::startInput(portId);
     }
 
     Mutex::Autolock _l(mLock);
@@ -8371,21 +8368,21 @@
         return PERMISSION_DENIED;
     }
 
-    if (isOutput()) {
-        // force volume update when a new track is added
-        mHalVolFloat = -1.0f;
-    } else if (!silenced) {
-        for (const sp<MmapTrack> &track : mActiveTracks) {
-            if (track->isSilenced_l() && track->uid() != client.clientUid)
-                track->invalidate();
-        }
-    }
-
     // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
     sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
                                         isOutput(), client.clientUid, client.clientPid, portId);
 
-    track->setSilenced_l(silenced);
+    if (isOutput()) {
+        // force volume update when a new track is added
+        mHalVolFloat = -1.0f;
+    } else if (!track->isSilenced_l()) {
+        for (const sp<MmapTrack> &t : mActiveTracks) {
+            if (t->isSilenced_l() && t->uid() != client.clientUid)
+                t->invalidate();
+        }
+    }
+
+
     mActiveTracks.add(track);
     sp<EffectChain> chain = getEffectChain_l(mSessionId);
     if (chain != 0) {