Add backward compatibility in effect hal default implementation

Skipping the reopen sequence for unsupported version
Add member initialize for EffectContext

Bug: 322780092
Test: latest libAudioHal with V1 effect HAL
Test: atest VtsHalAudioEffectTargetTest

Change-Id: I597194e5ebf25566d5adda533e151da2e99781f4
diff --git a/audio/aidl/default/EffectContext.cpp b/audio/aidl/default/EffectContext.cpp
index 4f226c4..9575790 100644
--- a/audio/aidl/default/EffectContext.cpp
+++ b/audio/aidl/default/EffectContext.cpp
@@ -22,6 +22,7 @@
 using aidl::android::hardware::audio::common::getChannelCount;
 using aidl::android::hardware::audio::common::getFrameSizeInBytes;
 using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
 using aidl::android::media::audio::common::PcmType;
 using ::android::hardware::EventFlag;
 
@@ -40,7 +41,8 @@
     mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
 
     if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) {
-        LOG(ERROR) << __func__ << " created invalid FMQ";
+        LOG(ERROR) << __func__ << " created invalid FMQ, statusMQ: " << mStatusMQ->isValid()
+                   << " inputMQ: " << mInputMQ->isValid() << " outputMQ: " << mOutputMQ->isValid();
     }
 
     ::android::status_t status =
@@ -52,7 +54,9 @@
 // reset buffer status by abandon input data in FMQ
 void EffectContext::resetBuffer() {
     auto buffer = static_cast<float*>(mWorkBuffer.data());
-    std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
+    if (mStatusMQ) {
+        std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
+    }
     if (mInputMQ) {
         mInputMQ->read(buffer, mInputMQ->availableToRead());
     }
@@ -71,7 +75,7 @@
 }
 
 void EffectContext::dupeFmq(IEffect::OpenEffectReturn* effectRet) {
-    if (effectRet) {
+    if (effectRet && mStatusMQ && mInputMQ && mOutputMQ) {
         effectRet->statusMQ = mStatusMQ->dupeDesc();
         effectRet->inputDataMQ = mInputMQ->dupeDesc();
         effectRet->outputDataMQ = mOutputMQ->dupeDesc();
@@ -191,24 +195,34 @@
 }
 
 RetCode EffectContext::updateIOFrameSize(const Parameter::Common& common) {
-    const auto iFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
+    const auto prevInputFrameSize = mInputFrameSize;
+    const auto prevOutputFrameSize = mOutputFrameSize;
+    mInputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
             common.input.base.format, common.input.base.channelMask);
-    const auto oFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
+    mOutputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
             common.output.base.format, common.output.base.channelMask);
 
+    // workBuffer and data MQ not allocated yet, no need to update
+    if (mWorkBuffer.size() == 0 || !mInputMQ || !mOutputMQ) {
+        return RetCode::SUCCESS;
+    }
+    // IEffect::reopen introduced in android.hardware.audio.effect-V2
+    if (mVersion < kReopenSupportedVersion) {
+        LOG(WARNING) << __func__ << " skipped for HAL version " << mVersion;
+        return RetCode::SUCCESS;
+    }
     bool needUpdateMq = false;
-    if (mInputMQ &&
-        (mInputFrameSize != iFrameSize || mCommon.input.frameCount != common.input.frameCount)) {
+    if (mInputFrameSize != prevInputFrameSize ||
+        mCommon.input.frameCount != common.input.frameCount) {
         mInputMQ.reset();
         needUpdateMq = true;
     }
-    if (mOutputMQ &&
-        (mOutputFrameSize != oFrameSize || mCommon.output.frameCount != common.output.frameCount)) {
+    if (mOutputFrameSize != prevOutputFrameSize ||
+        mCommon.output.frameCount != common.output.frameCount) {
         mOutputMQ.reset();
         needUpdateMq = true;
     }
-    mInputFrameSize = iFrameSize;
-    mOutputFrameSize = oFrameSize;
+
     if (needUpdateMq) {
         mWorkBuffer.resize(std::max(common.input.frameCount * mInputFrameSize / sizeof(float),
                                     common.output.frameCount * mOutputFrameSize / sizeof(float)));
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index c97a03e..4d7b980 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -49,10 +49,16 @@
     RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
                       common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
               EX_ILLEGAL_ARGUMENT, "dataMustBe32BitsFloat");
+
     std::lock_guard lg(mImplMutex);
     RETURN_OK_IF(mState != State::INIT);
     mImplContext = createContext(common);
     RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
+
+    int version = 0;
+    RETURN_IF(!getInterfaceVersion(&version).isOk(), EX_UNSUPPORTED_OPERATION,
+              "FailedToGetInterfaceVersion");
+    mImplContext->setVersion(version);
     mEventFlag = mImplContext->getStatusEventFlag();
 
     if (specific.has_value()) {
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index b3d730d..275378e 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -44,6 +44,7 @@
         }
     }
 
+    void setVersion(int version) { mVersion = version; }
     std::shared_ptr<StatusMQ> getStatusFmq() const;
     std::shared_ptr<DataMQ> getInputDataFmq() const;
     std::shared_ptr<DataMQ> getOutputDataFmq() const;
@@ -82,10 +83,11 @@
     virtual ::android::hardware::EventFlag* getStatusEventFlag();
 
   protected:
-    size_t mInputFrameSize;
-    size_t mOutputFrameSize;
-    size_t mInputChannelCount;
-    size_t mOutputChannelCount;
+    int mVersion = 0;
+    size_t mInputFrameSize = 0;
+    size_t mOutputFrameSize = 0;
+    size_t mInputChannelCount = 0;
+    size_t mOutputChannelCount = 0;
     Parameter::Common mCommon = {};
     std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice = {};
     aidl::android::media::audio::common::AudioMode mMode =
@@ -98,13 +100,13 @@
 
   private:
     // fmq and buffers
-    std::shared_ptr<StatusMQ> mStatusMQ;
-    std::shared_ptr<DataMQ> mInputMQ;
-    std::shared_ptr<DataMQ> mOutputMQ;
+    std::shared_ptr<StatusMQ> mStatusMQ = nullptr;
+    std::shared_ptr<DataMQ> mInputMQ = nullptr;
+    std::shared_ptr<DataMQ> mOutputMQ = nullptr;
     // std::shared_ptr<IEffect::OpenEffectReturn> mRet;
     // work buffer set by effect instances, the access and update are in same thread
-    std::vector<float> mWorkBuffer;
+    std::vector<float> mWorkBuffer = {};
 
-    ::android::hardware::EventFlag* mEfGroup;
+    ::android::hardware::EventFlag* mEfGroup = nullptr;
 };
 }  // namespace aidl::android::hardware::audio::effect