Snap for 12748980 from 917b6ba921f8d65f1e8e3593c36d3bbc76e09ac2 to 25Q1-release

Change-Id: I5a613e77a2fa2cc957772877615f7815c4d3a2f4
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index e72685c..ddafd57 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -1721,9 +1721,13 @@
  * audio hardware) have been played.
  *
  * The presentation end callback must be used together with the data callback.
- * The presentation edn callback won't be called if the stream is closed before all the data
+ * The presentation end callback won't be called if the stream is closed before all the data
  * is played.
  *
+ * The callback function will be called from the same thread as the data callback thread,
+ * which is a real-time thread owned by audio framework.
+ * The callback function will not be called after AAudioStream_close() is called.
+ *
  * Available since API level 36.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index 9fdde49..658fc18b 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -184,7 +184,7 @@
 status_t EffectHalAidl::process() {
     State state = State::INIT;
     if (mConversion->isBypassing() || !mEffect->getState(&state).isOk() ||
-        state != State::PROCESSING) {
+        (state != State::PROCESSING && state != State::DRAINING)) {
         ALOGI("%s skipping process because it's %s", mEffectName.c_str(),
               mConversion->isBypassing()
                       ? "bypassing"
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index f7b9b33..9107e2a 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -75,7 +75,8 @@
     bool     isEffectEnabled(int id) const;
     uint32_t getMaxEffectsCpuLoad() const;
     uint32_t getMaxEffectsMemory() const;
-    bool isNonOffloadableEffectEnabled() const;
+    bool isNonOffloadableEffectEnabled(
+            const std::optional<const effect_uuid_t>& uuid = std::nullopt) const;
 
     void moveEffects(audio_session_t session,
                      audio_io_handle_t srcOutput,
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 090da6c..6d66781 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -21,6 +21,7 @@
 
 #include "AudioInputDescriptor.h"
 #include "EffectDescriptor.h"
+#include <system/audio_effects/audio_effects_utils.h>
 #include <utils/String8.h>
 
 #include <AudioPolicyInterface.h>
@@ -157,14 +158,18 @@
     return NO_ERROR;
 }
 
-bool EffectDescriptorCollection::isNonOffloadableEffectEnabled() const
+bool EffectDescriptorCollection::isNonOffloadableEffectEnabled(
+        const std::optional<const effect_uuid_t>& uuid) const
 {
+    using namespace android::effect::utils;
     for (size_t i = 0; i < size(); i++) {
         sp<EffectDescriptor> effectDesc = valueAt(i);
-        if (effectDesc->mEnabled && (effectDesc->isMusicEffect()) &&
-                ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
-            ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
-                  effectDesc->mDesc.name, effectDesc->mSession);
+        if ((effectDesc->mEnabled && (effectDesc->isMusicEffect()) &&
+             ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) &&
+            (uuid == std::nullopt || uuid.value() == effectDesc->mDesc.uuid)) {
+            ALOGE("%s: non offloadable effect %s, uuid %s, enabled on session %d", __func__,
+                  effectDesc->mDesc.name, ToString(effectDesc->mDesc.uuid).c_str(),
+                  effectDesc->mSession);
             return true;
         }
     }