Loading services/audioflinger/AudioFlinger.cpp +19 −17 Original line number Diff line number Diff line Loading @@ -1102,8 +1102,9 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input, // move effect chain to this output thread if an effect on same session was waiting // for a track to be created if (effectThread != nullptr) { audio_utils::lock_guard _sl(effectThread->mutex()); if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) { // No thread safety analysis: double lock on a thread capability. audio_utils::lock_guard_no_thread_safety_analysis _sl(effectThread->mutex()); if (moveEffectChain_ll(sessionId, effectThread, thread) == NO_ERROR) { effectThreadId = thread->id(); effectIds = thread->getEffectIds_l(sessionId); } Loading Loading @@ -3034,7 +3035,7 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) audio_utils::scoped_lock sl(dstThread->mutex(), playbackThread->mutex()); Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l(); for (size_t i = 0; i < effectChains.size(); i ++) { moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(), moveEffectChain_ll(effectChains[i]->sessionId(), playbackThread.get(), dstThread); } } Loading Loading @@ -4298,7 +4299,7 @@ status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t } audio_utils::scoped_lock _ll(dstThread->mutex(), srcThread->mutex()); return moveEffectChain_l(sessionId, srcThread, dstThread); return moveEffectChain_ll(sessionId, srcThread, dstThread); } Loading @@ -4318,25 +4319,26 @@ void AudioFlinger::setEffectSuspended(int effectId, } // moveEffectChain_l must be called with both srcThread and dstThread mutex()s held status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, // moveEffectChain_ll must be called with the AudioFlinger::mutex() // and both srcThread and dstThread mutex()s held status_t AudioFlinger::moveEffectChain_ll(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) { ALOGV("moveEffectChain_l() session %d from thread %p to thread %p", sessionId, srcThread, dstThread); ALOGV("%s: session %d from thread %p to thread %p", __func__, sessionId, srcThread, dstThread); sp<IAfEffectChain> chain = srcThread->getEffectChain_l(sessionId); if (chain == 0) { ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p", sessionId, srcThread); ALOGW("%s: effect chain for session %d not on source thread %p", __func__, sessionId, srcThread); return INVALID_OPERATION; } // Check whether the destination thread and all effects in the chain are compatible if (!chain->isCompatibleWithThread_l(dstThread)) { ALOGW("moveEffectChain_l() effect chain failed because" ALOGW("%s: effect chain failed because" " destination thread %p is not compatible with effects in the chain", dstThread); __func__, dstThread); return INVALID_OPERATION; } Loading @@ -4358,7 +4360,7 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, effect = chain->getEffectFromId_l(0)) { srcThread->removeEffect_l(effect); removed.add(effect); status = dstThread->addEffect_l(effect); status = dstThread->addEffect_ll(effect); if (status != NO_ERROR) { errorString = StringPrintf( "cannot add effect %p to destination thread", effect.get()); Loading @@ -4384,7 +4386,7 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, for (const auto& effect : removed) { dstThread->removeEffect_l(effect); // Note: Depending on error location, the last // effect may not have been placed on dstThread. if (srcThread->addEffect_l(effect) == NO_ERROR) { if (srcThread->addEffect_ll(effect) == NO_ERROR) { ++restored; if (dstChain == nullptr) { dstChain = effect->getCallback()->chain().promote(); Loading Loading @@ -4449,16 +4451,16 @@ status_t AudioFlinger::moveAuxEffectToIo(int EffectId, return INVALID_OPERATION; } thread->removeEffect_l(effect); status = dstThread->addEffect_l(effect); status = dstThread->addEffect_ll(effect); if (status != NO_ERROR) { thread->addEffect_l(effect); thread->addEffect_ll(effect); status = INVALID_OPERATION; goto Exit; } dstChain = effect->getCallback()->chain().promote(); if (dstChain == 0) { thread->addEffect_l(effect); thread->addEffect_ll(effect); status = INVALID_OPERATION; } Loading services/audioflinger/AudioFlinger.h +3 −2 Original line number Diff line number Diff line Loading @@ -367,8 +367,9 @@ private: bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final EXCLUDES_AudioFlinger_Mutex; status_t moveEffectChain_l(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final REQUIRES(mutex()); status_t moveEffectChain_ll(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final REQUIRES(mutex(), audio_utils::ThreadBase_Mutex); // This is a helper that is called during incoming binder calls. // Requests media.log to start merging log buffers Loading services/audioflinger/Effects.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -3338,7 +3338,10 @@ status_t DeviceEffectProxy::onCreatePatch( } status_t DeviceEffectProxy::checkPort(const IAfPatchPanel::Patch& patch, const struct audio_port_config *port, sp<IAfEffectHandle> *handle) { const struct audio_port_config *port, sp<IAfEffectHandle> *handle) NO_THREAD_SAFETY_ANALYSIS // calling function 'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively { ALOGV("%s type %d device type %d address %s device ID %d patch.isSoftware() %d", __func__, port->type, port->ext.device.type, Loading services/audioflinger/IAfThread.h +41 −22 Original line number Diff line number Diff line Loading @@ -67,44 +67,56 @@ struct stream_type_t { // and hence may be used by the Effect / Track framework. class IAfThreadCallback : public virtual RefBase { public: virtual audio_utils::mutex& mutex() const = 0; virtual bool isNonOffloadableGlobalEffectEnabled_l() const = 0; // Tracks virtual audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0; virtual bool isNonOffloadableGlobalEffectEnabled_l() const REQUIRES(mutex()) = 0; // Tracks virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0; virtual bool btNrecIsOff() const = 0; virtual float masterVolume_l() const = 0; virtual bool masterMute_l() const = 0; virtual float getMasterBalance_l() const = 0; virtual bool streamMute_l(audio_stream_type_t stream) const = 0; virtual float masterVolume_l() const REQUIRES(mutex()) = 0; virtual bool masterMute_l() const REQUIRES(mutex()) = 0; virtual float getMasterBalance_l() const REQUIRES(mutex()) = 0; virtual bool streamMute_l(audio_stream_type_t stream) const REQUIRES(mutex()) = 0; virtual audio_mode_t getMode() const = 0; virtual bool isLowRamDevice() const = 0; virtual bool isAudioPolicyReady() const = 0; // Effects virtual uint32_t getScreenState() const = 0; virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const = 0; virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const REQUIRES(mutex()) = 0; virtual const sp<IAfPatchPanel>& getPatchPanel() const = 0; virtual const sp<MelReporter>& getMelReporter() const = 0; virtual const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const = 0; virtual sp<IAudioManager> getOrCreateAudioManager() = 0; // Tracks virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) = 0; virtual status_t moveEffectChain_l(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) = 0; virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) EXCLUDES_AudioFlinger_Mutex = 0; virtual status_t moveEffectChain_ll(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) REQUIRES(mutex(), audio_utils::ThreadBase_Mutex) = 0; virtual void requestLogMerge() = 0; virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name) = 0; virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name) REQUIRES(mutex()) = 0; virtual void unregisterWriter(const sp<NBLog::Writer>& writer) = 0; virtual sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type, audio_session_t triggerSession, audio_session_t listenerSession, const audioflinger::SyncEventCallback& callBack, const wp<IAfTrackBase>& cookie) = 0; const wp<IAfTrackBase>& cookie) EXCLUDES_AudioFlinger_Mutex = 0; virtual void ioConfigChanged(audio_io_config_event_t event, const sp<AudioIoDescriptor>& ioDesc, pid_t pid = 0) = 0; virtual void onNonOffloadableGlobalEffectEnable() = 0; pid_t pid = 0) EXCLUDES_AudioFlinger_ClientMutex = 0; virtual void onNonOffloadableGlobalEffectEnable() EXCLUDES_AudioFlinger_Mutex = 0; virtual void onSupportedLatencyModesChanged( audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) = 0; audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) EXCLUDES_AudioFlinger_ClientMutex = 0; }; class IAfThreadBase : public virtual RefBase { Loading Loading @@ -213,7 +225,8 @@ public: status_t* status /*non-NULL*/, bool pinned, bool probe, bool notifyFramesProcessed) = 0; bool notifyFramesProcessed) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; // return values for hasAudioSession (bit field) enum effect_state { Loading Loading @@ -255,7 +268,8 @@ public: // add and effect module. Also creates the effect chain is none exists for // the effects audio session. Only called in a context of moving an effect // from one thread to another virtual status_t addEffect_l(const sp<IAfEffectModule>& effect) = 0; virtual status_t addEffect_ll(const sp<IAfEffectModule>& effect) REQUIRES(audio_utils::AudioFlinger_Mutex, mutex()) = 0; // remove and effect module. Also removes the effect chain is this was the last // effect virtual void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) = 0; Loading Loading @@ -310,7 +324,8 @@ public: // deliver stats to mediametrics. virtual void sendStatistics(bool force) = 0; virtual audio_utils::mutex& mutex() const = 0; virtual audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) = 0; virtual void onEffectEnable(const sp<IAfEffectModule>& effect) = 0; virtual void onEffectDisable() = 0; Loading @@ -321,8 +336,10 @@ public: virtual void invalidateTracksForAudioSession(audio_session_t sessionId) const = 0; virtual bool isStreamInitialized() const = 0; virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) = 0; virtual void stopMelComputation_l() = 0; virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual void stopMelComputation_l() REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual product_strategy_t getStrategyForStream(audio_stream_type_t stream) const = 0; Loading Loading @@ -398,7 +415,8 @@ public: audio_port_handle_t portId, const sp<media::IAudioTrackCallback>& callback, bool isSpatialized, bool isBitPerfect) = 0; bool isBitPerfect) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual status_t addTrack_l(const sp<IAfTrack>& track) = 0; virtual bool destroyTrack_l(const sp<IAfTrack>& track) = 0; Loading Loading @@ -502,7 +520,8 @@ public: pid_t tid, status_t* status /*non-NULL*/, audio_port_handle_t portId, int32_t maxSharedAudioHistoryMs) = 0; int32_t maxSharedAudioHistoryMs) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual void destroyTrack_l(const sp<IAfRecordTrack>& track) = 0; virtual void removeTrack_l(const sp<IAfRecordTrack>& track) = 0; Loading services/audioflinger/Threads.cpp +119 −114 Original line number Diff line number Diff line Loading @@ -1794,9 +1794,9 @@ std::vector<int> ThreadBase::getEffectIds_l(audio_session_t sessionId) const return chain != nullptr ? chain->getEffectIds() : std::vector<int>{}; } // PlaybackThread::addEffect_l() must be called with AudioFlinger::mutex() and // PlaybackThread::mutex() held status_t ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect) // PlaybackThread::addEffect_ll() must be called with AudioFlinger::mutex() and // ThreadBase::mutex() held status_t ThreadBase::addEffect_ll(const sp<IAfEffectModule>& effect) { // check for existing effect chain with the requested audio session audio_session_t sessionId = effect->sessionId(); Loading @@ -1804,22 +1804,22 @@ status_t ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect) bool chainCreated = false; ALOGD_IF((mType == OFFLOAD) && !effect->isOffloadable(), "addEffect_l() on offloaded thread %p: effect %s does not support offload flags %#x", this, effect->desc().name, effect->desc().flags); "%s: on offloaded thread %p: effect %s does not support offload flags %#x", __func__, this, effect->desc().name, effect->desc().flags); if (chain == 0) { // create a new chain for this session ALOGV("addEffect_l() new effect chain for session %d", sessionId); ALOGV("%s: new effect chain for session %d", __func__, sessionId); chain = IAfEffectChain::create(this, sessionId); addEffectChain_l(chain); chain->setStrategy(getStrategyForSession_l(sessionId)); chainCreated = true; } ALOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get()); ALOGV("%s: %p chain %p effect %p", __func__, this, chain.get(), effect.get()); if (chain->getEffectFromId_l(effect->id()) != 0) { ALOGW("addEffect_l() %p effect %s already present in chain %p", this, effect->desc().name, chain.get()); ALOGW("%s: %p effect %s already present in chain %p", __func__, this, effect->desc().name, chain.get()); return BAD_VALUE; } Loading Loading @@ -3122,6 +3122,8 @@ void PlaybackThread::resetDraining(uint32_t sequence) } void PlaybackThread::readOutputParameters_l() NO_THREAD_SAFETY_ANALYSIS // 'moveEffectChain_ll' requires holding mutex 'AudioFlinger_Mutex' exclusively { // unfortunately we have no way of recovering from errors here, hence the LOG_ALWAYS_FATAL const audio_config_base_t audioConfig = mOutput->getAudioProperties(); Loading Loading @@ -3289,10 +3291,11 @@ void PlaybackThread::readOutputParameters_l() // Note that mutex() is not held when readOutputParameters_l() is called from the constructor // but in this case nothing is done below as no audio sessions have effect yet so it doesn't // matter. // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains // create a copy of mEffectChains as calling moveEffectChain_ll() // can reorder some effect chains Vector<sp<IAfEffectChain>> effectChains = mEffectChains; for (size_t i = 0; i < effectChains.size(); i ++) { mAfThreadCallback->moveEffectChain_l(effectChains[i]->sessionId(), mAfThreadCallback->moveEffectChain_ll(effectChains[i]->sessionId(), this/* srcThread */, this/* dstThread */); } Loading Loading @@ -7838,6 +7841,8 @@ status_t SpatializerThread::setRequestedLatencyMode(audio_latency_mode_t mode) { } void SpatializerThread::checkOutputStageEffects() NO_THREAD_SAFETY_ANALYSIS // 'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively { bool hasVirtualizer = false; bool hasDownMixer = false; Loading Loading
services/audioflinger/AudioFlinger.cpp +19 −17 Original line number Diff line number Diff line Loading @@ -1102,8 +1102,9 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input, // move effect chain to this output thread if an effect on same session was waiting // for a track to be created if (effectThread != nullptr) { audio_utils::lock_guard _sl(effectThread->mutex()); if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) { // No thread safety analysis: double lock on a thread capability. audio_utils::lock_guard_no_thread_safety_analysis _sl(effectThread->mutex()); if (moveEffectChain_ll(sessionId, effectThread, thread) == NO_ERROR) { effectThreadId = thread->id(); effectIds = thread->getEffectIds_l(sessionId); } Loading Loading @@ -3034,7 +3035,7 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output) audio_utils::scoped_lock sl(dstThread->mutex(), playbackThread->mutex()); Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l(); for (size_t i = 0; i < effectChains.size(); i ++) { moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(), moveEffectChain_ll(effectChains[i]->sessionId(), playbackThread.get(), dstThread); } } Loading Loading @@ -4298,7 +4299,7 @@ status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t } audio_utils::scoped_lock _ll(dstThread->mutex(), srcThread->mutex()); return moveEffectChain_l(sessionId, srcThread, dstThread); return moveEffectChain_ll(sessionId, srcThread, dstThread); } Loading @@ -4318,25 +4319,26 @@ void AudioFlinger::setEffectSuspended(int effectId, } // moveEffectChain_l must be called with both srcThread and dstThread mutex()s held status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, // moveEffectChain_ll must be called with the AudioFlinger::mutex() // and both srcThread and dstThread mutex()s held status_t AudioFlinger::moveEffectChain_ll(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) { ALOGV("moveEffectChain_l() session %d from thread %p to thread %p", sessionId, srcThread, dstThread); ALOGV("%s: session %d from thread %p to thread %p", __func__, sessionId, srcThread, dstThread); sp<IAfEffectChain> chain = srcThread->getEffectChain_l(sessionId); if (chain == 0) { ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p", sessionId, srcThread); ALOGW("%s: effect chain for session %d not on source thread %p", __func__, sessionId, srcThread); return INVALID_OPERATION; } // Check whether the destination thread and all effects in the chain are compatible if (!chain->isCompatibleWithThread_l(dstThread)) { ALOGW("moveEffectChain_l() effect chain failed because" ALOGW("%s: effect chain failed because" " destination thread %p is not compatible with effects in the chain", dstThread); __func__, dstThread); return INVALID_OPERATION; } Loading @@ -4358,7 +4360,7 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, effect = chain->getEffectFromId_l(0)) { srcThread->removeEffect_l(effect); removed.add(effect); status = dstThread->addEffect_l(effect); status = dstThread->addEffect_ll(effect); if (status != NO_ERROR) { errorString = StringPrintf( "cannot add effect %p to destination thread", effect.get()); Loading @@ -4384,7 +4386,7 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId, for (const auto& effect : removed) { dstThread->removeEffect_l(effect); // Note: Depending on error location, the last // effect may not have been placed on dstThread. if (srcThread->addEffect_l(effect) == NO_ERROR) { if (srcThread->addEffect_ll(effect) == NO_ERROR) { ++restored; if (dstChain == nullptr) { dstChain = effect->getCallback()->chain().promote(); Loading Loading @@ -4449,16 +4451,16 @@ status_t AudioFlinger::moveAuxEffectToIo(int EffectId, return INVALID_OPERATION; } thread->removeEffect_l(effect); status = dstThread->addEffect_l(effect); status = dstThread->addEffect_ll(effect); if (status != NO_ERROR) { thread->addEffect_l(effect); thread->addEffect_ll(effect); status = INVALID_OPERATION; goto Exit; } dstChain = effect->getCallback()->chain().promote(); if (dstChain == 0) { thread->addEffect_l(effect); thread->addEffect_ll(effect); status = INVALID_OPERATION; } Loading
services/audioflinger/AudioFlinger.h +3 −2 Original line number Diff line number Diff line Loading @@ -367,8 +367,9 @@ private: bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final EXCLUDES_AudioFlinger_Mutex; status_t moveEffectChain_l(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final REQUIRES(mutex()); status_t moveEffectChain_ll(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final REQUIRES(mutex(), audio_utils::ThreadBase_Mutex); // This is a helper that is called during incoming binder calls. // Requests media.log to start merging log buffers Loading
services/audioflinger/Effects.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -3338,7 +3338,10 @@ status_t DeviceEffectProxy::onCreatePatch( } status_t DeviceEffectProxy::checkPort(const IAfPatchPanel::Patch& patch, const struct audio_port_config *port, sp<IAfEffectHandle> *handle) { const struct audio_port_config *port, sp<IAfEffectHandle> *handle) NO_THREAD_SAFETY_ANALYSIS // calling function 'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively { ALOGV("%s type %d device type %d address %s device ID %d patch.isSoftware() %d", __func__, port->type, port->ext.device.type, Loading
services/audioflinger/IAfThread.h +41 −22 Original line number Diff line number Diff line Loading @@ -67,44 +67,56 @@ struct stream_type_t { // and hence may be used by the Effect / Track framework. class IAfThreadCallback : public virtual RefBase { public: virtual audio_utils::mutex& mutex() const = 0; virtual bool isNonOffloadableGlobalEffectEnabled_l() const = 0; // Tracks virtual audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0; virtual bool isNonOffloadableGlobalEffectEnabled_l() const REQUIRES(mutex()) = 0; // Tracks virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0; virtual bool btNrecIsOff() const = 0; virtual float masterVolume_l() const = 0; virtual bool masterMute_l() const = 0; virtual float getMasterBalance_l() const = 0; virtual bool streamMute_l(audio_stream_type_t stream) const = 0; virtual float masterVolume_l() const REQUIRES(mutex()) = 0; virtual bool masterMute_l() const REQUIRES(mutex()) = 0; virtual float getMasterBalance_l() const REQUIRES(mutex()) = 0; virtual bool streamMute_l(audio_stream_type_t stream) const REQUIRES(mutex()) = 0; virtual audio_mode_t getMode() const = 0; virtual bool isLowRamDevice() const = 0; virtual bool isAudioPolicyReady() const = 0; // Effects virtual uint32_t getScreenState() const = 0; virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const = 0; virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const REQUIRES(mutex()) = 0; virtual const sp<IAfPatchPanel>& getPatchPanel() const = 0; virtual const sp<MelReporter>& getMelReporter() const = 0; virtual const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const = 0; virtual sp<IAudioManager> getOrCreateAudioManager() = 0; // Tracks virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) = 0; virtual status_t moveEffectChain_l(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) = 0; virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) EXCLUDES_AudioFlinger_Mutex = 0; virtual status_t moveEffectChain_ll(audio_session_t sessionId, IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) REQUIRES(mutex(), audio_utils::ThreadBase_Mutex) = 0; virtual void requestLogMerge() = 0; virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name) = 0; virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name) REQUIRES(mutex()) = 0; virtual void unregisterWriter(const sp<NBLog::Writer>& writer) = 0; virtual sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type, audio_session_t triggerSession, audio_session_t listenerSession, const audioflinger::SyncEventCallback& callBack, const wp<IAfTrackBase>& cookie) = 0; const wp<IAfTrackBase>& cookie) EXCLUDES_AudioFlinger_Mutex = 0; virtual void ioConfigChanged(audio_io_config_event_t event, const sp<AudioIoDescriptor>& ioDesc, pid_t pid = 0) = 0; virtual void onNonOffloadableGlobalEffectEnable() = 0; pid_t pid = 0) EXCLUDES_AudioFlinger_ClientMutex = 0; virtual void onNonOffloadableGlobalEffectEnable() EXCLUDES_AudioFlinger_Mutex = 0; virtual void onSupportedLatencyModesChanged( audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) = 0; audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) EXCLUDES_AudioFlinger_ClientMutex = 0; }; class IAfThreadBase : public virtual RefBase { Loading Loading @@ -213,7 +225,8 @@ public: status_t* status /*non-NULL*/, bool pinned, bool probe, bool notifyFramesProcessed) = 0; bool notifyFramesProcessed) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; // return values for hasAudioSession (bit field) enum effect_state { Loading Loading @@ -255,7 +268,8 @@ public: // add and effect module. Also creates the effect chain is none exists for // the effects audio session. Only called in a context of moving an effect // from one thread to another virtual status_t addEffect_l(const sp<IAfEffectModule>& effect) = 0; virtual status_t addEffect_ll(const sp<IAfEffectModule>& effect) REQUIRES(audio_utils::AudioFlinger_Mutex, mutex()) = 0; // remove and effect module. Also removes the effect chain is this was the last // effect virtual void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) = 0; Loading Loading @@ -310,7 +324,8 @@ public: // deliver stats to mediametrics. virtual void sendStatistics(bool force) = 0; virtual audio_utils::mutex& mutex() const = 0; virtual audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) = 0; virtual void onEffectEnable(const sp<IAfEffectModule>& effect) = 0; virtual void onEffectDisable() = 0; Loading @@ -321,8 +336,10 @@ public: virtual void invalidateTracksForAudioSession(audio_session_t sessionId) const = 0; virtual bool isStreamInitialized() const = 0; virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) = 0; virtual void stopMelComputation_l() = 0; virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual void stopMelComputation_l() REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual product_strategy_t getStrategyForStream(audio_stream_type_t stream) const = 0; Loading Loading @@ -398,7 +415,8 @@ public: audio_port_handle_t portId, const sp<media::IAudioTrackCallback>& callback, bool isSpatialized, bool isBitPerfect) = 0; bool isBitPerfect) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual status_t addTrack_l(const sp<IAfTrack>& track) = 0; virtual bool destroyTrack_l(const sp<IAfTrack>& track) = 0; Loading Loading @@ -502,7 +520,8 @@ public: pid_t tid, status_t* status /*non-NULL*/, audio_port_handle_t portId, int32_t maxSharedAudioHistoryMs) = 0; int32_t maxSharedAudioHistoryMs) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; virtual void destroyTrack_l(const sp<IAfRecordTrack>& track) = 0; virtual void removeTrack_l(const sp<IAfRecordTrack>& track) = 0; Loading
services/audioflinger/Threads.cpp +119 −114 Original line number Diff line number Diff line Loading @@ -1794,9 +1794,9 @@ std::vector<int> ThreadBase::getEffectIds_l(audio_session_t sessionId) const return chain != nullptr ? chain->getEffectIds() : std::vector<int>{}; } // PlaybackThread::addEffect_l() must be called with AudioFlinger::mutex() and // PlaybackThread::mutex() held status_t ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect) // PlaybackThread::addEffect_ll() must be called with AudioFlinger::mutex() and // ThreadBase::mutex() held status_t ThreadBase::addEffect_ll(const sp<IAfEffectModule>& effect) { // check for existing effect chain with the requested audio session audio_session_t sessionId = effect->sessionId(); Loading @@ -1804,22 +1804,22 @@ status_t ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect) bool chainCreated = false; ALOGD_IF((mType == OFFLOAD) && !effect->isOffloadable(), "addEffect_l() on offloaded thread %p: effect %s does not support offload flags %#x", this, effect->desc().name, effect->desc().flags); "%s: on offloaded thread %p: effect %s does not support offload flags %#x", __func__, this, effect->desc().name, effect->desc().flags); if (chain == 0) { // create a new chain for this session ALOGV("addEffect_l() new effect chain for session %d", sessionId); ALOGV("%s: new effect chain for session %d", __func__, sessionId); chain = IAfEffectChain::create(this, sessionId); addEffectChain_l(chain); chain->setStrategy(getStrategyForSession_l(sessionId)); chainCreated = true; } ALOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get()); ALOGV("%s: %p chain %p effect %p", __func__, this, chain.get(), effect.get()); if (chain->getEffectFromId_l(effect->id()) != 0) { ALOGW("addEffect_l() %p effect %s already present in chain %p", this, effect->desc().name, chain.get()); ALOGW("%s: %p effect %s already present in chain %p", __func__, this, effect->desc().name, chain.get()); return BAD_VALUE; } Loading Loading @@ -3122,6 +3122,8 @@ void PlaybackThread::resetDraining(uint32_t sequence) } void PlaybackThread::readOutputParameters_l() NO_THREAD_SAFETY_ANALYSIS // 'moveEffectChain_ll' requires holding mutex 'AudioFlinger_Mutex' exclusively { // unfortunately we have no way of recovering from errors here, hence the LOG_ALWAYS_FATAL const audio_config_base_t audioConfig = mOutput->getAudioProperties(); Loading Loading @@ -3289,10 +3291,11 @@ void PlaybackThread::readOutputParameters_l() // Note that mutex() is not held when readOutputParameters_l() is called from the constructor // but in this case nothing is done below as no audio sessions have effect yet so it doesn't // matter. // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains // create a copy of mEffectChains as calling moveEffectChain_ll() // can reorder some effect chains Vector<sp<IAfEffectChain>> effectChains = mEffectChains; for (size_t i = 0; i < effectChains.size(); i ++) { mAfThreadCallback->moveEffectChain_l(effectChains[i]->sessionId(), mAfThreadCallback->moveEffectChain_ll(effectChains[i]->sessionId(), this/* srcThread */, this/* dstThread */); } Loading Loading @@ -7838,6 +7841,8 @@ status_t SpatializerThread::setRequestedLatencyMode(audio_latency_mode_t mode) { } void SpatializerThread::checkOutputStageEffects() NO_THREAD_SAFETY_ANALYSIS // 'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively { bool hasVirtualizer = false; bool hasDownMixer = false; Loading