Loading services/audioflinger/AudioFlinger.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -3625,13 +3625,13 @@ status_t AudioFlinger::invalidateTracks(const std::vector<audio_port_handle_t> & std::set<audio_port_handle_t> portIdSet(portIds.begin(), portIds.end()); for (size_t i = 0; i < mPlaybackThreads.size(); i++) { IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get(); thread->invalidateTracks(portIdSet); thread->invalidateTracks(&portIdSet); if (portIdSet.empty()) { return NO_ERROR; } } for (size_t i = 0; i < mMmapThreads.size(); i++) { mMmapThreads[i]->invalidateTracks(portIdSet); mMmapThreads[i]->invalidateTracks(&portIdSet); if (portIdSet.empty()) { return NO_ERROR; } Loading Loading @@ -5043,7 +5043,9 @@ void AudioFlinger::onNonOffloadableGlobalEffectEnable() for (size_t i = 0; i < mPlaybackThreads.size(); i++) { const sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i); if (t->type() == IAfThreadBase::OFFLOAD) { t->invalidateTracks(AUDIO_STREAM_MUSIC); // we could invalidate based on session id, but offload threads // are based on single client access, so we invalidate everything. t->invalidateTracks(); } } Loading services/audioflinger/IAfThread.h +10 −17 Original line number Diff line number Diff line Loading @@ -418,6 +418,16 @@ public: virtual std::vector<sp<IAfTrackBase>> getTracks_l() REQUIRES(mutex()) = 0; // Invalidate tracks by a set of port ids. The port id will be removed from // the given set if the corresponding track is found and invalidated. // // If portIds == nullptr, all tracks, including internal tracks are invalidated. virtual bool invalidateTracks_l(std::set<audio_port_handle_t>* portIds = {}) REQUIRES(mutex()) = 0; virtual bool invalidateTracks(std::set<audio_port_handle_t>* portIds = {}) EXCLUDES_ThreadBase_Mutex = 0; virtual status_t setPortsVolume(const std::vector<audio_port_handle_t> &portIds, float volume, bool muted) EXCLUDES_ThreadBase_Mutex = 0; Loading Loading @@ -520,16 +530,6 @@ public: virtual status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId) REQUIRES(mutex()) = 0; // called with AudioFlinger lock held virtual bool invalidateTracks_l(audio_stream_type_t streamType) REQUIRES(mutex()) = 0; virtual bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) REQUIRES(mutex()) = 0; virtual void invalidateTracks(audio_stream_type_t streamType) EXCLUDES_ThreadBase_Mutex = 0; // Invalidate tracks by a set of port ids. The port id will be removed from // the given set if the corresponding track is found and invalidated. virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) EXCLUDES_ThreadBase_Mutex = 0; virtual status_t getTimestamp_l(AudioTimestamp& timestamp) REQUIRES(mutex()) = 0; virtual void addPatchTrack(const sp<IAfPatchTrack>& track) EXCLUDES_ThreadBase_Mutex = 0; virtual void deletePatchTrack(const sp<IAfPatchTrack>& track) EXCLUDES_ThreadBase_Mutex = 0; Loading Loading @@ -691,13 +691,6 @@ public: virtual status_t reportData(const void* buffer, size_t frameCount) EXCLUDES_ThreadBase_Mutex = 0; // TODO(b/291317898) move to IAfThreadBase? virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) EXCLUDES_ThreadBase_Mutex = 0; virtual void invalidateTracks(audio_stream_type_t streamType) EXCLUDES_ThreadBase_Mutex = 0; // Sets the UID records silence - TODO(b/291317898) move to IAfMmapCaptureThread virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced) EXCLUDES_ThreadBase_Mutex = 0; Loading services/audioflinger/Threads.cpp +60 −101 Original line number Diff line number Diff line Loading @@ -1793,7 +1793,7 @@ void ThreadBase::onEffectEnable(const sp<IAfEffectModule>& effect) { if (!effect->isOffloadable()) { if (mType == ThreadBase::OFFLOAD) { PlaybackThread *t = (PlaybackThread *)this; t->invalidateTracks(AUDIO_STREAM_MUSIC); t->invalidateTracks(); } if (effect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) { mAfThreadCallback->onNonOffloadableGlobalEffectEnable(); Loading Loading @@ -2165,6 +2165,48 @@ void ThreadBase::stopMelComputation_l() ALOGW("%s: ThreadBase does not support CSD", __func__); } std::set<audio_port_handle_t> ThreadBase::getTrackPortIds_l() const { std::set<int32_t> result; for (const auto& t : mTracks) { if (t->isExternalTrack()) { result.insert(t->portId()); } } return result; } std::set<audio_port_handle_t> ThreadBase::getTrackPortIds() const { audio_utils::lock_guard _l(mutex()); return getTrackPortIds_l(); } bool ThreadBase::invalidateTracks(std::set<audio_port_handle_t>* portIds) { audio_utils::lock_guard _l(mutex()); return invalidateTracks_l(portIds); } // Only Playback Threads invalidate tracks based on portIds, but we keep // open the possibility that Record / Capture Threads may eventually use it. bool ThreadBase::invalidateTracks_l(std::set<audio_port_handle_t>* portIds) { bool trackMatch = false; for (const auto& t : mTracks) { if (portIds == nullptr || (t->isExternalTrack() && portIds->find(t->portId()) != portIds->end())) { t->invalidate(); if (portIds) portIds->erase(t->portId()); trackMatch = true; } } // TODO(b/410038399) consider to apply to all threads for symmetry. if (trackMatch && (type() == MMAP_PLAYBACK || type() == MMAP_CAPTURE)) { broadcast_l(); } return trackMatch; } status_t ThreadBase::setPortsVolume( const std::vector<audio_port_handle_t>& portIds, float volume, bool muted) { audio_utils::lock_guard _l(mutex()); Loading Loading @@ -3072,23 +3114,6 @@ void PlaybackThread::removeTrack_l(const sp<IAfTrack>& track) } } std::set<audio_port_handle_t> PlaybackThread::getTrackPortIds_l() { std::set<int32_t> result; for (const auto& t : mTracks) { if (t->isExternalTrack()) { result.insert(t->portId()); } } return result; } std::set<audio_port_handle_t> PlaybackThread::getTrackPortIds() { audio_utils::lock_guard _l(mutex()); return getTrackPortIds_l(); } String8 PlaybackThread::getParameters(const String8& keys) { audio_utils::lock_guard _l(mutex()); Loading Loading @@ -3728,46 +3753,6 @@ void PlaybackThread::cacheParameters_l() } } bool PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType) { ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %zu", this, streamType, mTracks.size()); bool trackMatch = false; for (const auto& t : mPlaybackTracksView) { if (t->streamType() == streamType && t->isExternalTrack()) { t->invalidate(); trackMatch = true; } } return trackMatch; } void PlaybackThread::invalidateTracks(audio_stream_type_t streamType) { audio_utils::lock_guard _l(mutex()); invalidateTracks_l(streamType); } void PlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) { audio_utils::lock_guard _l(mutex()); invalidateTracks_l(portIds); } bool PlaybackThread::invalidateTracks_l(std::set<audio_port_handle_t>& portIds) { bool trackMatch = false; for (const auto& t : mTracks) { if (t->isExternalTrack() && portIds.find(t->portId()) != portIds.end()) { t->invalidate(); portIds.erase(t->portId()); trackMatch = true; } if (portIds.empty()) { break; } } return trackMatch; } status_t PlaybackThread::addEffectChain_l(const sp<IAfEffectChain>& chain) { audio_session_t session = chain->sessionId(); Loading Loading @@ -5487,9 +5472,7 @@ void PlaybackThread::onAddNewTrack_l() void PlaybackThread::onAsyncError(bool isHardError) { auto allTrackPortIds = getTrackPortIds(); for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) { invalidateTracks((audio_stream_type_t)i); } invalidateTracks(); if (isHardError) { mAfThreadCallback->onHardError(allTrackPortIds); } Loading Loading @@ -7773,19 +7756,25 @@ void OffloadThread::flushHw_l() } } void OffloadThread::invalidateTracks(audio_stream_type_t streamType) { audio_utils::lock_guard _l(mutex()); if (PlaybackThread::invalidateTracks_l(streamType)) { mFlushPending = true; } } // TODO(b/410038399) move to base class and unify with Mmap implementation for clarity. void OffloadThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) { audio_utils::lock_guard _l(mutex()); if (PlaybackThread::invalidateTracks_l(portIds)) { bool OffloadThread::invalidateTracks_l(std::set<audio_port_handle_t>* portIds) { const bool trackMatch = ThreadBase::invalidateTracks_l(portIds); if (trackMatch) { // On invalidating an offload track, the IAudioTrack instance is // destroyed and the offload output is released. If it so happens // that APM::getOutputForAttr for the new IAudioTrack is called before // OffloadThread::prepareTracks_l checks and removes an invalid track, // the same output can get reused. // // The side effect of this is data present in HAL and below from before the // invalidate will be rendered before data from the new seek position // is rendered. This is unexpected. // // To fix this, set hint to issue flush when an offload track is invalidated. mFlushPending = true; } return trackMatch; } // ---------------------------------------------------------------------------- Loading Loading @@ -11343,36 +11332,6 @@ void MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted) } } void MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType) { audio_utils::lock_guard _l(mutex()); if (streamType == mStreamType) { for (const auto& track : mActiveTracks) { track->invalidate(); } broadcast_l(); } } void MmapPlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) { audio_utils::lock_guard _l(mutex()); bool trackMatch = false; for (const auto& track : mActiveTracks) { if (portIds.find(track->portId()) != portIds.end()) { track->invalidate(); trackMatch = true; portIds.erase(track->portId()); } if (portIds.empty()) { break; } } if (trackMatch) { broadcast_l(); } } void MmapPlaybackThread::processVolume_l() NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent { Loading services/audioflinger/Threads.h +13 −22 Original line number Diff line number Diff line Loading @@ -947,6 +947,18 @@ protected: std::vector<sp<IAfTrackBase>> getTracks_l() final REQUIRES(mutex()); std::set<audio_port_handle_t> getTrackPortIds_l() const REQUIRES(mutex()); std::set<audio_port_handle_t> getTrackPortIds() const EXCLUDES_ThreadBase_Mutex; // Invalidate tracks by a set of port ids. The port id will be removed from // the given set if the corresponding track is found and invalidated. // // If portIds == nullptr, all tracks, including internal tracks are invalidated. bool invalidateTracks_l(std::set<audio_port_handle_t>* portIds = {}) override REQUIRES(mutex()); bool invalidateTracks(std::set<audio_port_handle_t>* portIds = {}) override EXCLUDES_ThreadBase_Mutex; status_t setPortsVolume(const std::vector<audio_port_handle_t>& portIds, float volume, bool muted) final EXCLUDES_ThreadBase_Mutex; Loading Loading @@ -1172,17 +1184,6 @@ public: // could be static. bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const final; // Does this require the AudioFlinger mutex as well? bool invalidateTracks_l(audio_stream_type_t streamType) final REQUIRES(mutex()); bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) final REQUIRES(mutex()); void invalidateTracks(audio_stream_type_t streamType) override; // Invalidate tracks by a set of port ids. The port id will be removed from // the given set if the corresponding track is found and invalidated. void invalidateTracks(std::set<audio_port_handle_t>& portIds) override EXCLUDES_ThreadBase_Mutex; size_t frameCount() const final { return mNormalFrameCount; } audio_channel_mask_t mixerChannelMask() const final { Loading Loading @@ -1468,8 +1469,6 @@ protected: bool destroyTrack_l(const sp<IAfTrack>& track) final REQUIRES(mutex()); void removeTrack_l(const sp<IAfTrack>& track) REQUIRES(mutex()); std::set<audio_port_handle_t> getTrackPortIds_l() REQUIRES(mutex()); std::set<audio_port_handle_t> getTrackPortIds(); void readOutputParameters_l() REQUIRES(mutex()); MetadataUpdate updateMetadata_l() final REQUIRES(mutex(), ThreadBase_ThreadLoop); Loading Loading @@ -1855,8 +1854,7 @@ protected: bool waitingAsyncCallback() final; bool waitingAsyncCallback_l() final REQUIRES(mutex()); void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex; void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex; bool invalidateTracks_l(std::set<audio_port_handle_t>* portIds) final REQUIRES(mutex()); bool keepWakeLock() const final { return (mKeepWakeLock || (mDrainSequence & 1)); } Loading Loading @@ -2342,10 +2340,6 @@ class MmapThread : public ThreadBase, public virtual IAfMmapThread virtual audio_stream_type_t streamType_l() const REQUIRES(mutex()) { return AUDIO_STREAM_DEFAULT; } virtual void invalidateTracks(audio_stream_type_t /* streamType */) EXCLUDES_ThreadBase_Mutex {} void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) override EXCLUDES_ThreadBase_Mutex {} // Sets the UID records silence void setRecordSilenced( Loading Loading @@ -2440,9 +2434,6 @@ public: void setMasterMute_l(bool muted) REQUIRES(mutex()) { mMasterMute = muted; } void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex; void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex; audio_stream_type_t streamType_l() const final REQUIRES(mutex()) { return mStreamType; } Loading Loading
services/audioflinger/AudioFlinger.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -3625,13 +3625,13 @@ status_t AudioFlinger::invalidateTracks(const std::vector<audio_port_handle_t> & std::set<audio_port_handle_t> portIdSet(portIds.begin(), portIds.end()); for (size_t i = 0; i < mPlaybackThreads.size(); i++) { IAfPlaybackThread* const thread = mPlaybackThreads.valueAt(i).get(); thread->invalidateTracks(portIdSet); thread->invalidateTracks(&portIdSet); if (portIdSet.empty()) { return NO_ERROR; } } for (size_t i = 0; i < mMmapThreads.size(); i++) { mMmapThreads[i]->invalidateTracks(portIdSet); mMmapThreads[i]->invalidateTracks(&portIdSet); if (portIdSet.empty()) { return NO_ERROR; } Loading Loading @@ -5043,7 +5043,9 @@ void AudioFlinger::onNonOffloadableGlobalEffectEnable() for (size_t i = 0; i < mPlaybackThreads.size(); i++) { const sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i); if (t->type() == IAfThreadBase::OFFLOAD) { t->invalidateTracks(AUDIO_STREAM_MUSIC); // we could invalidate based on session id, but offload threads // are based on single client access, so we invalidate everything. t->invalidateTracks(); } } Loading
services/audioflinger/IAfThread.h +10 −17 Original line number Diff line number Diff line Loading @@ -418,6 +418,16 @@ public: virtual std::vector<sp<IAfTrackBase>> getTracks_l() REQUIRES(mutex()) = 0; // Invalidate tracks by a set of port ids. The port id will be removed from // the given set if the corresponding track is found and invalidated. // // If portIds == nullptr, all tracks, including internal tracks are invalidated. virtual bool invalidateTracks_l(std::set<audio_port_handle_t>* portIds = {}) REQUIRES(mutex()) = 0; virtual bool invalidateTracks(std::set<audio_port_handle_t>* portIds = {}) EXCLUDES_ThreadBase_Mutex = 0; virtual status_t setPortsVolume(const std::vector<audio_port_handle_t> &portIds, float volume, bool muted) EXCLUDES_ThreadBase_Mutex = 0; Loading Loading @@ -520,16 +530,6 @@ public: virtual status_t attachAuxEffect_l(const sp<IAfTrack>& track, int EffectId) REQUIRES(mutex()) = 0; // called with AudioFlinger lock held virtual bool invalidateTracks_l(audio_stream_type_t streamType) REQUIRES(mutex()) = 0; virtual bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) REQUIRES(mutex()) = 0; virtual void invalidateTracks(audio_stream_type_t streamType) EXCLUDES_ThreadBase_Mutex = 0; // Invalidate tracks by a set of port ids. The port id will be removed from // the given set if the corresponding track is found and invalidated. virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) EXCLUDES_ThreadBase_Mutex = 0; virtual status_t getTimestamp_l(AudioTimestamp& timestamp) REQUIRES(mutex()) = 0; virtual void addPatchTrack(const sp<IAfPatchTrack>& track) EXCLUDES_ThreadBase_Mutex = 0; virtual void deletePatchTrack(const sp<IAfPatchTrack>& track) EXCLUDES_ThreadBase_Mutex = 0; Loading Loading @@ -691,13 +691,6 @@ public: virtual status_t reportData(const void* buffer, size_t frameCount) EXCLUDES_ThreadBase_Mutex = 0; // TODO(b/291317898) move to IAfThreadBase? virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds) EXCLUDES_ThreadBase_Mutex = 0; virtual void invalidateTracks(audio_stream_type_t streamType) EXCLUDES_ThreadBase_Mutex = 0; // Sets the UID records silence - TODO(b/291317898) move to IAfMmapCaptureThread virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced) EXCLUDES_ThreadBase_Mutex = 0; Loading
services/audioflinger/Threads.cpp +60 −101 Original line number Diff line number Diff line Loading @@ -1793,7 +1793,7 @@ void ThreadBase::onEffectEnable(const sp<IAfEffectModule>& effect) { if (!effect->isOffloadable()) { if (mType == ThreadBase::OFFLOAD) { PlaybackThread *t = (PlaybackThread *)this; t->invalidateTracks(AUDIO_STREAM_MUSIC); t->invalidateTracks(); } if (effect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) { mAfThreadCallback->onNonOffloadableGlobalEffectEnable(); Loading Loading @@ -2165,6 +2165,48 @@ void ThreadBase::stopMelComputation_l() ALOGW("%s: ThreadBase does not support CSD", __func__); } std::set<audio_port_handle_t> ThreadBase::getTrackPortIds_l() const { std::set<int32_t> result; for (const auto& t : mTracks) { if (t->isExternalTrack()) { result.insert(t->portId()); } } return result; } std::set<audio_port_handle_t> ThreadBase::getTrackPortIds() const { audio_utils::lock_guard _l(mutex()); return getTrackPortIds_l(); } bool ThreadBase::invalidateTracks(std::set<audio_port_handle_t>* portIds) { audio_utils::lock_guard _l(mutex()); return invalidateTracks_l(portIds); } // Only Playback Threads invalidate tracks based on portIds, but we keep // open the possibility that Record / Capture Threads may eventually use it. bool ThreadBase::invalidateTracks_l(std::set<audio_port_handle_t>* portIds) { bool trackMatch = false; for (const auto& t : mTracks) { if (portIds == nullptr || (t->isExternalTrack() && portIds->find(t->portId()) != portIds->end())) { t->invalidate(); if (portIds) portIds->erase(t->portId()); trackMatch = true; } } // TODO(b/410038399) consider to apply to all threads for symmetry. if (trackMatch && (type() == MMAP_PLAYBACK || type() == MMAP_CAPTURE)) { broadcast_l(); } return trackMatch; } status_t ThreadBase::setPortsVolume( const std::vector<audio_port_handle_t>& portIds, float volume, bool muted) { audio_utils::lock_guard _l(mutex()); Loading Loading @@ -3072,23 +3114,6 @@ void PlaybackThread::removeTrack_l(const sp<IAfTrack>& track) } } std::set<audio_port_handle_t> PlaybackThread::getTrackPortIds_l() { std::set<int32_t> result; for (const auto& t : mTracks) { if (t->isExternalTrack()) { result.insert(t->portId()); } } return result; } std::set<audio_port_handle_t> PlaybackThread::getTrackPortIds() { audio_utils::lock_guard _l(mutex()); return getTrackPortIds_l(); } String8 PlaybackThread::getParameters(const String8& keys) { audio_utils::lock_guard _l(mutex()); Loading Loading @@ -3728,46 +3753,6 @@ void PlaybackThread::cacheParameters_l() } } bool PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType) { ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %zu", this, streamType, mTracks.size()); bool trackMatch = false; for (const auto& t : mPlaybackTracksView) { if (t->streamType() == streamType && t->isExternalTrack()) { t->invalidate(); trackMatch = true; } } return trackMatch; } void PlaybackThread::invalidateTracks(audio_stream_type_t streamType) { audio_utils::lock_guard _l(mutex()); invalidateTracks_l(streamType); } void PlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) { audio_utils::lock_guard _l(mutex()); invalidateTracks_l(portIds); } bool PlaybackThread::invalidateTracks_l(std::set<audio_port_handle_t>& portIds) { bool trackMatch = false; for (const auto& t : mTracks) { if (t->isExternalTrack() && portIds.find(t->portId()) != portIds.end()) { t->invalidate(); portIds.erase(t->portId()); trackMatch = true; } if (portIds.empty()) { break; } } return trackMatch; } status_t PlaybackThread::addEffectChain_l(const sp<IAfEffectChain>& chain) { audio_session_t session = chain->sessionId(); Loading Loading @@ -5487,9 +5472,7 @@ void PlaybackThread::onAddNewTrack_l() void PlaybackThread::onAsyncError(bool isHardError) { auto allTrackPortIds = getTrackPortIds(); for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) { invalidateTracks((audio_stream_type_t)i); } invalidateTracks(); if (isHardError) { mAfThreadCallback->onHardError(allTrackPortIds); } Loading Loading @@ -7773,19 +7756,25 @@ void OffloadThread::flushHw_l() } } void OffloadThread::invalidateTracks(audio_stream_type_t streamType) { audio_utils::lock_guard _l(mutex()); if (PlaybackThread::invalidateTracks_l(streamType)) { mFlushPending = true; } } // TODO(b/410038399) move to base class and unify with Mmap implementation for clarity. void OffloadThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) { audio_utils::lock_guard _l(mutex()); if (PlaybackThread::invalidateTracks_l(portIds)) { bool OffloadThread::invalidateTracks_l(std::set<audio_port_handle_t>* portIds) { const bool trackMatch = ThreadBase::invalidateTracks_l(portIds); if (trackMatch) { // On invalidating an offload track, the IAudioTrack instance is // destroyed and the offload output is released. If it so happens // that APM::getOutputForAttr for the new IAudioTrack is called before // OffloadThread::prepareTracks_l checks and removes an invalid track, // the same output can get reused. // // The side effect of this is data present in HAL and below from before the // invalidate will be rendered before data from the new seek position // is rendered. This is unexpected. // // To fix this, set hint to issue flush when an offload track is invalidated. mFlushPending = true; } return trackMatch; } // ---------------------------------------------------------------------------- Loading Loading @@ -11343,36 +11332,6 @@ void MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted) } } void MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType) { audio_utils::lock_guard _l(mutex()); if (streamType == mStreamType) { for (const auto& track : mActiveTracks) { track->invalidate(); } broadcast_l(); } } void MmapPlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) { audio_utils::lock_guard _l(mutex()); bool trackMatch = false; for (const auto& track : mActiveTracks) { if (portIds.find(track->portId()) != portIds.end()) { track->invalidate(); trackMatch = true; portIds.erase(track->portId()); } if (portIds.empty()) { break; } } if (trackMatch) { broadcast_l(); } } void MmapPlaybackThread::processVolume_l() NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent { Loading
services/audioflinger/Threads.h +13 −22 Original line number Diff line number Diff line Loading @@ -947,6 +947,18 @@ protected: std::vector<sp<IAfTrackBase>> getTracks_l() final REQUIRES(mutex()); std::set<audio_port_handle_t> getTrackPortIds_l() const REQUIRES(mutex()); std::set<audio_port_handle_t> getTrackPortIds() const EXCLUDES_ThreadBase_Mutex; // Invalidate tracks by a set of port ids. The port id will be removed from // the given set if the corresponding track is found and invalidated. // // If portIds == nullptr, all tracks, including internal tracks are invalidated. bool invalidateTracks_l(std::set<audio_port_handle_t>* portIds = {}) override REQUIRES(mutex()); bool invalidateTracks(std::set<audio_port_handle_t>* portIds = {}) override EXCLUDES_ThreadBase_Mutex; status_t setPortsVolume(const std::vector<audio_port_handle_t>& portIds, float volume, bool muted) final EXCLUDES_ThreadBase_Mutex; Loading Loading @@ -1172,17 +1184,6 @@ public: // could be static. bool isValidSyncEvent(const sp<audioflinger::SyncEvent>& event) const final; // Does this require the AudioFlinger mutex as well? bool invalidateTracks_l(audio_stream_type_t streamType) final REQUIRES(mutex()); bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds) final REQUIRES(mutex()); void invalidateTracks(audio_stream_type_t streamType) override; // Invalidate tracks by a set of port ids. The port id will be removed from // the given set if the corresponding track is found and invalidated. void invalidateTracks(std::set<audio_port_handle_t>& portIds) override EXCLUDES_ThreadBase_Mutex; size_t frameCount() const final { return mNormalFrameCount; } audio_channel_mask_t mixerChannelMask() const final { Loading Loading @@ -1468,8 +1469,6 @@ protected: bool destroyTrack_l(const sp<IAfTrack>& track) final REQUIRES(mutex()); void removeTrack_l(const sp<IAfTrack>& track) REQUIRES(mutex()); std::set<audio_port_handle_t> getTrackPortIds_l() REQUIRES(mutex()); std::set<audio_port_handle_t> getTrackPortIds(); void readOutputParameters_l() REQUIRES(mutex()); MetadataUpdate updateMetadata_l() final REQUIRES(mutex(), ThreadBase_ThreadLoop); Loading Loading @@ -1855,8 +1854,7 @@ protected: bool waitingAsyncCallback() final; bool waitingAsyncCallback_l() final REQUIRES(mutex()); void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex; void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex; bool invalidateTracks_l(std::set<audio_port_handle_t>* portIds) final REQUIRES(mutex()); bool keepWakeLock() const final { return (mKeepWakeLock || (mDrainSequence & 1)); } Loading Loading @@ -2342,10 +2340,6 @@ class MmapThread : public ThreadBase, public virtual IAfMmapThread virtual audio_stream_type_t streamType_l() const REQUIRES(mutex()) { return AUDIO_STREAM_DEFAULT; } virtual void invalidateTracks(audio_stream_type_t /* streamType */) EXCLUDES_ThreadBase_Mutex {} void invalidateTracks(std::set<audio_port_handle_t>& /* portIds */) override EXCLUDES_ThreadBase_Mutex {} // Sets the UID records silence void setRecordSilenced( Loading Loading @@ -2440,9 +2434,6 @@ public: void setMasterMute_l(bool muted) REQUIRES(mutex()) { mMasterMute = muted; } void invalidateTracks(audio_stream_type_t streamType) final EXCLUDES_ThreadBase_Mutex; void invalidateTracks(std::set<audio_port_handle_t>& portIds) final EXCLUDES_ThreadBase_Mutex; audio_stream_type_t streamType_l() const final REQUIRES(mutex()) { return mStreamType; } Loading