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) {