Merge "Add uid to audioflinger track dumps" into main
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index e9b757b..34ff367 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -30,8 +30,10 @@
 
 # Only turn on clang-format check for the following subfolders.
 clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+               camera/
                media/libaudioclient/tests/
                media/libaudiohal/tests/
                media/libmediatranscoding/
                services/camera/virtualcamera/
                services/mediatranscoding/
+               services/camera/libcameraservice/
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index ec36335..db33dd7 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -164,3 +164,10 @@
     description: "Enable stream reconfiguration for unchanged streams"
     bug: "341740105"
 }
+
+flag {
+    namespace: "camera_platform"
+    name: "use_context_attribution_source"
+    description: "Use the context-provided AttributionSource when checking for client permissions"
+    bug: "190657833"
+}
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 6d29ef5..53c4489 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -170,97 +170,78 @@
 }
 
 sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
-    if (mCameraService.get() == nullptr) {
-        if (CameraUtils::isCameraServiceDisabled()) {
-            return mCameraService;
-        }
+    if (mCameraService.get() != nullptr) {
+        return mCameraService;
+    }
+    if (CameraUtils::isCameraServiceDisabled()) {
+        return mCameraService;
+    }
 
-        sp<IServiceManager> sm = defaultServiceManager();
-        sp<IBinder> binder;
-        binder = sm->checkService(String16(kCameraServiceName));
-        if (binder == nullptr) {
-            ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder;
+    binder = sm->checkService(String16(kCameraServiceName));
+    if (binder == nullptr) {
+        ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
+        return nullptr;
+    }
+    sp<hardware::ICameraService> cameraService = interface_cast<hardware::ICameraService>(binder);
+    if (mDeathNotifier == nullptr) {
+        mDeathNotifier = new DeathNotifier(this);
+        binder->linkToDeath(mDeathNotifier);
+    }
+
+    // Setup looper thread to perform availability callbacks
+    if (mCbLooper == nullptr) {
+        mCbLooper = new ALooper;
+        mCbLooper->setName("C2N-mgr-looper");
+        status_t err = mCbLooper->start(
+                /*runOnCallingThread*/false,
+                /*canCallJava*/       true,
+                PRIORITY_DEFAULT);
+        if (err != OK) {
+            ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
+                    __FUNCTION__, strerror(-err), err);
+            mCbLooper.clear();
             return nullptr;
         }
-        if (mDeathNotifier == nullptr) {
-            mDeathNotifier = new DeathNotifier(this);
+        if (mHandler == nullptr) {
+            mHandler = new CallbackHandler(this);
         }
-        binder->linkToDeath(mDeathNotifier);
-        mCameraService = interface_cast<hardware::ICameraService>(binder);
+        mCbLooper->registerHandler(mHandler);
+    }
 
-        // Setup looper thread to perfrom availiability callbacks
-        if (mCbLooper == nullptr) {
-            mCbLooper = new ALooper;
-            mCbLooper->setName("C2N-mgr-looper");
-            status_t err = mCbLooper->start(
-                    /*runOnCallingThread*/false,
-                    /*canCallJava*/       true,
-                    PRIORITY_DEFAULT);
-            if (err != OK) {
-                ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
-                        __FUNCTION__, strerror(-err), err);
-                mCbLooper.clear();
-                return nullptr;
-            }
-            if (mHandler == nullptr) {
-                mHandler = new CallbackHandler(this);
-            }
-            mCbLooper->registerHandler(mHandler);
+    // register ICameraServiceListener
+    std::vector<hardware::CameraStatus> cameraStatuses{};
+    if (mCameraServiceListener == nullptr) {
+        mCameraServiceListener = new CameraServiceListener(this);
+        cameraService->addListener(mCameraServiceListener, &cameraStatuses);
+    }
+
+    for (auto& c : cameraStatuses) {
+        onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
+
+        for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
+            onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
+                                    c.deviceId, c.cameraId, unavailablePhysicalId);
         }
+    }
+    // setup vendor tags
+    if (!setupVendorTags(cameraService)) {
+        ALOGE("%s: Vendor tag descriptor cache couldn't be set up", __FUNCTION__);
+        return nullptr;
+    }
 
-        // register ICameraServiceListener
-        if (mCameraServiceListener == nullptr) {
-            mCameraServiceListener = new CameraServiceListener(this);
-        }
-        std::vector<hardware::CameraStatus> cameraStatuses{};
-        mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
-        for (auto& c : cameraStatuses) {
-            onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
+    mCameraService = cameraService;
+    ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
+    return mCameraService;
+}
 
-            for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
-                onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
-                                      c.deviceId, c.cameraId, unavailablePhysicalId);
-            }
-        }
-
-        // setup vendor tags
-        sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
-        binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
-
-        if (ret.isOk()) {
-            if (0 < desc->getTagCount()) {
-                status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
-                if (err != OK) {
-                    ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
-                            __FUNCTION__, strerror(-err), err);
-                }
-            } else {
-                sp<VendorTagDescriptorCache> cache =
-                        new VendorTagDescriptorCache();
-                binder::Status res =
-                        mCameraService->getCameraVendorTagCache(
-                                /*out*/cache.get());
-                if (res.serviceSpecificErrorCode() ==
-                        hardware::ICameraService::ERROR_DISCONNECTED) {
-                    // No camera module available, not an error on devices with no cameras
-                    VendorTagDescriptorCache::clearGlobalVendorTagCache();
-                } else if (res.isOk()) {
-                    status_t err =
-                            VendorTagDescriptorCache::setAsGlobalVendorTagCache(
-                                    cache);
-                    if (err != OK) {
-                        ALOGE("%s: Failed to set vendor tag cache,"
-                                "received error %s (%d)", __FUNCTION__,
-                                strerror(-err), err);
-                    }
-                } else {
-                    VendorTagDescriptorCache::clearGlobalVendorTagCache();
-                    ALOGE("%s: Failed to setup vendor tag cache: %s",
-                            __FUNCTION__, res.toString8().c_str());
-                }
-            }
-        } else if (ret.serviceSpecificErrorCode() ==
-                hardware::ICameraService::ERROR_DEPRECATED_HAL) {
+bool CameraManagerGlobal::setupVendorTags(sp<hardware::ICameraService> &cameraService) {
+    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
+    binder::Status ret = cameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
+    if (!ret.isOk()) {
+        if (ret.serviceSpecificErrorCode() ==
+            hardware::ICameraService::ERROR_DEPRECATED_HAL) {
             ALOGW("%s: Camera HAL too old; does not support vendor tags",
                     __FUNCTION__);
             VendorTagDescriptor::clearGlobalVendorTagDescriptor();
@@ -268,9 +249,45 @@
             ALOGE("%s: Failed to get vendor tag descriptors: %s",
                     __FUNCTION__, ret.toString8().c_str());
         }
+        return false;
     }
-    ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
-    return mCameraService;
+
+    if (0 < desc->getTagCount()) {
+        status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
+        if (err != OK) {
+            ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
+                    __FUNCTION__, strerror(-err), err);
+            return false;
+        }
+    } else {
+        sp<VendorTagDescriptorCache> cache =
+                new VendorTagDescriptorCache();
+        binder::Status res =
+                cameraService->getCameraVendorTagCache(
+                        /*out*/cache.get());
+        if (res.serviceSpecificErrorCode() ==
+                hardware::ICameraService::ERROR_DISCONNECTED) {
+            // No camera module available, not an error on devices with no cameras
+            VendorTagDescriptorCache::clearGlobalVendorTagCache();
+        } else if (res.isOk()) {
+            status_t err =
+                    VendorTagDescriptorCache::setAsGlobalVendorTagCache(
+                            cache);
+            if (err != OK) {
+                ALOGE("%s: Failed to set vendor tag cache,"
+                        "received error %s (%d)", __FUNCTION__,
+                        strerror(-err), err);
+                return false;
+            }
+        } else {
+            VendorTagDescriptorCache::clearGlobalVendorTagCache();
+            ALOGE("%s: Failed to setup vendor tag cache: %s",
+                    __FUNCTION__, res.toString8().c_str());
+            return false;
+        }
+    }
+
+    return true;
 }
 
 void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
@@ -290,6 +307,8 @@
                                       key.cameraId);
         }
         cm->mCameraService.clear();
+        cm->mCameraServiceListener.clear();
+        cm->mDeathNotifier.clear();
         // TODO: consider adding re-connect call here?
     }
 }
@@ -398,6 +417,9 @@
 bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
     bool camera2Support = false;
     auto cs = getCameraServiceLocked();
+    if (cs == nullptr) {
+        return false;
+    }
     binder::Status serviceRet =
         cs->supportsCameraApi(cameraId,
                 hardware::ICameraService::API_VERSION_2, &camera2Support);
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index f4124ef..cb7a4ff 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -105,6 +105,8 @@
     template <class T>
     void registerAvailCallback(const DeviceContext& deviceContext, const T* callback);
 
+    bool setupVendorTags(sp<hardware::ICameraService> &cameraService);
+
     class DeathNotifier : public IBinder::DeathRecipient {
       public:
         explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 1817490..7fb2d05 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -480,10 +480,21 @@
      * camera device auto-exposure routine for the overridden
      * fields for a given capture will be available in its
      * CaptureResult.</p>
+     * <p>When ACAMERA_CONTROL_AE_MODE is AE_MODE_ON and if the device
+     * supports manual flash strength control, i.e.,
+     * if ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL and
+     * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL are greater than 1, then
+     * the auto-exposure (AE) precapture metering sequence should be
+     * triggered to avoid the image being incorrectly exposed at
+     * different ACAMERA_FLASH_STRENGTH_LEVEL.</p>
      *
+     * @see ACAMERA_CONTROL_AE_MODE
      * @see ACAMERA_CONTROL_MODE
      * @see ACAMERA_FLASH_INFO_AVAILABLE
      * @see ACAMERA_FLASH_MODE
+     * @see ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL
+     * @see ACAMERA_FLASH_STRENGTH_LEVEL
+     * @see ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL
      * @see ACAMERA_SENSOR_EXPOSURE_TIME
      * @see ACAMERA_SENSOR_FRAME_DURATION
      * @see ACAMERA_SENSOR_SENSITIVITY
@@ -8233,7 +8244,17 @@
      * ACAMERA_SENSOR_FRAME_DURATION are ignored. The
      * application has control over the various
      * ACAMERA_FLASH_* fields.</p>
+     * <p>If the device supports manual flash strength control, i.e.,
+     * if ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL and
+     * ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL are greater than 1, then
+     * the auto-exposure (AE) precapture metering sequence should be
+     * triggered for the configured flash mode and strength to avoid
+     * the image being incorrectly exposed at different
+     * ACAMERA_FLASH_STRENGTH_LEVEL.</p>
      *
+     * @see ACAMERA_FLASH_SINGLE_STRENGTH_MAX_LEVEL
+     * @see ACAMERA_FLASH_STRENGTH_LEVEL
+     * @see ACAMERA_FLASH_TORCH_STRENGTH_MAX_LEVEL
      * @see ACAMERA_SENSOR_EXPOSURE_TIME
      * @see ACAMERA_SENSOR_FRAME_DURATION
      * @see ACAMERA_SENSOR_SENSITIVITY
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index cdba8ff..5b69f5c 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -194,11 +194,11 @@
     return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
 }
 
-bool CameraManagerGlobal::setupVendorTags() {
+bool CameraManagerGlobal::setupVendorTags(std::shared_ptr<ICameraService> &cameraService) {
     sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
     Status status = Status::NO_ERROR;
     std::vector<ProviderIdAndVendorTagSections> providerIdsAndVts;
-    ScopedAStatus remoteRet = mCameraService->getCameraVendorTagSections(&providerIdsAndVts);
+    ScopedAStatus remoteRet = cameraService->getCameraVendorTagSections(&providerIdsAndVts);
 
     if (!remoteRet.isOk()) {
         if (remoteRet.getExceptionCode() == EX_SERVICE_SPECIFIC) {
@@ -261,15 +261,12 @@
         ALOGE("%s: Could not get ICameraService instance.", __FUNCTION__);
         return nullptr;
     }
-
     if (mDeathRecipient.get() == nullptr) {
         mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(
                 AIBinder_DeathRecipient_new(CameraManagerGlobal::binderDeathCallback));
+        AIBinder_linkToDeath(cameraService->asBinder().get(),
+                             mDeathRecipient.get(), /*cookie=*/ this);
     }
-    AIBinder_linkToDeath(cameraService->asBinder().get(),
-                         mDeathRecipient.get(), /*cookie=*/ this);
-
-    mCameraService = cameraService;
 
     // Setup looper thread to perform availability callbacks
     if (mCbLooper == nullptr) {
@@ -291,33 +288,25 @@
         mCbLooper->registerHandler(mHandler);
     }
 
+    std::vector<CameraStatusAndId> cameraStatuses;
     // register ICameraServiceListener
     if (mCameraServiceListener == nullptr) {
         mCameraServiceListener = ndk::SharedRefBase::make<CameraServiceListener>(weak_from_this());
-    }
-
-    std::vector<CameraStatusAndId> cameraStatuses;
-    Status status = Status::NO_ERROR;
-    ScopedAStatus remoteRet = mCameraService->addListener(mCameraServiceListener,
-                                                          &cameraStatuses);
-
-    if (!remoteRet.isOk()) {
-        if (remoteRet.getExceptionCode() == EX_SERVICE_SPECIFIC) {
-            Status errStatus = static_cast<Status>(remoteRet.getServiceSpecificError());
-            ALOGE("%s: Failed to add listener to camera service: %s", __FUNCTION__,
-                toString(errStatus).c_str());
-        } else {
-            ALOGE("%s: Transaction failed when adding listener to camera service: %d",
-                __FUNCTION__, remoteRet.getExceptionCode());
+        ScopedAStatus remoteRet = cameraService->addListener(mCameraServiceListener,
+                                                            &cameraStatuses);
+        if (!remoteRet.isOk()) {
+            if (remoteRet.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+                Status errStatus = static_cast<Status>(remoteRet.getServiceSpecificError());
+                ALOGE("%s: Failed to add listener to camera service: %s", __FUNCTION__,
+                    toString(errStatus).c_str());
+            } else {
+                ALOGE("%s: Transaction failed when adding listener to camera service: %d",
+                    __FUNCTION__, remoteRet.getExceptionCode());
+            }
+            return nullptr;
         }
     }
 
-    // Setup vendor tags
-    if (!setupVendorTags()) {
-        ALOGE("Unable to set up vendor tags");
-        return nullptr;
-    }
-
     for (auto& csi: cameraStatuses){
         onStatusChangedLocked(csi.deviceStatus, csi.cameraId);
 
@@ -326,6 +315,13 @@
                                   csi.cameraId, unavailablePhysicalId);
         }
     }
+
+   // Setup vendor tags
+    if (!setupVendorTags(cameraService)) {
+        ALOGE("Unable to set up vendor tags");
+        return nullptr;
+    }
+    mCameraService = cameraService;
     return mCameraService;
 }
 
@@ -346,6 +342,8 @@
         instance->onStatusChangedLocked(deviceStatus, cameraId);
     }
     instance->mCameraService.reset();
+    instance->mDeathRecipient.release();
+    instance->mCameraServiceListener.reset();
     // TODO: consider adding re-connect call here?
 }
 
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index 2d8eefa..5688e76 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -188,7 +188,7 @@
                          const std::string &physicalCameraId);
     void onStatusChangedLocked(const CameraDeviceStatus &status, const std::string &cameraId,
                                const std::string &physicalCameraId);
-    bool setupVendorTags();
+    bool setupVendorTags(std::shared_ptr<ICameraService> &cameraService);
 
     // Utils for status
     static bool validStatus(CameraDeviceStatus status);
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 b8555df..411996e 100644
--- a/media/audio/aconfig/audio_framework.aconfig
+++ b/media/audio/aconfig/audio_framework.aconfig
@@ -47,6 +47,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 890a1c7..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,
@@ -1055,14 +1057,6 @@
     return OK;
 }
 
-namespace {
-    // Use '01' for LSB bits 0 and 1 as Bluetooth MAC addresses are never multicast
-    // and universaly administered
-    constexpr std::array<uint8_t, 4> BTANON_PREFIX {0xFD, 0xFF, 0xFF, 0xFF};
-    // Keep sync with ServiceUtilities.cpp mustAnonymizeBluetoothAddress
-    constexpr const char * BTANON_PREFIX_STR = "XX:XX:XX:XX:";
-}
-
 ::android::status_t aidl2legacy_AudioDevice_audio_device(
         const AudioDevice& aidl,
         audio_devices_t* legacyType, std::string* legacyAddress) {
@@ -1077,16 +1071,8 @@
         case Tag::mac: {
             const std::vector<uint8_t>& mac = aidl.address.get<AudioDeviceAddress::mac>();
             if (mac.size() != 6) return BAD_VALUE;
-            if (std::equal(BTANON_PREFIX.begin(), BTANON_PREFIX.end(), mac.begin())) {
-                // special case for anonymized mac address:
-                // change anonymized bytes back from FD:FF:FF:FF: to XX:XX:XX:XX:
-                snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN,
-                        "%s%02X:%02X", BTANON_PREFIX_STR, mac[4], mac[5]);
-            } else {
-                snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN,
-                        "%02X:%02X:%02X:%02X:%02X:%02X",
-                        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-            }
+            snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
+                    mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
         } break;
         case Tag::ipv4: {
             const std::vector<uint8_t>& ipv4 = aidl.address.get<AudioDeviceAddress::ipv4>();
@@ -1148,20 +1134,8 @@
         switch (suggestDeviceAddressTag(aidl.type)) {
             case Tag::mac: {
                 std::vector<uint8_t> mac(6);
-                int status;
-                // special case for anonymized mac address:
-                // change anonymized bytes so that they can be scanned as HEX bytes
-                if (legacyAddress.starts_with(BTANON_PREFIX_STR)) {
-                    std::copy(BTANON_PREFIX.begin(), BTANON_PREFIX.end(), mac.begin());
-                    LOG_ALWAYS_FATAL_IF(legacyAddress.length() <= strlen(BTANON_PREFIX_STR));
-                    status = sscanf(legacyAddress.c_str() + strlen(BTANON_PREFIX_STR),
-                                        "%hhX:%hhX",
-                                        &mac[4], &mac[5]);
-                    status += 4;
-                } else {
-                    status = sscanf(legacyAddress.c_str(), "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
-                            &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
-                }
+                int status = sscanf(legacyAddress.c_str(), "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
+                        &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
                 if (status != mac.size()) {
                     ALOGE("%s: malformed MAC address: \"%s\"", __func__, legacyAddress.c_str());
                     return unexpected(BAD_VALUE);
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/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/audio_aidl_legacy_conversion_tests.cpp b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
index 2076045..7f55e48 100644
--- a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
+++ b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp
@@ -483,27 +483,8 @@
                                  AudioDeviceAddress::make<AudioDeviceAddress::Tag::alsa>(
                                          std::vector<int32_t>{1, 2}))));
 
-TEST(AnonymizedBluetoothAddressRoundTripTest, Legacy2Aidl2Legacy) {
-    const std::vector<uint8_t> sAnonymizedAidlAddress {0xFD, 0xFF, 0xFF, 0xFF, 0xAB, 0xCD};
-    const std::string sAnonymizedLegacyAddress = std::string("XX:XX:XX:XX:AB:CD");
-    auto device = legacy2aidl_audio_device_AudioDevice(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
-                                                       sAnonymizedLegacyAddress);
-    ASSERT_TRUE(device.ok());
-    ASSERT_EQ(AudioDeviceAddress::Tag::mac, device.value().address.getTag());
-    ASSERT_EQ(sAnonymizedAidlAddress, device.value().address.get<AudioDeviceAddress::mac>());
-
-    audio_devices_t legacyType;
-    std::string legacyAddress;
-    status_t status =
-            aidl2legacy_AudioDevice_audio_device(device.value(), &legacyType, &legacyAddress);
-    ASSERT_EQ(OK, status);
-    EXPECT_EQ(legacyType, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP);
-    EXPECT_EQ(sAnonymizedLegacyAddress, legacyAddress);
-}
-
 class AudioFormatDescriptionRoundTripTest : public testing::TestWithParam<AudioFormatDescription> {
 };
-
 TEST_P(AudioFormatDescriptionRoundTripTest, Aidl2Legacy2Aidl) {
     const auto initial = GetParam();
     auto conv = aidl2legacy_AudioFormatDescription_audio_format_t(initial);
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/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/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index d5e3cf7..53d4311 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -90,6 +90,12 @@
     }
 }
 
+RetCode BundleContext::setCommon(const Parameter::Common& common) {
+    RetCode ret = EffectContext::setCommon(common);
+    RETURN_VALUE_IF(ret != RetCode::SUCCESS, ret, " setCommonFailed");
+    return init();
+}
+
 RetCode BundleContext::enable() {
     if (mEnabled) return RetCode::ERROR_ILLEGAL_PARAMETER;
     // Bass boost or Virtualizer can be temporarily disabled if playing over device speaker due to
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
index e5ab40d..d5de5bd 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -35,6 +35,8 @@
     void deInit();
     lvm::BundleEffectType getBundleType() const { return mType; }
 
+    RetCode setCommon(const Parameter::Common& common) override;
+
     RetCode enable() override;
     RetCode enableOperatingMode();
     RetCode disable() override;
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/libmedia/tests/mediaplayer/IMediaPlayerTest.cpp b/media/libmedia/tests/mediaplayer/IMediaPlayerTest.cpp
index cc60933..f0db018 100644
--- a/media/libmedia/tests/mediaplayer/IMediaPlayerTest.cpp
+++ b/media/libmedia/tests/mediaplayer/IMediaPlayerTest.cpp
@@ -50,7 +50,7 @@
 
     // We write a length greater than the following session id array. Should be discarded.
     data.writeUint32(2);
-    data.writeUnpadded(kMockByteArray, 1);
+    data.write(kMockByteArray, 1);
 
     status_t result = IMediaPlayer::asBinder(iMediaPlayer_)
             ->transact(PREPARE_DRM, data, &reply);
diff --git a/media/libmediametrics/MediaMetricsItem.cpp b/media/libmediametrics/MediaMetricsItem.cpp
index ecb248d..2c58461 100644
--- a/media/libmediametrics/MediaMetricsItem.cpp
+++ b/media/libmediametrics/MediaMetricsItem.cpp
@@ -334,21 +334,21 @@
 
     // This is checked only once in the lifetime of the process.
     const uid_t uid = getuid();
-    switch (uid) {
-    case AID_RADIO:     // telephony subsystem, RIL
+    const uid_t appid = multiuser_get_app_id(uid);
+
+    if (appid == AID_RADIO) {
+        // telephony subsystem, RIL
         return false;
-    default:
+    }
+
+    if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
         // Some isolated processes can access the audio system; see
         // AudioSystem::setAudioFlingerBinder (currently only the HotwordDetectionService). Instead
         // of also allowing access to the MediaMetrics service, it's simpler to just disable it for
         // now.
         // TODO(b/190151205): Either allow the HotwordDetectionService to access MediaMetrics or
         // make this disabling specific to that process.
-        uid_t appid = multiuser_get_app_id(uid);
-        if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
-            return false;
-        }
-        break;
+        return false;
     }
 
     int enabled = property_get_int32(Item::EnabledProperty, -1);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 8b50359..9abe037 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2018,6 +2018,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);
@@ -4497,9 +4498,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;
                     }
@@ -4578,9 +4586,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;
                     }
@@ -5946,7 +5961,7 @@
     }
 
     updateHdrMetrics(false /* isConfig */);
- }
+}
 
 void MediaCodec::extractCSD(const sp<AMessage> &format) {
     mCSD.clear();
@@ -6025,7 +6040,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;
@@ -6071,6 +6085,10 @@
 
         mInputFormat.clear();
         mOutputFormat.clear();
+        if (android::media::codec::provider_->codec_buffer_state_cleanup()) {
+            mCSD.clear();
+            mLeftover.clear();
+        }
         mFlags &= ~kFlagOutputFormatChanged;
         mFlags &= ~kFlagOutputBuffersChanged;
         mFlags &= ~kFlagStickyError;
@@ -6129,6 +6147,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();
             }
@@ -6481,6 +6501,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();
 
@@ -6497,6 +6518,7 @@
     sp<AMessage> msg = mLeftover.front();
     mLeftover.pop_front();
     msg->setSize("index", index);
+    ALOGV("handleLeftover(%zu)", index);
     return onQueueInputBuffer(msg);
 }
 
@@ -6565,6 +6587,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();
@@ -6677,6 +6700,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/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/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 4e6492f..e13f8f7 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -18,7 +18,6 @@
 #define LOG_TAG "ServiceUtilities"
 
 #include <audio_utils/clock.h>
-#include <android-base/properties.h>
 #include <binder/AppOpsManager.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -29,11 +28,9 @@
 #include <media/AidlConversionUtil.h>
 #include <android/content/AttributionSourceState.h>
 
-#include <algorithm>
 #include <iterator>
-#include <mutex>
+#include <algorithm>
 #include <pwd.h>
-#include <thread>
 
 /* When performing permission checks we do not use permission cache for
  * runtime permissions (protection level dangerous) as they may change at
@@ -399,106 +396,6 @@
     return NO_ERROR;
 }
 
-// TODO(b/285588444), clean this up on main, but soak it for backporting purposes for now
-namespace {
-class BluetoothPermissionCache {
-    static constexpr auto SYSPROP_NAME = "cache_key.system_server.package_info";
-    const String16 BLUETOOTH_PERM {"android.permission.BLUETOOTH_CONNECT"};
-    mutable std::mutex mLock;
-    // Cached property conditionally defined, since only avail on bionic. On host, don't inval cache
-#if defined(__BIONIC__)
-    // Unlocked, but only accessed from mListenerThread
-    base::CachedProperty mCachedProperty;
-#endif
-    // This thread is designed to never join/terminate, so no signal is fine
-    const std::thread mListenerThread;
-    GUARDED_BY(mLock)
-    std::string mPropValue;
-    GUARDED_BY(mLock)
-    std::unordered_map<uid_t, bool> mCache;
-    PermissionController mPc{};
-public:
-    BluetoothPermissionCache()
-#if defined(__BIONIC__)
-            : mCachedProperty{SYSPROP_NAME},
-            mListenerThread([this]() mutable {
-                    while (true) {
-                        std::string newVal = mCachedProperty.WaitForChange() ?: "";
-                        std::lock_guard l{mLock};
-                        if (newVal != mPropValue) {
-                            ALOGV("Bluetooth permission update");
-                            mPropValue = newVal;
-                            mCache.clear();
-                        }
-                    }
-                })
-#endif
-            {}
-
-    bool checkPermission(uid_t uid, pid_t pid) {
-        std::lock_guard l{mLock};
-        auto it = mCache.find(uid);
-        if (it == mCache.end()) {
-            it = mCache.insert({uid, mPc.checkPermission(BLUETOOTH_PERM, uid, pid)}).first;
-        }
-        return it->second;
-    }
-};
-
-// Don't call this from locks, since it potentially calls up to system server!
-// Check for non-app UIDs above this method!
-bool checkBluetoothPermission(const AttributionSourceState& attr) {
-    [[clang::no_destroy]]  static BluetoothPermissionCache impl{};
-    return impl.checkPermission(attr.uid, attr.pid);
-}
-} // anonymous
-
-/**
- * Determines if the MAC address in Bluetooth device descriptors returned by APIs of
- * a native audio service (audio flinger, audio policy) must be anonymized.
- * MAC addresses returned to system server or apps with BLUETOOTH_CONNECT permission
- * are not anonymized.
- *
- * @param attributionSource The attribution source of the calling app.
- * @param caller string identifying the caller for logging.
- * @return true if the MAC addresses must be anonymized, false otherwise.
- */
-bool mustAnonymizeBluetoothAddress(
-        const AttributionSourceState& attributionSource, const String16&) {
-    uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
-    bool res;
-    switch(multiuser_get_app_id(uid)) {
-        case AID_ROOT:
-        case AID_SYSTEM:
-        case AID_RADIO:
-        case AID_BLUETOOTH:
-        case AID_MEDIA:
-        case AID_AUDIOSERVER:
-            // Don't anonymize for privileged clients
-            res = false;
-            break;
-        default:
-            res = !checkBluetoothPermission(attributionSource);
-            break;
-    }
-    ALOGV("%s uid: %d, result: %d", __func__, uid, res);
-    return res;
-}
-
-/**
- * Modifies the passed MAC address string in place for consumption by unprivileged clients.
- * the string is assumed to have a valid MAC address format.
- * the anonymization must be kept in sync with toAnonymizedAddress() in BluetoothUtils.java
- *
- * @param address input/output the char string contining the MAC address to anonymize.
- */
-void anonymizeBluetoothAddress(char *address) {
-    if (address == nullptr || strlen(address) != strlen("AA:BB:CC:DD:EE:FF")) {
-        return;
-    }
-    memcpy(address, "XX:XX:XX:XX", strlen("XX:XX:XX:XX"));
-}
-
 sp<content::pm::IPackageManagerNative> MediaPackageManager::retrievePackageManager() {
     const sp<IServiceManager> sm = defaultServiceManager();
     if (sm == nullptr) {
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 461e190..2631469 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -114,10 +114,6 @@
 bool bypassInterruptionPolicyAllowed(const AttributionSourceState& attributionSource);
 bool callAudioInterceptionAllowed(const AttributionSourceState& attributionSource);
 void purgePermissionCache();
-bool mustAnonymizeBluetoothAddress(
-        const AttributionSourceState& attributionSource, const String16& caller);
-void anonymizeBluetoothAddress(char *address);
-
 int32_t getOpForSource(audio_source_t source);
 
 AttributionSourceState getCallingAttributionSource();
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index b9dbbad..0d5d61f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3055,7 +3055,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);
@@ -3090,7 +3090,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);
@@ -3099,22 +3099,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,
@@ -3178,7 +3178,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 2bc18ee..ace74ee 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 02d4fc2..d0b96de 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 eedf560..cca09d1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3254,9 +3254,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;
 
@@ -5191,7 +5191,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,
@@ -5280,7 +5289,10 @@
         mFastMixerNBLogWriter = afThreadCallback->newWriter_l(kFastMixerLogSize, "FastMixer");
         state->mNBLogWriter = mFastMixerNBLogWriter.get();
         sq->end();
-        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+        {
+            audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastMixer->getTid());
+            sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+        }
 
         NBLog::thread_info_t info;
         info.id = mId;
@@ -5339,8 +5351,11 @@
         }
         state->mCommand = FastMixerState::EXIT;
         sq->end();
-        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
-        mFastMixer->join();
+        {
+            audio_utils::mutex::scoped_join_wait_check queueWaitCheck(mFastMixer->getTid());
+            sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+            mFastMixer->join();
+        }
         // Though the fast mixer thread has exited, it's state queue is still valid.
         // We'll use that extract the final state which contains one remaining fast track
         // corresponding to our sub-mix.
@@ -5420,7 +5435,10 @@
                 FastThreadDumpState::kSamplingNforLowRamDevice : FastThreadDumpState::kSamplingN);
 #endif
             sq->end();
-            sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+            {
+                audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastMixer->getTid());
+                sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
+            }
             if (kUseFastMixer == FastMixer_Dynamic) {
                 mNormalSink = mPipeSink;
             }
@@ -5453,7 +5471,10 @@
             mFastMixerFutex = 0;
             sq->end();
             // BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now
-            sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
+            {
+                audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastMixer->getTid());
+                sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
+            }
             if (kUseFastMixer == FastMixer_Dynamic) {
                 mNormalSink = mOutputSink;
             }
@@ -6349,7 +6370,10 @@
         //
         // This occurs with BT suspend when we idle the FastMixer with
         // active tracks, which may be added or removed.
-        sq->push(coldIdle ? FastMixerStateQueue::BLOCK_NEVER : block);
+        {
+            audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastMixer->getTid());
+            sq->push(coldIdle ? FastMixerStateQueue::BLOCK_NEVER : block);
+        }
     }
 #ifdef AUDIO_WATCHDOG
     if (pauseAudioWatchdog && mAudioWatchdog != 0) {
@@ -7308,11 +7332,14 @@
 {
     PlaybackThread::flushHw_l();
     mOutput->flush();
-    mHwPaused = false;
     mFlushPending = false;
     mTimestampVerifier.discontinuity(discontinuityForStandbyOrFlush());
     mTimestamp.clear();
     mMonotonicFrameCounter.onFlush();
+    // We do not reset mHwPaused which is hidden from the Track client.
+    // Note: the client track in Tracks.cpp and AudioTrack.cpp
+    // has a FLUSHED state but the DirectOutputThread does not;
+    // those tracks will continue to show isStopped().
 }
 
 int64_t DirectOutputThread::computeWaitTimeNs_l() const {
@@ -8322,8 +8349,10 @@
                 afThreadCallback->newWriter_l(kFastCaptureLogSize, "FastCapture");
         state->mNBLogWriter = mFastCaptureNBLogWriter.get();
         sq->end();
-        sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
-
+        {
+            audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastCapture->getTid());
+            sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
+        }
         // start the fast capture
         mFastCapture->run("FastCapture", ANDROID_PRIORITY_URGENT_AUDIO);
         pid_t tid = mFastCapture->getTid();
@@ -8357,8 +8386,11 @@
         }
         state->mCommand = FastCaptureState::EXIT;
         sq->end();
-        sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
-        mFastCapture->join();
+        {
+            audio_utils::mutex::scoped_join_wait_check queueWaitCheck(mFastCapture->getTid());
+            sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED);
+            mFastCapture->join();
+        }
         mFastCapture.clear();
     }
     mAfThreadCallback->unregisterWriter(mFastCaptureNBLogWriter);
@@ -8991,7 +9023,11 @@
             mFastCaptureFutex = 0;
             sq->end();
             // BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now
-            sq->push(FastCaptureStateQueue::BLOCK_UNTIL_ACKED);
+            {
+                audio_utils::mutex::scoped_queue_wait_check queueWaitCheck(mFastCapture->getTid());
+                sq->push(FastCaptureStateQueue::BLOCK_UNTIL_ACKED);
+            }
+
 #if 0
             if (kUseFastCapture == FastCapture_Dynamic) {
                 // FIXME
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 e849bb4..edcb805 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -478,7 +478,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 3c296e7..835fad2 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 848051c..2c41de4 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -656,7 +656,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)
 {
@@ -686,7 +686,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;
@@ -704,7 +704,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
@@ -722,8 +722,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 4da645b..c1c4a28 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1677,14 +1677,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(),
@@ -1704,11 +1709,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();
@@ -4533,6 +4538,9 @@
             "Engine could not set preferred devices %s for audio source %d role %d",
             dumpAudioDeviceTypeAddrVector(devices).c_str(), audioSource, role);
 
+    if (status == NO_ERROR) {
+        updateInputRouting();
+    }
     return status;
 }
 
@@ -6154,7 +6162,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
@@ -6223,13 +6232,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(),
@@ -6237,7 +6246,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(),
@@ -6775,11 +6784,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());
@@ -8149,9 +8159,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);
         }
     }
@@ -8518,9 +8540,11 @@
     }
 
     float volumeDb = computeVolume(curves, volumeSource, index, deviceTypes);
+    const VolumeSource dtmfVolSrc = toVolumeSource(AUDIO_STREAM_DTMF, false);
     if (outputDesc->isFixedVolume(deviceTypes) ||
             // Force VoIP volume to max for bluetooth SCO/BLE device except if muted
-            (index != 0 && (isVoiceVolSrc || isBtScoVolSrc) &&
+            (index != 0 && (isVoiceVolSrc || isBtScoVolSrc
+                        || (isInCall() && (dtmfVolSrc == volumeSource))) &&
                     (isSingleDeviceType(deviceTypes, audio_is_bluetooth_out_sco_device)
                     || isSingleDeviceType(deviceTypes, audio_is_ble_out_device)))) {
         volumeDb = 0.0f;
@@ -8882,6 +8906,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;
@@ -9016,7 +9042,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;
@@ -9054,7 +9080,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;
@@ -9062,11 +9088,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/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 9a5365c..363dfa7 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/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 60b155da..24ab6a1 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1687,19 +1687,6 @@
     return Status::ok();
 }
 
-template <typename Port>
-void anonymizePortBluetoothAddress(Port& port) {
-    if (port.type != AUDIO_PORT_TYPE_DEVICE) {
-        return;
-    }
-    if (!(audio_is_a2dp_device(port.ext.device.type)
-            || audio_is_ble_device(port.ext.device.type)
-            || audio_is_bluetooth_sco_device(port.ext.device.type)
-            || audio_is_hearing_aid_out_device(port.ext.device.type))) {
-        return;
-    }
-    anonymizeBluetoothAddress(port.ext.device.address);
-}
 
 Status AudioPolicyService::listAudioPorts(media::AudioPortRole roleAidl,
                                           media::AudioPortType typeAidl, Int* count,
@@ -1718,27 +1705,14 @@
     std::unique_ptr<audio_port_v7[]> ports(new audio_port_v7[num_ports]);
     unsigned int generation;
 
-    const AttributionSourceState attributionSource = getCallingAttributionSource();
+    audio_utils::lock_guard _l(mMutex);
+    if (mAudioPolicyManager == NULL) {
+        return binderStatusFromStatusT(NO_INIT);
+    }
     AutoCallerClear acc;
-    {
-        audio_utils::lock_guard _l(mMutex);
-        if (mAudioPolicyManager == NULL) {
-            return binderStatusFromStatusT(NO_INIT);
-        }
-        // AudioPolicyManager->listAudioPorts makes a deep copy of port structs into ports
-        // so it is safe to access after releasing the mutex
-        RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
-                mAudioPolicyManager->listAudioPorts(
-                        role, type, &num_ports, ports.get(), &generation)));
-        numPortsReq = std::min(numPortsReq, num_ports);
-    }
-
-    if (mustAnonymizeBluetoothAddress(attributionSource, String16(__func__))) {
-        for (size_t i = 0; i < numPortsReq; ++i) {
-            anonymizePortBluetoothAddress(ports[i]);
-        }
-    }
-
+    RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
+            mAudioPolicyManager->listAudioPorts(role, type, &num_ports, ports.get(), &generation)));
+    numPortsReq = std::min(numPortsReq, num_ports);
     RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
             convertRange(ports.get(), ports.get() + numPortsReq, std::back_inserter(*portsAidl),
                          legacy2aidl_audio_port_v7_AudioPortFw)));
@@ -1761,24 +1735,12 @@
 Status AudioPolicyService::getAudioPort(int portId,
                                         media::AudioPortFw* _aidl_return) {
     audio_port_v7 port{ .id = portId };
-
-    const AttributionSourceState attributionSource = getCallingAttributionSource();
+    audio_utils::lock_guard _l(mMutex);
+    if (mAudioPolicyManager == NULL) {
+        return binderStatusFromStatusT(NO_INIT);
+    }
     AutoCallerClear acc;
-
-    {
-        audio_utils::lock_guard _l(mMutex);
-        if (mAudioPolicyManager == NULL) {
-            return binderStatusFromStatusT(NO_INIT);
-        }
-        // AudioPolicyManager->getAudioPort makes a deep copy of the port struct into port
-        // so it is safe to access after releasing the mutex
-        RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(mAudioPolicyManager->getAudioPort(&port)));
-    }
-
-    if (mustAnonymizeBluetoothAddress(attributionSource, String16(__func__))) {
-        anonymizePortBluetoothAddress(port);
-    }
-
+    RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(mAudioPolicyManager->getAudioPort(&port)));
     *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_port_v7_AudioPortFw(port));
     return Status::ok();
 }
@@ -1840,32 +1802,14 @@
     std::unique_ptr<audio_patch[]> patches(new audio_patch[num_patches]);
     unsigned int generation;
 
-    const AttributionSourceState attributionSource = getCallingAttributionSource();
+    audio_utils::lock_guard _l(mMutex);
+    if (mAudioPolicyManager == NULL) {
+        return binderStatusFromStatusT(NO_INIT);
+    }
     AutoCallerClear acc;
-
-    {
-        audio_utils::lock_guard _l(mMutex);
-        if (mAudioPolicyManager == NULL) {
-            return binderStatusFromStatusT(NO_INIT);
-        }
-        // AudioPolicyManager->listAudioPatches makes a deep copy of patches structs into patches
-        // so it is safe to access after releasing the mutex
-        RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
-                mAudioPolicyManager->listAudioPatches(&num_patches, patches.get(), &generation)));
-        numPatchesReq = std::min(numPatchesReq, num_patches);
-    }
-
-    if (mustAnonymizeBluetoothAddress(attributionSource, String16(__func__))) {
-        for (size_t i = 0; i < numPatchesReq; ++i) {
-            for (size_t j = 0; j < patches[i].num_sources; ++j) {
-                anonymizePortBluetoothAddress(patches[i].sources[j]);
-            }
-            for (size_t j = 0; j < patches[i].num_sinks; ++j) {
-                anonymizePortBluetoothAddress(patches[i].sinks[j]);
-            }
-        }
-    }
-
+    RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
+            mAudioPolicyManager->listAudioPatches(&num_patches, patches.get(), &generation)));
+    numPatchesReq = std::min(numPatchesReq, num_patches);
     RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
             convertRange(patches.get(), patches.get() + numPatchesReq,
                          std::back_inserter(*patchesAidl), legacy2aidl_audio_patch_AudioPatchFw)));
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index d74bc07..c47b5e9 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -823,7 +823,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 a120649..79c25ab 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 6f63721..9ddfd6c 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 924a664..39f9b8a 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -500,6 +500,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);
@@ -531,7 +534,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);
@@ -2547,7 +2550,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(
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 6a5d5e0..fa5eb6f 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1725,20 +1725,6 @@
     return Status::ok();
 }
 
-Status CameraService::errorNotTrusted(int clientPid, int clientUid, const std::string& cameraId,
-        const std::string& clientName, bool isPid) const {
-    int callingPid = getCallingPid();
-    int callingUid = getCallingUid();
-    ALOGE("CameraService::connect X (calling PID %d, calling UID %d) rejected "
-            "(don't trust %s %d)", callingPid, callingUid, isPid ? "clientPid" : "clientUid",
-            isPid ? clientPid : clientUid);
-    return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
-            "Untrusted caller (calling PID %d, UID %d) trying to "
-            "forward camera access to camera %s for client %s (PID %d, UID %d)",
-            getCallingPid(), getCallingUid(), cameraId.c_str(),
-            clientName.c_str(), clientPid, clientUid);
-}
-
 Status CameraService::validateClientPermissionsLocked(const std::string& cameraId,
         const std::string& clientName, int clientUid, int clientPid) const {
     int callingPid = getCallingPid();
@@ -2131,27 +2117,21 @@
 
     std::string clientPackageNameMaybe = clientAttribution.packageName.value_or("");
     bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
-    std::string clientPackageName = resolvePackageName(clientAttribution.uid,
-            clientPackageNameMaybe);
-    logConnectionAttempt(clientAttribution.pid, clientPackageName, cameraIdStr, API_1);
 
-    int clientUid = clientAttribution.uid;
-    int clientPid = clientAttribution.pid;
-
-    // Resolve the client identity. In the near future, we will no longer rely on USE_CALLING_*, and
-    // need a way to guarantee the caller identity early.
-
-    // Check if we can trust clientUid
-    if (!resolveClientUid(clientUid)) {
-        return errorNotTrusted(clientPid, clientUid, cameraIdStr, clientPackageName,
-                /* isPid=*/ false);
+    AttributionSourceState resolvedClientAttribution(clientAttribution);
+    ret = resolveAttributionSource(resolvedClientAttribution, __FUNCTION__, cameraIdStr);
+    if (!ret.isOk()) {
+        logRejected(cameraIdStr, getCallingPid(),
+                    clientAttribution.packageName.value_or("<unknown>"),
+                    toStdString(ret.toString8()));
+        return ret;
     }
 
-    // Check if we can trust clientUid
-    if (!resolveClientPid(clientPid)) {
-        return errorNotTrusted(clientPid, clientUid, cameraIdStr, clientPackageName,
-                /* isPid= */ true);
-    }
+    const int clientPid = resolvedClientAttribution.pid;
+    const int clientUid = resolvedClientAttribution.uid;
+    const std::string& clientPackageName = *resolvedClientAttribution.packageName;
+
+    logConnectionAttempt(clientPid, clientPackageName, cameraIdStr, API_1);
 
     sp<Client> client = nullptr;
     ret = connectHelper<ICameraClient,Client>(cameraClient, cameraIdStr, api1CameraId,
@@ -2161,8 +2141,9 @@
             rotationOverride, forceSlowJpegMode, cameraIdStr, isNonSystemNdk, /*out*/client);
 
     if (!ret.isOk()) {
-        logRejected(cameraIdStr, getCallingPid(), clientAttribution.packageName.value_or(""),
-                toStdString(ret.toString8()));
+        logRejected(cameraIdStr, getCallingPid(),
+                    clientAttribution.packageName.value_or("<unknown>"),
+                    toStdString(ret.toString8()));
         return ret;
     }
 
@@ -2268,31 +2249,30 @@
     std::string cameraId = cameraIdOptional.value();
 
     bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
-    std::string clientPackageName = resolvePackageName(clientAttribution.uid,
-            clientPackageNameMaybe);
-    logConnectionAttempt(clientAttribution.pid, clientPackageName, cameraId, API_2);
 
-    userid_t clientUserId = multiuser_get_user_id(clientAttribution.uid);
-    if (clientAttribution.uid == USE_CALLING_UID) {
-        clientUserId = multiuser_get_user_id(callingUid);
+    AttributionSourceState resolvedClientAttribution(clientAttribution);
+    if (!flags::use_context_attribution_source()) {
+        resolvedClientAttribution.pid = USE_CALLING_PID;
+    }
+    ret = resolveAttributionSource(resolvedClientAttribution, __FUNCTION__, cameraId);
+    if (!ret.isOk()) {
+        logRejected(cameraId, getCallingPid(), clientAttribution.packageName.value_or(""),
+                    toStdString(ret.toString8()));
+        return ret;
     }
 
-    // Resolve the client identity. In the near future, we will no longer rely on USE_CALLING_*, and
-    // need a way to guarantee the caller identity early.
+    const int clientPid = resolvedClientAttribution.pid;
+    const int clientUid = resolvedClientAttribution.uid;
+    const std::string& clientPackageName = *resolvedClientAttribution.packageName;
+    userid_t clientUserId = multiuser_get_user_id(resolvedClientAttribution.uid);
 
-    int clientUid = clientAttribution.uid;
-    int clientPid = callingPid;
-    // Check if we can trust clientUid
-    if (!resolveClientUid(clientUid)) {
-        return errorNotTrusted(clientPid, clientUid, cameraId, clientPackageName,
-                /* isPid= */ false);
-    }
+    logConnectionAttempt(clientPid, clientPackageName, cameraId, API_2);
 
     if (oomScoreOffset < 0) {
-        std::string msg =
-                fmt::sprintf("Cannot increase the priority of a client %s pid %d for "
-                        "camera id %s", clientPackageName.c_str(), callingPid,
-                        cameraId.c_str());
+        std::string msg = fmt::sprintf(
+                "Cannot increase the priority of a client %s pid %d for "
+                "camera id %s",
+                clientPackageName.c_str(), clientPid, cameraId.c_str());
         ALOGE("%s: %s", __FUNCTION__, msg.c_str());
         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
     }
@@ -2307,25 +2287,24 @@
     }
 
     // enforce system camera permissions
-    if (oomScoreOffset > 0
-            && !hasPermissionsForSystemCamera(cameraId, callingPid,
-                    callingUid)
-            && !isTrustedCallingUid(callingUid)) {
-        std::string msg = fmt::sprintf("Cannot change the priority of a client %s pid %d for "
-                        "camera id %s without SYSTEM_CAMERA permissions",
-                        clientPackageName.c_str(), callingPid, cameraId.c_str());
+    if (oomScoreOffset > 0 && !hasPermissionsForSystemCamera(cameraId, clientPid, callingUid) &&
+        !isTrustedCallingUid(callingUid)) {
+        std::string msg = fmt::sprintf(
+                "Cannot change the priority of a client %s pid %d for "
+                "camera id %s without SYSTEM_CAMERA permissions",
+                clientPackageName.c_str(), clientPid, cameraId.c_str());
         ALOGE("%s: %s", __FUNCTION__, msg.c_str());
         return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.c_str());
     }
 
-    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb,
-            cameraId, /*api1CameraId*/-1, clientPackageName, systemNativeClient,
-            clientAttribution.attributionTag, clientUid, clientPid, API_2,
+    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks, CameraDeviceClient>(
+            cameraCb, cameraId, /*api1CameraId*/ -1, clientPackageName, systemNativeClient,
+            resolvedClientAttribution.attributionTag, clientUid, clientPid, API_2,
             /*shimUpdateOnly*/ false, oomScoreOffset, targetSdkVersion, rotationOverride,
-            /*forceSlowJpegMode*/false, unresolvedCameraId, isNonSystemNdk, /*out*/client);
+            /*forceSlowJpegMode*/ false, unresolvedCameraId, isNonSystemNdk, /*out*/ client);
 
     if (!ret.isOk()) {
-        logRejected(cameraId, callingPid, clientPackageName, toStdString(ret.toString8()));
+        logRejected(cameraId, clientPid, clientPackageName, toStdString(ret.toString8()));
         return ret;
     }
 
@@ -2386,28 +2365,12 @@
 }
 
 void CameraService::logConnectionAttempt(int clientPid, const std::string& clientPackageName,
-        const std::string& cameraId, apiLevel effectiveApiLevel) const {
-    int packagePid = (clientPid == USE_CALLING_PID) ?
-        getCallingPid() : clientPid;
+                                         const std::string& cameraId,
+                                         apiLevel effectiveApiLevel) const {
     ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) and "
-            "Camera API version %d", packagePid, clientPackageName.c_str(), cameraId.c_str(),
-            static_cast<int>(effectiveApiLevel));
-}
-
-std::string CameraService::resolvePackageName(int clientUid,
-        const std::string& clientPackageNameMaybe) const {
-    if (clientPackageNameMaybe.size() <= 0) {
-        int packageUid = (clientUid == USE_CALLING_UID) ?
-                getCallingUid() : clientUid;
-        // NDK calls don't come with package names, but we need one for various cases.
-        // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
-        // do exist. For all authentication cases, all packages under the same UID get the
-        // same permissions, so picking any associated package name is sufficient. For some
-        // other cases, this may give inaccurate names for clients in logs.
-        return getPackageNameFromUid(packageUid);
-    } else {
-        return clientPackageNameMaybe;
-    }
+          "Camera API version %d",
+          clientPid, clientPackageName.c_str(), cameraId.c_str(),
+          static_cast<int>(effectiveApiLevel));
 }
 
 template<class CALLBACK, class CLIENT>
@@ -2419,11 +2382,6 @@
         const std::string& originalCameraId, bool isNonSystemNdk, /*out*/sp<CLIENT>& device) {
     binder::Status ret = binder::Status::ok();
 
-    int packageUid = (clientUid == USE_CALLING_UID) ?
-            getCallingUid() : clientUid;
-    int packagePid = (clientPid == USE_CALLING_PID) ?
-            getCallingPid() : clientPid;
-
     nsecs_t openTimeNs = systemTime();
 
     sp<CLIENT> client = nullptr;
@@ -2643,7 +2601,7 @@
         if (flags::camera_privacy_allowlist()) {
             // Set camera muting behavior.
             isCameraPrivacyEnabled = this->isCameraPrivacyEnabled(
-                    toString16(client->getPackageName()), cameraId, packagePid, packageUid);
+                    toString16(client->getPackageName()), cameraId, clientPid, clientUid);
         } else {
             isCameraPrivacyEnabled =
                     mSensorPrivacyPolicy->isCameraPrivacyEnabled();
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 80bd783..5eb2536 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -934,12 +934,8 @@
     binder::Status validateClientPermissionsLocked(const std::string& cameraId,
             const std::string& clientName, int clientUid, int clientPid) const;
 
-    // If clientPackageNameMaybe is empty, attempts to resolve the package name.
-    std::string resolvePackageName(int clientUid, const std::string& clientPackageNameMaybe) const;
     void logConnectionAttempt(int clientPid, const std::string& clientPackageName,
         const std::string& cameraId, apiLevel effectiveApiLevel) const;
-    binder::Status errorNotTrusted(int clientPid, int clientUid, const std::string& cameraId,
-            const std::string& clientName, bool isPid) const;
 
     bool isCameraPrivacyEnabled(const String16& packageName,const std::string& cameraId,
            int clientPid, int ClientUid);
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 77c037a..7090545 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -14,32 +14,39 @@
  * limitations under the License.
  */
 
-#include <inttypes.h>
-
 #define LOG_TAG "Camera3StreamSplitter"
 #define ATRACE_TAG ATRACE_TAG_CAMERA
 //#define LOG_NDEBUG 0
 
+#include <binder/ProcessState.h>
 #include <camera/StringUtils.h>
 #include <com_android_graphics_libgui_flags.h>
 #include <gui/BufferItem.h>
+#include <gui/BufferItemConsumer.h>
 #include <gui/BufferQueue.h>
 #include <gui/IGraphicBufferConsumer.h>
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/Surface.h>
-
+#include <system/window.h>
 #include <ui/GraphicBuffer.h>
-
-#include <binder/ProcessState.h>
-
 #include <utils/Trace.h>
 
 #include <cutils/atomic.h>
+#include <inttypes.h>
+#include <algorithm>
+#include <cstdint>
+#include <memory>
 
 #include "Camera3Stream.h"
+#include "Flags.h"
 
 #include "Camera3StreamSplitter.h"
 
+// We're relying on a large number of yet-to-be-fully-launched flag dependencies
+// here. So instead of flagging each one, we flag the entire implementation to
+// improve legibility.
+#if USE_NEW_STREAM_SPLITTER
+
 namespace android {
 
 status_t Camera3StreamSplitter::connect(const std::unordered_map<size_t, sp<Surface>> &surfaces,
@@ -55,7 +62,7 @@
     Mutex::Autolock lock(mMutex);
     status_t res = OK;
 
-    if (mOutputs.size() > 0 || mConsumer != nullptr) {
+    if (mOutputSurfaces.size() > 0 || mBufferItemConsumer != nullptr) {
         SP_LOGE("%s: already connected", __FUNCTION__);
         return BAD_VALUE;
     }
@@ -82,43 +89,43 @@
         }
     }
 
-#if !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
-    // Create BufferQueue for input
-    BufferQueue::createBufferQueue(&mProducer, &mConsumer);
-#endif  // !COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
-
     // Allocate 1 extra buffer to handle the case where all buffers are detached
     // from input, and attached to the outputs. In this case, the input queue's
     // dequeueBuffer can still allocate 1 extra buffer before being blocked by
     // the output's attachBuffer().
     mMaxConsumerBuffers++;
+
 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
-    mBufferItemConsumer = new BufferItemConsumer(consumerUsage, mMaxConsumerBuffers);
+    mBufferItemConsumer = sp<BufferItemConsumer>::make(consumerUsage, mMaxConsumerBuffers);
+    mSurface = mBufferItemConsumer->getSurface();
 #else
-    mBufferItemConsumer = new BufferItemConsumer(mConsumer, consumerUsage, mMaxConsumerBuffers);
+    // Create BufferQueue for input
+    sp<IGraphicBufferProducer> bqProducer;
+    sp<IGraphicBufferConsumer> bqConsumer;
+    BufferQueue::createBufferQueue(&bqProducer, &bqConsumer);
+
+    mBufferItemConsumer = new BufferItemConsumer(bqConsumer, consumerUsage, mMaxConsumerBuffers);
+    mSurface = new Surface(bqProducer);
 #endif  // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
+
     if (mBufferItemConsumer == nullptr) {
         return NO_MEMORY;
     }
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
-    mProducer = mBufferItemConsumer->getSurface()->getIGraphicBufferProducer();
-    mConsumer = mBufferItemConsumer->getIGraphicBufferConsumer();
-#endif  //  COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
-    mConsumer->setConsumerName(toString8(mConsumerName));
+    mBufferItemConsumer->setName(toString8(mConsumerName));
 
-    *consumer = new Surface(mProducer);
+    *consumer = mSurface;
     if (*consumer == nullptr) {
         return NO_MEMORY;
     }
 
-    res = mProducer->setAsyncMode(true);
+    res = mSurface->setAsyncMode(true);
     if (res != OK) {
         SP_LOGE("%s: Failed to enable input queue async mode: %s(%d)", __FUNCTION__,
                 strerror(-res), res);
         return res;
     }
 
-    res = mConsumer->consumerConnect(this, /* controlledByApp */ false);
+    mBufferItemConsumer->setFrameAvailableListener(this);
 
     mWidth = width;
     mHeight = height;
@@ -139,25 +146,19 @@
     ATRACE_CALL();
     Mutex::Autolock lock(mMutex);
 
-    for (auto& notifier : mNotifiers) {
-        sp<IGraphicBufferProducer> producer = notifier.first;
-        sp<OutputListener> listener = notifier.second;
-        IInterface::asBinder(producer)->unlinkToDeath(listener);
-    }
     mNotifiers.clear();
 
-    for (auto& output : mOutputs) {
+    for (auto& output : mOutputSurfaces) {
         if (output.second != nullptr) {
             output.second->disconnect(NATIVE_WINDOW_API_CAMERA);
         }
     }
-    mOutputs.clear();
     mOutputSurfaces.clear();
-    mOutputSlots.clear();
+    mHeldBuffers.clear();
     mConsumerBufferCount.clear();
 
-    if (mConsumer.get() != nullptr) {
-        mConsumer->consumerDisconnect();
+    if (mBufferItemConsumer != nullptr) {
+        mBufferItemConsumer->abandon();
     }
 
     if (mBuffers.size() > 0) {
@@ -189,7 +190,7 @@
     }
 
     if (mMaxConsumerBuffers > mAcquiredInputBuffers) {
-        res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
+        res = mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
     }
 
     return res;
@@ -207,7 +208,7 @@
         return BAD_VALUE;
     }
 
-    if (mOutputs[surfaceId] != nullptr) {
+    if (mOutputSurfaces[surfaceId] != nullptr) {
         SP_LOGE("%s: surfaceId: %u already taken!", __FUNCTION__, (unsigned) surfaceId);
         return BAD_VALUE;
     }
@@ -226,11 +227,9 @@
         return res;
     }
 
-    sp<IGraphicBufferProducer> gbp = outputQueue->getIGraphicBufferProducer();
     // Connect to the buffer producer
-    sp<OutputListener> listener(new OutputListener(this, gbp));
-    IInterface::asBinder(gbp)->linkToDeath(listener);
-    res = outputQueue->connect(NATIVE_WINDOW_API_CAMERA, listener);
+    sp<OutputListener> listener = sp<OutputListener>::make(this, outputQueue);
+    res = outputQueue->connect(NATIVE_WINDOW_API_CAMERA, listener, /* reportBufferRemoval */ false);
     if (res != NO_ERROR) {
         SP_LOGE("addOutput: failed to connect (%d)", res);
         return res;
@@ -272,22 +271,21 @@
         outputQueue->setDequeueTimeout(timeout);
     }
 
-    res = gbp->allowAllocation(false);
+    res = outputQueue->allowAllocation(false);
     if (res != OK) {
         SP_LOGE("%s: Failed to turn off allocation for outputQueue", __FUNCTION__);
         return res;
     }
 
     // Add new entry into mOutputs
-    mOutputs[surfaceId] = gbp;
     mOutputSurfaces[surfaceId] = outputQueue;
     mConsumerBufferCount[surfaceId] = maxConsumerBuffers;
     if (mConsumerBufferCount[surfaceId] > mMaxHalBuffers) {
         SP_LOGW("%s: Consumer buffer count %zu larger than max. Hal buffers: %zu", __FUNCTION__,
                 mConsumerBufferCount[surfaceId], mMaxHalBuffers);
     }
-    mNotifiers[gbp] = listener;
-    mOutputSlots[gbp] = std::make_unique<OutputSlots>(totalBufferCount);
+    mNotifiers[outputQueue] = listener;
+    mHeldBuffers[outputQueue] = std::make_unique<HeldBuffers>(totalBufferCount);
 
     mMaxConsumerBuffers += maxConsumerBuffers;
     return NO_ERROR;
@@ -304,7 +302,7 @@
     }
 
     if (mAcquiredInputBuffers < mMaxConsumerBuffers) {
-        res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
+        res = mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers);
         if (res != OK) {
             SP_LOGE("%s: setMaxAcquiredBufferCount failed %d", __FUNCTION__, res);
             return res;
@@ -315,70 +313,54 @@
 }
 
 status_t Camera3StreamSplitter::removeOutputLocked(size_t surfaceId) {
-    if (mOutputs[surfaceId] == nullptr) {
+    if (mOutputSurfaces[surfaceId] == nullptr) {
         SP_LOGE("%s: output surface is not present!", __FUNCTION__);
         return BAD_VALUE;
     }
 
-    sp<IGraphicBufferProducer> gbp = mOutputs[surfaceId];
+    sp<Surface> surface = mOutputSurfaces[surfaceId];
     //Search and decrement the ref. count of any buffers that are
     //still attached to the removed surface.
     std::vector<uint64_t> pendingBufferIds;
-    auto& outputSlots = *mOutputSlots[gbp];
-    for (size_t i = 0; i < outputSlots.size(); i++) {
-        if (outputSlots[i] != nullptr) {
-            pendingBufferIds.push_back(outputSlots[i]->getId());
-            auto rc = gbp->detachBuffer(i);
-            if (rc != NO_ERROR) {
-                //Buffers that fail to detach here will be scheduled for detach in the
-                //input buffer queue and the rest of the registered outputs instead.
-                //This will help ensure that camera stops accessing buffers that still
-                //can get referenced by the disconnected output.
-                mDetachedBuffers.emplace(outputSlots[i]->getId());
-            }
+
+    // TODO: can we simplify this to just use the tracker?
+    for (const auto& buffer : (*mHeldBuffers[surface])) {
+        pendingBufferIds.push_back(buffer->getId());
+        auto rc = surface->detachBuffer(buffer);
+        if (rc != NO_ERROR) {
+            // Buffers that fail to detach here will be scheduled for detach in the
+            // input buffer queue and the rest of the registered outputs instead.
+            // This will help ensure that camera stops accessing buffers that still
+            // can get referenced by the disconnected output.
+            mDetachedBuffers.emplace(buffer->getId());
         }
     }
-    mOutputs[surfaceId] = nullptr;
     mOutputSurfaces[surfaceId] = nullptr;
-    mOutputSlots[gbp] = nullptr;
+    mHeldBuffers[surface] = nullptr;
     for (const auto &id : pendingBufferIds) {
         decrementBufRefCountLocked(id, surfaceId);
     }
 
-    auto res = IInterface::asBinder(gbp)->unlinkToDeath(mNotifiers[gbp]);
-    if (res != OK) {
-        SP_LOGE("%s: Failed to unlink producer death listener: %d ", __FUNCTION__, res);
-        return res;
-    }
-
-    res = gbp->disconnect(NATIVE_WINDOW_API_CAMERA);
+    status_t res = surface->disconnect(NATIVE_WINDOW_API_CAMERA);
     if (res != OK) {
         SP_LOGE("%s: Unable disconnect from producer interface: %d ", __FUNCTION__, res);
         return res;
     }
 
-    mNotifiers[gbp] = nullptr;
+    mNotifiers[surface] = nullptr;
     mMaxConsumerBuffers -= mConsumerBufferCount[surfaceId];
     mConsumerBufferCount[surfaceId] = 0;
 
     return res;
 }
 
-status_t Camera3StreamSplitter::outputBufferLocked(const sp<IGraphicBufferProducer>& output,
+status_t Camera3StreamSplitter::outputBufferLocked(const sp<Surface>& output,
         const BufferItem& bufferItem, size_t surfaceId) {
     ATRACE_CALL();
     status_t res;
-    IGraphicBufferProducer::QueueBufferInput queueInput(
-            bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp,
-            bufferItem.mDataSpace, bufferItem.mCrop,
-            static_cast<int32_t>(bufferItem.mScalingMode),
-            bufferItem.mTransform, bufferItem.mFence);
-
-    IGraphicBufferProducer::QueueBufferOutput queueOutput;
 
     uint64_t bufferId = bufferItem.mGraphicBuffer->getId();
     const BufferTracker& tracker = *(mBuffers[bufferId]);
-    int slot = getSlotForOutputLocked(output, tracker.getBuffer());
 
     if (mOutputSurfaces[surfaceId] != nullptr) {
         sp<ANativeWindow> anw = mOutputSurfaces[surfaceId];
@@ -388,19 +370,26 @@
         SP_LOGE("%s: Invalid surface id: %zu!", __FUNCTION__, surfaceId);
     }
 
+    output->setBuffersTimestamp(bufferItem.mTimestamp);
+    output->setBuffersDataSpace(static_cast<ui::Dataspace>(bufferItem.mDataSpace));
+    output->setCrop(&bufferItem.mCrop);
+    output->setScalingMode(bufferItem.mScalingMode);
+    output->setBuffersTransform(bufferItem.mTransform);
+
     // In case the output BufferQueue has its own lock, if we hold splitter lock while calling
     // queueBuffer (which will try to acquire the output lock), the output could be holding its
     // own lock calling releaseBuffer (which  will try to acquire the splitter lock), running into
     // circular lock situation.
     mMutex.unlock();
-    res = output->queueBuffer(slot, queueInput, &queueOutput);
+    SurfaceQueueBufferOutput queueBufferOutput;
+    res = output->queueBuffer(bufferItem.mGraphicBuffer, bufferItem.mFence, &queueBufferOutput);
     mMutex.lock();
 
-    SP_LOGV("%s: Queuing buffer to buffer queue %p slot %d returns %d",
-            __FUNCTION__, output.get(), slot, res);
-    //During buffer queue 'mMutex' is not held which makes the removal of
-    //"output" possible. Check whether this is the case and return.
-    if (mOutputSlots[output] == nullptr) {
+    SP_LOGV("%s: Queuing buffer to buffer queue %p bufferId %" PRIu64 " returns %d", __FUNCTION__,
+            output.get(), bufferId, res);
+    // During buffer queue 'mMutex' is not held which makes the removal of
+    // "output" possible. Check whether this is the case and return.
+    if (mOutputSurfaces[surfaceId] == nullptr) {
         return res;
     }
     if (res != OK) {
@@ -418,7 +407,7 @@
     // If the queued buffer replaces a pending buffer in the async
     // queue, no onBufferReleased is called by the buffer queue.
     // Proactively trigger the callback to avoid buffer loss.
-    if (queueOutput.bufferReplaced) {
+    if (queueBufferOutput.bufferReplaced) {
         onBufferReplacedLocked(output, surfaceId);
     }
 
@@ -456,52 +445,32 @@
     auto tracker = std::make_unique<BufferTracker>(gb, surface_ids);
 
     for (auto& surface_id : surface_ids) {
-        sp<IGraphicBufferProducer>& gbp = mOutputs[surface_id];
-        if (gbp.get() == nullptr) {
+        sp<Surface>& surface = mOutputSurfaces[surface_id];
+        if (surface.get() == nullptr) {
             //Output surface got likely removed by client.
             continue;
         }
-        int slot = getSlotForOutputLocked(gbp, gb);
-        if (slot != BufferItem::INVALID_BUFFER_SLOT) {
-            //Buffer is already attached to this output surface.
-            continue;
-        }
+
         //Temporarly Unlock the mutex when trying to attachBuffer to the output
         //queue, because attachBuffer could block in case of a slow consumer. If
         //we block while holding the lock, onFrameAvailable and onBufferReleased
         //will block as well because they need to acquire the same lock.
         mMutex.unlock();
-        res = gbp->attachBuffer(&slot, gb);
+        res = surface->attachBuffer(anb);
         mMutex.lock();
         if (res != OK) {
-            SP_LOGE("%s: Cannot attachBuffer from GraphicBufferProducer %p: %s (%d)",
-                    __FUNCTION__, gbp.get(), strerror(-res), res);
+            SP_LOGE("%s: Cannot attachBuffer from GraphicBufferProducer %p: %s (%d)", __FUNCTION__,
+                    surface.get(), strerror(-res), res);
             // TODO: might need to detach/cleanup the already attached buffers before return?
             return res;
         }
-        if ((slot < 0) || (slot > BufferQueue::NUM_BUFFER_SLOTS)) {
-            SP_LOGE("%s: Slot received %d either bigger than expected maximum %d or negative!",
-                    __FUNCTION__, slot, BufferQueue::NUM_BUFFER_SLOTS);
-            return BAD_VALUE;
-        }
         //During buffer attach 'mMutex' is not held which makes the removal of
         //"gbp" possible. Check whether this is the case and continue.
-        if (mOutputSlots[gbp] == nullptr) {
+        if (mHeldBuffers[surface] == nullptr) {
             continue;
         }
-        auto& outputSlots = *mOutputSlots[gbp];
-        if (static_cast<size_t> (slot + 1) > outputSlots.size()) {
-            outputSlots.resize(slot + 1);
-        }
-        if (outputSlots[slot] != nullptr) {
-            // If the buffer is attached to a slot which already contains a buffer,
-            // the previous buffer will be removed from the output queue. Decrement
-            // the reference count accordingly.
-            decrementBufRefCountLocked(outputSlots[slot]->getId(), surface_id);
-        }
-        SP_LOGV("%s: Attached buffer %p to slot %d on output %p.",__FUNCTION__, gb.get(),
-                slot, gbp.get());
-        outputSlots[slot] = gb;
+        mHeldBuffers[surface]->insert(gb);
+        SP_LOGV("%s: Attached buffer %p on output %p.", __FUNCTION__, gb.get(), surface.get());
     }
 
     mBuffers[bufferId] = std::move(tracker);
@@ -515,25 +484,14 @@
 
     // Acquire and detach the buffer from the input
     BufferItem bufferItem;
-    status_t res = mConsumer->acquireBuffer(&bufferItem, /* presentWhen */ 0);
+    status_t res = mBufferItemConsumer->acquireBuffer(&bufferItem, /* presentWhen */ 0);
     if (res != NO_ERROR) {
         SP_LOGE("%s: Acquiring buffer from input failed (%d)", __FUNCTION__, res);
         mOnFrameAvailableRes.store(res);
         return;
     }
 
-    uint64_t bufferId;
-    if (bufferItem.mGraphicBuffer != nullptr) {
-        mInputSlots[bufferItem.mSlot] = bufferItem;
-    } else if (bufferItem.mAcquireCalled) {
-        bufferItem.mGraphicBuffer = mInputSlots[bufferItem.mSlot].mGraphicBuffer;
-        mInputSlots[bufferItem.mSlot].mFrameNumber = bufferItem.mFrameNumber;
-    } else {
-        SP_LOGE("%s: Invalid input graphic buffer!", __FUNCTION__);
-        mOnFrameAvailableRes.store(BAD_VALUE);
-        return;
-    }
-    bufferId = bufferItem.mGraphicBuffer->getId();
+    uint64_t bufferId = bufferItem.mGraphicBuffer->getId();
 
     if (mBuffers.find(bufferId) == mBuffers.end()) {
         SP_LOGE("%s: Acquired buffer doesn't exist in attached buffer map",
@@ -556,13 +514,12 @@
     SP_LOGV("%s: BufferTracker for buffer %" PRId64 ", number of requests %zu",
            __FUNCTION__, bufferItem.mGraphicBuffer->getId(), tracker.requestedSurfaces().size());
     for (const auto id : tracker.requestedSurfaces()) {
-
-        if (mOutputs[id] == nullptr) {
+        if (mOutputSurfaces[id] == nullptr) {
             //Output surface got likely removed by client.
             continue;
         }
 
-        res = outputBufferLocked(mOutputs[id], bufferItem, id);
+        res = outputBufferLocked(mOutputSurfaces[id], bufferItem, id);
         if (res != OK) {
             SP_LOGE("%s: outputBufferLocked failed %d", __FUNCTION__, res);
             mOnFrameAvailableRes.store(res);
@@ -601,26 +558,11 @@
     mBuffers.erase(id);
 
     uint64_t bufferId = tracker_ptr->getBuffer()->getId();
-    int consumerSlot = -1;
-    uint64_t frameNumber;
-    auto inputSlot = mInputSlots.begin();
-    for (; inputSlot != mInputSlots.end(); inputSlot++) {
-        if (inputSlot->second.mGraphicBuffer->getId() == bufferId) {
-            consumerSlot = inputSlot->second.mSlot;
-            frameNumber = inputSlot->second.mFrameNumber;
-            break;
-        }
-    }
-    if (consumerSlot == -1) {
-        SP_LOGE("%s: Buffer missing inside input slots!", __FUNCTION__);
-        return;
-    }
 
     auto detachBuffer = mDetachedBuffers.find(bufferId);
     bool detach = (detachBuffer != mDetachedBuffers.end());
     if (detach) {
         mDetachedBuffers.erase(detachBuffer);
-        mInputSlots.erase(inputSlot);
     }
     // Temporarily unlock mutex to avoid circular lock:
     // 1. This function holds splitter lock, calls releaseBuffer which triggers
@@ -629,15 +571,14 @@
     // 2. Camera3SharedOutputStream::getBufferLocked calls
     // attachBufferToOutputs, which holds the stream lock, and waits for the
     // splitter lock.
-    sp<IGraphicBufferConsumer> consumer(mConsumer);
     mMutex.unlock();
     int res = NO_ERROR;
-    if (consumer != nullptr) {
+    if (mBufferItemConsumer != nullptr) {
         if (detach) {
-            res = consumer->detachBuffer(consumerSlot);
+            res = mBufferItemConsumer->detachBuffer(tracker_ptr->getBuffer());
         } else {
-            res = consumer->releaseBuffer(consumerSlot, frameNumber,
-                    EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, tracker_ptr->getMergedFence());
+            res = mBufferItemConsumer->releaseBuffer(tracker_ptr->getBuffer(),
+                                                     tracker_ptr->getMergedFence());
         }
     } else {
         SP_LOGE("%s: consumer has become null!", __FUNCTION__);
@@ -659,23 +600,25 @@
     }
 }
 
-void Camera3StreamSplitter::onBufferReleasedByOutput(
-        const sp<IGraphicBufferProducer>& from) {
+void Camera3StreamSplitter::onBufferReleasedByOutput(const sp<Surface>& from) {
     ATRACE_CALL();
-    sp<Fence> fence;
 
-    int slot = BufferItem::INVALID_BUFFER_SLOT;
-    auto res = from->dequeueBuffer(&slot, &fence, mWidth, mHeight, mFormat, mProducerUsage,
-            nullptr, nullptr);
+    from->setBuffersDimensions(mWidth, mHeight);
+    from->setBuffersFormat(mFormat);
+    from->setUsage(mProducerUsage);
+
+    sp<GraphicBuffer> buffer;
+    sp<Fence> fence;
+    auto res = from->dequeueBuffer(&buffer, &fence);
     Mutex::Autolock lock(mMutex);
-    handleOutputDequeueStatusLocked(res, slot);
+    handleOutputDequeueStatusLocked(res, buffer);
     if (res != OK) {
         return;
     }
 
     size_t surfaceId = 0;
     bool found = false;
-    for (const auto& it : mOutputs) {
+    for (const auto& it : mOutputSurfaces) {
         if (it.second == from) {
             found = true;
             surfaceId = it.first;
@@ -687,36 +630,29 @@
         return;
     }
 
-    returnOutputBufferLocked(fence, from, surfaceId, slot);
+    returnOutputBufferLocked(fence, from, surfaceId, buffer);
 }
 
-void Camera3StreamSplitter::onBufferReplacedLocked(
-        const sp<IGraphicBufferProducer>& from, size_t surfaceId) {
+void Camera3StreamSplitter::onBufferReplacedLocked(const sp<Surface>& from, size_t surfaceId) {
     ATRACE_CALL();
-    sp<Fence> fence;
 
-    int slot = BufferItem::INVALID_BUFFER_SLOT;
-    auto res = from->dequeueBuffer(&slot, &fence, mWidth, mHeight, mFormat, mProducerUsage,
-            nullptr, nullptr);
-    handleOutputDequeueStatusLocked(res, slot);
+    from->setBuffersDimensions(mWidth, mHeight);
+    from->setBuffersFormat(mFormat);
+    from->setUsage(mProducerUsage);
+
+    sp<GraphicBuffer> buffer;
+    sp<Fence> fence;
+    auto res = from->dequeueBuffer(&buffer, &fence);
+    handleOutputDequeueStatusLocked(res, buffer);
     if (res != OK) {
         return;
     }
 
-    returnOutputBufferLocked(fence, from, surfaceId, slot);
+    returnOutputBufferLocked(fence, from, surfaceId, buffer);
 }
 
 void Camera3StreamSplitter::returnOutputBufferLocked(const sp<Fence>& fence,
-        const sp<IGraphicBufferProducer>& from, size_t surfaceId, int slot) {
-    sp<GraphicBuffer> buffer;
-
-    if (mOutputSlots[from] == nullptr) {
-        //Output surface got likely removed by client.
-        return;
-    }
-
-    auto outputSlots = *mOutputSlots[from];
-    buffer = outputSlots[slot];
+        const sp<Surface>& from, size_t surfaceId, const sp<GraphicBuffer>& buffer) {
     BufferTracker& tracker = *(mBuffers[buffer->getId()]);
     // Merge the release fence of the incoming buffer so that the fence we send
     // back to the input includes all of the outputs' fences
@@ -727,9 +663,16 @@
     auto detachBuffer = mDetachedBuffers.find(buffer->getId());
     bool detach = (detachBuffer != mDetachedBuffers.end());
     if (detach) {
-        auto res = from->detachBuffer(slot);
+        auto res = from->detachBuffer(buffer);
         if (res == NO_ERROR) {
-            outputSlots[slot] = nullptr;
+            if (mHeldBuffers.contains(from)) {
+                mHeldBuffers[from]->erase(buffer);
+            } else {
+                uint64_t surfaceId = 0;
+                from->getUniqueId(&surfaceId);
+                SP_LOGW("%s: buffer %" PRIu64 " not found in held buffers of surface %" PRIu64,
+                        __FUNCTION__, buffer->getId(), surfaceId);
+            }
         } else {
             SP_LOGE("%s: detach buffer from output failed (%d)", __FUNCTION__, res);
         }
@@ -739,22 +682,17 @@
     decrementBufRefCountLocked(buffer->getId(), surfaceId);
 }
 
-void Camera3StreamSplitter::handleOutputDequeueStatusLocked(status_t res, int slot) {
+void Camera3StreamSplitter::handleOutputDequeueStatusLocked(status_t res,
+        const sp<GraphicBuffer>& buffer) {
     if (res == NO_INIT) {
         // If we just discovered that this output has been abandoned, note that,
         // but we can't do anything else, since buffer is invalid
         onAbandonedLocked();
-    } else if (res == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
-        SP_LOGE("%s: Producer needs to re-allocate buffer!", __FUNCTION__);
-        SP_LOGE("%s: This should not happen with buffer allocation disabled!", __FUNCTION__);
-    } else if (res == IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
-        SP_LOGE("%s: All slot->buffer mapping should be released!", __FUNCTION__);
-        SP_LOGE("%s: This should not happen with buffer allocation disabled!", __FUNCTION__);
     } else if (res == NO_MEMORY) {
         SP_LOGE("%s: No free buffers", __FUNCTION__);
     } else if (res == WOULD_BLOCK) {
         SP_LOGE("%s: Dequeue call will block", __FUNCTION__);
-    } else if (res != OK || (slot == BufferItem::INVALID_BUFFER_SLOT)) {
+    } else if (res != OK || buffer == nullptr) {
         SP_LOGE("%s: dequeue buffer from output failed (%d)", __FUNCTION__, res);
     }
 }
@@ -773,36 +711,20 @@
     SP_LOGV("One of my outputs has abandoned me");
 }
 
-int Camera3StreamSplitter::getSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
-        const sp<GraphicBuffer>& gb) {
-    auto& outputSlots = *mOutputSlots[gbp];
-
-    for (size_t i = 0; i < outputSlots.size(); i++) {
-        if (outputSlots[i] == gb) {
-            return (int)i;
-        }
-    }
-
-    SP_LOGV("%s: Cannot find slot for gb %p on output %p", __FUNCTION__, gb.get(),
-            gbp.get());
-    return BufferItem::INVALID_BUFFER_SLOT;
-}
-
-Camera3StreamSplitter::OutputListener::OutputListener(
-        wp<Camera3StreamSplitter> splitter,
-        wp<IGraphicBufferProducer> output)
-      : mSplitter(splitter), mOutput(output) {}
+Camera3StreamSplitter::OutputListener::OutputListener(wp<Camera3StreamSplitter> splitter,
+        wp<Surface> output)
+    : mSplitter(splitter), mOutput(output) {}
 
 void Camera3StreamSplitter::OutputListener::onBufferReleased() {
     ATRACE_CALL();
     sp<Camera3StreamSplitter> splitter = mSplitter.promote();
-    sp<IGraphicBufferProducer> output = mOutput.promote();
+    sp<Surface> output = mOutput.promote();
     if (splitter != nullptr && output != nullptr) {
         splitter->onBufferReleasedByOutput(output);
     }
 }
 
-void Camera3StreamSplitter::OutputListener::binderDied(const wp<IBinder>& /* who */) {
+void Camera3StreamSplitter::OutputListener::onRemoteDied() {
     sp<Camera3StreamSplitter> splitter = mSplitter.promote();
     if (splitter != nullptr) {
         Mutex::Autolock lock(splitter->mMutex);
@@ -833,3 +755,5 @@
 }
 
 } // namespace android
+
+#endif  // USE_NEW_STREAM_SPLITTER
\ No newline at end of file
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 43f12fb..0440e08 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -14,22 +14,25 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SERVERS_STREAMSPLITTER_H
-#define ANDROID_SERVERS_STREAMSPLITTER_H
+#pragma once
 
+#include <memory>
 #include <unordered_set>
 
 #include <camera/CameraMetadata.h>
 
-#include <gui/IConsumerListener.h>
-#include <gui/Surface.h>
 #include <gui/BufferItemConsumer.h>
+#include <gui/Surface.h>
 
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
 #include <utils/StrongPointer.h>
 #include <utils/Timers.h>
 
+#include "Flags.h"
+
+#if USE_NEW_STREAM_SPLITTER  // trying to do this for each change would be a huge hassle.
+
 #define SP_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
 #define SP_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
 #define SP_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.c_str(), ##__VA_ARGS__)
@@ -38,8 +41,6 @@
 namespace android {
 
 class GraphicBuffer;
-class IGraphicBufferConsumer;
-class IGraphicBufferProducer;
 
 // Camera3StreamSplitter is an autonomous class that manages one input BufferQueue
 // and multiple output BufferQueues. By using the buffer attach and detach logic
@@ -47,9 +48,8 @@
 // BufferQueue, where each buffer queued to the input is available to be
 // acquired by each of the outputs, and is able to be dequeued by the input
 // again only once all of the outputs have released it.
-class Camera3StreamSplitter : public BnConsumerListener {
-public:
-
+class Camera3StreamSplitter : public BufferItemConsumer::FrameAvailableListener {
+  public:
     // Constructor
     Camera3StreamSplitter(bool useHalBufManager = false);
 
@@ -67,7 +67,7 @@
     //
     // A return value other than NO_ERROR means that an error has occurred and
     // outputQueue has not been added to the splitter. BAD_VALUE is returned if
-    // outputQueue is NULL. See IGraphicBufferProducer::connect for explanations
+    // outputQueue is NULL. See Surface::connect for explanations
     // of other error codes.
     status_t addOutput(size_t surfaceId, const sp<Surface>& outputQueue);
 
@@ -97,7 +97,7 @@
     void setHalBufferManager(bool enabled);
 
 private:
-    // From IConsumerListener
+    // From BufferItemConsumer::FrameAvailableListener
     //
     // During this callback, we store some tracking information, detach the
     // buffer from the input, and attach it to each of the outputs. This call
@@ -106,23 +106,13 @@
     // input.
     void onFrameAvailable(const BufferItem& item) override;
 
-    // From IConsumerListener
+    // From BufferItemConsumer::FrameAvailableListener
     //
     // Similar to onFrameAvailable, but buffer item is indeed replacing a buffer
     // in the buffer queue. This can happen when buffer queue is in droppable
     // mode.
     void onFrameReplaced(const BufferItem& item) override;
 
-    // From IConsumerListener
-    // We don't care about released buffers because we detach each buffer as
-    // soon as we acquire it. See the comment for onBufferReleased below for
-    // some clarifying notes about the name.
-    void onBuffersReleased() override {}
-
-    // From IConsumerListener
-    // We don't care about sideband streams, since we won't be splitting them
-    void onSidebandStreamChanged() override {}
-
     // This is the implementation of the onBufferReleased callback from
     // IProducerListener. It gets called from an OutputListener (see below), and
     // 'from' is which producer interface from which the callback was received.
@@ -132,10 +122,10 @@
     // last output releasing the buffer, and if so, release it to the input.
     // If we release the buffer to the input, we allow a blocked
     // onFrameAvailable call to proceed.
-    void onBufferReleasedByOutput(const sp<IGraphicBufferProducer>& from);
+    void onBufferReleasedByOutput(const sp<Surface>& from);
 
     // Called by outputBufferLocked when a buffer in the async buffer queue got replaced.
-    void onBufferReplacedLocked(const sp<IGraphicBufferProducer>& from, size_t surfaceId);
+    void onBufferReplacedLocked(const sp<Surface>& from, size_t surfaceId);
 
     // When this is called, the splitter disconnects from (i.e., abandons) its
     // input queue and signals any waiting onFrameAvailable calls to wake up.
@@ -149,35 +139,32 @@
     void decrementBufRefCountLocked(uint64_t id, size_t surfaceId);
 
     // Check for and handle any output surface dequeue errors.
-    void handleOutputDequeueStatusLocked(status_t res, int slot);
+    void handleOutputDequeueStatusLocked(status_t res, const sp<GraphicBuffer>& buffer);
 
     // Handles released output surface buffers.
-    void returnOutputBufferLocked(const sp<Fence>& fence, const sp<IGraphicBufferProducer>& from,
-            size_t surfaceId, int slot);
+    void returnOutputBufferLocked(const sp<Fence>& fence, const sp<Surface>& from, size_t surfaceId,
+            const sp<GraphicBuffer>& buffer);
 
     // This is a thin wrapper class that lets us determine which BufferQueue
     // the IProducerListener::onBufferReleased callback is associated with. We
     // create one of these per output BufferQueue, and then pass the producer
     // into onBufferReleasedByOutput above.
-    class OutputListener : public SurfaceListener,
-                           public IBinder::DeathRecipient {
-    public:
-        OutputListener(wp<Camera3StreamSplitter> splitter,
-                wp<IGraphicBufferProducer> output);
+    class OutputListener : public SurfaceListener {
+      public:
+        OutputListener(wp<Camera3StreamSplitter> splitter, wp<Surface> output);
         virtual ~OutputListener() = default;
 
-        // From IProducerListener
+        // From SurfaceListener
         void onBufferReleased() override;
         bool needsReleaseNotify() override { return true; };
-        void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& /*buffers*/) override {};
+        void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>&) override {}
         void onBufferDetached(int /*slot*/) override {}
 
-        // From IBinder::DeathRecipient
-        void binderDied(const wp<IBinder>& who) override;
+        void onRemoteDied() override;
 
     private:
         wp<Camera3StreamSplitter> mSplitter;
-        wp<IGraphicBufferProducer> mOutput;
+        wp<Surface> mOutput;
     };
 
     class BufferTracker {
@@ -198,7 +185,6 @@
         const std::vector<size_t> requestedSurfaces() const { return mRequestedSurfaces; }
 
     private:
-
         // Disallow copying
         BufferTracker(const BufferTracker& other);
         BufferTracker& operator=(const BufferTracker& other);
@@ -223,16 +209,12 @@
     // Send a buffer to particular output, and increment the reference count
     // of the buffer. If this output is abandoned, the buffer's reference count
     // won't be incremented.
-    status_t outputBufferLocked(const sp<IGraphicBufferProducer>& output,
-            const BufferItem& bufferItem, size_t surfaceId);
+    status_t outputBufferLocked(const sp<Surface>& output, const BufferItem& bufferItem,
+            size_t surfaceId);
 
     // Get unique name for the buffer queue consumer
     std::string getUniqueConsumerName();
 
-    // Helper function to get the BufferQueue slot where a particular buffer is attached to.
-    int getSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
-            const sp<GraphicBuffer>& gb);
-
     // Sum of max consumer buffers for all outputs
     size_t mMaxConsumerBuffers = 0;
     size_t mMaxHalBuffers = 0;
@@ -249,17 +231,9 @@
 
     Mutex mMutex;
 
-    sp<IGraphicBufferProducer> mProducer;
-    sp<IGraphicBufferConsumer> mConsumer;
     sp<BufferItemConsumer> mBufferItemConsumer;
     sp<Surface> mSurface;
 
-    //Map graphic buffer ids -> buffer items
-    std::unordered_map<uint64_t, BufferItem> mInputSlots;
-
-    //Map surface ids -> gbp outputs
-    std::unordered_map<int, sp<IGraphicBufferProducer> > mOutputs;
-
     //Map surface ids -> gbp outputs
     std::unordered_map<int, sp<Surface>> mOutputSurfaces;
 
@@ -271,18 +245,22 @@
     // buffer, but also contain merged release fences).
     std::unordered_map<uint64_t, std::unique_ptr<BufferTracker> > mBuffers;
 
-    struct GBPHash {
-        std::size_t operator()(const sp<IGraphicBufferProducer>& producer) const {
-            return std::hash<IGraphicBufferProducer *>{}(producer.get());
+    struct SurfaceHash {
+        std::size_t operator()(const sp<Surface>& producer) const {
+            return std::hash<Surface*>{}(producer.get());
         }
     };
 
-    std::unordered_map<sp<IGraphicBufferProducer>, sp<OutputListener>,
-            GBPHash> mNotifiers;
+    struct BufferHash {
+        std::size_t operator()(const sp<GraphicBuffer>& buffer) const {
+            return std::hash<GraphicBuffer*>{}(buffer.get());
+        }
+    };
 
-    typedef std::vector<sp<GraphicBuffer>> OutputSlots;
-    std::unordered_map<sp<IGraphicBufferProducer>, std::unique_ptr<OutputSlots>,
-            GBPHash> mOutputSlots;
+    std::unordered_map<sp<Surface>, sp<OutputListener>, SurfaceHash> mNotifiers;
+
+    typedef std::unordered_set<sp<GraphicBuffer>, BufferHash> HeldBuffers;
+    std::unordered_map<sp<Surface>, std::unique_ptr<HeldBuffers>, SurfaceHash> mHeldBuffers;
 
     //A set of buffers that could potentially stay in some of the outputs after removal
     //and therefore should be detached from the input queue.
@@ -301,4 +279,4 @@
 
 } // namespace android
 
-#endif
+#endif  // USE_NEW_STREAM_SPLITTER
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
index 6c16317..37903e1 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "AttributionAndPermissionUtils"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+
 #include "AttributionAndPermissionUtils.h"
 
 #include <binder/AppOpsManager.h>
@@ -25,12 +28,12 @@
 #include "CameraService.h"
 
 #include <binder/IPCThreadState.h>
-#include <hwbinder/IPCThreadState.h>
 #include <binderthreadstate/CallerUtils.h>
+#include <hwbinder/IPCThreadState.h>
 
 namespace {
-    static const std::string kPermissionServiceName = "permission";
-} // namespace anonymous
+static const std::string kPermissionServiceName = "permission";
+} // namespace
 
 namespace android {
 
@@ -39,8 +42,7 @@
 const std::string AttributionAndPermissionUtils::sDumpPermission("android.permission.DUMP");
 const std::string AttributionAndPermissionUtils::sManageCameraPermission(
         "android.permission.MANAGE_CAMERA");
-const std::string AttributionAndPermissionUtils::sCameraPermission(
-        "android.permission.CAMERA");
+const std::string AttributionAndPermissionUtils::sCameraPermission("android.permission.CAMERA");
 const std::string AttributionAndPermissionUtils::sSystemCameraPermission(
         "android.permission.SYSTEM_CAMERA");
 const std::string AttributionAndPermissionUtils::sCameraHeadlessSystemUserPermission(
@@ -54,14 +56,14 @@
 const std::string AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission(
         "android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
 
-int AttributionAndPermissionUtils::getCallingUid() {
+int AttributionAndPermissionUtils::getCallingUid() const {
     if (getCurrentServingCall() == BinderCallType::HWBINDER) {
         return hardware::IPCThreadState::self()->getCallingUid();
     }
     return IPCThreadState::self()->getCallingUid();
 }
 
-int AttributionAndPermissionUtils::getCallingPid() {
+int AttributionAndPermissionUtils::getCallingPid() const {
     if (getCurrentServingCall() == BinderCallType::HWBINDER) {
         return hardware::IPCThreadState::self()->getCallingPid();
     }
@@ -84,67 +86,38 @@
     return;
 }
 
-// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
-bool AttributionAndPermissionUtils::resolveClientUid(/*inout*/ int& clientUid) {
-    int callingUid = getCallingUid();
-
-    if (clientUid == hardware::ICameraService::USE_CALLING_UID) {
-        clientUid = callingUid;
-    } else if (!isTrustedCallingUid(callingUid)) {
-        return false;
+binder::Status AttributionAndPermissionUtils::resolveAttributionSource(
+        /*inout*/ AttributionSourceState& resolvedAttributionSource, const std::string& methodName,
+        const std::optional<std::string>& cameraIdMaybe) {
+    // Check if we can trust clientUid
+    if (!resolveClientUid(resolvedAttributionSource.uid)) {
+        return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
+                               methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
+                               /* isPid= */ false);
     }
 
-    return true;
-}
+    resolveAttributionPackage(resolvedAttributionSource);
 
-// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
-bool AttributionAndPermissionUtils::resolveClientPid(/*inout*/ int& clientPid) {
-    int callingUid = getCallingUid();
-    int callingPid = getCallingPid();
-
-    if (clientPid == hardware::ICameraService::USE_CALLING_PID) {
-        clientPid = callingPid;
-    } else if (!isTrustedCallingUid(callingUid)) {
-        return false;
+    if (!resolveClientPid(resolvedAttributionSource.pid)) {
+        return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
+                               methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
+                               /* isPid= */ true);
     }
 
-    return true;
+    return binder::Status::ok();
 }
 
-bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(const std::string &cameraId,
-        const AttributionSourceState &attributionSource) {
-    if (isAutomotivePrivilegedClient(attributionSource.uid)) {
-        // If cameraId is empty, then it means that this check is not used for the
-        // purpose of accessing a specific camera, hence grant permission just
-        // based on uid to the automotive privileged client.
-        if (cameraId.empty())
-            return true;
-
-        auto cameraService = mCameraService.promote();
-        if (cameraService == nullptr) {
-            ALOGE("%s: CameraService unavailable.", __FUNCTION__);
-            return false;
-        }
-
-        // If this call is used for accessing a specific camera then cam_id must be provided.
-        // In that case, only pre-grants the permission for accessing the exterior system only
-        // camera.
-        return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
-    }
-
-    return false;
-}
-
-bool AttributionAndPermissionUtils::checkPermissionForPreflight(const std::string &cameraId,
-        const std::string &permission, const AttributionSourceState &attributionSource,
-        const std::string& message, int32_t attributedOpCode) {
+bool AttributionAndPermissionUtils::checkPermissionForPreflight(
+        const std::string& cameraId, const std::string& permission,
+        const AttributionSourceState& attributionSource, const std::string& message,
+        int32_t attributedOpCode) {
     if (checkAutomotivePrivilegedClient(cameraId, attributionSource)) {
         return true;
     }
 
     return mPermissionChecker->checkPermissionForPreflight(
-                    toString16(permission), attributionSource, toString16(message),
-                    attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
+                   toString16(permission), attributionSource, toString16(message),
+                   attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
 }
 
 // Can camera service trust the caller based on the calling UID?
@@ -177,8 +150,7 @@
 
 bool AttributionAndPermissionUtils::isAutomotivePrivilegedClient(int32_t uid) {
     // Returns false if this is not an automotive device type.
-    if (!isAutomotiveDevice())
-        return false;
+    if (!isAutomotiveDevice()) return false;
 
     // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
     // privileged client uid used for safety critical use cases such as
@@ -213,8 +185,8 @@
     return packageName;
 }
 
-status_t AttributionAndPermissionUtils::getUidForPackage(const std::string &packageName,
-        int userId, /*inout*/uid_t& uid, int err) {
+status_t AttributionAndPermissionUtils::getUidForPackage(const std::string& packageName, int userId,
+                                                         /*inout*/ uid_t& uid, int err) {
     PermissionController pc;
     uid = pc.getPackageUid(toString16(packageName), 0);
     if (uid <= 0) {
@@ -237,36 +209,128 @@
     return (getCallingPid() == getpid());
 }
 
-bool AttributionAndPermissionUtils::hasPermissionsForCamera(const std::string& cameraId,
-        const AttributionSourceState& attributionSource) {
-    return checkPermissionForPreflight(cameraId, sCameraPermission,
-            attributionSource, std::string(), AppOpsManager::OP_NONE);
+bool AttributionAndPermissionUtils::hasPermissionsForCamera(
+        const std::string& cameraId, const AttributionSourceState& attributionSource) {
+    return checkPermissionForPreflight(cameraId, sCameraPermission, attributionSource,
+                                       std::string(), AppOpsManager::OP_NONE);
 }
 
-bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(const std::string& cameraId,
-        const AttributionSourceState& attributionSource, bool checkCameraPermissions) {
-    bool systemCameraPermission = checkPermissionForPreflight(cameraId,
-            sSystemCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
-    return systemCameraPermission && (!checkCameraPermissions
-            || hasPermissionsForCamera(cameraId, attributionSource));
+bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(
+        const std::string& cameraId, const AttributionSourceState& attributionSource,
+        bool checkCameraPermissions) {
+    bool systemCameraPermission =
+            checkPermissionForPreflight(cameraId, sSystemCameraPermission, attributionSource,
+                                        std::string(), AppOpsManager::OP_NONE);
+    return systemCameraPermission &&
+           (!checkCameraPermissions || hasPermissionsForCamera(cameraId, attributionSource));
 }
 
 bool AttributionAndPermissionUtils::hasPermissionsForCameraHeadlessSystemUser(
         const std::string& cameraId, const AttributionSourceState& attributionSource) {
     return checkPermissionForPreflight(cameraId, sCameraHeadlessSystemUserPermission,
-            attributionSource, std::string(), AppOpsManager::OP_NONE);
+                                       attributionSource, std::string(), AppOpsManager::OP_NONE);
 }
 
 bool AttributionAndPermissionUtils::hasPermissionsForCameraPrivacyAllowlist(
         const AttributionSourceState& attributionSource) {
     return checkPermissionForPreflight(std::string(), sCameraPrivacyAllowlistPermission,
-            attributionSource, std::string(), AppOpsManager::OP_NONE);
+                                       attributionSource, std::string(), AppOpsManager::OP_NONE);
 }
 
 bool AttributionAndPermissionUtils::hasPermissionsForOpenCloseListener(
         const AttributionSourceState& attributionSource) {
     return checkPermissionForPreflight(std::string(), sCameraOpenCloseListenerPermission,
-            attributionSource, std::string(), AppOpsManager::OP_NONE);
+                                       attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(
+        const std::string& cameraId, const AttributionSourceState& attributionSource) {
+    if (isAutomotivePrivilegedClient(attributionSource.uid)) {
+        // If cameraId is empty, then it means that this check is not used for the
+        // purpose of accessing a specific camera, hence grant permission just
+        // based on uid to the automotive privileged client.
+        if (cameraId.empty()) return true;
+
+        auto cameraService = mCameraService.promote();
+        if (cameraService == nullptr) {
+            ALOGE("%s: CameraService unavailable.", __FUNCTION__);
+            return false;
+        }
+
+        // If this call is used for accessing a specific camera then cam_id must be provided.
+        // In that case, only pre-grants the permission for accessing the exterior system only
+        // camera.
+        return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
+    }
+
+    return false;
+}
+
+void AttributionAndPermissionUtils::resolveAttributionPackage(
+        AttributionSourceState& resolvedAttributionSource) {
+    if (resolvedAttributionSource.packageName.has_value() &&
+        resolvedAttributionSource.packageName->size() > 0) {
+        return;
+    }
+
+    // NDK calls don't come with package names, but we need one for various cases.
+    // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
+    // do exist. For all authentication cases, all packages under the same UID get the
+    // same permissions, so picking any associated package name is sufficient. For some
+    // other cases, this may give inaccurate names for clients in logs.
+    resolvedAttributionSource.packageName = getPackageNameFromUid(resolvedAttributionSource.uid);
+}
+
+// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
+bool AttributionAndPermissionUtils::resolveClientUid(/*inout*/ int& clientUid) {
+    int callingUid = getCallingUid();
+
+    bool validUid = true;
+    if (clientUid == hardware::ICameraService::USE_CALLING_UID) {
+        clientUid = callingUid;
+    } else {
+        validUid = isTrustedCallingUid(callingUid);
+        if (flags::use_context_attribution_source()) {
+            validUid = validUid || (clientUid == callingUid);
+        }
+    }
+
+    return validUid;
+}
+
+// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
+bool AttributionAndPermissionUtils::resolveClientPid(/*inout*/ int& clientPid) {
+    int callingUid = getCallingUid();
+    int callingPid = getCallingPid();
+
+    bool validPid = true;
+    if (clientPid == hardware::ICameraService::USE_CALLING_PID) {
+        clientPid = callingPid;
+    } else {
+        validPid = isTrustedCallingUid(callingUid);
+        if (flags::use_context_attribution_source()) {
+            validPid = validPid || (clientPid == callingPid);
+        }
+    }
+
+    return validPid;
+}
+
+binder::Status AttributionAndPermissionUtils::errorNotTrusted(
+        int clientPid, int clientUid, const std::string& methodName,
+        const std::optional<std::string>& cameraIdMaybe, const std::string& clientName,
+        bool isPid) const {
+    int callingPid = getCallingPid();
+    int callingUid = getCallingUid();
+    ALOGE("CameraService::%s X (calling PID %d, calling UID %d) rejected "
+          "(don't trust %s %d)",
+          methodName.c_str(), callingPid, callingUid, isPid ? "clientPid" : "clientUid",
+          isPid ? clientPid : clientUid);
+    return STATUS_ERROR_FMT(hardware::ICameraService::ERROR_PERMISSION_DENIED,
+                            "Untrusted caller (calling PID %d, UID %d) trying to "
+                            "forward camera access to camera %s for client %s (PID %d, UID %d)",
+                            getCallingPid(), getCallingUid(), cameraIdMaybe.value_or("N/A").c_str(),
+                            clientName.c_str(), clientPid, clientUid);
 }
 
 const sp<IPermissionController>& AttributionAndPermissionUtils::getPermissionController() const {
@@ -274,7 +338,7 @@
     static thread_local sp<IPermissionController> sPermissionController = nullptr;
 
     if (sPermissionController == nullptr ||
-            !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
+        !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder = sm->checkService(toString16(kPermissionControllerService));
         if (binder == nullptr) {
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
index 8bfe6d8..22abccc 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
@@ -35,12 +35,10 @@
  */
 class AttributionAndPermissionUtils {
   public:
-    AttributionAndPermissionUtils() { }
+    AttributionAndPermissionUtils() {}
     virtual ~AttributionAndPermissionUtils() {}
 
-    void setCameraService(wp<CameraService> cameraService) {
-        mCameraService = cameraService;
-    }
+    void setCameraService(wp<CameraService> cameraService) { mCameraService = cameraService; }
 
     static AttributionSourceState buildAttributionSource(int callingPid, int callingUid) {
         AttributionSourceState attributionSource{};
@@ -50,20 +48,31 @@
     }
 
     static AttributionSourceState buildAttributionSource(int callingPid, int callingUid,
-            int32_t deviceId) {
+                                                         int32_t deviceId) {
         AttributionSourceState attributionSource = buildAttributionSource(callingPid, callingUid);
         attributionSource.deviceId = deviceId;
         return attributionSource;
     }
 
     // Utilities handling Binder calling identities (previously in CameraThreadState)
-    virtual int getCallingUid();
-    virtual int getCallingPid();
+    virtual int getCallingUid() const;
+    virtual int getCallingPid() const;
     virtual int64_t clearCallingIdentity();
     virtual void restoreCallingIdentity(int64_t token);
 
-    virtual bool resolveClientUid(/*inout*/ int& clientUid);
-    virtual bool resolveClientPid(/*inout*/ int& clientPid);
+    /**
+     * If flag::use_context_attribution_source() is enabled, check the calling attribution source
+     * and resolve its package name, or fill in the pid/uid/package name if necessary.
+     *
+     * @param resolvedAttributionSource The resolved attribution source.
+     * @param methodName The name of the method calling this function (for logging only).
+     * @param cameraIdMaybe The camera ID, if applicable.
+     * @return The status of the operation.
+     */
+    virtual binder::Status resolveAttributionSource(
+            /*inout*/ AttributionSourceState& resolvedAttributionSource,
+            const std::string& methodName,
+            const std::optional<std::string>& cameraIdMaybe = std::nullopt);
 
     /**
      * Pre-grants the permission if the attribution source uid is for an automotive
@@ -74,9 +83,10 @@
      * which is located outside of the vehicle body frame because camera located inside the vehicle
      * cabin would need user permission.
      */
-    virtual bool checkPermissionForPreflight(const std::string &cameraId,
-            const std::string &permission, const AttributionSourceState& attributionSource,
-            const std::string& message, int32_t attributedOpCode);
+    virtual bool checkPermissionForPreflight(const std::string& cameraId,
+                                             const std::string& permission,
+                                             const AttributionSourceState& attributionSource,
+                                             const std::string& message, int32_t attributedOpCode);
 
     // Can camera service trust the caller based on the calling UID?
     virtual bool isTrustedCallingUid(uid_t uid);
@@ -98,17 +108,18 @@
     // stats based on app ops may be slightly off.
     virtual std::string getPackageNameFromUid(int clientUid) const;
 
-    virtual status_t getUidForPackage(const std::string &packageName, int userId,
-            /*inout*/uid_t& uid, int err);
+    virtual status_t getUidForPackage(const std::string& packageName, int userId,
+                                      /*inout*/ uid_t& uid, int err);
     virtual bool isCallerCameraServerNotDelegating();
 
     // Utils for checking specific permissions
     virtual bool hasPermissionsForCamera(const std::string& cameraId,
-            const AttributionSourceState& attributionSource);
+                                         const AttributionSourceState& attributionSource);
     virtual bool hasPermissionsForSystemCamera(const std::string& cameraId,
-            const AttributionSourceState& attributionSource, bool checkCameraPermissions = true);
-    virtual bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId,
-            const AttributionSourceState& attributionSource);
+                                               const AttributionSourceState& attributionSource,
+                                               bool checkCameraPermissions = true);
+    virtual bool hasPermissionsForCameraHeadlessSystemUser(
+            const std::string& cameraId, const AttributionSourceState& attributionSource);
     virtual bool hasPermissionsForCameraPrivacyAllowlist(
             const AttributionSourceState& attributionSource);
     virtual bool hasPermissionsForOpenCloseListener(
@@ -127,8 +138,20 @@
   protected:
     wp<CameraService> mCameraService;
 
-    bool checkAutomotivePrivilegedClient(const std::string &cameraId,
-            const AttributionSourceState &attributionSource);
+    bool checkAutomotivePrivilegedClient(const std::string& cameraId,
+                                         const AttributionSourceState& attributionSource);
+
+    // If the package name is missing from the AttributionSource and a package name exists for the
+    // AttributionSource's uid, fills in the missing package name.
+    void resolveAttributionPackage(AttributionSourceState& resolvedAttributionSource);
+
+    virtual bool resolveClientUid(/*inout*/ int& clientUid);
+    virtual bool resolveClientPid(/*inout*/ int& clientPid);
+
+    virtual binder::Status errorNotTrusted(int clientPid, int clientUid,
+                                           const std::string& methodName,
+                                           const std::optional<std::string>& cameraIdMaybe,
+                                           const std::string& clientName, bool isPid) const;
 
   private:
     virtual const sp<IPermissionController>& getPermissionController() const;
@@ -143,39 +166,36 @@
  * in the encapsulating class's methods.
  */
 class AttributionAndPermissionUtilsEncapsulator {
-protected:
+  protected:
     std::shared_ptr<AttributionAndPermissionUtils> mAttributionAndPermissionUtils;
 
-public:
+  public:
     AttributionAndPermissionUtilsEncapsulator(
-        std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils)
-            : mAttributionAndPermissionUtils(attributionAndPermissionUtils) { }
+            std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils)
+        : mAttributionAndPermissionUtils(attributionAndPermissionUtils) {}
 
     static AttributionSourceState buildAttributionSource(int callingPid, int callingUid) {
         return AttributionAndPermissionUtils::buildAttributionSource(callingPid, callingUid);
     }
 
     static AttributionSourceState buildAttributionSource(int callingPid, int callingUid,
-            int32_t deviceId) {
-        return AttributionAndPermissionUtils::buildAttributionSource(
-                callingPid, callingUid, deviceId);
+                                                         int32_t deviceId) {
+        return AttributionAndPermissionUtils::buildAttributionSource(callingPid, callingUid,
+                                                                     deviceId);
     }
 
     static AttributionSourceState buildAttributionSource(int callingPid, int callingUid,
-            const std::string& packageName, int32_t deviceId) {
-        AttributionSourceState attributionSource = buildAttributionSource(callingPid, callingUid,
-                deviceId);
+                                                         const std::string& packageName,
+                                                         int32_t deviceId) {
+        AttributionSourceState attributionSource =
+                buildAttributionSource(callingPid, callingUid, deviceId);
         attributionSource.packageName = packageName;
         return attributionSource;
     }
 
-    int getCallingUid() const {
-        return mAttributionAndPermissionUtils->getCallingUid();
-    }
+    int getCallingUid() const { return mAttributionAndPermissionUtils->getCallingUid(); }
 
-    int getCallingPid() const {
-        return mAttributionAndPermissionUtils->getCallingPid();
-    }
+    int getCallingPid() const { return mAttributionAndPermissionUtils->getCallingPid(); }
 
     int64_t clearCallingIdentity() const {
         return mAttributionAndPermissionUtils->clearCallingIdentity();
@@ -185,56 +205,52 @@
         mAttributionAndPermissionUtils->restoreCallingIdentity(token);
     }
 
-    bool resolveClientUid(/*inout*/ int& clientUid) const {
-        return mAttributionAndPermissionUtils->resolveClientUid(clientUid);
-    }
-
-    bool resolveClientPid(/*inout*/ int& clientPid) const {
-        return mAttributionAndPermissionUtils->resolveClientPid(clientPid);
+    binder::Status resolveAttributionSource(AttributionSourceState& resolvedAttributionSource,
+                                            const std::string& methodName,
+                                            const std::optional<std::string>& cameraIdMaybe) {
+        return mAttributionAndPermissionUtils->resolveAttributionSource(resolvedAttributionSource,
+                                                                        methodName, cameraIdMaybe);
     }
 
     // The word 'System' here does not refer to callers only on the system
     // partition. They just need to have an android system uid.
-    bool callerHasSystemUid() const {
-        return (getCallingUid() < AID_APP_START);
-    }
+    bool callerHasSystemUid() const { return (getCallingUid() < AID_APP_START); }
 
     bool hasPermissionsForCamera(int callingPid, int callingUid, int32_t deviceId) const {
         return hasPermissionsForCamera(std::string(), callingPid, callingUid, deviceId);
     }
 
-    bool hasPermissionsForCamera(int callingPid, int callingUid,
-            const std::string& packageName, int32_t deviceId) const {
+    bool hasPermissionsForCamera(int callingPid, int callingUid, const std::string& packageName,
+                                 int32_t deviceId) const {
         return hasPermissionsForCamera(std::string(), callingPid, callingUid, packageName,
-                deviceId);
+                                       deviceId);
     }
 
-    bool hasPermissionsForCamera(const std::string& cameraId, int callingPid,
-            int callingUid, int32_t deviceId) const {
-        auto attributionSource = buildAttributionSource(callingPid, callingUid,
-                deviceId);
+    bool hasPermissionsForCamera(const std::string& cameraId, int callingPid, int callingUid,
+                                 int32_t deviceId) const {
+        auto attributionSource = buildAttributionSource(callingPid, callingUid, deviceId);
         return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, attributionSource);
     }
 
     bool hasPermissionsForCamera(const std::string& cameraId, int callingPid, int callingUid,
-            const std::string& packageName, int32_t deviceId) const {
-        auto attributionSource = buildAttributionSource(callingPid, callingUid, packageName,
-                deviceId);
+                                 const std::string& packageName, int32_t deviceId) const {
+        auto attributionSource =
+                buildAttributionSource(callingPid, callingUid, packageName, deviceId);
         return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, attributionSource);
     }
 
     bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid,
-            bool checkCameraPermissions = true) const  {
+                                       bool checkCameraPermissions = true) const {
         auto attributionSource = buildAttributionSource(callingPid, callingUid);
         return mAttributionAndPermissionUtils->hasPermissionsForSystemCamera(
-                    cameraId, attributionSource, checkCameraPermissions);
+                cameraId, attributionSource, checkCameraPermissions);
     }
 
     bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId, int callingPid,
-            int callingUid) const {
+                                                   int callingUid) const {
         auto attributionSource = buildAttributionSource(callingPid, callingUid);
         return mAttributionAndPermissionUtils->hasPermissionsForCameraHeadlessSystemUser(
-                    cameraId, attributionSource);
+                cameraId, attributionSource);
     }
 
     bool hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const {
@@ -249,9 +265,7 @@
                 attributionSource);
     }
 
-    bool isAutomotiveDevice() const {
-        return mAttributionAndPermissionUtils->isAutomotiveDevice();
-    }
+    bool isAutomotiveDevice() const { return mAttributionAndPermissionUtils->isAutomotiveDevice(); }
 
     bool isAutomotivePrivilegedClient(int32_t uid) const {
         return mAttributionAndPermissionUtils->isAutomotivePrivilegedClient(uid);
@@ -265,8 +279,8 @@
         return mAttributionAndPermissionUtils->isHeadlessSystemUserMode();
     }
 
-    status_t getUidForPackage(const std::string &packageName, int userId,
-            /*inout*/uid_t& uid, int err) const {
+    status_t getUidForPackage(const std::string& packageName, int userId,
+                              /*inout*/ uid_t& uid, int err) const {
         return mAttributionAndPermissionUtils->getUidForPackage(packageName, userId, uid, err);
     }
 
@@ -281,4 +295,4 @@
 
 } // namespace android
 
-#endif // ANDROID_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H
+#endif  // ANDROID_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H
diff --git a/services/tuner/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index 84a2b4e..e393c44 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -335,26 +335,40 @@
 
 /////////////// FilterCallback ///////////////////////
 ::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterStatus(DemuxFilterStatus status) {
-    Mutex::Autolock _l(mCallbackLock);
-    if (mTunerFilterCallback != nullptr) {
-        mTunerFilterCallback->onFilterStatus(status);
+    shared_ptr<ITunerFilterCallback> cb(nullptr);
+    {
+        Mutex::Autolock _l(mCallbackLock);
+        cb = mTunerFilterCallback;
+    }
+    if (cb != nullptr) {
+        cb->onFilterStatus(status);
     }
     return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterEvent(
         const vector<DemuxFilterEvent>& events) {
-    Mutex::Autolock _l(mCallbackLock);
-    if (mTunerFilterCallback != nullptr) {
-        mTunerFilterCallback->onFilterEvent(events);
+    shared_ptr<ITunerFilterCallback> cb(nullptr);
+    {
+        Mutex::Autolock _l(mCallbackLock);
+        cb = mTunerFilterCallback;
+    }
+    if (cb != nullptr) {
+        cb->onFilterEvent(events);
     }
     return ::ndk::ScopedAStatus::ok();
 }
 
 void TunerFilter::FilterCallback::sendSharedFilterStatus(int32_t status) {
-    Mutex::Autolock _l(mCallbackLock);
-    if (mTunerFilterCallback != nullptr && mOriginalCallback != nullptr) {
-        mTunerFilterCallback->onFilterStatus(static_cast<DemuxFilterStatus>(status));
+    shared_ptr<ITunerFilterCallback> cb(nullptr);
+    shared_ptr<ITunerFilterCallback> orig_cb(nullptr);
+    {
+        Mutex::Autolock _l(mCallbackLock);
+        cb = mTunerFilterCallback;
+        orig_cb = mOriginalCallback;
+    }
+    if (cb != nullptr && orig_cb != nullptr) {
+        cb->onFilterStatus(static_cast<DemuxFilterStatus>(status));
     }
 }