APC: Wake OffloadThread on AppOps mute
Bug: 289885996
Test: atest AudioPlaybackConfigurationTest with setprop audio.offload.min.duration.secs 1
Change-Id: I93c3a507eb3f9146ff8d80ce5f34ea0e46a49e5a
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index b2ec9df..d28b2a0 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -559,11 +559,12 @@
// static
sp<OpPlayAudioMonitor> 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));
+ Vector<String16> packages;
+ const uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
getPackagesForUid(uid, packages);
if (isServiceUid(uid)) {
if (packages.isEmpty()) {
@@ -585,15 +586,20 @@
id, attr.flags);
return nullptr;
}
- return new OpPlayAudioMonitor(attributionSource, attr.usage, id);
+ return sp<OpPlayAudioMonitor>::make(thread, attributionSource, attr.usage, id, uid);
}
-OpPlayAudioMonitor::OpPlayAudioMonitor(
- const AttributionSourceState& attributionSource, audio_usage_t usage, int id)
- : mHasOpPlayAudio(true), mAttributionSource(attributionSource), mUsage((int32_t) usage),
- mId(id)
-{
-}
+OpPlayAudioMonitor::OpPlayAudioMonitor(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("")))) {}
OpPlayAudioMonitor::~OpPlayAudioMonitor()
{
@@ -609,9 +615,7 @@
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);
}
}
@@ -624,16 +628,20 @@
// - not called from PlayAudioOpCallback because the callback is not installed in this case
void 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();
+ }
}
}
@@ -759,7 +767,7 @@
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),