Loading services/audioflinger/PlaybackTracks.h +8 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <audio_utils/mutex.h> #include <audio_utils/LinearMap.h> #include <binder/AppOpsManager.h> #include <media/AppOpsSession.h> #include <utils/RWLock.h> namespace android { Loading Loading @@ -298,8 +299,7 @@ protected: } bool isPlaybackRestrictedControl() const final { return false; // return mOpAudioControlSoftMonitor ? !mOpAudioControlSoftMonitor->hasOp() : false; return mOpControlSession ? !mHasOpControl.load(std::memory_order_acquire) : false; } bool isPlaybackRestricted() const final { Loading Loading @@ -354,6 +354,12 @@ protected: sp<OpPlayAudioMonitor> mOpPlayAudioMonitor; // logically const std::optional<media::permission::AppOpsSession<media::permission::DefaultAppOpsFacade>> mOpControlSession; std::atomic<bool> mHasOpControl {true}; bool mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not // scale to play haptic data os::HapticScale mHapticScale = os::HapticScale::mute(); Loading services/audioflinger/Tracks.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -30,7 +30,9 @@ #include <audio_utils/StringUtils.h> #include <audio_utils/minifloat.h> #include <com_android_media_audio.h> #include <media/AudioValidator.h> #include <media/AppOpsSession.h> #include <media/RecordBufferConverter.h> #include <media/nbaio/Pipe.h> #include <media/nbaio/PipeReader.h> Loading Loading @@ -71,8 +73,10 @@ namespace android { using ::android::aidl_utils::binderStatusFromStatusT; using binder::Status; using ::com::android::media::audio::hardening_impl; using content::AttributionSourceState; using media::VolumeShaper; // ---------------------------------------------------------------------------- // TrackBase // ---------------------------------------------------------------------------- Loading Loading @@ -926,6 +930,26 @@ Track::Track( return; } using media::permission::ValidatedAttributionSourceState; using media::permission::Ops; if (hardening_impl()) { // Don't bother for non-output tracks and server uids if (!media::permission::skipOpsForUid(attributionSource.uid) && type != TYPE_PATCH) { mOpControlSession.emplace( ValidatedAttributionSourceState::createFromTrustedSource(attributionSource), Ops { .attributedOp = AppOpsManager::OP_CONTROL_AUDIO_PARTIAL }, [this] (bool isPermitted) { mHasOpControl.store(isPermitted, std::memory_order_release); if (isOffloaded()) { signal(); } } ); } } if (sharedBuffer == 0) { mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount, mFrameSize, !isExternalTrack(), sampleRate); Loading Loading @@ -1493,6 +1517,13 @@ status_t Track::start(AudioSystem::sync_event_t event __unused, status = BAD_VALUE; } if (status == NO_ERROR) { // start OP_AUDIO_CONTROL session for track // TODO(b/385417236) once mute logic is centralized, the delivery request session should be // tied to sonifying playback instead of track start->pause if (mOpControlSession) { mHasOpControl.store(mOpControlSession->beginDeliveryRequest(), std::memory_order_release); } // send format to AudioManager for playback activity monitoring const sp<IAudioManager> audioManager = thread->afThreadCallback()->getOrCreateAudioManager(); Loading Loading @@ -1554,6 +1585,15 @@ void Track::stop() } forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->stop(); }); } // TODO(b/385417236) // Due to the complexity of state management for offload we do not call endDeliveryRequest(). // For offload tracks, sonification may continue significantly after the STOP // phase begins. Leave the session on-going until the track is eventually // destroyed. We continue to allow appop callbacks during STOPPING and STOPPED state. // This is suboptimal but harmless. if (mOpControlSession && !isOffloaded()) { mOpControlSession->endDeliveryRequest(); } } void Track::pause() Loading Loading @@ -1598,6 +1638,11 @@ void Track::pause() // Pausing the TeePatch to avoid a glitch on underrun, at the cost of buffered audio loss. forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->pause(); }); } // When stopping a paused track, there will be two endDeliveryRequests. This is tolerated by // the implementation. if (mOpControlSession) { mOpControlSession->endDeliveryRequest(); } } void Track::flush() Loading Loading
services/audioflinger/PlaybackTracks.h +8 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <audio_utils/mutex.h> #include <audio_utils/LinearMap.h> #include <binder/AppOpsManager.h> #include <media/AppOpsSession.h> #include <utils/RWLock.h> namespace android { Loading Loading @@ -298,8 +299,7 @@ protected: } bool isPlaybackRestrictedControl() const final { return false; // return mOpAudioControlSoftMonitor ? !mOpAudioControlSoftMonitor->hasOp() : false; return mOpControlSession ? !mHasOpControl.load(std::memory_order_acquire) : false; } bool isPlaybackRestricted() const final { Loading Loading @@ -354,6 +354,12 @@ protected: sp<OpPlayAudioMonitor> mOpPlayAudioMonitor; // logically const std::optional<media::permission::AppOpsSession<media::permission::DefaultAppOpsFacade>> mOpControlSession; std::atomic<bool> mHasOpControl {true}; bool mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not // scale to play haptic data os::HapticScale mHapticScale = os::HapticScale::mute(); Loading
services/audioflinger/Tracks.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -30,7 +30,9 @@ #include <audio_utils/StringUtils.h> #include <audio_utils/minifloat.h> #include <com_android_media_audio.h> #include <media/AudioValidator.h> #include <media/AppOpsSession.h> #include <media/RecordBufferConverter.h> #include <media/nbaio/Pipe.h> #include <media/nbaio/PipeReader.h> Loading Loading @@ -71,8 +73,10 @@ namespace android { using ::android::aidl_utils::binderStatusFromStatusT; using binder::Status; using ::com::android::media::audio::hardening_impl; using content::AttributionSourceState; using media::VolumeShaper; // ---------------------------------------------------------------------------- // TrackBase // ---------------------------------------------------------------------------- Loading Loading @@ -926,6 +930,26 @@ Track::Track( return; } using media::permission::ValidatedAttributionSourceState; using media::permission::Ops; if (hardening_impl()) { // Don't bother for non-output tracks and server uids if (!media::permission::skipOpsForUid(attributionSource.uid) && type != TYPE_PATCH) { mOpControlSession.emplace( ValidatedAttributionSourceState::createFromTrustedSource(attributionSource), Ops { .attributedOp = AppOpsManager::OP_CONTROL_AUDIO_PARTIAL }, [this] (bool isPermitted) { mHasOpControl.store(isPermitted, std::memory_order_release); if (isOffloaded()) { signal(); } } ); } } if (sharedBuffer == 0) { mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount, mFrameSize, !isExternalTrack(), sampleRate); Loading Loading @@ -1493,6 +1517,13 @@ status_t Track::start(AudioSystem::sync_event_t event __unused, status = BAD_VALUE; } if (status == NO_ERROR) { // start OP_AUDIO_CONTROL session for track // TODO(b/385417236) once mute logic is centralized, the delivery request session should be // tied to sonifying playback instead of track start->pause if (mOpControlSession) { mHasOpControl.store(mOpControlSession->beginDeliveryRequest(), std::memory_order_release); } // send format to AudioManager for playback activity monitoring const sp<IAudioManager> audioManager = thread->afThreadCallback()->getOrCreateAudioManager(); Loading Loading @@ -1554,6 +1585,15 @@ void Track::stop() } forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->stop(); }); } // TODO(b/385417236) // Due to the complexity of state management for offload we do not call endDeliveryRequest(). // For offload tracks, sonification may continue significantly after the STOP // phase begins. Leave the session on-going until the track is eventually // destroyed. We continue to allow appop callbacks during STOPPING and STOPPED state. // This is suboptimal but harmless. if (mOpControlSession && !isOffloaded()) { mOpControlSession->endDeliveryRequest(); } } void Track::pause() Loading Loading @@ -1598,6 +1638,11 @@ void Track::pause() // Pausing the TeePatch to avoid a glitch on underrun, at the cost of buffered audio loss. forEachTeePatchTrack_l([](const auto& patchTrack) { patchTrack->pause(); }); } // When stopping a paused track, there will be two endDeliveryRequests. This is tolerated by // the implementation. if (mOpControlSession) { mOpControlSession->endDeliveryRequest(); } } void Track::flush() Loading