Merge "Update initialization data to CodecPrivate format for VP9" into main
diff --git a/camera/Android.bp b/camera/Android.bp
index 9e1efae..b6241f4 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -54,7 +54,13 @@
 cc_aconfig_library {
     name: "camera_platform_flags_c_lib",
     aconfig_declarations: "camera_platform_flags",
+}
+
+cc_aconfig_library {
+    name: "camera_platform_flags_c_lib_for_test",
+    aconfig_declarations: "camera_platform_flags",
     host_supported: true,
+    mode: "test",
 }
 
 java_aconfig_library {
diff --git a/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h b/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h
index f046785..97a8cc4 100644
--- a/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h
+++ b/drm/libmediadrmrkp/include/DrmRemotelyProvisionedComponent.h
@@ -35,7 +35,8 @@
 class DrmRemotelyProvisionedComponent : public BnRemotelyProvisionedComponent {
   public:
     DrmRemotelyProvisionedComponent(std::shared_ptr<IDrmPlugin> drm, std::string drmVendor,
-                                    std::string drmDesc, std::vector<uint8_t> bcc);
+                                    std::string drmDesc, std::vector<uint8_t> bcc,
+                                    std::vector<uint8_t> bcc_signature);
     ScopedAStatus getHardwareInfo(RpcHardwareInfo* info) override;
 
     ScopedAStatus generateEcdsaP256KeyPair(bool testMode, MacedPublicKey* macedPublicKey,
@@ -60,6 +61,7 @@
     std::string mDrmVendor;
     std::string mDrmDesc;
     std::vector<uint8_t> mBcc;
+    std::vector<uint8_t> mBccSignature;
 };
 }  // namespace android::mediadrm
 
diff --git a/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp b/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp
index 440be79..65054b0 100644
--- a/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp
+++ b/drm/libmediadrmrkp/src/DrmRemotelyProvisionedComponent.cpp
@@ -28,11 +28,13 @@
 DrmRemotelyProvisionedComponent::DrmRemotelyProvisionedComponent(std::shared_ptr<IDrmPlugin> drm,
                                                                  std::string drmVendor,
                                                                  std::string drmDesc,
-                                                                 std::vector<uint8_t> bcc)
+                                                                 std::vector<uint8_t> bcc,
+                                                                 std::vector<uint8_t> bcc_signature)
     : mDrm(std::move(drm)),
       mDrmVendor(std::move(drmVendor)),
       mDrmDesc(std::move(drmDesc)),
-      mBcc(std::move(bcc)) {}
+      mBcc(std::move(bcc)),
+      mBccSignature(std::move(bcc_signature)) {}
 
 ScopedAStatus DrmRemotelyProvisionedComponent::getHardwareInfo(RpcHardwareInfo* info) {
     info->versionNumber = 3;
@@ -107,7 +109,7 @@
     for (auto i : keyToProp) {
         auto key = i.first;
         auto prop = i.second;
-        const auto& val= deviceInfoMap.get(key);
+        const auto& val = deviceInfoMap.get(key);
         if (val == nullptr || val->asTstr()->value().empty()) {
             std::string propValue = android::base::GetProperty(prop, "");
             if (propValue.empty()) {
@@ -161,12 +163,16 @@
     }
 
     // assemble AuthenticatedRequest (definition in IRemotelyProvisionedComponent.aidl)
-    *out = cppbor::Array()
-                   .add(1 /* version */)
-                   .add(cppbor::Map() /* UdsCerts */)
-                   .add(cppbor::EncodedItem(mBcc))
-                   .add(cppbor::EncodedItem(std::move(deviceSignedCsrPayload)))
-                   .encode();
+    cppbor::Array request_array = cppbor::Array().add(1 /* version */);
+    if (!mBccSignature.empty()) {
+        request_array.add(cppbor::EncodedItem(mBccSignature) /* UdsCerts */);
+    } else {
+        request_array.add(cppbor::Map() /* empty UdsCerts */);
+    }
+    request_array.add(cppbor::EncodedItem(mBcc))
+            .add(cppbor::EncodedItem(std::move(deviceSignedCsrPayload)));
+    *out = request_array.encode();
+
     return ScopedAStatus::ok();
 }
 }  // namespace android::mediadrm
\ No newline at end of file
diff --git a/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp b/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp
index 515d157..750b51e 100644
--- a/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp
+++ b/drm/libmediadrmrkp/src/DrmRkpAdapter.cpp
@@ -87,13 +87,21 @@
                           status.getDescription().c_str());
                     return;
                 }
-
+                std::vector<uint8_t> bcc_signature;
+                status =
+                        mDrm->getPropertyByteArray("bootCertificateChainSignature", &bcc_signature);
+                if (!status.isOk()) {
+                    ALOGW("mDrm->getPropertyByteArray(\"bootCertificateChainSignature\") failed."
+                          "Detail: [%s].",
+                          status.getDescription().c_str());
+                    // bcc signature is optional, no need to return when it is unavailable.
+                }
                 std::string compName(instance);
                 auto comps = static_cast<
                         std::map<std::string, std::shared_ptr<IRemotelyProvisionedComponent>>*>(
                         context);
                 (*comps)[compName] = ::ndk::SharedRefBase::make<DrmRemotelyProvisionedComponent>(
-                        mDrm, drmVendor, drmDesc, bcc);
+                        mDrm, drmVendor, drmDesc, bcc, bcc_signature);
             });
     return comps;
 }
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index 1a637ac..695cad6 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -45,6 +45,32 @@
             "file_patterns": ["(?i)drm|crypto"]
         }
     ],
+    "postsubmit": [
+        {
+            "name": "MctsMediaCodecTestCases",
+            "options": [
+                {
+                    "include-filter": "android.media.codec.cts.EncodeDecodeTest"
+                }
+            ]
+        },
+        {
+            "name": "MctsMediaCodecTestCases",
+            "options": [
+                {
+                    "include-filter": "android.media.codec.cts.DecodeEditEncodeTest"
+                }
+            ]
+        },
+        {
+            "name": "MctsMediaCodecTestCases",
+            "options": [
+                {
+                    "include-filter": "android.media.codec.cts.ExtractDecodeEditEncodeMuxTest"
+                }
+            ]
+        }
+    ],
     // Postsubmit tests for TV devices
     "tv-postsubmit": [
         {
diff --git a/media/aconfig/codec_fwk.aconfig b/media/aconfig/codec_fwk.aconfig
index 2bf53f9..ed1522b 100644
--- a/media/aconfig/codec_fwk.aconfig
+++ b/media/aconfig/codec_fwk.aconfig
@@ -13,6 +13,16 @@
 }
 
 flag {
+  name: "codec_buffer_state_cleanup"
+  namespace: "codec_fwk"
+  description: "Bugfix flag for more buffer state cleanup in MediaCodec"
+  bug: "343502509"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "dataspace_v0_partial"
   namespace: "codec_fwk"
   description: "Bugfix flag for using V0 dataspace in some cases"
diff --git a/media/audio/aconfig/audio_framework.aconfig b/media/audio/aconfig/audio_framework.aconfig
index 0209e28..ea5f26d 100644
--- a/media/audio/aconfig/audio_framework.aconfig
+++ b/media/audio/aconfig/audio_framework.aconfig
@@ -40,6 +40,14 @@
     bug: "316414750"
 }
 
+flag {
+    name: "dolby_ac4_level4_encoding_api"
+    namespace: "media_audio"
+    description: "Feature flag for Dolby AC-4 level 4 AudioFormat encoding."
+    is_fixed_read_only: true
+    bug: "266537650"
+}
+
 # TODO remove
 flag {
     name: "foreground_audio_control"
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp
index 01b6e42..90996a3 100644
--- a/media/audioaidlconversion/AidlConversionCppNdk.cpp
+++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp
@@ -741,6 +741,8 @@
             {// Note: not in the IANA registry.
              AUDIO_FORMAT_APTX_HD, make_AudioFormatDescription("audio/vnd.qcom.aptx.hd")},
             {AUDIO_FORMAT_AC4, make_AudioFormatDescription(::android::MEDIA_MIMETYPE_AUDIO_AC4)},
+            {AUDIO_FORMAT_AC4_L4, make_AudioFormatDescription(
+                    std::string(::android::MEDIA_MIMETYPE_AUDIO_AC4) + ";version=02.01.04")},
             {// Note: not in the IANA registry.
              AUDIO_FORMAT_LDAC, make_AudioFormatDescription("audio/vnd.sony.ldac")},
             {AUDIO_FORMAT_MAT,
diff --git a/media/codec2/components/mp3/C2SoftMp3Dec.cpp b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
index 149c6ee..aed5e68 100644
--- a/media/codec2/components/mp3/C2SoftMp3Dec.cpp
+++ b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
@@ -114,7 +114,9 @@
 c2_status_t C2SoftMP3::onStop() {
     // Make sure that the next buffer output does not still
     // depend on fragments from the last one decoded.
-    pvmp3_InitDecoder(mConfig, mDecoderBuf);
+    if (mDecoderBuf) {
+        pvmp3_InitDecoder(mConfig, mDecoderBuf);
+    }
     mSignalledError = false;
     mIsFirst = true;
     mSignalledOutputEos = false;
diff --git a/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h b/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h
index de0f566..bb4c596 100644
--- a/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h
+++ b/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h
@@ -52,6 +52,13 @@
 using ::aidl::android::hardware::media::bufferpool2::IClientManager;
 
 struct ComponentStore : public BnComponentStore {
+    /**
+     * Constructor for ComponentStore.
+     *
+     * IMPORTANT: SetPreferredCodec2ComponentStore() is called in the constructor.
+     * Be careful about the order of SetPreferredCodec2ComponentStore() and
+     * ComponentStore() in the code.
+     */
     ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
     virtual ~ComponentStore();
 
diff --git a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
index 847c90c..028238b 100644
--- a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
+++ b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
@@ -55,6 +55,13 @@
 using ::android::sp;
 
 struct ComponentStore : public IComponentStore {
+    /**
+     * Constructor for ComponentStore.
+     *
+     * IMPORTANT: SetPreferredCodec2ComponentStore() is called in the constructor.
+     * Be careful about the order of SetPreferredCodec2ComponentStore() and
+     * ComponentStore() in the code.
+     */
     ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
     virtual ~ComponentStore();
 
diff --git a/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h b/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
index 9028149..b023115 100644
--- a/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
+++ b/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
@@ -56,6 +56,13 @@
 using ::android::sp;
 
 struct ComponentStore : public IComponentStore {
+    /**
+     * Constructor for ComponentStore.
+     *
+     * IMPORTANT: SetPreferredCodec2ComponentStore() is called in the constructor.
+     * Be careful about the order of SetPreferredCodec2ComponentStore() and
+     * ComponentStore() in the code.
+     */
     ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
     virtual ~ComponentStore();
 
diff --git a/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h b/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h
index 4fd260b..a7e043b 100644
--- a/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h
+++ b/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h
@@ -56,6 +56,13 @@
 using ::android::sp;
 
 struct ComponentStore : public IComponentStore {
+    /**
+     * Constructor for ComponentStore.
+     *
+     * IMPORTANT: SetPreferredCodec2ComponentStore() is called in the constructor.
+     * Be careful about the order of SetPreferredCodec2ComponentStore() and
+     * ComponentStore() in the code.
+     */
     ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
     virtual ~ComponentStore();
 
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 1cbfc75..3ef2f84 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -2628,8 +2628,6 @@
         switch (action) {
         case OutputBuffers::SKIP:
             return;
-        case OutputBuffers::DISCARD:
-            break;
         case OutputBuffers::NOTIFY_CLIENT:
         {
             // TRICKY: we want popped buffers reported in order, so sending
@@ -2656,13 +2654,16 @@
                     outBuffer->meta()->setObject("accessUnitInfo", obj);
                 }
             }
+            mCallback->onOutputBufferAvailable(index, outBuffer);
+            [[fallthrough]];
+        }
+        case OutputBuffers::DISCARD: {
             if (mHasInputSurface && android::media::codec::provider_->input_surface_throttle()) {
                 Mutexed<InputSurface>::Locked inputSurface(mInputSurface);
                 --inputSurface->numProcessingBuffersBalance;
-                ALOGV("[%s] onOutputBufferAvailable: numProcessingBuffersBalance = %lld",
-                      mName, static_cast<long long>(inputSurface->numProcessingBuffersBalance));
+                ALOGV("[%s] onWorkDone: numProcessingBuffersBalance = %lld",
+                        mName, static_cast<long long>(inputSurface->numProcessingBuffersBalance));
             }
-            mCallback->onOutputBufferAvailable(index, outBuffer);
             break;
         }
         case OutputBuffers::REALLOCATE:
diff --git a/media/libaudioclient/TEST_MAPPING b/media/libaudioclient/TEST_MAPPING
index 68dba34..29b876c 100644
--- a/media/libaudioclient/TEST_MAPPING
+++ b/media/libaudioclient/TEST_MAPPING
@@ -47,12 +47,7 @@
       "name": "audioeffect_analysis"
     },
     {
-      "name": "CtsVirtualDevicesTestCases",
-      "options" : [
-        {
-          "include-filter": "android.virtualdevice.cts.VirtualAudioTest"
-        }
-      ]
+      "name": "CtsVirtualDevicesAudioTestCases"
     }
   ]
 }
diff --git a/media/libaudioclient/tests/audiorouting_tests.cpp b/media/libaudioclient/tests/audiorouting_tests.cpp
index 8151d39..a3ab9d2 100644
--- a/media/libaudioclient/tests/audiorouting_tests.cpp
+++ b/media/libaudioclient/tests/audiorouting_tests.cpp
@@ -86,7 +86,18 @@
     }
 }
 
-TEST(AudioTrackTest, DefaultRoutingTest) {
+class AudioTrackTest
+        : public ::testing::TestWithParam<int> {
+
+public:
+    AudioTrackTest()
+            : mSampleRate(GetParam()){};
+
+    const uint32_t mSampleRate;
+
+};
+
+TEST_P(AudioTrackTest, DefaultRoutingTest) {
     audio_port_v7 port;
     if (OK != getPortByAttributes(AUDIO_PORT_ROLE_SOURCE, AUDIO_PORT_TYPE_DEVICE,
                                   AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", port)) {
@@ -95,7 +106,8 @@
 
     // create record instance
     sp<AudioCapture> capture = sp<AudioCapture>::make(
-            AUDIO_SOURCE_REMOTE_SUBMIX, 48000, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO);
+            AUDIO_SOURCE_REMOTE_SUBMIX, mSampleRate, AUDIO_FORMAT_PCM_16_BIT,
+            AUDIO_CHANNEL_IN_STEREO);
     ASSERT_NE(nullptr, capture);
     ASSERT_EQ(OK, capture->create()) << "record creation failed";
     sp<OnAudioDeviceUpdateNotifier> cbCapture = sp<OnAudioDeviceUpdateNotifier>::make();
@@ -103,7 +115,7 @@
 
     // create playback instance
     sp<AudioPlayback> playback = sp<AudioPlayback>::make(
-            48000 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+            mSampleRate, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
             AUDIO_OUTPUT_FLAG_NONE, AUDIO_SESSION_NONE);
     ASSERT_NE(nullptr, playback);
     ASSERT_EQ(OK, playback->loadResource("/data/local/tmp/bbb_2ch_24kHz_s16le.raw"))
@@ -133,6 +145,12 @@
     playback->stop();
 }
 
+INSTANTIATE_TEST_SUITE_P(
+        AudioTrackParameterizedTest,
+        AudioTrackTest,
+        ::testing::Values(44100, 48000)
+);
+
 class AudioRoutingTest : public ::testing::Test {
   public:
     void SetUp() override {
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 3cc923d..629cd7c 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -22,6 +22,7 @@
 #include <aidl/android/hardware/audio/core/BnStreamCallback.h>
 #include <aidl/android/hardware/audio/core/BnStreamOutEventCallback.h>
 #include <aidl/android/hardware/audio/core/StreamDescriptor.h>
+#include <android/binder_ibinder_platform.h>
 #include <error/expected_utils.h>
 #include <media/AidlConversionCppNdk.h>
 #include <media/AidlConversionNdk.h>
@@ -29,6 +30,8 @@
 #include <media/AidlConversionUtil.h>
 #include <mediautils/TimeCheck.h>
 #include <system/audio.h>
+#include <system/thread_defs.h>
+
 #include <Utils.h>
 #include <utils/Log.h>
 
@@ -504,8 +507,15 @@
     std::shared_ptr<OutputStreamCallbackAidl> streamCb;
     if (isOffload) {
         streamCb = ndk::SharedRefBase::make<OutputStreamCallbackAidl>(this);
+        ndk::SpAIBinder binder = streamCb->asBinder();
+        AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
+        AIBinder_setInheritRt(binder.get(), true);
     }
     auto eventCb = ndk::SharedRefBase::make<OutputStreamEventCallbackAidl>(this);
+    ndk::SpAIBinder binder = eventCb->asBinder();
+    AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
+    AIBinder_setInheritRt(binder.get(), true);
+
     if (isOffload || isHwAvSync) {
         args.offloadInfo = aidlConfig.offloadInfo;
     }
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 0a262e4..263ef96 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -619,7 +619,14 @@
             result != NO_ERROR) {
         return result;
     }
-    return processReturn("setConnectedState", mDevice->setConnectedState(hidlAddress, connected));
+    Return<Result> ret = mDevice->setConnectedState(hidlAddress, connected);
+    if (ret.isOk() || ret == Result::NOT_SUPPORTED) {
+        // The framework is only interested in errors occurring due to connection state handling,
+        // so it can decide whether retrying is needed. If the HAL does not support this operation,
+        // it's not an error.
+        return NO_ERROR;
+    }
+    return processReturn("setConnectedState", ret);
 }
 
 error::Result<audio_hw_sync_t> DeviceHalHidl::getHwAvSync() {
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.cpp b/media/libaudiohal/impl/Hal2AidlMapper.cpp
index f352849..0cdf0f2 100644
--- a/media/libaudiohal/impl/Hal2AidlMapper.cpp
+++ b/media/libaudiohal/impl/Hal2AidlMapper.cpp
@@ -368,16 +368,21 @@
         const AudioConfig& config, const std::optional<AudioIoFlags>& flags, int32_t ioHandle,
         AudioSource source, const std::set<int32_t>& destinationPortIds,
         AudioPortConfig* portConfig, bool* created) {
-    // These flags get removed one by one in this order when retrying port finding.
-    static const std::vector<AudioInputFlags> kOptionalInputFlags{
-        AudioInputFlags::FAST, AudioInputFlags::RAW, AudioInputFlags::VOIP_TX };
     if (auto portConfigIt = findPortConfig(config, flags, ioHandle);
             portConfigIt == mPortConfigs.end() && flags.has_value()) {
-        auto optionalInputFlagsIt = kOptionalInputFlags.begin();
+        // These input flags get removed one by one in this order when retrying port finding.
+        std::vector<AudioInputFlags> optionalInputFlags {
+            AudioInputFlags::FAST, AudioInputFlags::RAW, AudioInputFlags::VOIP_TX };
+        // For remote submix input, retry with direct input flag removed as the remote submix
+        // input is not expected to manipulate the contents of the audio stream.
+        if (mRemoteSubmixIn.has_value()) {
+            optionalInputFlags.push_back(AudioInputFlags::DIRECT);
+        }
+        auto optionalInputFlagsIt = optionalInputFlags.begin();
         AudioIoFlags matchFlags = flags.value();
         auto portsIt = findPort(config, matchFlags, destinationPortIds);
         while (portsIt == mPorts.end() && matchFlags.getTag() == AudioIoFlags::Tag::input
-                && optionalInputFlagsIt != kOptionalInputFlags.end()) {
+                && optionalInputFlagsIt != optionalInputFlags.end()) {
             if (!isBitPositionFlagSet(
                             matchFlags.get<AudioIoFlags::Tag::input>(), *optionalInputFlagsIt)) {
                 ++optionalInputFlagsIt;
@@ -392,6 +397,36 @@
                         config.toString().c_str(), flags.value().toString().c_str(),
                         matchFlags.toString().c_str());
         }
+        // These output flags get removed one by one in this order when retrying port finding.
+        std::vector<AudioOutputFlags> optionalOutputFlags { };
+        // For remote submix output, retry with these output flags removed one by one:
+        // 1. DIRECT: remote submix outputs are expected not to manipulate the contents of the
+        //            audio stream.
+        // 2. IEC958_NONAUDIO: remote submix outputs are not connected to ALSA and do not require
+        //                     non audio signalling.
+        if (mRemoteSubmixOut.has_value()) {
+            optionalOutputFlags.push_back(AudioOutputFlags::DIRECT);
+            optionalOutputFlags.push_back(AudioOutputFlags::IEC958_NONAUDIO);
+        }
+        auto optionalOutputFlagsIt = optionalOutputFlags.begin();
+        matchFlags = flags.value();
+        while (portsIt == mPorts.end() && matchFlags.getTag() == AudioIoFlags::Tag::output
+                && optionalOutputFlagsIt != optionalOutputFlags.end()) {
+            if (!isBitPositionFlagSet(
+                            matchFlags.get<AudioIoFlags::Tag::output>(),*optionalOutputFlagsIt)) {
+                ++optionalOutputFlagsIt;
+                continue;
+            }
+            matchFlags.set<AudioIoFlags::Tag::output>(matchFlags.get<AudioIoFlags::Tag::output>() &
+                    ~makeBitPositionFlagMask(*optionalOutputFlagsIt++));
+            portsIt = findPort(config, matchFlags, destinationPortIds);
+            AUGMENT_LOG(I,
+                        "mix port for config %s, flags %s was not found"
+                        "retried with flags %s",
+                        config.toString().c_str(), flags.value().toString().c_str(),
+                        matchFlags.toString().c_str());
+        }
+
         if (portsIt == mPorts.end()) {
             AUGMENT_LOG(E, "mix port for config %s, flags %s is not found",
                         config.toString().c_str(), matchFlags.toString().c_str());
@@ -792,7 +827,8 @@
     status_t status = prepareToOpenStreamHelper(ioHandle, devicePortConfig.portId,
             devicePortConfig.id, flags, source, initialConfig, cleanups, config,
             mixPortConfig, patch);
-    if (status != OK) {
+    if (status != OK && !(mRemoteSubmixOut.has_value() &&
+                initialConfig.base.format.type != AudioFormatType::PCM)) {
         // If using the client-provided config did not work out for establishing a mix port config
         // or patching, try with the device port config. Note that in general device port config and
         // mix port config are not required to be the same, however they must match if the HAL
diff --git a/media/libmedia/include/media/mediametadataretriever.h b/media/libmedia/include/media/mediametadataretriever.h
index 116ed9a..d76ed25 100644
--- a/media/libmedia/include/media/mediametadataretriever.h
+++ b/media/libmedia/include/media/mediametadataretriever.h
@@ -122,6 +122,10 @@
     static sp<IMediaPlayerService>            sService;
 
     Mutex                                     mLock;
+    // Static lock was added to the client in order to consume at most
+    // one service thread from image extraction requests of the same
+    // client process(See also b/21277449).
+    static Mutex                              sLock;
     sp<IMediaMetadataRetriever>               mRetriever;
 
 };
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 40fd022..9196f9f 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -35,6 +35,8 @@
 sp<IMediaPlayerService> MediaMetadataRetriever::sService;
 sp<MediaMetadataRetriever::DeathNotifier> MediaMetadataRetriever::sDeathNotifier;
 
+Mutex MediaMetadataRetriever::sLock;
+
 const sp<IMediaPlayerService> MediaMetadataRetriever::getService()
 {
     Mutex::Autolock lock(sServiceLock);
@@ -143,6 +145,7 @@
     ALOGV("getFrameAtTime: time(%" PRId64 " us) option(%d) colorFormat(%d) metaOnly(%d)",
             timeUs, option, colorFormat, metaOnly);
     Mutex::Autolock _l(mLock);
+    Mutex::Autolock _gLock(sLock);
     if (mRetriever == 0) {
         ALOGE("retriever is not initialized");
         return NULL;
@@ -155,6 +158,7 @@
     ALOGV("getImageAtIndex: index(%d) colorFormat(%d) metaOnly(%d) thumbnail(%d)",
             index, colorFormat, metaOnly, thumbnail);
     Mutex::Autolock _l(mLock);
+    Mutex::Autolock _gLock(sLock);
     if (mRetriever == 0) {
         ALOGE("retriever is not initialized");
         return NULL;
@@ -167,6 +171,7 @@
     ALOGV("getImageRectAtIndex: index(%d) colorFormat(%d) rect {%d, %d, %d, %d}",
             index, colorFormat, left, top, right, bottom);
     Mutex::Autolock _l(mLock);
+    Mutex::Autolock _gLock(sLock);
     if (mRetriever == 0) {
         ALOGE("retriever is not initialized");
         return NULL;
@@ -180,6 +185,7 @@
     ALOGV("getFrameAtIndex: index(%d), colorFormat(%d) metaOnly(%d)",
             index, colorFormat, metaOnly);
     Mutex::Autolock _l(mLock);
+    Mutex::Autolock _gLock(sLock);
     if (mRetriever == 0) {
         ALOGE("retriever is not initialized");
         return NULL;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index eea5242..7d47837 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2015,6 +2015,7 @@
     int32_t flags;
     CHECK(buffer->meta()->findInt32("flags", &flags));
     if (flags & BUFFER_FLAG_DECODE_ONLY) {
+        ALOGV("discardDecodeOnlyOutputBuffer: mPortBuffers[out][%zu] NOT owned by client", index);
         info->mOwnedByClient = false;
         info->mData.clear();
         mBufferChannel->discardBuffer(buffer);
@@ -4494,9 +4495,16 @@
                 {
                     /* size_t index = */updateBuffers(kPortIndexInput, msg);
 
-                    if (mState == FLUSHING
-                            || mState == STOPPING
-                            || mState == RELEASING) {
+                    bool inStateToReturnBuffers =
+                        mState == FLUSHING || mState == STOPPING || mState == RELEASING;
+                    if (android::media::codec::provider_->codec_buffer_state_cleanup()) {
+                        // Late callbacks from the codec could arrive here
+                        // after the codec is already stopped or released.
+                        inStateToReturnBuffers = mState == FLUSHING ||
+                                                 mState == STOPPING || mState == INITIALIZED ||
+                                                 mState == RELEASING || mState == UNINITIALIZED;
+                    }
+                    if (inStateToReturnBuffers) {
                         returnBuffersToCodecOnPort(kPortIndexInput);
                         break;
                     }
@@ -4575,9 +4583,16 @@
 
                     /* size_t index = */updateBuffers(kPortIndexOutput, msg);
 
-                    if (mState == FLUSHING
-                            || mState == STOPPING
-                            || mState == RELEASING) {
+                    bool inStateToReturnBuffers =
+                        mState == FLUSHING || mState == STOPPING || mState == RELEASING;
+                    if (android::media::codec::provider_->codec_buffer_state_cleanup()) {
+                        // Late callbacks from the codec could arrive here
+                        // after the codec is already stopped or released.
+                        inStateToReturnBuffers = mState == FLUSHING ||
+                                                 mState == STOPPING || mState == INITIALIZED ||
+                                                 mState == RELEASING || mState == UNINITIALIZED;
+                    }
+                    if (inStateToReturnBuffers) {
                         returnBuffersToCodecOnPort(kPortIndexOutput);
                         break;
                     }
@@ -5943,7 +5958,7 @@
     }
 
     updateHdrMetrics(false /* isConfig */);
- }
+}
 
 void MediaCodec::extractCSD(const sp<AMessage> &format) {
     mCSD.clear();
@@ -6022,7 +6037,6 @@
             return -EINVAL;
         }
         if (codecInputData->data() == NULL) {
-            ALOGV("Input buffer %zu is not properly allocated", bufferIndex);
             mErrorLog.log(LOG_TAG, base::StringPrintf(
                     "Fatal error: input buffer %zu is not properly allocated", bufferIndex));
             return -EINVAL;
@@ -6068,6 +6082,10 @@
 
         mInputFormat.clear();
         mOutputFormat.clear();
+        if (android::media::codec::provider_->codec_buffer_state_cleanup()) {
+            mCSD.clear();
+            mLeftover.clear();
+        }
         mFlags &= ~kFlagOutputFormatChanged;
         mFlags &= ~kFlagOutputBuffersChanged;
         mFlags &= ~kFlagStickyError;
@@ -6126,6 +6144,8 @@
                 ALOGD("port %d buffer %zu still owned by client when codec is reclaimed",
                         portIndex, i);
             } else {
+                ALOGV("returnBuffersToCodecOnPort: mPortBuffers[%s][%zu] NOT owned by client",
+                      portIndex == kPortIndexInput ? "in" : "out", i);
                 info->mOwnedByClient = false;
                 info->mData.clear();
             }
@@ -6478,6 +6498,7 @@
 
         // synchronization boundary for getBufferAndFormat
         Mutex::Autolock al(mBufferLock);
+        ALOGV("onQueueInputBuffer: mPortBuffers[in][%zu] NOT owned by client", index);
         info->mOwnedByClient = false;
         info->mData.clear();
 
@@ -6494,6 +6515,7 @@
     sp<AMessage> msg = mLeftover.front();
     mLeftover.pop_front();
     msg->setSize("index", index);
+    ALOGV("handleLeftover(%zu)", index);
     return onQueueInputBuffer(msg);
 }
 
@@ -6562,6 +6584,7 @@
     sp<MediaCodecBuffer> buffer;
     {
         Mutex::Autolock al(mBufferLock);
+        ALOGV("onReleaseOutputBuffer: mPortBuffers[out][%zu] NOT owned by client", index);
         info->mOwnedByClient = false;
         buffer = info->mData;
         info->mData.clear();
@@ -6674,6 +6697,8 @@
 
     {
         Mutex::Autolock al(mBufferLock);
+        ALOGV("dequeuePortBuffer: mPortBuffers[%s][%zu] checking if not owned by client",
+              portIndex == kPortIndexInput ? "in" : "out", index);
         CHECK(!info->mOwnedByClient);
         info->mOwnedByClient = true;
 
diff --git a/media/libstagefright/TEST_MAPPING b/media/libstagefright/TEST_MAPPING
index b7efbce..354fab0 100644
--- a/media/libstagefright/TEST_MAPPING
+++ b/media/libstagefright/TEST_MAPPING
@@ -85,13 +85,37 @@
     // writerTest fails about 5 out of 66
     // { "name": "writerTest" },
     {
-       "name": "BatteryChecker_test"
+        "name": "BatteryChecker_test"
     },
     {
         "name": "ExtractorFactoryTest"
     },
     {
         "name": "HEVCUtilsUnitTest"
+    },
+    {
+      "name": "MctsMediaDecoderTestCases",
+      "options": [
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        }
+      ]
+    },
+    {
+      "name": "MctsMediaEncoderTestCases",
+      "options": [
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        }
+      ]
+    },
+    {
+      "name": "MctsMediaCodecTestCases",
+      "options": [
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        }
+      ]
     }
   ]
 }
diff --git a/media/mediaserver/Android.bp b/media/mediaserver/Android.bp
index 6ea40e3..d916fd1 100644
--- a/media/mediaserver/Android.bp
+++ b/media/mediaserver/Android.bp
@@ -54,6 +54,8 @@
 mediaserver_cc_binary {
     name: "mediaserver",
 
+    defaults: ["libcodec2_hal_selection"],
+
     srcs: ["main_mediaserver.cpp"],
 
     shared_libs: [
@@ -61,6 +63,7 @@
         "libicu",
         "libfmq",
         "libbinder",
+        "libbinder_ndk",
         "libhidlbase",
         "liblog",
         "libmediaplayerservice",
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 026847a..8a62f30 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -17,11 +17,12 @@
 
 #define LOG_TAG "mediaserver"
 //#define LOG_NDEBUG 0
-
+#include <android/binder_process.h>
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
 #include <hidl/HidlTransportSupport.h>
+#include <codec2/common/HalSelection.h>
 #include <utils/Log.h>
 #include "RegisterExtensions.h"
 
@@ -30,6 +31,14 @@
 
 using namespace android;
 
+namespace {
+    constexpr int kCodecThreadPoolCount = 16;
+
+    // This is the default thread count for binder thread pool
+    // if the thread count is not configured.
+    constexpr int kDefaultBinderThreadPoolCount = 15;
+}; // anonymous
+
 int main(int argc __unused, char **argv __unused)
 {
     signal(SIGPIPE, SIG_IGN);
@@ -40,8 +49,14 @@
     MediaPlayerService::instantiate();
     ResourceManagerService::instantiate();
     registerExtensions();
-    ::android::hardware::configureRpcThreadpool(16, false);
+
+    bool aidl = ::android::IsCodec2AidlHalSelected();
+    if (!aidl) {
+        ::android::hardware::configureRpcThreadpool(kCodecThreadPoolCount, false);
+    } else {
+        ABinderProcess_setThreadPoolMaxThreadCount(
+                kCodecThreadPoolCount + kDefaultBinderThreadPoolCount);
+    }
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();
-    ::android::hardware::joinRpcThreadpool();
 }
diff --git a/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
index 8817621..64fdfb9 100644
--- a/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
+++ b/media/module/codecs/amrnb/common/include/basic_op_c_equivalent.h
@@ -115,7 +115,6 @@
      Returns:
         L_sum = 32-bit sum of L_var1 and L_var2 (Word32)
     */
-    __attribute__((no_sanitize("integer")))
     static inline Word32 L_add(Word32 L_var1, Word32 L_var2, Flag *pOverflow)
     {
         Word32 L_sum;
@@ -454,7 +453,8 @@
     {
         Word32 result;
 
-        result = L_var3 + L_var1 * L_var2;
+        __builtin_mul_overflow(L_var1, L_var2, &result);
+        __builtin_add_overflow(L_var3, result, &result);
 
         return result;
     }
@@ -463,7 +463,8 @@
     {
         Word32 result;
 
-        result = L_var3 - L_var1 * L_var2;
+        __builtin_mul_overflow(L_var1, L_var2, &result);
+        __builtin_sub_overflow(L_var3, result, &result);
 
         return result;
     }
diff --git a/media/module/codecs/amrnb/common/src/az_lsp.cpp b/media/module/codecs/amrnb/common/src/az_lsp.cpp
index f3098f5..a19ddbf 100644
--- a/media/module/codecs/amrnb/common/src/az_lsp.cpp
+++ b/media/module/codecs/amrnb/common/src/az_lsp.cpp
@@ -237,9 +237,6 @@
 
 ------------------------------------------------------------------------------
 */
-#ifdef __clang__
-__attribute__((no_sanitize("integer")))
-#endif
 static Word16 Chebps(Word16 x,
                      Word16 f[], /* (n) */
                      Word16 n,
diff --git a/media/module/codecs/amrnb/common/src/l_abs.cpp b/media/module/codecs/amrnb/common/src/l_abs.cpp
index 7e0ae99..b13a40a 100644
--- a/media/module/codecs/amrnb/common/src/l_abs.cpp
+++ b/media/module/codecs/amrnb/common/src/l_abs.cpp
@@ -186,8 +186,12 @@
     ; Function body here
     ----------------------------------------------------------------------------*/
 
-    Word32 y = L_var1 - (L_var1 < 0);
-    y = y ^(y >> 31);
-    return (y);
+    if (L_var1 >= 0) return L_var1;
+    if (L_var1 != 0x80000000) return -L_var1;
+    // abs(0x80000000) can not be represented in Word32.
+    // we choose to return the closest value we can -- 0x7fffffff
+    // This is acceptable because it keeps the result within the valid 32-bit signed integer range,
+    // consistent with other overflow handling in the code. such as amrnb/enc/src/l_negate.cpp.
+    return 0x7FFFFFFF;
 
 }
diff --git a/media/module/codecs/amrnb/common/src/lsp_az.cpp b/media/module/codecs/amrnb/common/src/lsp_az.cpp
index 495359f..bb8a34d 100644
--- a/media/module/codecs/amrnb/common/src/lsp_az.cpp
+++ b/media/module/codecs/amrnb/common/src/lsp_az.cpp
@@ -281,8 +281,8 @@
             t0 += ((Word32)lo * *lsp) >> 15;
 
             *(f) +=  *(f - 2);          /*      *f += f[-2]      */
-            *(f--) -=  t0 << 2;         /*      *f -= t0         */
-
+            __builtin_sub_overflow(*(f), (t0 << 2), f);   /*      *f -= t0         */
+            f--;
         }
 
         *f -= (Word32)(*lsp++) << 10;
diff --git a/media/module/codecs/amrnb/common/src/norm_l.cpp b/media/module/codecs/amrnb/common/src/norm_l.cpp
index d8d1259..b24ebda 100644
--- a/media/module/codecs/amrnb/common/src/norm_l.cpp
+++ b/media/module/codecs/amrnb/common/src/norm_l.cpp
@@ -211,8 +211,7 @@
     if (L_var1)
     {
 
-        Word32 y = L_var1 - (L_var1 < 0);
-        L_var1 = y ^(y >> 31);
+        L_var1 = L_abs(L_var1);
 
 
         while (!(0x40000000L & L_var1))
diff --git a/media/module/codecs/amrnb/common/src/residu.cpp b/media/module/codecs/amrnb/common/src/residu.cpp
index 2ad132f..9b077e2 100644
--- a/media/module/codecs/amrnb/common/src/residu.cpp
+++ b/media/module/codecs/amrnb/common/src/residu.cpp
@@ -227,22 +227,35 @@
         p_input3 = p_input_ptr--;
         p_input4 = p_input_ptr--;
 
+        Word32 tmp;
         for (j = M >> 1; j != 0; j--)
         {
-            s1 += ((Word32) * (p_coef) * *(p_input1++));
-            s2 += ((Word32) * (p_coef) * *(p_input2++));
-            s3 += ((Word32) * (p_coef) * *(p_input3++));
-            s4 += ((Word32) * (p_coef--) * *(p_input4++));
-            s1 += ((Word32) * (p_coef) * *(p_input1++));
-            s2 += ((Word32) * (p_coef) * *(p_input2++));
-            s3 += ((Word32) * (p_coef) * *(p_input3++));
-            s4 += ((Word32) * (p_coef--) * *(p_input4++));
+            __builtin_mul_overflow(*p_coef, *(p_input1++), &tmp);
+            __builtin_add_overflow(s1, tmp, &s1);
+            __builtin_mul_overflow(*p_coef, *(p_input2++), &tmp);
+            __builtin_add_overflow(s2, tmp, &s2);
+            __builtin_mul_overflow(*p_coef, *(p_input3++), &tmp);
+            __builtin_add_overflow(s3, tmp, &s3);
+            __builtin_mul_overflow(*(p_coef--), *(p_input4++), &tmp);
+            __builtin_add_overflow(s4, tmp, &s4);
+            __builtin_mul_overflow(*p_coef, *(p_input1++), &tmp);
+            __builtin_add_overflow(s1, tmp, &s1);
+            __builtin_mul_overflow(*p_coef, *(p_input2++), &tmp);
+            __builtin_add_overflow(s2, tmp, &s2);
+            __builtin_mul_overflow(*p_coef, *(p_input3++), &tmp);
+            __builtin_add_overflow(s3, tmp, &s3);
+            __builtin_mul_overflow(*(p_coef--), *(p_input4++), &tmp);
+            __builtin_add_overflow(s4, tmp, &s4);
         }
 
-        s1 += (((Word32) * (p_coef)) * *(p_input1));
-        s2 += (((Word32) * (p_coef)) * *(p_input2));
-        s3 += (((Word32) * (p_coef)) * *(p_input3));
-        s4 += (((Word32) * (p_coef)) * *(p_input4));
+        __builtin_mul_overflow(*p_coef, *(p_input1), &tmp);
+        __builtin_add_overflow(s1, tmp, &s1);
+        __builtin_mul_overflow(*p_coef, *(p_input2), &tmp);
+        __builtin_add_overflow(s2, tmp, &s2);
+        __builtin_mul_overflow(*p_coef, *(p_input3), &tmp);
+        __builtin_add_overflow(s3, tmp, &s3);
+        __builtin_mul_overflow(*p_coef, *(p_input4), &tmp);
+        __builtin_add_overflow(s4, tmp, &s4);
 
         *(p_residual_ptr--) = (Word16)(s1 >> 12);
         *(p_residual_ptr--) = (Word16)(s2 >> 12);
diff --git a/media/module/codecs/amrnb/common/src/sub.cpp b/media/module/codecs/amrnb/common/src/sub.cpp
index b956912..d936128 100644
--- a/media/module/codecs/amrnb/common/src/sub.cpp
+++ b/media/module/codecs/amrnb/common/src/sub.cpp
@@ -187,9 +187,6 @@
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
 
-#ifdef __clang__
-__attribute__((no_sanitize("integer")))
-#endif
 Word16 sub(Word16 var1, Word16 var2, Flag *pOverflow)
 {
 
diff --git a/media/module/codecs/amrnb/common/src/syn_filt.cpp b/media/module/codecs/amrnb/common/src/syn_filt.cpp
index 36c1d84..82770f1 100644
--- a/media/module/codecs/amrnb/common/src/syn_filt.cpp
+++ b/media/module/codecs/amrnb/common/src/syn_filt.cpp
@@ -245,9 +245,6 @@
 
 ------------------------------------------------------------------------------
 */
-#ifdef __clang__
-__attribute__((no_sanitize("integer")))
-#endif
 void Syn_filt(
     Word16 a[],     /* (i)   : a[M+1] prediction coefficients   (M=10)  */
     Word16 x[],     /* (i)   : input signal                             */
diff --git a/media/module/codecs/amrnb/enc/src/autocorr.cpp b/media/module/codecs/amrnb/enc/src/autocorr.cpp
index c71811d..a078f5a 100644
--- a/media/module/codecs/amrnb/enc/src/autocorr.cpp
+++ b/media/module/codecs/amrnb/enc/src/autocorr.cpp
@@ -312,6 +312,7 @@
 
     Word16 y[L_WINDOW];
     Word32 sum;
+    Word32 mul;
     Word16 overfl_shft;
 
 
@@ -343,7 +344,8 @@
         temp = (amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_wind++), 0x04000)) >> 15;
         *(p_y++) = temp;
 
-        sum += ((Word32)temp * temp) << 1;
+        __builtin_mul_overflow(temp, temp, &mul);
+        __builtin_add_overflow(sum, mul << 1, &sum);
         if (sum < 0)
         {
             /*
@@ -395,10 +397,12 @@
         {
             temp = *p_y >> 2;
             *(p_y++) = temp;
-            sum += ((Word32)temp * temp) << 1;
+            __builtin_mul_overflow(temp, temp, &mul);
+            __builtin_add_overflow(sum, mul << 1, &sum);
             temp = *p_y >> 2;
             *(p_y++) = temp;
-            sum += ((Word32)temp * temp) << 1;
+            __builtin_mul_overflow(temp, temp, &mul);
+            __builtin_add_overflow(sum, mul << 1, &sum);
         }
         if (sum > 0)
         {
diff --git a/media/module/codecs/amrnb/enc/src/c2_9pf.cpp b/media/module/codecs/amrnb/enc/src/c2_9pf.cpp
index b211032..56b4fb8 100644
--- a/media/module/codecs/amrnb/enc/src/c2_9pf.cpp
+++ b/media/module/codecs/amrnb/enc/src/c2_9pf.cpp
@@ -610,6 +610,7 @@
         Word32 alp1;
         Word16 i;
         Word32 L_temp;
+        Word32 mul;
         Word16 *p_codvec = &codvec[0];
 
         OSCL_UNUSED_ARG(pOverflow);
@@ -693,7 +694,8 @@
                     L_temp = ((Word32) alp * sq1) << 1;
 
                     /* s = L_msu(L_temp, sq, alp_16, pOverflow); */
-                    s = L_temp - (((Word32) sq * alp_16) << 1);
+                    __builtin_mul_overflow(sq, alp_16, &mul);
+                    __builtin_sub_overflow(L_temp, (mul << 1), &s);
 
                     if (s > 0)
                     {
diff --git a/media/module/codecs/amrnb/enc/src/c3_14pf.cpp b/media/module/codecs/amrnb/enc/src/c3_14pf.cpp
index 58ab2fa..bb4fe36 100644
--- a/media/module/codecs/amrnb/enc/src/c3_14pf.cpp
+++ b/media/module/codecs/amrnb/enc/src/c3_14pf.cpp
@@ -403,6 +403,7 @@
     Word16 *p_codvec = &codvec[0];
 
     Word32 s;
+    Word32 mul;
     Word32 alp0;
     Word32 alp1;
 
@@ -487,7 +488,8 @@
                             s = ((Word32) alp * sq1) << 1;
 
                             /* s = L_msu(s, sq, alp_16, pOverflow); */
-                            s -= (((Word32) sq * alp_16) << 1);
+                            __builtin_mul_overflow(sq, alp_16, &mul);
+                            __builtin_sub_overflow(s, (mul << 1), &s);
 
                             if (s > 0)
                             {
diff --git a/media/module/codecs/amrnb/enc/src/c4_17pf.cpp b/media/module/codecs/amrnb/enc/src/c4_17pf.cpp
index d52b43b..062ee5a 100644
--- a/media/module/codecs/amrnb/enc/src/c4_17pf.cpp
+++ b/media/module/codecs/amrnb/enc/src/c4_17pf.cpp
@@ -416,6 +416,7 @@
         Word16 *p_codvec = &codvec[0];
 
         Word32 s;
+        Word32 mul;
         Word32 alp0;
         Word32 alp1;
 
@@ -497,7 +498,8 @@
                             s = ((Word32) alp * sq1) << 1;
 
                             /* s = L_msu(s, sq, alp_16, pOverflow); */
-                            s -= (((Word32) sq * alp_16) << 1);
+                            __builtin_mul_overflow(sq, alp_16, &mul);
+                            __builtin_sub_overflow(s, (mul << 1), &s);
 
                             if (s > 0)
                             {
@@ -610,7 +612,8 @@
                             s = ((Word32) alp * sq1) << 1;
 
                             /* s = L_msu(s, sq, alp_16, pOverflow); */
-                            s -= (((Word32) sq * alp_16) << 1);
+                            __builtin_mul_overflow(sq, alp_16, &mul);
+                            __builtin_sub_overflow(s, (mul << 1), &s);
 
                             if (s > 0)
                             {
@@ -630,7 +633,8 @@
                         s = ((Word32) alpk * sq) << 1;
 
                         /* s = L_msu(s, psk, alp, pOverflow); */
-                        s -= (((Word32) psk * alp) << 1);
+                        __builtin_mul_overflow(psk, alp, &mul);
+                        __builtin_sub_overflow(s, (mul << 1), &s);
 
                         if (s > 0)
                         {
diff --git a/media/module/codecs/amrnb/enc/src/cor_h_x.cpp b/media/module/codecs/amrnb/enc/src/cor_h_x.cpp
index c25c026..398c71f 100644
--- a/media/module/codecs/amrnb/enc/src/cor_h_x.cpp
+++ b/media/module/codecs/amrnb/enc/src/cor_h_x.cpp
@@ -254,6 +254,7 @@
     Word16 k;
 
     Word32 s;
+    Word32 mul;
     Word32 y32[L_CODE];
     Word32 max;
     Word32 tot;
@@ -275,15 +276,19 @@
 
             for (j = (L_CODE - i - 1) >> 1; j != 0; j--)
             {
-                s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
-                s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
+                __builtin_mul_overflow(*(p_x++), *(p_ptr++), &mul);
+                __builtin_add_overflow(s, mul << 1, &s);
+                __builtin_mul_overflow(*(p_x++), *(p_ptr++), &mul);
+                __builtin_add_overflow(s, mul << 1, &s);
             }
 
-            s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
+            __builtin_mul_overflow(*(p_x++), *(p_ptr++), &mul);
+            __builtin_add_overflow(s, mul << 1, &s);
 
             if (!((L_CODE - i) & 1))    /* if even number of iterations */
             {
-                s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
+                __builtin_mul_overflow(*(p_x++), *(p_ptr++), &mul);
+                __builtin_add_overflow(s, mul << 1, &s);
             }
 
             y32[i] = s;
@@ -299,7 +304,7 @@
             }
         }
 
-        tot += (max >> 1);
+        __builtin_add_overflow(tot, (max >> 1), &tot);
     }
 
 
@@ -310,10 +315,13 @@
 
     for (i = L_CODE >> 1; i != 0; i--)
     {
+        Word32 result;
         s = L_shl(*(p_y32++), j, pOverflow);
-        *(p_ptr++) = (s + 0x00008000) >> 16;
+        __builtin_add_overflow(s, 0x00008000, &result);
+        *(p_ptr++) = result >> 16;
         s = L_shl(*(p_y32++), j, pOverflow);
-        *(p_ptr++) = (s + 0x00008000) >> 16;
+        __builtin_add_overflow(s, 0x00008000, &result);
+        *(p_ptr++) = result >> 16;
     }
 
     return;
diff --git a/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp b/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
index e32eb4a..80ebb73 100644
--- a/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
+++ b/media/module/codecs/amrnb/enc/src/cor_h_x2.cpp
@@ -268,7 +268,7 @@
                 max = s;
             }
         }
-        tot = (tot + (max >> 1));
+        __builtin_add_overflow(tot, (max >> 1), &tot);
     }
 
     j = sub(norm_l(tot), sf, pOverflow);
diff --git a/media/module/codecs/amrnb/enc/src/dtx_enc.cpp b/media/module/codecs/amrnb/enc/src/dtx_enc.cpp
index 2ccb777..0d56c9b 100644
--- a/media/module/codecs/amrnb/enc/src/dtx_enc.cpp
+++ b/media/module/codecs/amrnb/enc/src/dtx_enc.cpp
@@ -945,6 +945,7 @@
 
     Word16 i;
     Word32 L_frame_en;
+    Word32 mul;
     Word32 L_temp;
     Word16 log_en_e;
     Word16 log_en_m;
@@ -967,7 +968,8 @@
 
     for (i = L_FRAME; i != 0; i--)
     {
-        L_frame_en += (((Word32) * p_speech) * *(p_speech)) << 1;
+        __builtin_mul_overflow(*p_speech, *p_speech, &mul);
+        __builtin_add_overflow(L_frame_en, mul << 1, &L_frame_en);
         p_speech++;
         if (L_frame_en < 0)
         {
diff --git a/media/module/codecs/amrnb/enc/src/levinson.cpp b/media/module/codecs/amrnb/enc/src/levinson.cpp
index 29cdac6..83dd81e 100644
--- a/media/module/codecs/amrnb/enc/src/levinson.cpp
+++ b/media/module/codecs/amrnb/enc/src/levinson.cpp
@@ -731,7 +731,7 @@
         t0 = t0 << 5;
 
         t1 = ((Word32) * (Rh + i) << 16) + ((Word32)(*(Rl + i)) << 1);
-        t0 += t1;
+        __builtin_add_overflow(t0, t1, &t0);
 
         /* K = -t0 / Alpha */
 
diff --git a/media/module/codecs/amrnb/enc/src/pitch_fr.cpp b/media/module/codecs/amrnb/enc/src/pitch_fr.cpp
index 584f79b..ab0a221 100644
--- a/media/module/codecs/amrnb/enc/src/pitch_fr.cpp
+++ b/media/module/codecs/amrnb/enc/src/pitch_fr.cpp
@@ -326,6 +326,7 @@
     Word16 norm_h;
     Word16 norm_l;
     Word32 s;
+    Word32 mul;
     Word32 s2;
     Word16 excf[L_SUBFR];
     Word16 scaling;
@@ -353,10 +354,12 @@
     {
         temp = *(p_excf++);
         *(p_s_excf++) = temp >> 2;
-        s += (Word32) temp * temp;
+        __builtin_mul_overflow(temp, temp, &mul);
+        __builtin_add_overflow(s, mul, &s);
         temp = *(p_excf++);
         *(p_s_excf++) = temp >> 2;
-        s += (Word32) temp * temp;
+        __builtin_mul_overflow(temp, temp, &mul);
+        __builtin_add_overflow(s, mul, &s);
     }
 
 
@@ -387,20 +390,24 @@
 
         while (j--)
         {
-            s  += (Word32) * (p_x++) * *(p_s_excf);
-            s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf)));
+            __builtin_mul_overflow(*(p_x++), *p_s_excf, &mul);
+            __builtin_add_overflow(s, mul, &s);
+            __builtin_mul_overflow(*p_s_excf, *p_s_excf, &mul);
+            __builtin_add_overflow(s2, mul, &s2);
             p_s_excf++;
-            s  += (Word32) * (p_x++) * *(p_s_excf);
-            s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf)));
+            __builtin_mul_overflow(*(p_x++), *p_s_excf, &mul);
+            __builtin_add_overflow(s, mul, &s);
+            __builtin_mul_overflow(*p_s_excf, *p_s_excf, &mul);
+            __builtin_add_overflow(s2, mul, &s2);
             p_s_excf++;
         }
 
         s2     = s2 << 1;
         s2     = Inv_sqrt(s2, pOverflow);
         norm_h = (Word16)(s2 >> 16);
-        norm_l = (Word16)((s2 >> 1) - (norm_h << 15));
+        __builtin_sub_overflow((s2 >> 1), (norm_h << 15), &norm_l);
         corr_h = (Word16)(s >> 15);
-        corr_l = (Word16)((s) - (corr_h << 15));
+        __builtin_sub_overflow(s, (corr_h << 15), &corr_l);
 
         /* Normalize correlation = correlation * (1/sqrt(energy)) */
 
diff --git a/media/module/codecs/amrnb/enc/src/pitch_ol.cpp b/media/module/codecs/amrnb/enc/src/pitch_ol.cpp
index c039bb0..0e4b74b 100644
--- a/media/module/codecs/amrnb/enc/src/pitch_ol.cpp
+++ b/media/module/codecs/amrnb/enc/src/pitch_ol.cpp
@@ -959,6 +959,7 @@
     Word16 p_max3;
     Word16 scal_flag = 0;
     Word32 t0;
+    Word32 mul;
 
 #ifdef VAD2
     Word32 r01;
@@ -1002,7 +1003,8 @@
 
     for (i = -pit_max; i < L_frame; i++)
     {
-        t0 += (((Word32) * (p_signal)) * *(p_signal)) << 1;
+        __builtin_mul_overflow(*p_signal, *p_signal, &mul);
+        __builtin_add_overflow(t0, mul << 1, &t0);
         p_signal++;
         if (t0 < 0)
         {
diff --git a/media/module/codecs/amrnb/enc/src/pre_proc.cpp b/media/module/codecs/amrnb/enc/src/pre_proc.cpp
index 042920e..0e2be41 100644
--- a/media/module/codecs/amrnb/enc/src/pre_proc.cpp
+++ b/media/module/codecs/amrnb/enc/src/pre_proc.cpp
@@ -576,7 +576,7 @@
         *(p_signal++) = (Word16)((L_tmp + 0x0000800L) >> 12);
 
         st->y1_hi = (Word16)(L_tmp >> 12);
-        st->y1_lo = (Word16)((L_tmp << 3) - ((Word32)(st->y1_hi) << 15));
+        __builtin_sub_overflow((Word16)(L_tmp << 3), (st->y1_hi) << 15, &st->y1_lo);
 
     }
 
diff --git a/media/module/codecs/amrnb/enc/src/s10_8pf.cpp b/media/module/codecs/amrnb/enc/src/s10_8pf.cpp
index 352b611..97d0318 100644
--- a/media/module/codecs/amrnb/enc/src/s10_8pf.cpp
+++ b/media/module/codecs/amrnb/enc/src/s10_8pf.cpp
@@ -746,11 +746,13 @@
 
             for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
             {
-                ps2 = ps1 + *(p_temp1++);
+                __builtin_add_overflow(ps1, *(p_temp1++), &ps2);
 
-                alp2 = alp1 + ((Word32) * (p_temp2 + i5) << 12);
+                __builtin_add_overflow(alp1, *(p_temp2 + i5) << 12, &alp2);
 
-                alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
+                Word32 result;
+                __builtin_add_overflow(alp2, *(p_temp1++) << 14, &result);
+                alp_16 = (Word16)(result >> 16);
                 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
 
                 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
diff --git a/media/module/codecs/amrnb/enc/src/set_sign.cpp b/media/module/codecs/amrnb/enc/src/set_sign.cpp
index fa43f78..55658a4 100644
--- a/media/module/codecs/amrnb/enc/src/set_sign.cpp
+++ b/media/module/codecs/amrnb/enc/src/set_sign.cpp
@@ -505,6 +505,7 @@
     Word16 en[L_CODE];                  /* correlation vector */
     Word32 s;
     Word32 t;
+    Word32 mul;
     Word32 L_temp;
     Word16 *p_cn;
     Word16 *p_dn;
@@ -525,7 +526,8 @@
         val = *(p_cn++);
         s = L_mac(s, val, val, pOverflow);
         val = *(p_dn++);
-        t += ((Word32) val * val) << 1;
+        __builtin_mul_overflow(val, val, &mul);
+        __builtin_add_overflow(t, mul << 1, &t);
     }
     s = Inv_sqrt(s, pOverflow);
     k_cn = (Word16)((L_shl(s, 5, pOverflow)) >> 16);
diff --git a/media/module/codecs/amrnb/enc/src/spstproc.cpp b/media/module/codecs/amrnb/enc/src/spstproc.cpp
index b9574aa..5210a39 100644
--- a/media/module/codecs/amrnb/enc/src/spstproc.cpp
+++ b/media/module/codecs/amrnb/enc/src/spstproc.cpp
@@ -192,6 +192,7 @@
     Word16 i;
     Word16 j;
     Word16 temp;
+    Word32 mul;
     Word32 L_temp;
     Word32 L_temp2;
     Word16 tempShift;
@@ -262,8 +263,10 @@
          */
         L_temp     = ((Word32) * (p_exc++) * pitch_fac) << 1;
         L_temp2    = ((Word32) * (p_exc--) * pitch_fac) << 1;
-        L_temp    += ((Word32) * (p_code++) * gain_code) << 1;
-        L_temp2   += ((Word32) * (p_code++) * gain_code) << 1;
+        __builtin_mul_overflow(*(p_code++), gain_code, &mul);
+        __builtin_add_overflow(L_temp, mul << 1, &L_temp);
+        __builtin_mul_overflow(*(p_code++), gain_code, &mul);
+        __builtin_add_overflow(L_temp2, mul << 1, &L_temp2);
         L_temp   <<=  tempShift;
         L_temp2  <<=  tempShift;
         *(p_exc++) = (Word16)((L_temp  + 0x08000L) >> 16);
diff --git a/media/module/codecs/amrwb/enc/src/az_isp.c b/media/module/codecs/amrwb/enc/src/az_isp.c
index d7074f0..22a5c25 100644
--- a/media/module/codecs/amrwb/enc/src/az_isp.c
+++ b/media/module/codecs/amrwb/enc/src/az_isp.c
@@ -248,10 +248,10 @@
         b1_h = b0_h;
     }
 
-    t0 = ((b1_h * x)<<1) + (((b1_l * x)>>15)<<1);
-    t0 += (b2_h * (-32768))<<1;             /* t0 = x*b1 - b2          */
-    t0 -= (b2_l << 1);
-    t0 += (f[n] << 12);                     /* t0 = x*b1 - b2 + f[i]/2 */
+    __builtin_add_overflow(((b1_h * x)<<1), (((b1_l * x)>>15)<<1), &t0);
+    __builtin_add_overflow(t0, (b2_h * (-32768))<<1, &t0);   /* t0 = x*b1 - b2          */
+    __builtin_sub_overflow(t0, (b2_l << 1), &t0);
+    __builtin_add_overflow(t0, (f[n] << 12), &t0);     /* t0 = x*b1 - b2 + f[i]/2 */
 
     t0 = L_shl2(t0, 6);                     /* Q24 to Q30 with saturation */
 
diff --git a/media/module/codecs/amrwb/enc/src/syn_filt.c b/media/module/codecs/amrwb/enc/src/syn_filt.c
index 7eba12f..40398f5 100644
--- a/media/module/codecs/amrwb/enc/src/syn_filt.c
+++ b/media/module/codecs/amrwb/enc/src/syn_filt.c
@@ -109,38 +109,38 @@
         p2 = &sig_lo[i - 1];
         p3 = &sig_hi[i - 1];
 
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
-        L_tmp  -= vo_mult32((*p2--), (*p1));
-        L_tmp1 -= vo_mult32((*p3--), (*p1++));
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
+        __builtin_sub_overflow(L_tmp, vo_mult32((*p2--), (*p1)), &L_tmp);
+        __builtin_sub_overflow(L_tmp1, vo_mult32((*p3--), (*p1++)), &L_tmp1);
 
         L_tmp = L_tmp >> 11;
         L_tmp += vo_L_mult(exc[i], a0);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 537a097..8215247 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2923,7 +2923,7 @@
                                                         audio_config_base_t *mixerConfig,
                                                         audio_devices_t deviceType,
                                                         const String8& address,
-                                                        audio_output_flags_t flags,
+                                                        audio_output_flags_t *flags,
                                                         const audio_attributes_t attributes)
 {
     AudioHwDevice *outHwDev = findSuitableHwDev_l(module, deviceType);
@@ -2958,7 +2958,7 @@
     mHardwareStatus = AUDIO_HW_IDLE;
 
     if (status == NO_ERROR) {
-        if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
+        if (*flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
             const sp<IAfMmapPlaybackThread> thread = IAfMmapPlaybackThread::create(
                     this, *output, outHwDev, outputStream, mSystemReady);
             mMmapThreads.add(*output, thread);
@@ -2967,22 +2967,22 @@
             return thread;
         } else {
             sp<IAfPlaybackThread> thread;
-            if (flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
+            if (*flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
                 thread = IAfPlaybackThread::createBitPerfectThread(
                         this, outputStream, *output, mSystemReady);
                 ALOGV("%s() created bit-perfect output: ID %d thread %p",
                       __func__, *output, thread.get());
-            } else if (flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) {
+            } else if (*flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) {
                 thread = IAfPlaybackThread::createSpatializerThread(this, outputStream, *output,
                                                     mSystemReady, mixerConfig);
                 ALOGV("openOutput_l() created spatializer output: ID %d thread %p",
                       *output, thread.get());
-            } else if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+            } else if (*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
                 thread = IAfPlaybackThread::createOffloadThread(this, outputStream, *output,
                         mSystemReady, halConfig->offload_info);
                 ALOGV("openOutput_l() created offload output: ID %d thread %p",
                       *output, thread.get());
-            } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
+            } else if ((*flags & AUDIO_OUTPUT_FLAG_DIRECT)
                     || !IAfThreadBase::isValidPcmSinkFormat(halConfig->format)
                     || !IAfThreadBase::isValidPcmSinkChannelMask(halConfig->channel_mask)) {
                 thread = IAfPlaybackThread::createDirectOutputThread(this, outputStream, *output,
@@ -3046,7 +3046,7 @@
     audio_utils::lock_guard _l(mutex());
 
     const sp<IAfThreadBase> thread = openOutput_l(module, &output, &halConfig,
-            &mixerConfig, deviceType, address, flags, attributes);
+            &mixerConfig, deviceType, address, &flags, attributes);
     if (thread != 0) {
         uint32_t latencyMs = 0;
         if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 21c171d..6777075 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -337,7 +337,7 @@
             audio_config_base_t* mixerConfig,
             audio_devices_t deviceType,
             const String8& address,
-            audio_output_flags_t flags,
+            audio_output_flags_t* flags,
             audio_attributes_t attributes) final REQUIRES(mutex());
     const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
             getAudioHwDevs_l() const final REQUIRES(mutex(), hardwareMutex()) {
diff --git a/services/audioflinger/IAfPatchPanel.h b/services/audioflinger/IAfPatchPanel.h
index 37dce3a..15b6ddf 100644
--- a/services/audioflinger/IAfPatchPanel.h
+++ b/services/audioflinger/IAfPatchPanel.h
@@ -82,7 +82,7 @@
             audio_config_base_t* mixerConfig,
             audio_devices_t deviceType,
             const String8& address,
-            audio_output_flags_t flags,
+            audio_output_flags_t* flags,
             audio_attributes_t attributes) REQUIRES(mutex()) = 0;
     virtual audio_utils::mutex& mutex() const
             RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 35f17c1..994dd47 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -268,7 +268,7 @@
                                                             &mixerConfig,
                                                             outputDevice,
                                                             outputDeviceAddress,
-                                                            flags,
+                                                            &flags,
                                                             attributes);
                     ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get());
                     if (thread == 0) {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index ecbd0ae..90d3ef9 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3220,9 +3220,9 @@
 
     // Calculate size of normal sink buffer relative to the HAL output buffer size
     double multiplier = 1.0;
-    // Note: mType == SPATIALIZER does not support FastMixer.
-    if (mType == MIXER && (kUseFastMixer == FastMixer_Static ||
-            kUseFastMixer == FastMixer_Dynamic)) {
+    // Note: mType == SPATIALIZER does not support FastMixer and DEEP is by definition not "fast"
+    if ((mType == MIXER && !(mOutput->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) &&
+            (kUseFastMixer == FastMixer_Static || kUseFastMixer == FastMixer_Dynamic)) {
         size_t minNormalFrameCount = (kMinNormalSinkBufferSizeMs * mSampleRate) / 1000;
         size_t maxNormalFrameCount = (kMaxNormalSinkBufferSizeMs * mSampleRate) / 1000;
 
@@ -5135,7 +5135,16 @@
             break;
         case FastMixer_Static:
         case FastMixer_Dynamic:
-            initFastMixer = mFrameCount < mNormalFrameCount;
+            if (mType == MIXER && (output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
+                /* Do not init fast mixer on deep buffer, warn if buffers are confed too small */
+                initFastMixer = false;
+                ALOGW_IF(mFrameCount * 1000 / mSampleRate < kMinNormalSinkBufferSizeMs,
+                         "HAL DEEP BUFFER Buffer (%zu ms) is smaller than set minimal buffer "
+                         "(%u ms), seems like a configuration error",
+                         mFrameCount * 1000 / mSampleRate, kMinNormalSinkBufferSizeMs);
+            } else {
+                initFastMixer = mFrameCount < mNormalFrameCount;
+            }
             break;
         }
         ALOGW_IF(initFastMixer == false && mFrameCount < mNormalFrameCount,
diff --git a/services/audioflinger/datapath/AudioHwDevice.cpp b/services/audioflinger/datapath/AudioHwDevice.cpp
index 5314e9e..c2e538c 100644
--- a/services/audioflinger/datapath/AudioHwDevice.cpp
+++ b/services/audioflinger/datapath/AudioHwDevice.cpp
@@ -41,19 +41,20 @@
         AudioStreamOut **ppStreamOut,
         audio_io_handle_t handle,
         audio_devices_t deviceType,
-        audio_output_flags_t flags,
+        audio_output_flags_t *flags,
         struct audio_config *config,
         const char *address,
         const std::vector<playback_track_metadata_v7_t>& sourceMetadata)
 {
 
     struct audio_config originalConfig = *config;
-    auto outputStream = new AudioStreamOut(this, flags);
+    auto outputStream = new AudioStreamOut(this);
 
     // Try to open the HAL first using the current format.
     ALOGV("openOutputStream(), try sampleRate %d, format %#x, channelMask %#x", config->sample_rate,
             config->format, config->channel_mask);
-    status_t status = outputStream->open(handle, deviceType, config, address, sourceMetadata);
+    status_t status = outputStream->open(handle, deviceType, config, flags, address,
+                                        sourceMetadata);
 
     if (status != NO_ERROR) {
         delete outputStream;
@@ -67,19 +68,25 @@
 
         // If the data is encoded then try again using wrapped PCM.
         const bool wrapperNeeded = !audio_has_proportional_frames(originalConfig.format)
-                && ((flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0)
-                && ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0);
+                && ((*flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0)
+                && ((*flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0);
 
         if (wrapperNeeded) {
             if (SPDIFEncoder::isFormatSupported(originalConfig.format)) {
-                outputStream = new SpdifStreamOut(this, flags, originalConfig.format);
-                status = outputStream->open(handle, deviceType, &originalConfig, address,
+                outputStream = new SpdifStreamOut(this, originalConfig.format);
+                status = outputStream->open(handle, deviceType, &originalConfig, flags, address,
                                             sourceMetadata);
                 if (status != NO_ERROR) {
                     ALOGE("ERROR - openOutputStream(), SPDIF open returned %d",
                         status);
                     delete outputStream;
                     outputStream = nullptr;
+                } else {
+                    // on success, we need to assign the actual HAL stream config so that clients
+                    // know and can later patch correctly.
+                    config->format = originalConfig.format;
+                    config->channel_mask = originalConfig.channel_mask;
+                    config->sample_rate = originalConfig.sample_rate;
                 }
             } else {
                 ALOGE("ERROR - openOutputStream(), SPDIFEncoder does not support format 0x%08x",
@@ -153,6 +160,12 @@
                         status);
                     delete inputStream;
                     inputStream = nullptr;
+                } else {
+                    // on success, we need to assign the actual HAL stream config so that clients
+                    // know and can later patch correctly.
+                    config->format = originalConfig.format;
+                    config->channel_mask = originalConfig.channel_mask;
+                    config->sample_rate = originalConfig.sample_rate;
                 }
             } else {
                 ALOGE("ERROR - openInputStream(), SPDIFDecoder does not support format 0x%08x",
diff --git a/services/audioflinger/datapath/AudioHwDevice.h b/services/audioflinger/datapath/AudioHwDevice.h
index e1a9018..6a35b91 100644
--- a/services/audioflinger/datapath/AudioHwDevice.h
+++ b/services/audioflinger/datapath/AudioHwDevice.h
@@ -85,7 +85,7 @@
             AudioStreamOut **ppStreamOut,
             audio_io_handle_t handle,
             audio_devices_t deviceType,
-            audio_output_flags_t flags,
+            audio_output_flags_t *flags,
             struct audio_config *config,
             const char *address,
             const std::vector<playback_track_metadata_v7_t>& sourceMetadata);
diff --git a/services/audioflinger/datapath/AudioStreamOut.cpp b/services/audioflinger/datapath/AudioStreamOut.cpp
index c65373e..7aadda3 100644
--- a/services/audioflinger/datapath/AudioStreamOut.cpp
+++ b/services/audioflinger/datapath/AudioStreamOut.cpp
@@ -30,9 +30,8 @@
 namespace android {
 
 // ----------------------------------------------------------------------------
-AudioStreamOut::AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags)
+AudioStreamOut::AudioStreamOut(AudioHwDevice *dev)
         : audioHwDev(dev)
-        , flags(flags)
 {
 }
 
@@ -93,14 +92,16 @@
         audio_io_handle_t handle,
         audio_devices_t deviceType,
         struct audio_config *config,
+        audio_output_flags_t *flagsPtr,
         const char *address,
         const std::vector<playback_track_metadata_v7_t>& sourceMetadata)
 {
     sp<StreamOutHalInterface> outStream;
 
-    const audio_output_flags_t customFlags = (config->format == AUDIO_FORMAT_IEC61937)
-                ? (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
-                : flags;
+    audio_output_flags_t customFlags = (config->format == AUDIO_FORMAT_IEC61937)
+                ? (audio_output_flags_t)(*flagsPtr | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
+                : *flagsPtr;
+    *flagsPtr = flags = customFlags;
 
     int status = hwDev()->openOutputStream(
             handle,
diff --git a/services/audioflinger/datapath/AudioStreamOut.h b/services/audioflinger/datapath/AudioStreamOut.h
index 2bf94a1..1857099 100644
--- a/services/audioflinger/datapath/AudioStreamOut.h
+++ b/services/audioflinger/datapath/AudioStreamOut.h
@@ -37,16 +37,17 @@
 public:
     AudioHwDevice * const audioHwDev;
     sp<StreamOutHalInterface> stream;
-    const audio_output_flags_t flags;
+    audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
 
     [[nodiscard]] sp<DeviceHalInterface> hwDev() const;
 
-    AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags);
+    explicit AudioStreamOut(AudioHwDevice *dev);
 
     virtual status_t open(
             audio_io_handle_t handle,
             audio_devices_t deviceType,
             struct audio_config *config,
+            audio_output_flags_t *flagsPtr,
             const char *address,
             const std::vector<playback_track_metadata_v7_t>& sourceMetadata);
 
diff --git a/services/audioflinger/datapath/SpdifStreamIn.cpp b/services/audioflinger/datapath/SpdifStreamIn.cpp
index 98ce712..0090bc5 100644
--- a/services/audioflinger/datapath/SpdifStreamIn.cpp
+++ b/services/audioflinger/datapath/SpdifStreamIn.cpp
@@ -81,6 +81,11 @@
             outputDevice,
             outputDeviceAddress);
 
+    // reset config back to whatever is returned by HAL
+    config->sample_rate = customConfig.sample_rate;
+    config->format = customConfig.format;
+    config->channel_mask = customConfig.channel_mask;
+
     ALOGI("SpdifStreamIn::open() status = %d", status);
 
 #ifdef TEE_SINK
diff --git a/services/audioflinger/datapath/SpdifStreamOut.cpp b/services/audioflinger/datapath/SpdifStreamOut.cpp
index d3983b0..a565955 100644
--- a/services/audioflinger/datapath/SpdifStreamOut.cpp
+++ b/services/audioflinger/datapath/SpdifStreamOut.cpp
@@ -33,10 +33,8 @@
  * PCM then we need to wrap the data in an SPDIF wrapper.
  */
 SpdifStreamOut::SpdifStreamOut(AudioHwDevice *dev,
-            audio_output_flags_t flags,
             audio_format_t format)
-        // Tell the HAL that the data will be compressed audio wrapped in a data burst.
-        : AudioStreamOut(dev, (audio_output_flags_t) (flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO))
+        : AudioStreamOut(dev)
         , mSpdifEncoder(this, format)
 {
 }
@@ -45,6 +43,7 @@
         audio_io_handle_t handle,
         audio_devices_t devices,
         struct audio_config *config,
+        audio_output_flags_t *flags,
         const char *address,
         const std::vector<playback_track_metadata_v7_t>& sourceMetadata)
 {
@@ -63,6 +62,8 @@
 
     customConfig.format = AUDIO_FORMAT_PCM_16_BIT;
     customConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+    // Tell the HAL that the data will be compressed audio wrapped in a data burst.
+    *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO);
 
     // Always print this because otherwise it could be very confusing if the
     // HAL and AudioFlinger are using different formats.
@@ -76,9 +77,15 @@
             handle,
             devices,
             &customConfig,
+            flags,
             address,
             sourceMetadata);
 
+    // reset config back to whatever is returned by HAL
+    config->sample_rate = customConfig.sample_rate;
+    config->format = customConfig.format;
+    config->channel_mask = customConfig.channel_mask;
+
     ALOGI("SpdifStreamOut::open() status = %d", status);
 
 #ifdef TEE_SINK
diff --git a/services/audioflinger/datapath/SpdifStreamOut.h b/services/audioflinger/datapath/SpdifStreamOut.h
index 1cd8f65..3241d6f 100644
--- a/services/audioflinger/datapath/SpdifStreamOut.h
+++ b/services/audioflinger/datapath/SpdifStreamOut.h
@@ -36,13 +36,13 @@
 class SpdifStreamOut : public AudioStreamOut {
 public:
 
-    SpdifStreamOut(AudioHwDevice *dev, audio_output_flags_t flags,
-            audio_format_t format);
+    SpdifStreamOut(AudioHwDevice *dev, audio_format_t format);
 
     status_t open(
             audio_io_handle_t handle,
             audio_devices_t devices,
             struct audio_config *config,
+            audio_output_flags_t *flags,
             const char *address,
             const std::vector<playback_track_metadata_v7_t>& sourceMetadata) override;
 
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 1bac259..35973c1 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -477,7 +477,7 @@
                                 audio_config_base_t *mixerConfig,
                                 const sp<DeviceDescriptorBase>& device,
                                 uint32_t *latencyMs,
-                                audio_output_flags_t flags,
+                                audio_output_flags_t *flags,
                                 audio_attributes_t audioAttributes) = 0;
     // creates a special output that is duplicated to the two outputs passed as arguments.
     // The duplication is performed by a special mixer thread in the AudioFlinger.
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 3b7cae3..d499222 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -29,19 +29,21 @@
 /**
  * Legacy audio policy product strategies IDs. These strategies are supported by the default
  * policy engine.
+ * IMPORTANT NOTE: the order of this enum is important as it determines the priority
+ * between active strategies for routing decisions: lower enum value => higher prioriy
  */
 enum legacy_strategy {
     STRATEGY_NONE = -1,
-    STRATEGY_MEDIA,
     STRATEGY_PHONE,
     STRATEGY_SONIFICATION,
-    STRATEGY_SONIFICATION_RESPECTFUL,
-    STRATEGY_DTMF,
     STRATEGY_ENFORCED_AUDIBLE,
-    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
     STRATEGY_ACCESSIBILITY,
-    STRATEGY_REROUTING,
+    STRATEGY_SONIFICATION_RESPECTFUL,
+    STRATEGY_MEDIA,
+    STRATEGY_DTMF,
     STRATEGY_CALL_ASSISTANT,
+    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
+    STRATEGY_REROUTING,
     STRATEGY_PATCH,
 };
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index bfb28a5..a18cf1f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -412,7 +412,7 @@
                       const audio_config_base_t *mixerConfig,
                       const DeviceVector &devices,
                       audio_stream_type_t stream,
-                      audio_output_flags_t flags,
+                      audio_output_flags_t *flags,
                       audio_io_handle_t *output,
                       audio_attributes_t attributes);
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index d206637..26bb94f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -137,6 +137,7 @@
 class HwModuleCollection : public Vector<sp<HwModule> >
 {
 public:
+    sp<HwModule> getModuleFromHandle(audio_module_handle_t handle) const;
     sp<HwModule> getModuleFromName(const char *name) const;
 
     /**
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index a8663fa..3c2f46a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -587,7 +587,7 @@
                                        const audio_config_base_t *mixerConfig,
                                        const DeviceVector &devices,
                                        audio_stream_type_t stream,
-                                       audio_output_flags_t flags,
+                                       audio_output_flags_t *flags,
                                        audio_io_handle_t *output,
                                        audio_attributes_t attributes)
 {
@@ -617,7 +617,7 @@
     // create a default one
     if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
             lHalConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
-        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
+        *flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
         lHalConfig.offload_info = AUDIO_INFO_INITIALIZER;
         lHalConfig.offload_info.sample_rate = lHalConfig.sample_rate;
         lHalConfig.offload_info.channel_mask = lHalConfig.channel_mask;
@@ -635,7 +635,7 @@
         lMixerConfig = *mixerConfig;
     }
 
-    mFlags = (audio_output_flags_t)(mFlags | flags);
+    mFlags = (audio_output_flags_t)(mFlags | *flags);
 
     // If no mixer config is specified for a spatializer output, default to 5.1 for proper
     // configuration of the final downmixer or spatializer
@@ -653,8 +653,9 @@
                                                    &lMixerConfig,
                                                    device,
                                                    &mLatency,
-                                                   mFlags,
+                                                   &mFlags,
                                                    attributes);
+    *flags = mFlags;
 
     if (status == NO_ERROR) {
         LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
index f5e135e..723887d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyConfig.cpp
@@ -342,7 +342,8 @@
                 AUDIO_FORMAT_AAC_XHE}},
         {AUDIO_FORMAT_DOLBY_TRUEHD, {}},
         {AUDIO_FORMAT_E_AC3_JOC, {}},
-        {AUDIO_FORMAT_AC4, {}}};
+        {AUDIO_FORMAT_AC4, {}},     // L0-3
+        {AUDIO_FORMAT_AC4_L4, {}}};
 }
 
 bool AudioPolicyConfig::useDeepBufferForMedia() const {
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 6696b45..2d8231a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -283,6 +283,16 @@
     dumpAudioRouteVector(mRoutes, dst, spaces);
 }
 
+sp<HwModule> HwModuleCollection::getModuleFromHandle(audio_module_handle_t handle) const
+{
+    for (const auto& module : *this) {
+        if (module->getHandle() == handle) {
+            return module;
+        }
+    }
+    return nullptr;
+}
+
 sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
 {
     for (const auto& module : *this) {
diff --git a/services/audiopolicy/config/surround_sound_configuration_5_0.xml b/services/audiopolicy/config/surround_sound_configuration_5_0.xml
index 590a181..6a268d8 100644
--- a/services/audiopolicy/config/surround_sound_configuration_5_0.xml
+++ b/services/audiopolicy/config/surround_sound_configuration_5_0.xml
@@ -27,5 +27,6 @@
     <format name="AUDIO_FORMAT_DTS_HD" />
     <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
     <format name="AUDIO_FORMAT_AC4" />
+    <format name="AUDIO_FORMAT_AC4_L4" />
   </formats>
 </surroundSound>
diff --git a/services/audiopolicy/config/surround_sound_configuration_aidl.xml b/services/audiopolicy/config/surround_sound_configuration_aidl.xml
index cf15711..51ccaa9 100644
--- a/services/audiopolicy/config/surround_sound_configuration_aidl.xml
+++ b/services/audiopolicy/config/surround_sound_configuration_aidl.xml
@@ -30,5 +30,6 @@
     <format name="AUDIO_FORMAT_DTS_UHD_P2" />
     <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
     <format name="AUDIO_FORMAT_AC4" />
+    <format name="AUDIO_FORMAT_AC4_L4" />
   </formats>
 </surroundSound>
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 2ff2907..3ec3fb3 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -122,17 +122,16 @@
     }
 }
 
-void AudioPolicyManager::broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
+status_t AudioPolicyManager::broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
                                                         media::DeviceConnectedState state)
 {
     audio_port_v7 devicePort;
     device->toAudioPort(&devicePort);
-    if (status_t status = mpClientInterface->setDeviceConnectedState(&devicePort, state);
-            status != OK) {
-        ALOGE("Error %d while setting connected state %d for device %s",
-                status, static_cast<int>(state),
-                device->getDeviceTypeAddr().toString(false).c_str());
-    }
+    status_t status = mpClientInterface->setDeviceConnectedState(&devicePort, state);
+    ALOGE_IF(status != OK, "Error %d while setting connected state %d for device %s", status,
+             static_cast<int>(state), device->getDeviceTypeAddr().toString(false).c_str());
+
+    return status;
 }
 
 status_t AudioPolicyManager::setDeviceConnectionStateInt(
@@ -213,7 +212,14 @@
 
             // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
             // parameters on newly connected devices (instead of opening the outputs...)
-            broadcastDeviceConnectionState(device, media::DeviceConnectedState::CONNECTED);
+            if (broadcastDeviceConnectionState(
+                        device, media::DeviceConnectedState::CONNECTED) != NO_ERROR) {
+                mAvailableOutputDevices.remove(device);
+                mHwModules.cleanUpForDevice(device);
+                ALOGE("%s() device %s format %x connection failed", __func__,
+                      device->toString().c_str(), device->getEncodedFormat());
+                return INVALID_OPERATION;
+            }
 
             if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) {
                 mAvailableOutputDevices.remove(device);
@@ -398,7 +404,14 @@
 
             // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
             // parameters on newly connected devices (instead of opening the inputs...)
-            broadcastDeviceConnectionState(device, media::DeviceConnectedState::CONNECTED);
+            if (broadcastDeviceConnectionState(
+                        device, media::DeviceConnectedState::CONNECTED) != NO_ERROR) {
+                mAvailableInputDevices.remove(device);
+                mHwModules.cleanUpForDevice(device);
+                ALOGE("%s() device %s format %x connection failed", __func__,
+                      device->toString().c_str(), device->getEncodedFormat());
+                return INVALID_OPERATION;
+            }
             // Propagate device availability to Engine
             setEngineDeviceConnectionState(device, state);
 
@@ -1610,14 +1623,19 @@
     releaseMsdOutputPatches(devices);
 
     status_t status =
-            outputDesc->open(config, nullptr /* mixerConfig */, devices, stream, flags, output,
+            outputDesc->open(config, nullptr /* mixerConfig */, devices, stream, &flags, output,
                              attributes);
 
-    // only accept an output with the requested parameters
+    // only accept an output with the requested parameters, unless the format can be IEC61937
+    // encapsulated and opened by AudioFlinger as wrapped IEC61937.
+    const bool ignoreRequestedParametersCheck = audio_is_iec61937_compatible(config->format)
+            && (flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
+            && audio_has_proportional_frames(outputDesc->getFormat());
     if (status != NO_ERROR ||
-        (config->sample_rate != 0 && config->sample_rate != outputDesc->getSamplingRate()) ||
-        (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->getFormat()) ||
-        (config->channel_mask != 0 && config->channel_mask != outputDesc->getChannelMask())) {
+        (!ignoreRequestedParametersCheck &&
+        ((config->sample_rate != 0 && config->sample_rate != outputDesc->getSamplingRate()) ||
+         (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->getFormat()) ||
+         (config->channel_mask != 0 && config->channel_mask != outputDesc->getChannelMask())))) {
         ALOGV("%s failed opening direct output: output %d sample rate %d %d,"
                 "format %d %d, channel mask %04x %04x", __func__, *output, config->sample_rate,
                 outputDesc->getSamplingRate(), config->format, outputDesc->getFormat(),
@@ -1637,11 +1655,11 @@
     outputDesc->mDirectClientSession = session;
 
     addOutput(*output, outputDesc);
-    setOutputDevices(__func__, outputDesc,
-                     devices,
-                     true,
-                     0,
-                     NULL);
+    // The version check is essentially to avoid making this call in the case of the HIDL HAL.
+    if (auto hwModule = mHwModules.getModuleFromHandle(mPrimaryModuleHandle); hwModule &&
+            hwModule->getHalVersionMajor() >= 3) {
+        setOutputDevices(__func__, outputDesc, devices, true, 0, NULL);
+    }
     mPreviousOutputs = mOutputs;
     ALOGV("%s returns new direct output %d", __func__, *output);
     mpClientInterface->onAudioPortListUpdate();
@@ -5985,7 +6003,8 @@
         audio_devices_t deviceType = device->type();
         // Enabling/disabling formats are applied to only HDMI devices. So, this function
         // returns formats reported by HDMI devices.
-        if (deviceType != AUDIO_DEVICE_OUT_HDMI) {
+        if (deviceType != AUDIO_DEVICE_OUT_HDMI &&
+            deviceType != AUDIO_DEVICE_OUT_HDMI_ARC && deviceType != AUDIO_DEVICE_OUT_HDMI_EARC) {
             continue;
         }
         // Formats reported by sink devices
@@ -6054,13 +6073,13 @@
 
     sp<SwAudioOutputDescriptor> outputDesc;
     bool profileUpdated = false;
-    DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromType(
-        AUDIO_DEVICE_OUT_HDMI);
+    DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromTypes(
+        {AUDIO_DEVICE_OUT_HDMI, AUDIO_DEVICE_OUT_HDMI_ARC, AUDIO_DEVICE_OUT_HDMI_EARC});
     for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
         // Simulate reconnection to update enabled surround sound formats.
         String8 address = String8(hdmiOutputDevices[i]->address().c_str());
         std::string name = hdmiOutputDevices[i]->getName();
-        status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
+        status_t status = setDeviceConnectionStateInt(hdmiOutputDevices[i]->type(),
                                                       AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
                                                       address.c_str(),
                                                       name.c_str(),
@@ -6068,7 +6087,7 @@
         if (status != NO_ERROR) {
             continue;
         }
-        status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
+        status = setDeviceConnectionStateInt(hdmiOutputDevices[i]->type(),
                                              AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
                                              address.c_str(),
                                              name.c_str(),
@@ -6608,11 +6627,12 @@
             sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
                                                                                  mpClientInterface);
             audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+            audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
             audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
             status_t status = outputDesc->open(nullptr /* halConfig */, nullptr /* mixerConfig */,
                                                DeviceVector(supportedDevice),
                                                AUDIO_STREAM_DEFAULT,
-                                               AUDIO_OUTPUT_FLAG_NONE, &output, attributes);
+                                               &flags, &output, attributes);
             if (status != NO_ERROR) {
                 ALOGW("Cannot open output stream for devices %s on hw module %s",
                       supportedDevice->toString().c_str(), hwModule->getName());
@@ -7982,9 +8002,21 @@
                         if (result.source == AUDIO_SOURCE_HOTWORD && !inputDesc->isSoundTrigger()) {
                             result.source = AUDIO_SOURCE_VOICE_RECOGNITION;
                         }
-                        return result; }).
+                        return result; });
             //only one input device for now
-                    addSource(device);
+            if (audio_is_remote_submix_device(device->type())) {
+                // remote submix HAL does not support audio conversion, need source device
+                // audio config to match the sink input descriptor audio config, otherwise AIDL
+                // HAL patching will fail
+                audio_port_config srcDevicePortConfig = {};
+                device->toAudioPortConfig(&srcDevicePortConfig, nullptr);
+                srcDevicePortConfig.sample_rate = inputDesc->getSamplingRate();
+                srcDevicePortConfig.channel_mask = inputDesc->getChannelMask();
+                srcDevicePortConfig.format = inputDesc->getFormat();
+                patchBuilder.addSource(srcDevicePortConfig);
+            } else {
+                patchBuilder.addSource(device);
+            }
             status = installPatch(__func__, patchHandle, inputDesc.get(), patchBuilder.patch(), 0);
         }
     }
@@ -8693,6 +8725,8 @@
     mReportedFormatsMap[devDesc] = formats;
 
     if (devDesc->type() == AUDIO_DEVICE_OUT_HDMI ||
+        devDesc->type() == AUDIO_DEVICE_OUT_HDMI_ARC ||
+        devDesc->type() == AUDIO_DEVICE_OUT_HDMI_EARC ||
         isDeviceOfModule(devDesc,AUDIO_HARDWARE_MODULE_ID_MSD)) {
         modifySurroundFormats(devDesc, &formats);
         size_t modifiedNumProfiles = 0;
@@ -8827,7 +8861,7 @@
     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
     audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
     status_t status = desc->open(halConfig, mixerConfig, devices,
-            AUDIO_STREAM_DEFAULT, flags, &output, attributes);
+            AUDIO_STREAM_DEFAULT, &flags, &output, attributes);
     if (status != NO_ERROR) {
         ALOGE("%s failed to open output %d", __func__, status);
         return nullptr;
@@ -8865,7 +8899,7 @@
         config.offload_info.channel_mask = config.channel_mask;
         config.offload_info.format = config.format;
 
-        status = desc->open(&config, mixerConfig, devices, AUDIO_STREAM_DEFAULT, flags, &output,
+        status = desc->open(&config, mixerConfig, devices, AUDIO_STREAM_DEFAULT, &flags, &output,
                             attributes);
         if (status != NO_ERROR) {
             return nullptr;
@@ -8873,11 +8907,11 @@
     }
 
     addOutput(output, desc);
-    setOutputDevices(__func__, desc,
-                     devices,
-                     true,
-                     0,
-                     NULL);
+    // The version check is essentially to avoid making this call in the case of the HIDL HAL.
+    if (auto hwModule = mHwModules.getModuleFromHandle(mPrimaryModuleHandle); hwModule &&
+            hwModule->getHalVersionMajor() >= 3) {
+        setOutputDevices(__func__, desc, devices, true, 0, NULL);
+    }
     sp<DeviceDescriptor> speaker = mAvailableOutputDevices.getDevice(
             AUDIO_DEVICE_OUT_SPEAKER, String8(""), AUDIO_FORMAT_DEFAULT);
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 953fd2a..9d2166a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -1105,8 +1105,8 @@
         // It can give a chance to HAL implementer to retrieve dynamic capabilities associated
         // to this device for example.
         // TODO avoid opening stream to retrieve capabilities of a profile.
-        void broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
-                                            media::DeviceConnectedState state);
+        status_t broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
+                                                media::DeviceConnectedState state);
 
         // updates device caching and output for streams that can influence the
         //    routing of notifications
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 22fc151..6d2c772 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -56,7 +56,7 @@
                                                            audio_config_base_t *mixerConfig,
                                                            const sp<DeviceDescriptorBase>& device,
                                                            uint32_t *latencyMs,
-                                                           audio_output_flags_t flags,
+                                                           audio_output_flags_t *flags,
                                                            audio_attributes_t attributes)
 {
     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
@@ -74,7 +74,7 @@
     request.mixerConfig = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_config_base_t_AudioConfigBase(*mixerConfig, false /*isInput*/));
     request.device = VALUE_OR_RETURN_STATUS(legacy2aidl_DeviceDescriptorBase(device));
-    request.flags = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
+    request.flags = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_output_flags_t_int32_t_mask(*flags));
     request.attributes = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(attributes));
 
@@ -89,7 +89,9 @@
             .channel_mask = halConfig->channel_mask,
             .format = halConfig->format,
         };
-        mAudioPolicyService->registerOutput(*output, config, flags);
+        *flags = VALUE_OR_RETURN_STATUS(
+                aidl2legacy_int32_t_audio_output_flags_t_mask(response.flags));
+        mAudioPolicyService->registerOutput(*output, config, *flags);
     }
     return status;
 }
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 5d9813f..eccefa7 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -790,7 +790,7 @@
                                     audio_config_base_t *mixerConfig,
                                     const sp<DeviceDescriptorBase>& device,
                                     uint32_t *latencyMs,
-                                    audio_output_flags_t flags,
+                                    audio_output_flags_t *flags,
                                     audio_attributes_t attributes);
         // creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by
         // a special mixer thread in the AudioFlinger.
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index ca7ad40..483f827 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -42,7 +42,7 @@
                         audio_config_base_t *mixerConfig,
                         const sp<DeviceDescriptorBase>& /*device*/,
                         uint32_t * /*latencyMs*/,
-                        audio_output_flags_t flags,
+                        audio_output_flags_t *flags,
                         audio_attributes_t /*attributes*/) override {
         if (module >= mNextModuleHandle) {
             ALOGE("%s: Module handle %d has not been allocated yet (next is %d)",
@@ -50,13 +50,13 @@
             return BAD_VALUE;
         }
         *output = mNextIoHandle++;
-        mOpenedOutputs[*output] = flags;
+        mOpenedOutputs[*output] = *flags;
         ALOGD("%s: opened output %d: HAL(%s %s %d) Mixer(%s %s %d) %s", __func__, *output,
               audio_channel_out_mask_to_string(halConfig->channel_mask),
               audio_format_to_string(halConfig->format), halConfig->sample_rate,
               audio_channel_out_mask_to_string(mixerConfig->channel_mask),
               audio_format_to_string(mixerConfig->format), mixerConfig->sample_rate,
-              android::toString(flags).c_str());
+              android::toString(*flags).c_str());
         return NO_ERROR;
     }
 
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index 0299160..6116eab 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -37,7 +37,7 @@
                         audio_config_base_t* /*mixerConfig*/,
                         const sp<DeviceDescriptorBase>& /*device*/,
                         uint32_t* /*latencyMs*/,
-                        audio_output_flags_t /*flags*/,
+                        audio_output_flags_t* /*flags*/,
                         audio_attributes_t /*attributes*/) override { return NO_INIT; }
     audio_io_handle_t openDuplicateOutput(audio_io_handle_t /*output1*/,
                                           audio_io_handle_t /*output2*/) override {
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 08855c9..5278b73 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -498,6 +498,9 @@
 void AudioPolicyManagerTestMsd::SetUpManagerConfig() {
     // TODO: Consider using Serializer to load part of the config from a string.
     ASSERT_NO_FATAL_FAILURE(AudioPolicyManagerTest::SetUpManagerConfig());
+    mConfig->getHwModules().getModuleFromName(
+            AUDIO_HARDWARE_MODULE_ID_PRIMARY)->setHalVersion(3, 0);
+
     mMsdOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_BUS);
     sp<AudioProfile> pcmOutputProfile = new AudioProfile(
             AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
@@ -529,7 +532,7 @@
                 addOutputProfile(spdifOutputProfile);
     }
 
-    sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 2 /*halVersionMajor*/);
+    sp<HwModule> msdModule = new HwModule(AUDIO_HARDWARE_MODULE_ID_MSD, 3 /*halVersionMajor*/);
     HwModuleCollection modules = mConfig->getHwModules();
     modules.add(msdModule);
     mConfig->setHwModules(modules);
@@ -2517,7 +2520,7 @@
                         audio_config_base_t * mixerConfig,
                         const sp<DeviceDescriptorBase>& device,
                         uint32_t * latencyMs,
-                        audio_output_flags_t flags,
+                        audio_output_flags_t *flags,
                         audio_attributes_t attributes) override {
         return mSimulateFailure ? BAD_VALUE :
                 AudioPolicyManagerTestClient::openOutput(
@@ -2539,8 +2542,29 @@
 
     void setSimulateFailure(bool simulateFailure) { mSimulateFailure = simulateFailure; }
 
+    void setSimulateBroadcastDeviceStatus(audio_devices_t device, status_t status) {
+        if (status != NO_ERROR) {
+            // simulate device connect status
+            mSimulateBroadcastDeviceStatus[device] = status;
+        } else {
+            // remove device connection fixed status
+            mSimulateBroadcastDeviceStatus.erase(device);
+        }
+    }
+
+    status_t setDeviceConnectedState(const struct audio_port_v7* port,
+                                     media::DeviceConnectedState state) override {
+        if (mSimulateBroadcastDeviceStatus.find(port->ext.device.type) !=
+            mSimulateBroadcastDeviceStatus.end()) {
+            // If a simulated status exists, return a status value
+            return mSimulateBroadcastDeviceStatus[port->ext.device.type];
+        }
+        return AudioPolicyManagerTestClient::setDeviceConnectedState(port, state);
+    }
+
   private:
     bool mSimulateFailure = false;
+    std::map<audio_devices_t, status_t> mSimulateBroadcastDeviceStatus;
 };
 
 }  // namespace
@@ -2561,6 +2585,9 @@
     void setSimulateOpenFailure(bool simulateFailure) {
         mFullClient->setSimulateFailure(simulateFailure); }
 
+    void setSimulateBroadcastDeviceStatus(audio_devices_t device, status_t status) {
+        mFullClient->setSimulateBroadcastDeviceStatus(device, status); }
+
     static const std::string sBluetoothConfig;
 
   private:
@@ -2604,6 +2631,30 @@
     }
 }
 
+TEST_P(AudioPolicyManagerTestDeviceConnectionFailed, BroadcastDeviceFailure) {
+    const audio_devices_t type = std::get<0>(GetParam());
+    const std::string name = std::get<1>(GetParam());
+    const std::string address = std::get<2>(GetParam());
+    const audio_format_t format = std::get<3>(GetParam());
+
+    // simulate broadcastDeviceConnectionState return failure
+    setSimulateBroadcastDeviceStatus(type, INVALID_OPERATION);
+    ASSERT_EQ(INVALID_OPERATION, mManager->setDeviceConnectionState(
+            type, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+            address.c_str(), name.c_str(), format));
+
+    // if broadcast is fail, device should not be added to available devices list
+    if (audio_is_output_device(type)) {
+        auto availableDevices = mManager->getAvailableOutputDevices();
+        EXPECT_FALSE(availableDevices.containsDeviceWithType(type));
+    } else if (audio_is_input_device(type)) {
+        auto availableDevices = mManager->getAvailableInputDevices();
+        EXPECT_FALSE(availableDevices.containsDeviceWithType(type));
+    }
+
+    setSimulateBroadcastDeviceStatus(type, NO_ERROR);
+}
+
 INSTANTIATE_TEST_CASE_P(
         DeviceConnectionFailure,
         AudioPolicyManagerTestDeviceConnectionFailed,
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 38476a4..0c4bfcb 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -265,9 +265,21 @@
         "liblog",
         "libutils",
         "libxml2",
-        "camera_platform_flags_c_lib",
     ],
 
+    target: {
+        android: {
+            shared_libs: [
+                "camera_platform_flags_c_lib",
+            ],
+        },
+        host: {
+            shared_libs: [
+                "camera_platform_flags_c_lib_for_test",
+            ],
+        },
+    },
+
     include_dirs: [
         "frameworks/av/camera/include",
         "frameworks/av/camera/include/camera",
diff --git a/services/camera/libcameraservice/tests/Android.bp b/services/camera/libcameraservice/tests/Android.bp
index 55e2c9d..d49aad6 100644
--- a/services/camera/libcameraservice/tests/Android.bp
+++ b/services/camera/libcameraservice/tests/Android.bp
@@ -44,13 +44,25 @@
         "libjpeg",
         "liblog",
         "libutils",
-        "camera_platform_flags_c_lib",
     ],
 
     static_libs: [
         "libgmock",
     ],
 
+    target: {
+        android: {
+            shared_libs: [
+                "camera_platform_flags_c_lib",
+            ],
+        },
+        host: {
+            shared_libs: [
+                "camera_platform_flags_c_lib_for_test",
+            ],
+        },
+    },
+
     cflags: [
         "-Wall",
         "-Wextra",