Loading services/audioflinger/IAfTrack.h +4 −0 Original line number Diff line number Diff line Loading @@ -511,6 +511,10 @@ public: // protected by MMapThread::mLock virtual bool getAndSetSilencedNotified_l() = 0; // TODO(b/241533526): Refactor shared logic between MMAP and legacy virtual bool isPlaybackRestrictedControl() const = 0; virtual void maybeLogPlaybackHardening(media::IAudioManagerNative& am) const = 0; /** * Updates the mute state and notifies the audio service. Call this only when holding player * thread lock. Loading services/audioflinger/MmapTracks.h +23 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "TrackBase.h" #include <android/content/AttributionSourceState.h> #include <media/AppOpsSession.h> namespace android { Loading Loading @@ -60,6 +61,18 @@ public: mSilencedNotified = true; return silencedNotified; } // The following functions are duplicated from PlaybackTrack // TODO(b/241533526) refactor common code bool hasOpControlPartial() const { return mOpControlSession ? mHasOpControlPartial.load(std::memory_order_acquire) : true; } bool isPlaybackRestrictedControl() const final { return !(mIsExemptedFromOpControl || hasOpControlPartial()); } void maybeLogPlaybackHardening(media::IAudioManagerNative& am) const final; /** * Updates the mute state and notifies the audio service. Call this only when holding player * thread lock. Loading Loading @@ -105,6 +118,16 @@ private: bool mMutedFromPort; float mVolume = 0.0f; // logically const std::optional<media::permission::AppOpsSession<media::permission::DefaultAppOpsFacade>> mOpControlSession; // logically const bool mIsExemptedFromOpControl = false; std::atomic<bool> mHasOpControlPartial {true}; mutable std::atomic<bool> mPlaybackHardeningLogged {false}; }; // end of Track } // namespace android services/audioflinger/Threads.cpp +22 −5 Original line number Diff line number Diff line Loading @@ -10641,9 +10641,13 @@ status_t MmapThread::start(const AudioClient& client, sp<IAfMmapTrack> track = IAfMmapTrack::create( this, attr == nullptr ? mAttr : *attr, mSampleRate, mFormat, mChannelMask, mSessionId, isOutput(), client.attributionSource, adjAttributionSource, IPCThreadState::self()->getCallingPid(), portId, volume, muted); // MMAP tracks are only created when they are started, so mark them as Start for the purposes // of the IAfTrackBase interface track->start(); if (!isOutput()) { track->setSilenced_l(isClientSilenced_l(portId)); } Loading @@ -10654,7 +10658,7 @@ status_t MmapThread::start(const AudioClient& client, } else if (!track->isSilenced_l()) { for (const sp<IAfMmapTrack>& t : mActiveTracks) { if (t->isSilenced_l() && t->uid() != static_cast<uid_t>(client.attributionSource.uid)) { && t->uid() != static_cast<uid_t>(adjAttributionSource.uid)) { t->invalidate(); } } Loading Loading @@ -10709,6 +10713,7 @@ status_t MmapThread::stop(audio_port_handle_t handle) mActiveTracks.remove(track); eraseClientSilencedState_l(track->portId()); track->stop(); mutex().unlock(); if (isOutput()) { Loading Loading @@ -11403,6 +11408,13 @@ NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent_l } } } bool shouldMutePlaybackHardening = std::all_of(mActiveTracks.begin(), mActiveTracks.end(), [](const auto& x) { return x->isPlaybackRestrictedControl(); }); if (shouldMutePlaybackHardening) { volume = 0; } if (volume != mHalVolFloat) { // Convert volumes from float to 8.24 uint32_t vol = (uint32_t)(volume * (1 << 24)); Loading Loading @@ -11444,7 +11456,8 @@ NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent_l false /*muteFromPlaybackRestricted*/, false /*muteFromClientVolume*/, false /*muteFromVolumeShaper*/, false /*muteFromPortVolume*/}); false /*muteFromPortVolume*/, shouldMutePlaybackHardening}); } else { track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(), /*muteState=*/{mMasterMute, Loading @@ -11454,8 +11467,12 @@ NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent_l false /*muteFromPlaybackRestricted*/, false /*muteFromClientVolume*/, false /*muteFromVolumeShaper*/, track->getPortMute()}); track->getPortMute(), shouldMutePlaybackHardening}); } track->maybeLogPlaybackHardening( *mAfThreadCallback->getOrCreateAudioManager()->getNativeInterface()); } } } Loading services/audioflinger/Tracks.cpp +42 −3 Original line number Diff line number Diff line Loading @@ -1916,8 +1916,8 @@ void Track::maybeLogPlaybackHardening(media::IAudioManagerNative& am) const { !isPlaybackRestrictedControl()); } } } // must be called with player thread lock held void Track::processMuteEvent_l(const sp< IAudioManager>& audioManager, mute_state_t muteState) Loading Loading @@ -3821,6 +3821,24 @@ MmapTrack::MmapTrack(IAfThreadBase* thread, mUid(VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid))), mSilenced(false), mSilencedNotified(false), mVolume(volume) { using media::permission::ValidatedAttributionSourceState; using media::permission::Ops; if (hardening_impl()) { // Don't bother for trusted uids if (!media::permission::skipOpsForUid(attributionSource.uid)) { mOpControlSession.emplace( ValidatedAttributionSourceState::createFromTrustedSource(attributionSource), Ops { .attributedOp = AppOpsManager::OP_CONTROL_AUDIO_PARTIAL }, [this] (bool isPermitted) { mHasOpControlPartial.store(isPermitted, std::memory_order_release); signal(); } ); mIsExemptedFromOpControl = shouldExemptFromOpControl(attr.usage); } } mMutedFromPort = muted; // Once this item is logged by the server, the client can add properties. mTrackMetrics.logConstructor(creatorPid, uid(), id()); Loading @@ -3844,6 +3862,10 @@ status_t MmapTrack::initCheck() const status_t MmapTrack::start(AudioSystem::sync_event_t event __unused, audio_session_t triggerSession __unused) { if (mOpControlSession) { mHasOpControlPartial.store(mOpControlSession->beginDeliveryRequest(), std::memory_order_release); } if (ATRACE_ENABLED()) [[unlikely]] { ATRACE_INSTANT_FOR_TRACK(mTraceActionId.c_str(), audio_utils::trace::Object{} .set(AUDIO_TRACE_OBJECT_KEY_EVENT, AUDIO_TRACE_EVENT_START) Loading @@ -3854,6 +3876,9 @@ status_t MmapTrack::start(AudioSystem::sync_event_t event __unused, void MmapTrack::stop() { if (mOpControlSession) { mOpControlSession->endDeliveryRequest(); } if (ATRACE_ENABLED()) [[unlikely]] { ATRACE_INSTANT_FOR_TRACK(mTraceActionId.c_str(), audio_utils::trace::Object{} .set(AUDIO_TRACE_OBJECT_KEY_EVENT, AUDIO_TRACE_EVENT_STOP) Loading Loading @@ -3883,6 +3908,20 @@ void MmapTrack::onTimestamp(const ExtendedTimestamp& timestamp __unused) { } void MmapTrack::maybeLogPlaybackHardening(media::IAudioManagerNative& am) const { using media::IAudioManagerNative::HardeningType::PARTIAL; // The op state deviates from if the track is actually muted if the playback was exempted for // some compat reason. // The state could have technically TOCTOU, but this is for metrics and that is very unlikely if (!hasOpControlPartial()) { if (!mPlaybackHardeningLogged.exchange(true, std::memory_order_acq_rel)) { am.playbackHardeningEvent(uid(), PARTIAL, /* bypassed= */ !isPlaybackRestrictedControl()); } } } void MmapTrack::processMuteEvent_l(const sp<IAudioManager>& audioManager, mute_state_t muteState) { if (mMuteState == muteState) { Loading Loading
services/audioflinger/IAfTrack.h +4 −0 Original line number Diff line number Diff line Loading @@ -511,6 +511,10 @@ public: // protected by MMapThread::mLock virtual bool getAndSetSilencedNotified_l() = 0; // TODO(b/241533526): Refactor shared logic between MMAP and legacy virtual bool isPlaybackRestrictedControl() const = 0; virtual void maybeLogPlaybackHardening(media::IAudioManagerNative& am) const = 0; /** * Updates the mute state and notifies the audio service. Call this only when holding player * thread lock. Loading
services/audioflinger/MmapTracks.h +23 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "TrackBase.h" #include <android/content/AttributionSourceState.h> #include <media/AppOpsSession.h> namespace android { Loading Loading @@ -60,6 +61,18 @@ public: mSilencedNotified = true; return silencedNotified; } // The following functions are duplicated from PlaybackTrack // TODO(b/241533526) refactor common code bool hasOpControlPartial() const { return mOpControlSession ? mHasOpControlPartial.load(std::memory_order_acquire) : true; } bool isPlaybackRestrictedControl() const final { return !(mIsExemptedFromOpControl || hasOpControlPartial()); } void maybeLogPlaybackHardening(media::IAudioManagerNative& am) const final; /** * Updates the mute state and notifies the audio service. Call this only when holding player * thread lock. Loading Loading @@ -105,6 +118,16 @@ private: bool mMutedFromPort; float mVolume = 0.0f; // logically const std::optional<media::permission::AppOpsSession<media::permission::DefaultAppOpsFacade>> mOpControlSession; // logically const bool mIsExemptedFromOpControl = false; std::atomic<bool> mHasOpControlPartial {true}; mutable std::atomic<bool> mPlaybackHardeningLogged {false}; }; // end of Track } // namespace android
services/audioflinger/Threads.cpp +22 −5 Original line number Diff line number Diff line Loading @@ -10641,9 +10641,13 @@ status_t MmapThread::start(const AudioClient& client, sp<IAfMmapTrack> track = IAfMmapTrack::create( this, attr == nullptr ? mAttr : *attr, mSampleRate, mFormat, mChannelMask, mSessionId, isOutput(), client.attributionSource, adjAttributionSource, IPCThreadState::self()->getCallingPid(), portId, volume, muted); // MMAP tracks are only created when they are started, so mark them as Start for the purposes // of the IAfTrackBase interface track->start(); if (!isOutput()) { track->setSilenced_l(isClientSilenced_l(portId)); } Loading @@ -10654,7 +10658,7 @@ status_t MmapThread::start(const AudioClient& client, } else if (!track->isSilenced_l()) { for (const sp<IAfMmapTrack>& t : mActiveTracks) { if (t->isSilenced_l() && t->uid() != static_cast<uid_t>(client.attributionSource.uid)) { && t->uid() != static_cast<uid_t>(adjAttributionSource.uid)) { t->invalidate(); } } Loading Loading @@ -10709,6 +10713,7 @@ status_t MmapThread::stop(audio_port_handle_t handle) mActiveTracks.remove(track); eraseClientSilencedState_l(track->portId()); track->stop(); mutex().unlock(); if (isOutput()) { Loading Loading @@ -11403,6 +11408,13 @@ NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent_l } } } bool shouldMutePlaybackHardening = std::all_of(mActiveTracks.begin(), mActiveTracks.end(), [](const auto& x) { return x->isPlaybackRestrictedControl(); }); if (shouldMutePlaybackHardening) { volume = 0; } if (volume != mHalVolFloat) { // Convert volumes from float to 8.24 uint32_t vol = (uint32_t)(volume * (1 << 24)); Loading Loading @@ -11444,7 +11456,8 @@ NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent_l false /*muteFromPlaybackRestricted*/, false /*muteFromClientVolume*/, false /*muteFromVolumeShaper*/, false /*muteFromPortVolume*/}); false /*muteFromPortVolume*/, shouldMutePlaybackHardening}); } else { track->processMuteEvent_l(mAfThreadCallback->getOrCreateAudioManager(), /*muteState=*/{mMasterMute, Loading @@ -11454,8 +11467,12 @@ NO_THREAD_SAFETY_ANALYSIS // access of track->processMuteEvent_l false /*muteFromPlaybackRestricted*/, false /*muteFromClientVolume*/, false /*muteFromVolumeShaper*/, track->getPortMute()}); track->getPortMute(), shouldMutePlaybackHardening}); } track->maybeLogPlaybackHardening( *mAfThreadCallback->getOrCreateAudioManager()->getNativeInterface()); } } } Loading
services/audioflinger/Tracks.cpp +42 −3 Original line number Diff line number Diff line Loading @@ -1916,8 +1916,8 @@ void Track::maybeLogPlaybackHardening(media::IAudioManagerNative& am) const { !isPlaybackRestrictedControl()); } } } // must be called with player thread lock held void Track::processMuteEvent_l(const sp< IAudioManager>& audioManager, mute_state_t muteState) Loading Loading @@ -3821,6 +3821,24 @@ MmapTrack::MmapTrack(IAfThreadBase* thread, mUid(VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid))), mSilenced(false), mSilencedNotified(false), mVolume(volume) { using media::permission::ValidatedAttributionSourceState; using media::permission::Ops; if (hardening_impl()) { // Don't bother for trusted uids if (!media::permission::skipOpsForUid(attributionSource.uid)) { mOpControlSession.emplace( ValidatedAttributionSourceState::createFromTrustedSource(attributionSource), Ops { .attributedOp = AppOpsManager::OP_CONTROL_AUDIO_PARTIAL }, [this] (bool isPermitted) { mHasOpControlPartial.store(isPermitted, std::memory_order_release); signal(); } ); mIsExemptedFromOpControl = shouldExemptFromOpControl(attr.usage); } } mMutedFromPort = muted; // Once this item is logged by the server, the client can add properties. mTrackMetrics.logConstructor(creatorPid, uid(), id()); Loading @@ -3844,6 +3862,10 @@ status_t MmapTrack::initCheck() const status_t MmapTrack::start(AudioSystem::sync_event_t event __unused, audio_session_t triggerSession __unused) { if (mOpControlSession) { mHasOpControlPartial.store(mOpControlSession->beginDeliveryRequest(), std::memory_order_release); } if (ATRACE_ENABLED()) [[unlikely]] { ATRACE_INSTANT_FOR_TRACK(mTraceActionId.c_str(), audio_utils::trace::Object{} .set(AUDIO_TRACE_OBJECT_KEY_EVENT, AUDIO_TRACE_EVENT_START) Loading @@ -3854,6 +3876,9 @@ status_t MmapTrack::start(AudioSystem::sync_event_t event __unused, void MmapTrack::stop() { if (mOpControlSession) { mOpControlSession->endDeliveryRequest(); } if (ATRACE_ENABLED()) [[unlikely]] { ATRACE_INSTANT_FOR_TRACK(mTraceActionId.c_str(), audio_utils::trace::Object{} .set(AUDIO_TRACE_OBJECT_KEY_EVENT, AUDIO_TRACE_EVENT_STOP) Loading Loading @@ -3883,6 +3908,20 @@ void MmapTrack::onTimestamp(const ExtendedTimestamp& timestamp __unused) { } void MmapTrack::maybeLogPlaybackHardening(media::IAudioManagerNative& am) const { using media::IAudioManagerNative::HardeningType::PARTIAL; // The op state deviates from if the track is actually muted if the playback was exempted for // some compat reason. // The state could have technically TOCTOU, but this is for metrics and that is very unlikely if (!hasOpControlPartial()) { if (!mPlaybackHardeningLogged.exchange(true, std::memory_order_acq_rel)) { am.playbackHardeningEvent(uid(), PARTIAL, /* bypassed= */ !isPlaybackRestrictedControl()); } } } void MmapTrack::processMuteEvent_l(const sp<IAudioManager>& audioManager, mute_state_t muteState) { if (mMuteState == muteState) { Loading