APC: Wake OffloadThread on AppOps mute

Bug: 289885996
Test: atest AudioPlaybackConfigurationTest with setprop audio.offload.min.duration.secs 1
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:9d7c6f8f6649574362e087641a7b50805294a07c)

Merged-In: I93c3a507eb3f9146ff8d80ce5f34ea0e46a49e5a
Change-Id: I93c3a507eb3f9146ff8d80ce5f34ea0e46a49e5a
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 78da621..2602efb 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -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);
 
@@ -53,10 +57,13 @@
     // 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
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 18c57ca..4f4ad93 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -511,11 +511,12 @@
 // 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));
+    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()) {
@@ -537,15 +538,21 @@
             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()
 {
@@ -561,9 +568,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);
     }
 }
 
@@ -576,16 +581,20 @@
 // - 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();
+        }
     }
 }
 
@@ -662,7 +671,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),