summaryrefslogtreecommitdiffstats
path: root/services/audiopolicy/managerdefault
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-09-18 18:32:07 -0700
committerEric Laurent <elaurent@google.com>2015-09-22 01:07:14 +0000
commit64265b2fb8f5be63b6c2ad4fcbec9acf74705bc4 (patch)
treea92838f2510034b35b41e78a71bb6385d6f7b557 /services/audiopolicy/managerdefault
parent6fe78a875793188ff80512db247312109038f181 (diff)
downloadframeworks_av-64265b2fb8f5be63b6c2ad4fcbec9acf74705bc4.zip
frameworks_av-64265b2fb8f5be63b6c2ad4fcbec9acf74705bc4.tar.gz
frameworks_av-64265b2fb8f5be63b6c2ad4fcbec9acf74705bc4.tar.bz2
audio policy: fix preemtible capture race
Because a preemtible capture session can preempt another one, we end up in an endless loop situation were each session is allowed to restart after being preempted, thus preempting the other one which restarts and so on. To avoid this situation, we store which audio session was preempted when a particular input started and prevent preemption of this active input by this session. We also inherit sessions from the preempted input to avoid a 3 way preemption loop etc... Bug: 24007220. Change-Id: I0eab5299440ef3ab9e987635dc9a300cf42f2c79
Diffstat (limited to 'services/audiopolicy/managerdefault')
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index dfb477d..8419ed5 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1485,10 +1485,15 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
// If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
// otherwise the active input continues and the new input cannot be started.
sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
- if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
+ if ((activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) &&
+ !activeDesc->hasPreemptedSession(session)) {
ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
- stopInput(activeInput, activeDesc->mSessions.itemAt(0));
- releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
+ audio_session_t activeSession = activeDesc->mSessions.itemAt(0);
+ SortedVector<audio_session_t> sessions = activeDesc->getPreemptedSessions();
+ sessions.add(activeSession);
+ inputDesc->setPreemptedSessions(sessions);
+ stopInput(activeInput, activeSession);
+ releaseInput(activeInput, activeSession);
} else {
ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
return INVALID_OPERATION;
@@ -1592,6 +1597,7 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
if (mInputs.activeInputsCount() == 0) {
SoundTrigger::setCaptureState(false);
}
+ inputDesc->clearPreemptedSessions();
}
return NO_ERROR;
}