Merge changes from topic "inputsurfaceconnection" into main

* changes:
  InputSurface: implement InputSurfaceConnection
  InputSurface: add FrameQueueThread
  InputSurface: input buffer work status config update
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 1a6e5e8..db00a22 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -757,7 +757,8 @@
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_HEVC)  ? asString_HEVCProfile(pl.mProfile) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP9)   ? asString_VP9Profile(pl.mProfile) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)   ? asString_AV1Profile(pl.mProfile) :
-                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION) ? asString_DolbyVisionProfile(pl.mProfile) :"??";
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION) ? asString_DolbyVisionProfile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_AUDIO_AC4)   ? asString_AC4Profile(pl.mProfile) : "??";
                     const char *niceLevel =
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_MPEG2) ? asString_MPEG2Level(pl.mLevel) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_H263)  ? asString_H263Level(pl.mLevel) :
@@ -768,6 +769,7 @@
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP9)   ? asString_VP9Level(pl.mLevel) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)   ? asString_AV1Level(pl.mLevel) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION) ? asString_DolbyVisionLevel(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_AUDIO_AC4)   ? asString_AC4Level(pl.mLevel) :
                         "??";
 
                     list.add(AStringPrintf("% 5u/% 5u (%s/%s)",
diff --git a/media/codec2/components/iamf/Android.bp b/media/codec2/components/iamf/Android.bp
index 8b6c8fa..8d5ee6a 100644
--- a/media/codec2/components/iamf/Android.bp
+++ b/media/codec2/components/iamf/Android.bp
@@ -4,10 +4,15 @@
 
 cc_library {
     name: "libcodec2_soft_iamfdec",
-
-    srcs: [],
+    defaults: [
+        "libcodec2_soft-defaults",
+        "libcodec2_soft_sanitize_all-defaults",
+    ],
+    srcs: [
+        "C2SoftIamfDec.cpp",
+    ],
 
     shared_libs: [
-        // iamf_tools library will need to go here.
+        "iamf_tools",
     ],
 }
diff --git a/media/codec2/components/iamf/C2SoftIamfDec.cpp b/media/codec2/components/iamf/C2SoftIamfDec.cpp
index cfd5369..88d1a25 100644
--- a/media/codec2/components/iamf/C2SoftIamfDec.cpp
+++ b/media/codec2/components/iamf/C2SoftIamfDec.cpp
@@ -17,6 +17,10 @@
 #define LOG_TAG "C2SoftIamfDec"
 #include <log/log.h>
 
+#include <C2PlatformSupport.h>
+#include <SimpleC2Interface.h>
+#include "C2SoftIamfDec.h"
+
 namespace android {
 
 namespace {
@@ -35,13 +39,12 @@
         // Configure (e.g. noPrivateBuffers(), etc.)
         // Add parameters.
     }
-}
+};
 
 C2SoftIamfDec::C2SoftIamfDec(const char* name, c2_node_id_t id,
                              const std::shared_ptr<IntfImpl>& intfImpl)
     : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
-      mIntf(intfImpl) {
-}
+      mIntf(intfImpl) {}
 
 C2SoftIamfDec::~C2SoftIamfDec() {
     onRelease();
@@ -69,11 +72,65 @@
 
 void C2SoftIamfDec::process(const std::unique_ptr<C2Work>& work,
                             const std::shared_ptr<C2BlockPool>& pool) {
-    return;
+    (void)pool;  // Temporary solution to suppress unused var.
+    work->result = C2_NO_INIT;
 }
 
 c2_status_t C2SoftIamfDec::drain(uint32_t drainMode, const std::shared_ptr<C2BlockPool>& pool) {
-    return C2_NO_INIT;
+    (void)pool;
+    if (drainMode == NO_DRAIN) {
+        ALOGW("drain with NO_DRAIN: no-op");
+        return C2_OK;
+    }
+    if (drainMode == DRAIN_CHAIN) {
+        ALOGW("DRAIN_CHAIN not supported");
+        return C2_OMITTED;
+    }
+
+    return C2_OK;
 }
 
+class C2SoftIamfDecFactory : public C2ComponentFactory {
+  public:
+    C2SoftIamfDecFactory()
+        : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
+                  GetCodec2PlatformComponentStore()->getParamReflector())) {}
+
+    virtual c2_status_t createComponent(c2_node_id_t id,
+                                        std::shared_ptr<C2Component>* const component,
+                                        std::function<void(C2Component*)> deleter) override {
+        *component = std::shared_ptr<C2Component>(
+                new C2SoftIamfDec(COMPONENT_NAME, id,
+                                  std::make_shared<C2SoftIamfDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual c2_status_t createInterface(
+            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
+            std::function<void(C2ComponentInterface*)> deleter) override {
+        *interface = std::shared_ptr<C2ComponentInterface>(
+                new SimpleInterface<C2SoftIamfDec::IntfImpl>(
+                        COMPONENT_NAME, id, std::make_shared<C2SoftIamfDec::IntfImpl>(mHelper)),
+                deleter);
+        return C2_OK;
+    }
+
+    virtual ~C2SoftIamfDecFactory() override = default;
+
+  private:
+    std::shared_ptr<C2ReflectorHelper> mHelper;
+};
+
 }  // namespace android
+
+__attribute__((cfi_canonical_jump_table)) extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
+    ALOGV("in %s", __func__);
+    return new ::android::C2SoftIamfDecFactory();
+}
+
+__attribute__((cfi_canonical_jump_table)) extern "C" void DestroyCodec2Factory(
+        ::C2ComponentFactory* factory) {
+    ALOGV("in %s", __func__);
+    delete factory;
+}
diff --git a/media/codec2/components/iamf/C2SoftIamfDec.h b/media/codec2/components/iamf/C2SoftIamfDec.h
index 547b3ba..0cc9492 100644
--- a/media/codec2/components/iamf/C2SoftIamfDec.h
+++ b/media/codec2/components/iamf/C2SoftIamfDec.h
@@ -22,10 +22,10 @@
 namespace android {
 
 class C2SoftIamfDec : public SimpleC2Component {
+  public:
     // Forward declaration of the C2 interface implementation.
     class IntfImpl;
 
-  public:
     C2SoftIamfDec(const char* name, c2_node_id_t id, const std::shared_ptr<IntfImpl>& intfImpl);
     virtual ~C2SoftIamfDec();
 
@@ -41,7 +41,9 @@
 
   private:
     std::shared_ptr<IntfImpl> mIntf;
-}
+
+    C2_DO_NOT_COPY(C2SoftIamfDec);
+};
 
 }  // namespace android
 
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 458cfb3..7c206b5 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -29,8 +29,8 @@
  * Enumerated boolean.
  */
 C2ENUM(c2_bool_t, uint32_t,
-    C2_FALSE, ///< true
-    C2_TRUE,  ///< false
+    C2_FALSE, ///< false
+    C2_TRUE,  ///< true
 )
 
 typedef C2SimpleValueStruct<c2_bool_t> C2BoolValue;
@@ -447,7 +447,8 @@
     _C2_PL_VP8_BASE  = 0xA000,
     _C2_PL_MPEGH_BASE = 0xB000,     // MPEG-H 3D Audio
     _C2_PL_APV_BASE = 0xC000,     // APV
-
+    _C2_PL_AC4_BASE  = 0xD000,
+    _C2_PL_IAMF_START = 0xE000,
     C2_PROFILE_LEVEL_VENDOR_START = 0x70000000,
 };
 
@@ -623,6 +624,30 @@
     PROFILE_APV_4444_10,                        ///< APV 4444-10 Profile
     PROFILE_APV_4444_12,                        ///< APV 4444-12 Profile
     PROFILE_APV_400_10,                         ///< APV 400-10 Profile
+
+    // AC-4 profiles
+    // Below profiles are labelled “AC-4 Profile xx.yy” where xx is the bitstream_version
+    // and yy is the presentation_version as described in "The MIME codecs parameter", Annex E.13
+    // found at https://www.etsi.org/deliver/etsi_ts/103100_103199/10319002/01.02.01_60/ts_10319002v010201p.pdf
+    PROFILE_AC4_0_0 = _C2_PL_AC4_BASE,          ///< AC-4 Profile 00.00
+    PROFILE_AC4_1_0,                            ///< AC-4 Profile 01.00
+    PROFILE_AC4_1_1,                            ///< AC-4 Profile 01.01
+    PROFILE_AC4_2_1,                            ///< AC-4 Profile 02.01
+    PROFILE_AC4_2_2,                            ///< AC-4 Profile 02.02
+
+    // IAMF Profiles
+    PROFILE_IAMF_SIMPLE_AAC = _C2_PL_IAMF_START, ///< IAMF Simple Profile with AAC
+    PROFILE_IAMF_SIMPLE_FLAC,                    ///< IAMF Simple Profile with FLAC
+    PROFILE_IAMF_SIMPLE_OPUS,                    ///< IAMF Simple Profile with Opus
+    PROFILE_IAMF_SIMPLE_PCM,                     ///< IAMF Simple Profile with PCM
+    PROFILE_IAMF_BASE_AAC,                       ///< IAMF Base Profile with AAC
+    PROFILE_IAMF_BASE_FLAC,                      ///< IAMF Base Profile with FLAC
+    PROFILE_IAMF_BASE_OPUS,                      ///< IAMF Base Profile with Opus
+    PROFILE_IAMF_BASE_PCM,                       ///< IAMF Base Profile with PCM
+    PROFILE_IAMF_BASE_ENHANCED_AAC,              ///< IAMF Base Enhanced with AAC
+    PROFILE_IAMF_BASE_ENHANCED_FLAC,             ///< IAMF Base Enhanced with FLAC
+    PROFILE_IAMF_BASE_ENHANCED_OPUS,             ///< IAMF Base Enhanced with Opus
+    PROFILE_IAMF_BASE_ENHANCED_PCM,              ///< IAMF Base Enhanced with PCM
 };
 
 enum C2Config::level_t : uint32_t {
@@ -840,6 +865,15 @@
     LEVEL_APV_7_BAND_3,                              ///< APV L 7, BAND 3
     LEVEL_APV_7_1_BAND_3,                            ///< APV L 7.1, BAND 3
 
+    // AC-4 levels
+    // Below levels are labelled “AC-4 Level zz” where zz is the mdcompat as described in
+    // "The MIME codecs parameter", Annex E.13
+    // found at https://www.etsi.org/deliver/etsi_ts/103100_103199/10319002/01.02.01_60/ts_10319002v010201p.pdf
+    LEVEL_AC4_0 = _C2_PL_AC4_BASE,              ///< AC-4 Level 00
+    LEVEL_AC4_1,                                ///< AC-4 Level 01
+    LEVEL_AC4_2,                                ///< AC-4 Level 02
+    LEVEL_AC4_3,                                ///< AC-4 Level 03
+    LEVEL_AC4_4,                                ///< AC-4 Level 04
 };
 
 struct C2ProfileLevelStruct {
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.cpp b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
index 3841831..925a1b37e 100644
--- a/media/codec2/sfplugin/utils/Codec2Mapper.cpp
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
@@ -547,6 +547,22 @@
     { C2Config::picture_type_t::B_FRAME,        PICTURE_TYPE_B },
 };
 
+ALookup<C2Config::profile_t, int32_t> sAc4Profiles = {
+    { C2Config::PROFILE_AC4_0_0, AC4Profile00 },
+    { C2Config::PROFILE_AC4_1_0, AC4Profile10 },
+    { C2Config::PROFILE_AC4_1_1, AC4Profile11 },
+    { C2Config::PROFILE_AC4_2_1, AC4Profile21 },
+    { C2Config::PROFILE_AC4_2_2, AC4Profile22 },
+};
+
+ALookup<C2Config::level_t, int32_t> sAc4Levels = {
+    { C2Config::LEVEL_AC4_0, AC4Level0 },
+    { C2Config::LEVEL_AC4_1, AC4Level1 },
+    { C2Config::LEVEL_AC4_2, AC4Level2 },
+    { C2Config::LEVEL_AC4_3, AC4Level3 },
+    { C2Config::LEVEL_AC4_4, AC4Level4 },
+};
+
 /**
  * A helper that passes through vendor extension profile and level values.
  */
@@ -831,6 +847,21 @@
     bool mIsHdr10Plus;
 };
 
+struct Ac4ProfileLevelMapper : ProfileLevelMapperHelper {
+    virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
+        return sAc4Levels.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
+        return sAc4Levels.map(from, to);
+    }
+    virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
+        return sAc4Profiles.map(from, to);
+    }
+    virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
+        return sAc4Profiles.map(from, to);
+    }
+};
+
 } // namespace
 
 // the default mapper is used for media types that do not support HDR
@@ -866,6 +897,8 @@
         return std::make_shared<Av1ProfileLevelMapper>();
     } else if (mediaType == MIMETYPE_VIDEO_APV) {
         return std::make_shared<ApvProfileLevelMapper>();
+    } else if (mediaType == MIMETYPE_AUDIO_AC4) {
+        return std::make_shared<Ac4ProfileLevelMapper>();
     }
     return nullptr;
 }
diff --git a/media/codec2/vndk/C2Config.cpp b/media/codec2/vndk/C2Config.cpp
index e9223fb..fa90c5a 100644
--- a/media/codec2/vndk/C2Config.cpp
+++ b/media/codec2/vndk/C2Config.cpp
@@ -150,6 +150,11 @@
         { "mpegh-high", C2Config::PROFILE_MPEGH_HIGH },
         { "mpegh-lc", C2Config::PROFILE_MPEGH_LC },
         { "mpegh-baseline", C2Config::PROFILE_MPEGH_BASELINE },
+        { "ac4-00-00", C2Config::PROFILE_AC4_0_0 },
+        { "ac4-01-00", C2Config::PROFILE_AC4_1_0 },
+        { "ac4-01-01", C2Config::PROFILE_AC4_1_1 },
+        { "ac4-02-01", C2Config::PROFILE_AC4_2_1 },
+        { "ac4-02-02", C2Config::PROFILE_AC4_2_2 },
 }))
 
 DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(C2Config::level_t, ({
@@ -261,6 +266,11 @@
         { "mpegh-3", C2Config::LEVEL_MPEGH_3 },
         { "mpegh-4", C2Config::LEVEL_MPEGH_4 },
         { "mpegh-5", C2Config::LEVEL_MPEGH_5 },
+        { "ac4-00", C2Config::LEVEL_AC4_0 },
+        { "ac4-01", C2Config::LEVEL_AC4_1 },
+        { "ac4-02", C2Config::LEVEL_AC4_2 },
+        { "ac4-03", C2Config::LEVEL_AC4_3 },
+        { "ac4-04", C2Config::LEVEL_AC4_4 },
 }))
 
 DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(C2BufferData::type_t, ({
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.cpp b/media/libaudiohal/impl/Hal2AidlMapper.cpp
index 0cdf0f2..5642b6e 100644
--- a/media/libaudiohal/impl/Hal2AidlMapper.cpp
+++ b/media/libaudiohal/impl/Hal2AidlMapper.cpp
@@ -1176,7 +1176,8 @@
 }
 
 void Hal2AidlMapper::updateDynamicMixPorts() {
-    for (int32_t portId : mDynamicMixPortIds) {
+    const auto dynamicMixPortIds = mDynamicMixPortIds;
+    for (int32_t portId : dynamicMixPortIds) {
         if (auto it = mPorts.find(portId); it != mPorts.end()) {
             updateAudioPort(portId, &it->second);
         } else {
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 4e9b547..c0cabe3 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -428,10 +428,15 @@
         AUGMENT_LOG(W, "No position was reported by the HAL");
         return INVALID_OPERATION;
     }
-    int64_t mostRecentResetPoint = std::max(statePositions.hardware.framesAtStandby,
-                                            statePositions.hardware.framesAtFlushOrDrain);
-    int64_t aidlFrames = reply.hardware.frames;
-    *frames = aidlFrames <= mostRecentResetPoint ? 0 : aidlFrames - mostRecentResetPoint;
+    if (mSupportsCreateMmapBuffer) {
+        // HAL is required to report continuous position. Reset for compatibility.
+        int64_t mostRecentResetPoint = std::max(statePositions.hardware.framesAtStandby,
+                statePositions.hardware.framesAtFlushOrDrain);
+        int64_t aidlFrames = reply.hardware.frames;
+        *frames = aidlFrames <= mostRecentResetPoint ? 0 : aidlFrames - mostRecentResetPoint;
+    } else {
+        *frames = reply.hardware.frames;
+    }
     *timestamp = reply.hardware.timeNs;
     return OK;
 }
@@ -771,13 +776,13 @@
                     } else if (command.getTag() == StreamDescriptor::Command::flush &&
                             reply->state == StreamDescriptor::State::IDLE) {
                         mStatePositions.observable.framesAtFlushOrDrain = reply->observable.frames;
-                        mStatePositions.hardware.framesAtFlushOrDrain = reply->observable.frames;
+                        mStatePositions.hardware.framesAtFlushOrDrain = reply->hardware.frames;
                     } else if (!mContext.isAsynchronous() &&
                             command.getTag() == StreamDescriptor::Command::drain &&
                             (reply->state == StreamDescriptor::State::IDLE ||
                                     reply->state == StreamDescriptor::State::DRAINING)) {
                         mStatePositions.observable.framesAtFlushOrDrain = reply->observable.frames;
-                        mStatePositions.hardware.framesAtFlushOrDrain = reply->observable.frames;
+                        mStatePositions.hardware.framesAtFlushOrDrain = reply->hardware.frames;
                     } // for asynchronous drain, the frame count is saved in 'onAsyncDrainReady'
                 }
                 if (mContext.isAsynchronous() &&
diff --git a/media/libeffects/preprocessing/aidl/PreProcessingContext.cpp b/media/libeffects/preprocessing/aidl/PreProcessingContext.cpp
index 2d549ef..613196d 100644
--- a/media/libeffects/preprocessing/aidl/PreProcessingContext.cpp
+++ b/media/libeffects/preprocessing/aidl/PreProcessingContext.cpp
@@ -16,6 +16,7 @@
 
 #include <cstddef>
 #define LOG_TAG "PreProcessingContext"
+#include <audio_utils/primitives.h>
 #include <Utils.h>
 
 #include "PreProcessingContext.h"
@@ -137,7 +138,7 @@
 }
 
 RetCode PreProcessingContext::setCommon(const Parameter::Common& common) {
-    if(auto ret = updateIOFrameSize(common); ret != RetCode::SUCCESS) {
+    if (auto ret = updateIOFrameSize(common); ret != RetCode::SUCCESS) {
         return ret;
     }
     mCommon = common;
@@ -148,10 +149,10 @@
 void PreProcessingContext::updateConfigs(const Parameter::Common& common) {
     mInputConfig.set_sample_rate_hz(common.input.base.sampleRate);
     mInputConfig.set_num_channels(::aidl::android::hardware::audio::common::getChannelCount(
-                    common.input.base.channelMask));
+            common.input.base.channelMask));
     mOutputConfig.set_sample_rate_hz(common.input.base.sampleRate);
     mOutputConfig.set_num_channels(::aidl::android::hardware::audio::common::getChannelCount(
-                    common.output.base.channelMask));
+            common.output.base.channelMask));
 }
 
 RetCode PreProcessingContext::setAcousticEchoCancelerEchoDelay(int echoDelayUs) {
@@ -267,33 +268,41 @@
     RETURN_VALUE_IF(inputFrameCount != outputFrameCount, status, "FrameCountMismatch");
     RETURN_VALUE_IF(0 == getInputFrameSize(), status, "zeroFrameSize");
 
-    mProcessedMsk |= (1 << int(mType));
 
     // webrtc implementation clear out was_stream_delay_set every time after ProcessStream() call
     mAudioProcessingModule->set_stream_delay_ms(mEchoDelayUs / 1000);
 
+    std::vector<int16_t> in16(samples);
+    std::vector<int16_t> out16(samples, 0);
+    memcpy_to_i16_from_float(in16.data(), in, samples);
+
+    mProcessedMsk |= (1 << int(mType));
+
     if ((mProcessedMsk & mEnabledMsk) == mEnabledMsk) {
         mProcessedMsk = 0;
-        int processStatus = mAudioProcessingModule->ProcessStream(
-                (const int16_t* const)in, mInputConfig, mOutputConfig, (int16_t* const)out);
+        int processStatus = mAudioProcessingModule->ProcessStream(in16.data(), mInputConfig,
+                                                                  mOutputConfig, out16.data());
         if (processStatus != 0) {
             LOG(ERROR) << "Process stream failed with error " << processStatus;
             return status;
         }
     }
 
-    mRevProcessedMsk |= (1 << int(mType));
-
-    if ((mRevProcessedMsk & mRevEnabledMsk) == mRevEnabledMsk) {
-        mRevProcessedMsk = 0;
-        int revProcessStatus = mAudioProcessingModule->ProcessReverseStream(
-                (const int16_t* const)in, mInputConfig, mInputConfig, (int16_t* const)out);
-        if (revProcessStatus != 0) {
-            LOG(ERROR) << "Process reverse stream failed with error " << revProcessStatus;
-            return status;
+    if (mType == PreProcessingEffectType::ACOUSTIC_ECHO_CANCELLATION) {
+        mRevProcessedMsk |= (1 << int(mType));
+        if ((mRevProcessedMsk & mRevEnabledMsk) == mRevEnabledMsk) {
+            mRevProcessedMsk = 0;
+            int revProcessStatus = mAudioProcessingModule->ProcessReverseStream(
+                    in16.data(), mInputConfig, mInputConfig, out16.data());
+            if (revProcessStatus != 0) {
+                LOG(ERROR) << "Process reverse stream failed with error " << revProcessStatus;
+                return status;
+            }
         }
     }
 
+    memcpy_to_float_from_i16(out, out16.data(), samples);
+
     return {STATUS_OK, samples, samples};
 }
 
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 0067344..de9c93b 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -390,7 +390,9 @@
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)
                             ? asString_AV1Profile(pl.mProfile) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION)
-                            ? asString_DolbyVisionProfile(pl.mProfile) : "??";
+                            ? asString_DolbyVisionProfile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_AUDIO_AC4)
+                            ? asString_AC4Profile(pl.mProfile) : "??";
                     const char *niceLevel =
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_MPEG2)
                             ? asString_MPEG2Level(pl.mLevel) :
@@ -409,7 +411,9 @@
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)
                             ? asString_AV1Level(pl.mLevel) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION)
-                            ? asString_DolbyVisionLevel(pl.mLevel) : "??";
+                            ? asString_DolbyVisionLevel(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_AUDIO_AC4)
+                            ? asString_AC4Level(pl.mLevel) : "??";
 
                     list.add(AStringPrintf("% 5u/% 5u (%s/%s)",
                             pl.mProfile, pl.mLevel, niceProfile, niceLevel));
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index 85d4376..d1f9da2 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -719,6 +719,54 @@
     }
 }
 
+// Profiles and levels for AC-4 Codec, corresponding to the definitions in
+// "The MIME codecs parameter", Annex E.13
+// found at https://www.etsi.org/deliver/etsi_ts/103100_103199/10319002/01.02.01_60/ts_10319002v010201p.pdf
+// profile = ((1 << bitstream_version) << 8) | (1 << presentation_version);
+// level = 1 << mdcompat;
+
+inline constexpr int32_t AC4BitstreamVersion0 = 0x01;
+inline constexpr int32_t AC4BitstreamVersion1 = 0x02;
+inline constexpr int32_t AC4BitstreamVersion2 = 0x04;
+
+inline constexpr int32_t AC4PresentationVersion0 = 0x01;
+inline constexpr int32_t AC4PresentationVersion1 = 0x02;
+inline constexpr int32_t AC4PresentationVersion2 = 0x04;
+
+inline constexpr int32_t AC4Profile00 = AC4BitstreamVersion0 << 8 | AC4PresentationVersion0;
+inline constexpr int32_t AC4Profile10 = AC4BitstreamVersion1 << 8 | AC4PresentationVersion0;
+inline constexpr int32_t AC4Profile11 = AC4BitstreamVersion1 << 8 | AC4PresentationVersion1;
+inline constexpr int32_t AC4Profile21 = AC4BitstreamVersion2 << 8 | AC4PresentationVersion1;
+inline constexpr int32_t AC4Profile22 = AC4BitstreamVersion2 << 8 | AC4PresentationVersion2;
+
+inline static const char *asString_AC4Profile(int32_t profile, const char *def = "??") {
+    switch (profile) {
+        case AC4Profile00: return "00.00";
+        case AC4Profile10: return "01.00";
+        case AC4Profile11: return "01.01";
+        case AC4Profile21: return "02.01";
+        case AC4Profile22: return "02.02";
+        default:           return def;
+    }
+}
+
+inline constexpr int32_t AC4Level0 = 0x01;
+inline constexpr int32_t AC4Level1 = 0x02;
+inline constexpr int32_t AC4Level2 = 0x04;
+inline constexpr int32_t AC4Level3 = 0x08;
+inline constexpr int32_t AC4Level4 = 0x10;
+
+inline static const char *asString_AC4Level(int32_t level, const char *def = "??") {
+    switch (level) {
+        case AC4Level0: return "00";
+        case AC4Level1: return "01";
+        case AC4Level2: return "02";
+        case AC4Level3: return "03";
+        case AC4Level4: return "04";
+        default:        return def;
+    }
+}
+
 inline constexpr int32_t BITRATE_MODE_CBR = 2;
 inline constexpr int32_t BITRATE_MODE_CBR_FD = 3;
 inline constexpr int32_t BITRATE_MODE_CQ = 0;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 6d5f684..e526c0d 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -3394,7 +3394,7 @@
     if (t == nullptr) {
         return;
     }
-    t->onEffectDisable();
+    t->onEffectDisable(effect->asEffectModule());
 }
 
 bool EffectChain::EffectCallback::disconnectEffectHandle(IAfEffectHandle *handle,
diff --git a/services/audioflinger/IAfThread.h b/services/audioflinger/IAfThread.h
index 3962d73..4ba95ab 100644
--- a/services/audioflinger/IAfThread.h
+++ b/services/audioflinger/IAfThread.h
@@ -378,7 +378,7 @@
             RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) = 0;
 
     virtual void onEffectEnable(const sp<IAfEffectModule>& effect) EXCLUDES_ThreadBase_Mutex = 0;
-    virtual void onEffectDisable() EXCLUDES_ThreadBase_Mutex = 0;
+    virtual void onEffectDisable(const sp<IAfEffectModule>& effect) EXCLUDES_ThreadBase_Mutex = 0;
 
     // invalidateTracksForAudioSession_l must be called with holding mLock.
     virtual void invalidateTracksForAudioSession_l(audio_session_t sessionId) const
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index fcd9a7d..0085b81 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1800,7 +1800,7 @@
     }
 }
 
-void ThreadBase::onEffectDisable() {
+void ThreadBase::onEffectDisable([[maybe_unused]] const sp<IAfEffectModule>& effect) {
     if (isOffloadOrMmap()) {
         audio_utils::lock_guard _l(mutex());
         broadcast_l();
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index e8d0c7f..50b08cb 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -545,7 +545,7 @@
     mutable audio_utils::mutex mMutex{audio_utils::MutexOrder::kThreadBase_Mutex};
 
     void onEffectEnable(const sp<IAfEffectModule>& effect) final EXCLUDES_ThreadBase_Mutex;
-    void onEffectDisable() final EXCLUDES_ThreadBase_Mutex;
+    void onEffectDisable(const sp<IAfEffectModule>& effect) final EXCLUDES_ThreadBase_Mutex;
 
                 // invalidateTracksForAudioSession_l must be called with holding mutex().
     void invalidateTracksForAudioSession_l(audio_session_t /* sessionId */) const override
diff --git a/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp b/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
index b0e4ca3..81b60d1 100644
--- a/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DeviceInjectionMethods.cpp
@@ -127,6 +127,13 @@
         wasActive = true;
     }
 
+    res = parent->mRequestThread->setHalInterface(mBackupHalInterface);
+    if (res != OK) {
+        ALOGE("%s: Failed to restore the HalInterface in RequestThread!", __FUNCTION__);
+        injectionDisconnectImpl();
+        return res;
+    }
+
     res = replaceHalInterface(mBackupHalInterface, false);
     if (res != OK) {
         ALOGE("%s: Failed to restore the backup HalInterface!", __FUNCTION__);