Cache the volume that should be applied before the volume control.

Once the volume is set successfully, there is a cache for the volume so
that there is no need to call set volume again to the effect if the
requested volume is the same as the cached value. Besides caching the
volume, it is also necessary the returned volume value as it is used to
indicate what should be the volume level to apply before the volume
effect. When the requested volume is the same as the cached one, the
setVolume API should return the cached returned value.

Bug: 334207991
Test: repro steps in the bug
Change-Id: Ica44459da2f82b5e2e4f71984c528acbc4588863
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 9406bcd..ad043c8 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1378,6 +1378,11 @@
 status_t EffectModule::setVolumeInternal(
         uint32_t *left, uint32_t *right, bool controller) {
     if (mVolume.has_value() && *left == mVolume.value()[0] && *right == mVolume.value()[1]) {
+        LOG_ALWAYS_FATAL_IF(
+                !mReturnedVolume.has_value(),
+                "The cached returned volume must not be null when the cached volume has value");
+        *left = mReturnedVolume.value()[0];
+        *right = mReturnedVolume.value()[1];
         return NO_ERROR;
     }
     LOG_ALWAYS_FATAL_IF(mEffectInterface == nullptr, "%s", mEffectInterfaceDebug.c_str());
@@ -1393,6 +1398,7 @@
         mVolume = {*left, *right}; // Cache the value that has been set
         *left = volume[0];
         *right = volume[1];
+        mReturnedVolume = {*left, *right};
     }
     return status;
 }
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 64a4e62..b516c37 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -307,7 +307,11 @@
     // this tid is allowed to call setVolume() without acquiring the mutex.
     pid_t mSetVolumeReentrantTid = INVALID_PID;
 
+    // Cache the volume that has been set successfully.
     std::optional<std::vector<uint32_t>> mVolume;
+    // Cache the volume that returned from the effect when setting volume successfully. The value
+    // here is used to indicate the volume to apply before this effect.
+    std::optional<std::vector<uint32_t>> mReturnedVolume;
     // TODO: b/315995877, remove this debugging string after root cause
     std::string mEffectInterfaceDebug;
 };