Loading services/audioflinger/PlaybackTracks.h +9 −2 Original line number Diff line number Diff line Loading @@ -20,21 +20,25 @@ #endif #include <math.h> #include <sys/types.h> // Checks and monitors OP_PLAY_AUDIO class OpPlayAudioMonitor : public RefBase { friend class sp<OpPlayAudioMonitor>; public: ~OpPlayAudioMonitor() override; bool hasOpPlayAudio() const; static sp<OpPlayAudioMonitor> createIfNeeded( AudioFlinger::ThreadBase* thread, const AttributionSourceState& attributionSource, const audio_attributes_t& attr, int id, audio_stream_type_t streamType); private: OpPlayAudioMonitor(const AttributionSourceState& attributionSource, audio_usage_t usage, int id); OpPlayAudioMonitor(AudioFlinger::ThreadBase* thread, const AttributionSourceState& attributionSource, audio_usage_t usage, int id, uid_t uid); void onFirstRef() override; static void getPackagesForUid(uid_t uid, Vector<String16>& packages); Loading @@ -53,10 +57,13 @@ private: // called by PlayAudioOpCallback when OP_PLAY_AUDIO is updated in AppOp callback void checkPlayAudioForUsage(); wp<AudioFlinger::ThreadBase> mThread; std::atomic_bool mHasOpPlayAudio; const AttributionSourceState mAttributionSource; const int32_t mUsage; // on purpose not audio_usage_t because always checked in appOps as int32_t const int mId; // for logging purposes only const uid_t mUid; const String16 mPackageName; }; // playback track Loading services/audioflinger/Tracks.cpp +31 −22 Original line number Diff line number Diff line Loading @@ -511,11 +511,12 @@ Status AudioFlinger::TrackHandle::setPlaybackRateParameters( // static sp<AudioFlinger::PlaybackThread::OpPlayAudioMonitor> AudioFlinger::PlaybackThread::OpPlayAudioMonitor::createIfNeeded( AudioFlinger::ThreadBase* thread, const AttributionSourceState& attributionSource, const audio_attributes_t& attr, int id, audio_stream_type_t streamType) { Vector<String16> packages; uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid)); const uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid)); getPackagesForUid(uid, packages); if (isServiceUid(uid)) { if (packages.isEmpty()) { Loading @@ -537,15 +538,21 @@ AudioFlinger::PlaybackThread::OpPlayAudioMonitor::createIfNeeded( id, attr.flags); return nullptr; } return new OpPlayAudioMonitor(attributionSource, attr.usage, id); return sp<OpPlayAudioMonitor>::make(thread, attributionSource, attr.usage, id, uid); } AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor( const AttributionSourceState& attributionSource, audio_usage_t usage, int id) : mHasOpPlayAudio(true), mAttributionSource(attributionSource), mUsage((int32_t) usage), mId(id) { } AudioFlinger::ThreadBase* thread, const AttributionSourceState& attributionSource, audio_usage_t usage, int id, uid_t uid) : mThread(wp<AudioFlinger::ThreadBase>::fromExisting(thread)), mHasOpPlayAudio(true), mAttributionSource(attributionSource), mUsage((int32_t)usage), mId(id), mUid(uid), mPackageName(VALUE_OR_FATAL(aidl2legacy_string_view_String16( attributionSource.packageName.value_or("")))) {} AudioFlinger::PlaybackThread::OpPlayAudioMonitor::~OpPlayAudioMonitor() { Loading @@ -561,9 +568,7 @@ void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::onFirstRef() if (mAttributionSource.packageName.has_value()) { mOpCallback = new PlayAudioOpCallback(this); mAppOpsManager.startWatchingMode(AppOpsManager::OP_PLAY_AUDIO, VALUE_OR_FATAL(aidl2legacy_string_view_String16( mAttributionSource.packageName.value_or(""))) , mOpCallback); mPackageName, mOpCallback); } } Loading @@ -576,16 +581,20 @@ bool AudioFlinger::PlaybackThread::OpPlayAudioMonitor::hasOpPlayAudio() const { // - not called from PlayAudioOpCallback because the callback is not installed in this case void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::checkPlayAudioForUsage() { if (!mAttributionSource.packageName.has_value()) { mHasOpPlayAudio.store(false); } else { uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mAttributionSource.uid)); String16 packageName = VALUE_OR_FATAL( aidl2legacy_string_view_String16(mAttributionSource.packageName.value_or(""))); bool hasIt = mAppOpsManager.checkAudioOpNoThrow(AppOpsManager::OP_PLAY_AUDIO, mUsage, uid, packageName) == AppOpsManager::MODE_ALLOWED; ALOGD("OpPlayAudio: track:%d usage:%d %smuted", mId, mUsage, hasIt ? "not " : ""); mHasOpPlayAudio.store(hasIt); const bool hasAppOps = mAttributionSource.packageName.has_value() && mAppOpsManager.checkAudioOpNoThrow( AppOpsManager::OP_PLAY_AUDIO, mUsage, mUid, mPackageName) == AppOpsManager::MODE_ALLOWED; bool shouldChange = !hasAppOps; // check if we need to update. if (mHasOpPlayAudio.compare_exchange_strong(shouldChange, hasAppOps)) { ALOGD("OpPlayAudio: track:%d usage:%d %smuted", mId, mUsage, hasAppOps ? "not " : ""); auto thread = mThread.promote(); if (thread != nullptr && thread->type() == AudioFlinger::ThreadBase::OFFLOAD) { // Wake up Thread if offloaded, otherwise it may be several seconds for update. Mutex::Autolock _l(thread->mLock); thread->broadcast_l(); } } } Loading Loading @@ -662,7 +671,7 @@ AudioFlinger::PlaybackThread::Track::Track( mAuxEffectId(0), mHasVolumeController(false), mFrameMap(16 /* sink-frame-to-track-frame map memory */), mVolumeHandler(new media::VolumeHandler(sampleRate)), mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(attributionSource, attr, id(), mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(thread, attributionSource, attr, id(), streamType)), // mSinkTimestamp mFastIndex(-1), Loading Loading
services/audioflinger/PlaybackTracks.h +9 −2 Original line number Diff line number Diff line Loading @@ -20,21 +20,25 @@ #endif #include <math.h> #include <sys/types.h> // Checks and monitors OP_PLAY_AUDIO class OpPlayAudioMonitor : public RefBase { friend class sp<OpPlayAudioMonitor>; public: ~OpPlayAudioMonitor() override; bool hasOpPlayAudio() const; static sp<OpPlayAudioMonitor> createIfNeeded( AudioFlinger::ThreadBase* thread, const AttributionSourceState& attributionSource, const audio_attributes_t& attr, int id, audio_stream_type_t streamType); private: OpPlayAudioMonitor(const AttributionSourceState& attributionSource, audio_usage_t usage, int id); OpPlayAudioMonitor(AudioFlinger::ThreadBase* thread, const AttributionSourceState& attributionSource, audio_usage_t usage, int id, uid_t uid); void onFirstRef() override; static void getPackagesForUid(uid_t uid, Vector<String16>& packages); Loading @@ -53,10 +57,13 @@ private: // called by PlayAudioOpCallback when OP_PLAY_AUDIO is updated in AppOp callback void checkPlayAudioForUsage(); wp<AudioFlinger::ThreadBase> mThread; std::atomic_bool mHasOpPlayAudio; const AttributionSourceState mAttributionSource; const int32_t mUsage; // on purpose not audio_usage_t because always checked in appOps as int32_t const int mId; // for logging purposes only const uid_t mUid; const String16 mPackageName; }; // playback track Loading
services/audioflinger/Tracks.cpp +31 −22 Original line number Diff line number Diff line Loading @@ -511,11 +511,12 @@ Status AudioFlinger::TrackHandle::setPlaybackRateParameters( // static sp<AudioFlinger::PlaybackThread::OpPlayAudioMonitor> AudioFlinger::PlaybackThread::OpPlayAudioMonitor::createIfNeeded( AudioFlinger::ThreadBase* thread, const AttributionSourceState& attributionSource, const audio_attributes_t& attr, int id, audio_stream_type_t streamType) { Vector<String16> packages; uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid)); const uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid)); getPackagesForUid(uid, packages); if (isServiceUid(uid)) { if (packages.isEmpty()) { Loading @@ -537,15 +538,21 @@ AudioFlinger::PlaybackThread::OpPlayAudioMonitor::createIfNeeded( id, attr.flags); return nullptr; } return new OpPlayAudioMonitor(attributionSource, attr.usage, id); return sp<OpPlayAudioMonitor>::make(thread, attributionSource, attr.usage, id, uid); } AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor( const AttributionSourceState& attributionSource, audio_usage_t usage, int id) : mHasOpPlayAudio(true), mAttributionSource(attributionSource), mUsage((int32_t) usage), mId(id) { } AudioFlinger::ThreadBase* thread, const AttributionSourceState& attributionSource, audio_usage_t usage, int id, uid_t uid) : mThread(wp<AudioFlinger::ThreadBase>::fromExisting(thread)), mHasOpPlayAudio(true), mAttributionSource(attributionSource), mUsage((int32_t)usage), mId(id), mUid(uid), mPackageName(VALUE_OR_FATAL(aidl2legacy_string_view_String16( attributionSource.packageName.value_or("")))) {} AudioFlinger::PlaybackThread::OpPlayAudioMonitor::~OpPlayAudioMonitor() { Loading @@ -561,9 +568,7 @@ void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::onFirstRef() if (mAttributionSource.packageName.has_value()) { mOpCallback = new PlayAudioOpCallback(this); mAppOpsManager.startWatchingMode(AppOpsManager::OP_PLAY_AUDIO, VALUE_OR_FATAL(aidl2legacy_string_view_String16( mAttributionSource.packageName.value_or(""))) , mOpCallback); mPackageName, mOpCallback); } } Loading @@ -576,16 +581,20 @@ bool AudioFlinger::PlaybackThread::OpPlayAudioMonitor::hasOpPlayAudio() const { // - not called from PlayAudioOpCallback because the callback is not installed in this case void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::checkPlayAudioForUsage() { if (!mAttributionSource.packageName.has_value()) { mHasOpPlayAudio.store(false); } else { uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mAttributionSource.uid)); String16 packageName = VALUE_OR_FATAL( aidl2legacy_string_view_String16(mAttributionSource.packageName.value_or(""))); bool hasIt = mAppOpsManager.checkAudioOpNoThrow(AppOpsManager::OP_PLAY_AUDIO, mUsage, uid, packageName) == AppOpsManager::MODE_ALLOWED; ALOGD("OpPlayAudio: track:%d usage:%d %smuted", mId, mUsage, hasIt ? "not " : ""); mHasOpPlayAudio.store(hasIt); const bool hasAppOps = mAttributionSource.packageName.has_value() && mAppOpsManager.checkAudioOpNoThrow( AppOpsManager::OP_PLAY_AUDIO, mUsage, mUid, mPackageName) == AppOpsManager::MODE_ALLOWED; bool shouldChange = !hasAppOps; // check if we need to update. if (mHasOpPlayAudio.compare_exchange_strong(shouldChange, hasAppOps)) { ALOGD("OpPlayAudio: track:%d usage:%d %smuted", mId, mUsage, hasAppOps ? "not " : ""); auto thread = mThread.promote(); if (thread != nullptr && thread->type() == AudioFlinger::ThreadBase::OFFLOAD) { // Wake up Thread if offloaded, otherwise it may be several seconds for update. Mutex::Autolock _l(thread->mLock); thread->broadcast_l(); } } } Loading Loading @@ -662,7 +671,7 @@ AudioFlinger::PlaybackThread::Track::Track( mAuxEffectId(0), mHasVolumeController(false), mFrameMap(16 /* sink-frame-to-track-frame map memory */), mVolumeHandler(new media::VolumeHandler(sampleRate)), mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(attributionSource, attr, id(), mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(thread, attributionSource, attr, id(), streamType)), // mSinkTimestamp mFastIndex(-1), Loading