Loading services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h +12 −0 Original line number Diff line number Diff line Loading @@ -56,9 +56,21 @@ public: const struct audio_port_config *srcConfig = NULL) const; virtual sp<AudioPort> getAudioPort() const { return mProfile; } void toAudioPort(struct audio_port *port) const; void setPreemptedSessions(const SortedVector<audio_session_t>& sessions); SortedVector<audio_session_t> getPreemptedSessions() const; bool hasPreemptedSession(audio_session_t session) const; void clearPreemptedSessions(); private: audio_port_handle_t mId; // 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... SortedVector<audio_session_t> mPreemptedSessions; }; class AudioInputCollection : Loading services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,26 @@ void AudioInputDescriptor::toAudioPort(struct audio_port *port) const port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL; } void AudioInputDescriptor::setPreemptedSessions(const SortedVector<audio_session_t>& sessions) { mPreemptedSessions = sessions; } SortedVector<audio_session_t> AudioInputDescriptor::getPreemptedSessions() const { return mPreemptedSessions; } bool AudioInputDescriptor::hasPreemptedSession(audio_session_t session) const { return (mPreemptedSessions.indexOf(session) >= 0); } void AudioInputDescriptor::clearPreemptedSessions() { mPreemptedSessions.clear(); } status_t AudioInputDescriptor::dump(int fd) { const size_t SIZE = 256; Loading services/audiopolicy/managerdefault/AudioPolicyManager.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading
services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h +12 −0 Original line number Diff line number Diff line Loading @@ -56,9 +56,21 @@ public: const struct audio_port_config *srcConfig = NULL) const; virtual sp<AudioPort> getAudioPort() const { return mProfile; } void toAudioPort(struct audio_port *port) const; void setPreemptedSessions(const SortedVector<audio_session_t>& sessions); SortedVector<audio_session_t> getPreemptedSessions() const; bool hasPreemptedSession(audio_session_t session) const; void clearPreemptedSessions(); private: audio_port_handle_t mId; // 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... SortedVector<audio_session_t> mPreemptedSessions; }; class AudioInputCollection : Loading
services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,26 @@ void AudioInputDescriptor::toAudioPort(struct audio_port *port) const port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL; } void AudioInputDescriptor::setPreemptedSessions(const SortedVector<audio_session_t>& sessions) { mPreemptedSessions = sessions; } SortedVector<audio_session_t> AudioInputDescriptor::getPreemptedSessions() const { return mPreemptedSessions; } bool AudioInputDescriptor::hasPreemptedSession(audio_session_t session) const { return (mPreemptedSessions.indexOf(session) >= 0); } void AudioInputDescriptor::clearPreemptedSessions() { mPreemptedSessions.clear(); } status_t AudioInputDescriptor::dump(int fd) { const size_t SIZE = 256; Loading
services/audiopolicy/managerdefault/AudioPolicyManager.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading