Merge "libaudiohal@aidl: Process telephony parameters" into udc-qpr-dev
diff --git a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
index 332d3ac..bb6c1b8 100644
--- a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
@@ -82,6 +82,7 @@
         return false;
     }
 
+    // Default scenario --- the consumer is display or GPU
     const AHardwareBuffer_Desc desc = {
             .width = 320,
             .height = 240,
@@ -96,7 +97,40 @@
             .rfu1 = 0,
     };
 
-    return AHardwareBuffer_isSupported(&desc);
+    // The consumer is a HW encoder
+    const AHardwareBuffer_Desc descHwEncoder = {
+            .width = 320,
+            .height = 240,
+            .format = format,
+            .layers = 1,
+            .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY |
+                     AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
+                     AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
+                     AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY |
+                     AHARDWAREBUFFER_USAGE_VIDEO_ENCODE,
+            .stride = 0,
+            .rfu0 = 0,
+            .rfu1 = 0,
+    };
+
+    // The consumer is a SW encoder
+    const AHardwareBuffer_Desc descSwEncoder = {
+            .width = 320,
+            .height = 240,
+            .format = format,
+            .layers = 1,
+            .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
+                     AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
+                     AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
+                     AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY,
+            .stride = 0,
+            .rfu0 = 0,
+            .rfu1 = 0,
+    };
+
+    return AHardwareBuffer_isSupported(&desc)
+            && AHardwareBuffer_isSupported(&descHwEncoder)
+            && AHardwareBuffer_isSupported(&descSwEncoder);
 }
 
 }  // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index 72aa7d8..049c358 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -209,12 +209,12 @@
             mEffect->close();
             return status;
         }
-        mCommon = common;
     } else if (mCommon != common) {
         ALOGI("%s at state %s, setParameter", __func__, android::internal::ToString(state).c_str());
-        Parameter aidlParam = UNION_MAKE(Parameter, common, mCommon);
+        Parameter aidlParam = UNION_MAKE(Parameter, common, common);
         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam)));
     }
+    mCommon = common;
 
     return *static_cast<int32_t*>(pReplyData) = OK;
 }
@@ -352,9 +352,14 @@
     if (mIsProxyEffect) {
         ALOGI("%s offload param offload %s ioHandle %d", __func__,
               offload->isOffload ? "true" : "false", offload->ioHandle);
-        mCommon.ioHandle = offload->ioHandle;
         const auto& effectProxy = std::static_pointer_cast<EffectProxy>(mEffect);
         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(effectProxy->setOffloadParam(offload)));
+        if (mCommon.ioHandle != offload->ioHandle) {
+            ALOGI("%s ioHandle update [%d to %d]", __func__, mCommon.ioHandle, offload->ioHandle);
+            mCommon.ioHandle = offload->ioHandle;
+            Parameter aidlParam = UNION_MAKE(Parameter, common, mCommon);
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->setParameter(aidlParam)));
+        }
         // update FMQs if the effect instance already open
         if (State state; effectProxy->getState(&state).isOk() && state != State::INIT) {
             mStatusQ = effectProxy->getStatusMQ();
diff --git a/media/libaudiohal/impl/EffectProxy.cpp b/media/libaudiohal/impl/EffectProxy.cpp
index f83d479..cb5b4b9 100644
--- a/media/libaudiohal/impl/EffectProxy.cpp
+++ b/media/libaudiohal/impl/EffectProxy.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <algorithm>
+#include <cstddef>
 #include <iterator>
 #include <memory>
 #define LOG_TAG "EffectProxy"
@@ -90,12 +91,16 @@
                                                                 "noActiveEffctFound");
     }
 
-    mActiveSubIdx = std::distance(mSubEffects.begin(), itor);
-    ALOGV("%s: active %soffload sub-effect %zu descriptor: %s", __func__,
+    const size_t newIndex = std::distance(mSubEffects.begin(), itor);
+    mActiveSubIdx = newIndex;
+
+    ALOGI("%s: active %soffload sub-effect %zu descriptor: %s", __func__,
           offload->isOffload ? "" : "non-", mActiveSubIdx,
           ::android::audio::utils::toString(mSubEffects[mActiveSubIdx].descriptor.common.id.uuid)
                   .c_str());
-    return ndk::ScopedAStatus::ok();
+    return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
+        return effect->setParameter(Parameter::make<Parameter::offload>(offload->isOffload));
+    });
 }
 
 // EffectProxy go over sub-effects and call IEffect interfaces
@@ -133,8 +138,8 @@
 }
 
 ndk::ScopedAStatus EffectProxy::getDescriptor(Descriptor* desc) {
-    desc->common = mDescriptorCommon;
-    desc->capability = mSubEffects[mActiveSubIdx].descriptor.capability;
+    *desc = mSubEffects[mActiveSubIdx].descriptor;
+    desc->common.id.uuid = desc->common.id.proxy.value();
     return ndk::ScopedAStatus::ok();
 }
 
@@ -168,7 +173,7 @@
         // same as HIDL EffectProxy flags
         common.flags.type = Flags::Type::INSERT;
         common.flags.insert = Flags::Insert::LAST;
-        common.flags.volume = Flags::Volume::CTRL;
+        common.flags.volume = Flags::Volume::NONE;
 
         // set indication if any sub-effect indication was set
         common.flags.offloadIndication |= desc.common.flags.offloadIndication;
diff --git a/media/libaudiohal/tests/EffectProxy_test.cpp b/media/libaudiohal/tests/EffectProxy_test.cpp
index 8668e85..2953b0a 100644
--- a/media/libaudiohal/tests/EffectProxy_test.cpp
+++ b/media/libaudiohal/tests/EffectProxy_test.cpp
@@ -53,7 +53,9 @@
     void SetUp() override {
         auto serviceName = android::getAidlHalInstanceNames(IFactory::descriptor);
         // only unit test with the first one in case more than one EffectFactory service exist
-        ASSERT_NE(0ul, serviceName.size());
+        if (0ul == serviceName.size()) {
+            GTEST_SKIP() << "EffectFactory not available on device, skipping";
+        }
         mFactory = IFactory::fromBinder(
                 ndk::SpAIBinder(AServiceManager_waitForService(serviceName[0].c_str())));
         ASSERT_NE(nullptr, mFactory);
@@ -157,6 +159,7 @@
         effect_offload_param_t offloadParam{false, 0};
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
         offloadParam.isOffload = true;
+        offloadParam.ioHandle++;
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
         EXPECT_TRUE(proxy->close().isOk());
         EXPECT_TRUE(proxy->destroy().isOk());
@@ -189,21 +192,21 @@
     Parameter::Common common = createParamCommon();
     IEffect::OpenEffectReturn ret;
     Parameter::VolumeStereo volumeStereo({.left = .1f, .right = -0.8f});
-    Parameter param = Parameter::make<Parameter::volumeStereo>(volumeStereo);
-    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
+    Parameter expect = Parameter::make<Parameter::volumeStereo>(volumeStereo);
+    const Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
     State state;
     for (const auto& itor : proxyMap) {
-        Parameter expect;
+        Parameter getParam = Parameter::make<Parameter::offload>(true);
         auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
         effect_offload_param_t offloadParam{true, 0};
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
 
         EXPECT_TRUE(proxy->open(common, std::nullopt, &ret).isOk());
 
-        EXPECT_TRUE(proxy->setParameter(param).isOk());
-        EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
-        EXPECT_EQ(expect, param) << " EXPECTED: " << expect.toString()
-                                 << "\nACTUAL: " << param.toString();
+        EXPECT_TRUE(proxy->setParameter(expect).isOk());
+        EXPECT_TRUE(proxy->getParameter(id, &getParam).isOk());
+        EXPECT_EQ(expect, getParam)
+                << " EXPECTED: " << expect.toString() << "\nACTUAL: " << getParam.toString();
 
         EXPECT_TRUE(proxy->command(CommandId::START).isOk());
         EXPECT_TRUE(proxy->getState(&state).isOk());
@@ -225,25 +228,25 @@
     Parameter::Common common = createParamCommon();
     IEffect::OpenEffectReturn ret;
     Parameter::VolumeStereo volumeStereo({.left = .5f, .right = .8f});
-    Parameter param = Parameter::make<Parameter::volumeStereo>(volumeStereo);
-    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
+    Parameter expect = Parameter::make<Parameter::volumeStereo>(volumeStereo);
+    const Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
     for (const auto& itor : proxyMap) {
-        Parameter expect;
+        Parameter getParam = Parameter::make<Parameter::offload>(true);
         auto& proxy = std::get<TupleIndex::HANDLE>(itor.second);
         EXPECT_TRUE(proxy->open(common, std::nullopt, &ret).isOk());
-        EXPECT_TRUE(proxy->setParameter(param).isOk());
-        EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
-        EXPECT_EQ(expect, param);
+        EXPECT_TRUE(proxy->setParameter(expect).isOk());
+        EXPECT_TRUE(proxy->getParameter(id, &getParam).isOk());
+        EXPECT_EQ(expect, getParam);
 
         effect_offload_param_t offloadParam{false, 0};
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
-        EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
-        EXPECT_EQ(expect, param);
+        EXPECT_TRUE(proxy->getParameter(id, &getParam).isOk());
+        EXPECT_EQ(expect, getParam);
 
         offloadParam.isOffload = true;
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
-        EXPECT_TRUE(proxy->getParameter(id, &expect).isOk());
-        EXPECT_EQ(expect, param);
+        EXPECT_TRUE(proxy->getParameter(id, &getParam).isOk());
+        EXPECT_EQ(expect, getParam);
 
         EXPECT_TRUE(proxy->close().isOk());
         EXPECT_TRUE(proxy->destroy().isOk());
@@ -271,13 +274,9 @@
 
         effect_offload_param_t offloadParam{false, 0};
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
-        EXPECT_TRUE(proxy->getState(&state).isOk());
-        EXPECT_EQ(State::PROCESSING, state);
 
         offloadParam.isOffload = true;
         EXPECT_TRUE(proxy->setOffloadParam(&offloadParam).isOk());
-        EXPECT_TRUE(proxy->getState(&state).isOk());
-        EXPECT_EQ(State::PROCESSING, state);
 
         EXPECT_TRUE(proxy->command(CommandId::STOP).isOk());
         EXPECT_TRUE(proxy->getState(&state).isOk());
diff --git a/media/libeffects/visualizer/aidl/VisualizerContext.cpp b/media/libeffects/visualizer/aidl/VisualizerContext.cpp
index 5d0d08d..a1726ad 100644
--- a/media/libeffects/visualizer/aidl/VisualizerContext.cpp
+++ b/media/libeffects/visualizer/aidl/VisualizerContext.cpp
@@ -223,8 +223,7 @@
         deltaSamples = kMaxCaptureBufSize;
     }
 
-    int32_t capturePoint;
-    //capturePoint = (int32_t)mCaptureIdx - deltaSamples;
+    int32_t capturePoint, captureSamples = mCaptureSamples;
     __builtin_sub_overflow((int32_t) mCaptureIdx, deltaSamples, &capturePoint);
     // a negative capturePoint means we wrap the buffer.
     if (capturePoint < 0) {
@@ -232,13 +231,14 @@
         if (size > mCaptureSamples) {
             size = mCaptureSamples;
         }
+        // first part of two stages copy, capture to the end of buffer and reset the size/point
         result.insert(result.end(), &mCaptureBuf[kMaxCaptureBufSize + capturePoint],
                         &mCaptureBuf[kMaxCaptureBufSize + capturePoint + size]);
-        mCaptureSamples -= size;
+        captureSamples -= size;
         capturePoint = 0;
     }
     result.insert(result.end(), &mCaptureBuf[capturePoint],
-                    &mCaptureBuf[capturePoint + mCaptureSamples]);
+                  &mCaptureBuf[capturePoint + captureSamples]);
     mLastCaptureIdx = mCaptureIdx;
     return result;
 }