Merge "Send onFrameRendered differently depending on whether the surface is a display" into udc-dev
diff --git a/media/audioaidlconversion/AidlConversionCore.cpp b/media/audioaidlconversion/AidlConversionCore.cpp
new file mode 100644
index 0000000..948e35d
--- /dev/null
+++ b/media/audioaidlconversion/AidlConversionCore.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlConversionCore"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <media/AidlConversionCore.h>
+#include <media/AidlConversionCppNdk.h>
+
+namespace aidl {
+namespace android {
+
+using MicrophoneDirection = hardware::audio::core::IStreamIn::MicrophoneDirection;
+using ::android::BAD_VALUE;
+using ::android::OK;
+using ::android::status_t;
+using ::android::base::unexpected;
+
+ConversionResult<audio_microphone_direction_t>
+aidl2legacy_MicrophoneDirection_audio_microphone_direction_t(MicrophoneDirection aidl) {
+    switch (aidl) {
+        case MicrophoneDirection::UNSPECIFIED:
+            return MIC_DIRECTION_UNSPECIFIED;
+        case MicrophoneDirection::FRONT:
+            return MIC_DIRECTION_FRONT;
+        case MicrophoneDirection::BACK:
+            return MIC_DIRECTION_BACK;
+        case MicrophoneDirection::EXTERNAL:
+            return MIC_DIRECTION_EXTERNAL;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+ConversionResult<MicrophoneDirection>
+legacy2aidl_audio_microphone_direction_t_MicrophoneDirection(audio_microphone_direction_t legacy) {
+    switch (legacy) {
+        case MIC_DIRECTION_UNSPECIFIED:
+            return MicrophoneDirection::UNSPECIFIED;
+        case MIC_DIRECTION_FRONT:
+            return MicrophoneDirection::FRONT;
+        case MIC_DIRECTION_BACK:
+            return MicrophoneDirection::BACK;
+        case MIC_DIRECTION_EXTERNAL:
+            return MicrophoneDirection::EXTERNAL;
+    }
+    return unexpected(BAD_VALUE);
+}
+
+}  // namespace android
+}  // aidl
diff --git a/media/audioaidlconversion/Android.bp b/media/audioaidlconversion/Android.bp
index bdb3a2c..1ec4849 100644
--- a/media/audioaidlconversion/Android.bp
+++ b/media/audioaidlconversion/Android.bp
@@ -152,6 +152,37 @@
 }
 
 /**
+ * Only including AIDL core HAL conversion.
+ */
+cc_library {
+    name: "libaudio_aidl_conversion_core_ndk",
+    srcs: [
+        "AidlConversionCore.cpp",
+    ],
+    header_libs: [
+        "libaudio_aidl_conversion_common_util_ndk",
+    ],
+    export_header_lib_headers: [
+        "libaudio_aidl_conversion_common_util_ndk",
+    ],
+    defaults: [
+        "audio_aidl_conversion_common_default",
+        "latest_android_hardware_audio_common_ndk_shared",
+        "latest_android_hardware_audio_core_ndk_shared",
+        "latest_android_media_audio_common_types_ndk_shared",
+    ],
+    shared_libs: [
+        "libaudio_aidl_conversion_common_ndk",
+        "libbinder_ndk",
+        "libbase",
+    ],
+    cflags: [
+        "-DBACKEND_NDK",
+    ],
+    min_sdk_version: "31", //AParcelableHolder has been introduced in 31
+}
+
+/**
  * Only including AIDL effect HAL conversion.
  */
 cc_library {
diff --git a/media/audioaidlconversion/include/media/AidlConversionCore.h b/media/audioaidlconversion/include/media/AidlConversionCore.h
new file mode 100644
index 0000000..aaa2e53
--- /dev/null
+++ b/media/audioaidlconversion/include/media/AidlConversionCore.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+/**
+ * Can only handle conversion between AIDL (NDK backend) and legacy type.
+ */
+#include <aidl/android/hardware/audio/core/IStreamIn.h>
+#include <media/AidlConversionUtil.h>
+#include <system/audio.h>
+
+namespace aidl {
+namespace android {
+
+ConversionResult<audio_microphone_direction_t>
+aidl2legacy_MicrophoneDirection_audio_microphone_direction_t(
+        hardware::audio::core::IStreamIn::MicrophoneDirection aidl);
+ConversionResult<hardware::audio::core::IStreamIn::MicrophoneDirection>
+legacy2aidl_audio_microphone_direction_t_MicrophoneDirection(audio_microphone_direction_t legacy);
+
+}  // namespace android
+}  // namespace aidl
diff --git a/media/libaudiofoundation/AudioProfile.cpp b/media/libaudiofoundation/AudioProfile.cpp
index 2170cd8..999e263 100644
--- a/media/libaudiofoundation/AudioProfile.cpp
+++ b/media/libaudiofoundation/AudioProfile.cpp
@@ -327,6 +327,24 @@
     return false;
 }
 
+const SampleRateSet AudioProfileVector::getSampleRatesFor(audio_format_t format) const {
+    for (const auto& profile : *this) {
+        if (profile->getFormat() == format) {
+            return profile->getSampleRates();
+        }
+    }
+    return {};
+}
+
+const ChannelMaskSet AudioProfileVector::getChannelMasksFor(audio_format_t format) const {
+    for (const auto& profile : *this) {
+        if (profile->getFormat() == format) {
+            return profile->getChannels();
+        }
+    }
+    return {};
+}
+
 bool AudioProfileVector::contains(const sp<AudioProfile>& profile, bool ignoreDynamicFlags) const
 {
     for (const auto& audioProfile : *this) {
diff --git a/media/libaudiofoundation/include/media/AudioProfile.h b/media/libaudiofoundation/include/media/AudioProfile.h
index 79dfd12..a668afe 100644
--- a/media/libaudiofoundation/include/media/AudioProfile.h
+++ b/media/libaudiofoundation/include/media/AudioProfile.h
@@ -139,6 +139,9 @@
     bool hasDynamicProfile() const;
     bool hasDynamicRateFor(audio_format_t format) const;
 
+    const SampleRateSet getSampleRatesFor(audio_format_t format) const;
+    const ChannelMaskSet getChannelMasksFor(audio_format_t format) const;
+
     bool contains(const sp<AudioProfile>& profile, bool ignoreDynamicFlags = false) const;
 
     virtual void dump(std::string *dst, int spaces) const;
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 15726ff..9dbb591 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -290,6 +290,7 @@
         "libbinder_ndk",
         "libaudio_aidl_conversion_common_cpp",
         "libaudio_aidl_conversion_common_ndk",
+        "libaudio_aidl_conversion_core_ndk",
         "libaudio_aidl_conversion_effect_ndk",
         "libaudioaidlcommon",
     ],
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 25ee61a..aafe6e0 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -937,10 +937,13 @@
     return mModule->dump(fd, Args(args).args(), args.size());
 }
 
-int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports __unused) {
+int32_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports) {
     TIME_CHECK();
-    ALOGE("%s not implemented yet", __func__);
-    return INVALID_OPERATION;
+    if (!mModule) return NO_INIT;
+    if (supports == nullptr) {
+        return BAD_VALUE;
+    }
+    return statusTFromBinderStatus(mModule->supportsVariableLatency(supports));
 }
 
 status_t DeviceHalAidl::getSoundDoseInterface(const std::string& module,
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
index 5ab7c84..52fed91 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <cstddef>
 #include <cstdint>
 #include <cstring>
 #include <optional>
@@ -44,6 +45,7 @@
 using ::aidl::android::media::audio::common::AudioDeviceDescription;
 using ::aidl::android::media::audio::common::AudioMode;
 using ::aidl::android::media::audio::common::AudioSource;
+using ::android::hardware::EventFlag;
 using android::effect::utils::EffectParamReader;
 using android::effect::utils::EffectParamWriter;
 
@@ -127,6 +129,8 @@
 status_t EffectConversionHelperAidl::handleGetParameter(uint32_t cmdSize, const void* pCmdData,
                                                         uint32_t* replySize, void* pReplyData) {
     if (cmdSize < sizeof(effect_param_t) || !pCmdData || !replySize || !pReplyData) {
+        ALOGE("%s illegal cmdSize %u pCmdData %p replySize %p replyData %p", __func__, cmdSize,
+              pCmdData, replySize, pReplyData);
         return BAD_VALUE;
     }
 
@@ -183,8 +187,9 @@
     }
 
     if (state == State::INIT) {
-        ALOGI("%s at state %s, opening effect", __func__,
-              android::internal::ToString(state).c_str());
+        ALOGI("%s at state %s, opening effect with input %s output %s", __func__,
+              android::internal::ToString(state).c_str(), common.input.toString().c_str(),
+              common.output.toString().c_str());
         IEffect::OpenEffectReturn openReturn;
         RETURN_STATUS_IF_ERROR(
                 statusTFromBinderStatus(mEffect->open(common, std::nullopt, &openReturn)));
@@ -200,6 +205,11 @@
             mInputQ = std::make_shared<DataMQ>(openReturn.inputDataMQ);
             mOutputQ = std::make_shared<DataMQ>(openReturn.outputDataMQ);
         }
+
+        if (status_t status = updateEventFlags(); status != OK) {
+            mEffect->close();
+            return status;
+        }
         mCommon = common;
     } else if (mCommon != common) {
         ALOGI("%s at state %s, setParameter", __func__, android::internal::ToString(state).c_str());
@@ -343,6 +353,7 @@
         mStatusQ = std::make_shared<StatusMQ>(ret->statusMQ);
         mInputQ = std::make_shared<DataMQ>(ret->inputDataMQ);
         mOutputQ = std::make_shared<DataMQ>(ret->outputDataMQ);
+        RETURN_STATUS_IF_ERROR(updateEventFlags());
     }
     return *static_cast<int32_t*>(pReplyData) = OK;
 }
@@ -387,5 +398,20 @@
     return visualizerMeasure(replySize, pReplyData);
 }
 
+status_t EffectConversionHelperAidl::updateEventFlags() {
+    status_t status = BAD_VALUE;
+    EventFlag* efGroup = nullptr;
+    if (mStatusQ->isValid()) {
+        status = EventFlag::createEventFlag(mStatusQ->getEventFlagWord(), &efGroup);
+        if (status != OK || !efGroup) {
+            ALOGE("%s: create EventFlagGroup failed, ret %d, egGroup %p", __func__, status,
+                  efGroup);
+            status = (status == OK) ? BAD_VALUE : status;
+        }
+    }
+    mEfGroup.reset(efGroup, EventFlagDeleter());
+    return status;
+}
+
 }  // namespace effect
 }  // namespace android
diff --git a/media/libaudiohal/impl/EffectConversionHelperAidl.h b/media/libaudiohal/impl/EffectConversionHelperAidl.h
index 1200264..0c682ff 100644
--- a/media/libaudiohal/impl/EffectConversionHelperAidl.h
+++ b/media/libaudiohal/impl/EffectConversionHelperAidl.h
@@ -40,6 +40,7 @@
     std::shared_ptr<StatusMQ> getStatusMQ() { return mStatusQ; }
     std::shared_ptr<DataMQ> getInputMQ() { return mInputQ; }
     std::shared_ptr<DataMQ> getOutputMQ() { return mOutputQ; }
+    std::shared_ptr<android::hardware::EventFlag> getEventFlagGroup() { return mEfGroup; }
 
   protected:
     const int32_t mSessionId;
@@ -85,6 +86,17 @@
     std::shared_ptr<StatusMQ> mStatusQ = nullptr;
     std::shared_ptr<DataMQ> mInputQ = nullptr, mOutputQ = nullptr;
 
+
+    struct EventFlagDeleter {
+        void operator()(::android::hardware::EventFlag* flag) const {
+            if (flag) {
+                ::android::hardware::EventFlag::deleteEventFlag(&flag);
+            }
+        }
+    };
+    std::shared_ptr<android::hardware::EventFlag> mEfGroup = nullptr;
+    status_t updateEventFlags();
+
     status_t handleInit(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
                         void* pReplyData);
     status_t handleSetConfig(uint32_t cmdSize, const void* pCmdData, uint32_t* replySize,
@@ -121,6 +133,7 @@
     virtual status_t visualizerMeasure(uint32_t* replySize __unused, void* pReplyData __unused) {
         return BAD_VALUE;
     }
+
 };
 
 }  // namespace effect
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index d6135af..faf5f45 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -161,16 +161,17 @@
     return OK;
 }
 
-
 // write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
 status_t EffectHalAidl::process() {
     auto statusQ = mConversion->getStatusMQ();
     auto inputQ = mConversion->getInputMQ();
     auto outputQ = mConversion->getOutputMQ();
+    auto efGroup = mConversion->getEventFlagGroup();
     if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
-        !outputQ->isValid()) {
-        ALOGE("%s invalid FMQ [Status %d I %d O %d]", __func__, statusQ ? statusQ->isValid() : 0,
-              inputQ ? inputQ->isValid() : 0, outputQ ? outputQ->isValid() : 0);
+        !outputQ->isValid() || !efGroup) {
+        ALOGE("%s invalid FMQ [Status %d I %d O %d] efGroup %p", __func__,
+              statusQ ? statusQ->isValid() : 0, inputQ ? inputQ->isValid() : 0,
+              outputQ ? outputQ->isValid() : 0, efGroup.get());
         return INVALID_OPERATION;
     }
 
@@ -187,6 +188,7 @@
               floatsToWrite, mInBuffer->audioBuffer(), inputQ->availableToWrite());
         return INVALID_OPERATION;
     }
+    efGroup->wake(aidl::android::hardware::audio::effect::kEventFlagNotEmpty);
 
     IEffect::Status retStatus{};
     if (!statusQ->readBlocking(&retStatus, 1) || retStatus.status != OK ||
diff --git a/media/libaudiohal/impl/EffectHalAidl.h b/media/libaudiohal/impl/EffectHalAidl.h
index 8966363..47049d7 100644
--- a/media/libaudiohal/impl/EffectHalAidl.h
+++ b/media/libaudiohal/impl/EffectHalAidl.h
@@ -23,6 +23,7 @@
 #include <fmq/AidlMessageQueue.h>
 #include <media/audiohal/EffectHalInterface.h>
 #include <system/audio_effect.h>
+#include <system/audio_effects/aidl_effects_utils.h>
 
 #include "EffectConversionHelperAidl.h"
 
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 2c37349..6c43591 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -22,6 +22,7 @@
 
 #include <audio_utils/clock.h>
 #include <media/AidlConversion.h>
+#include <media/AidlConversionCore.h>
 #include <media/AidlConversionCppNdk.h>
 #include <media/AidlConversionNdk.h>
 #include <media/AidlConversionUtil.h>
@@ -167,9 +168,8 @@
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
     values->clear();
-    if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    // AIDL HAL doesn't support getParameters API.
+    return INVALID_OPERATION;
 }
 
 status_t StreamHalAidl::getFrameSize(size_t *size) {
@@ -599,11 +599,10 @@
     return statusTFromBinderStatus(mStream->setHwVolume({left, right}));
 }
 
-status_t StreamOutHalAidl::selectPresentation(int presentationId __unused, int programId __unused) {
+status_t StreamOutHalAidl::selectPresentation(int presentationId, int programId) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    return statusTFromBinderStatus(mStream->selectPresentation(presentationId, programId));
 }
 
 status_t StreamOutHalAidl::write(const void *buffer, size_t bytes, size_t *written) {
@@ -709,48 +708,61 @@
     return statusTFromBinderStatus(mStream->updateMetadata(aidlMetadata));
 }
 
-status_t StreamOutHalAidl::getDualMonoMode(audio_dual_mono_mode_t* mode __unused) {
+status_t StreamOutHalAidl::getDualMonoMode(audio_dual_mono_mode_t* mode) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
+    if (mode == nullptr) {
+        return BAD_VALUE;
+    }
+    ::aidl::android::media::audio::common::AudioDualMonoMode aidlMode;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mStream->getDualMonoMode(&aidlMode)));
+    *mode = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::aidl2legacy_AudioDualMonoMode_audio_dual_mono_mode_t(aidlMode));
     return OK;
 }
 
-status_t StreamOutHalAidl::setDualMonoMode(audio_dual_mono_mode_t mode __unused) {
+status_t StreamOutHalAidl::setDualMonoMode(audio_dual_mono_mode_t mode) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
+    ::aidl::android::media::audio::common::AudioDualMonoMode aidlMode = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::legacy2aidl_audio_dual_mono_mode_t_AudioDualMonoMode(mode));
+    return statusTFromBinderStatus(mStream->setDualMonoMode(aidlMode));
+}
+
+status_t StreamOutHalAidl::getAudioDescriptionMixLevel(float* leveldB) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    if (leveldB == nullptr) {
+        return BAD_VALUE;
+    }
+    return statusTFromBinderStatus(mStream->getAudioDescriptionMixLevel(leveldB));
+}
+
+status_t StreamOutHalAidl::setAudioDescriptionMixLevel(float leveldB) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    return statusTFromBinderStatus(mStream->setAudioDescriptionMixLevel(leveldB));
+}
+
+status_t StreamOutHalAidl::getPlaybackRateParameters(audio_playback_rate_t* playbackRate) {
+    TIME_CHECK();
+    if (!mStream) return NO_INIT;
+    if (playbackRate == nullptr) {
+        return BAD_VALUE;
+    }
+    ::aidl::android::media::audio::common::AudioPlaybackRate aidlRate;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mStream->getPlaybackRateParameters(&aidlRate)));
+    *playbackRate = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::aidl2legacy_AudioPlaybackRate_audio_playback_rate_t(aidlRate));
     return OK;
 }
 
-status_t StreamOutHalAidl::getAudioDescriptionMixLevel(float* leveldB __unused) {
+status_t StreamOutHalAidl::setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
-}
-
-status_t StreamOutHalAidl::setAudioDescriptionMixLevel(float leveldB __unused) {
-    TIME_CHECK();
-    if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
-}
-
-status_t StreamOutHalAidl::getPlaybackRateParameters(
-        audio_playback_rate_t* playbackRate __unused) {
-    TIME_CHECK();
-    if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return BAD_VALUE;
-}
-
-status_t StreamOutHalAidl::setPlaybackRateParameters(
-        const audio_playback_rate_t& playbackRate __unused) {
-    TIME_CHECK();
-    if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return BAD_VALUE;
+    ::aidl::android::media::audio::common::AudioPlaybackRate aidlRate = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::legacy2aidl_audio_playback_rate_t_AudioPlaybackRate(playbackRate));
+    return statusTFromBinderStatus(mStream->setPlaybackRateParameters(aidlRate));
 }
 
 status_t StreamOutHalAidl::setEventCallback(
@@ -763,18 +775,27 @@
     return OK;
 }
 
-status_t StreamOutHalAidl::setLatencyMode(audio_latency_mode_t mode __unused) {
+status_t StreamOutHalAidl::setLatencyMode(audio_latency_mode_t mode) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    ::aidl::android::media::audio::common::AudioLatencyMode aidlMode = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::legacy2aidl_audio_latency_mode_t_AudioLatencyMode(mode));
+    return statusTFromBinderStatus(mStream->setLatencyMode(aidlMode));
 };
 
-status_t StreamOutHalAidl::getRecommendedLatencyModes(
-        std::vector<audio_latency_mode_t> *modes __unused) {
+status_t StreamOutHalAidl::getRecommendedLatencyModes(std::vector<audio_latency_mode_t> *modes) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
+    if (modes == nullptr) {
+        return BAD_VALUE;
+    }
+    std::vector<::aidl::android::media::audio::common::AudioLatencyMode> aidlModes;
+    RETURN_STATUS_IF_ERROR(
+            statusTFromBinderStatus(mStream->getRecommendedLatencyModes(&aidlModes)));
+    *modes = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::convertContainer<std::vector<audio_latency_mode_t>>(
+                    aidlModes,
+                    ::aidl::android::aidl2legacy_AudioLatencyMode_audio_latency_mode_t));
     return OK;
 };
 
@@ -870,11 +891,10 @@
                 std::move(context), getStreamCommon(stream)),
           mStream(stream), mMicInfoProvider(micInfoProvider) {}
 
-status_t StreamInHalAidl::setGain(float gain __unused) {
+status_t StreamInHalAidl::setGain(float gain) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    return statusTFromBinderStatus(mStream->setHwGain({gain}));
 }
 
 status_t StreamInHalAidl::read(void *buffer, size_t bytes, size_t *read) {
@@ -947,19 +967,20 @@
     return statusTFromBinderStatus(mStream->updateMetadata(aidlMetadata));
 }
 
-status_t StreamInHalAidl::setPreferredMicrophoneDirection(
-            audio_microphone_direction_t direction __unused) {
+status_t StreamInHalAidl::setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    ::aidl::android::hardware::audio::core::IStreamIn::MicrophoneDirection aidlDirection =
+              VALUE_OR_RETURN_STATUS(
+                      ::aidl::android::legacy2aidl_audio_microphone_direction_t_MicrophoneDirection(
+                              direction));
+    return statusTFromBinderStatus(mStream->setMicrophoneDirection(aidlDirection));
 }
 
-status_t StreamInHalAidl::setPreferredMicrophoneFieldDimension(float zoom __unused) {
+status_t StreamInHalAidl::setPreferredMicrophoneFieldDimension(float zoom) {
     TIME_CHECK();
     if (!mStream) return NO_INIT;
-    ALOGE("%s not implemented yet", __func__);
-    return OK;
+    return statusTFromBinderStatus(mStream->setMicrophoneFieldDimension(zoom));
 }
 
 } // namespace android
diff --git a/media/libaudioprocessing/include/media/BufferProviders.h b/media/libaudioprocessing/include/media/BufferProviders.h
index 7a41002..a0b025f 100644
--- a/media/libaudioprocessing/include/media/BufferProviders.h
+++ b/media/libaudioprocessing/include/media/BufferProviders.h
@@ -143,7 +143,7 @@
     bool isValid() const { return mIsValid; }
 
 protected:
-    audio_utils::channels::ChannelMix mChannelMix;
+    audio_utils::channels::ChannelMix<AUDIO_CHANNEL_OUT_STEREO> mChannelMix;
     bool mIsValid = false;
 };
 
diff --git a/media/libeffects/downmix/EffectDownmix.cpp b/media/libeffects/downmix/EffectDownmix.cpp
index d8f5787..7f8455a 100644
--- a/media/libeffects/downmix/EffectDownmix.cpp
+++ b/media/libeffects/downmix/EffectDownmix.cpp
@@ -40,7 +40,7 @@
     downmix_type_t type;
     bool apply_volume_correction;
     uint8_t input_channel_count;
-    android::audio_utils::channels::ChannelMix channelMix;
+    android::audio_utils::channels::ChannelMix<AUDIO_CHANNEL_OUT_STEREO> channelMix;
 };
 
 typedef struct downmix_module_s {
diff --git a/media/libeffects/downmix/aidl/DownmixContext.h b/media/libeffects/downmix/aidl/DownmixContext.h
index 9a9f2da..1571c38 100644
--- a/media/libeffects/downmix/aidl/DownmixContext.h
+++ b/media/libeffects/downmix/aidl/DownmixContext.h
@@ -56,7 +56,7 @@
     DownmixState mState;
     Downmix::Type mType;
     ::aidl::android::media::audio::common::AudioChannelLayout mChMask;
-    ::android::audio_utils::channels::ChannelMix mChannelMix;
+    ::android::audio_utils::channels::ChannelMix<AUDIO_CHANNEL_OUT_STEREO> mChannelMix;
 
     // Common Params
     void init_params(const Parameter::Common& common);
diff --git a/media/libeffects/downmix/benchmark/downmix_benchmark.cpp b/media/libeffects/downmix/benchmark/downmix_benchmark.cpp
index d9d40ed..c4e0d65 100644
--- a/media/libeffects/downmix/benchmark/downmix_benchmark.cpp
+++ b/media/libeffects/downmix/benchmark/downmix_benchmark.cpp
@@ -60,34 +60,35 @@
 static constexpr size_t kFrameCount = 1000;
 
 /*
-Pixel 4XL
-$ adb shell /data/benchmarktest/downmix_benchmark/vendor/downmix_benchmark
+Pixel 7
+$ atest downmix_benchmark
 
 --------------------------------------------------------
 Benchmark              Time             CPU   Iterations
 --------------------------------------------------------
-BM_Downmix/0        3638 ns         3624 ns       197517 AUDIO_CHANNEL_OUT_MONO
-BM_Downmix/1        4040 ns         4024 ns       178766
-BM_Downmix/2        4759 ns         4740 ns       134741 AUDIO_CHANNEL_OUT_STEREO
-BM_Downmix/3        6042 ns         6017 ns       129546 AUDIO_CHANNEL_OUT_2POINT1
-BM_Downmix/4        6897 ns         6868 ns        96316 AUDIO_CHANNEL_OUT_2POINT0POINT2
-BM_Downmix/5        2117 ns         2109 ns       331705 AUDIO_CHANNEL_OUT_QUAD
-BM_Downmix/6        2097 ns         2088 ns       335421 AUDIO_CHANNEL_OUT_QUAD_SIDE
-BM_Downmix/7        7291 ns         7263 ns        96256 AUDIO_CHANNEL_OUT_SURROUND
-BM_Downmix/8        8246 ns         8206 ns        84318 AUDIO_CHANNEL_OUT_2POINT1POINT2
-BM_Downmix/9        8341 ns         8303 ns        84298 AUDIO_CHANNEL_OUT_3POINT0POINT2
-BM_Downmix/10       7549 ns         7517 ns        84293 AUDIO_CHANNEL_OUT_PENTA
-BM_Downmix/11       9395 ns         9354 ns        75209 AUDIO_CHANNEL_OUT_3POINT1POINT2
-BM_Downmix/12       3267 ns         3253 ns       215596 AUDIO_CHANNEL_OUT_5POINT1
-BM_Downmix/13       3178 ns         3163 ns       220132 AUDIO_CHANNEL_OUT_5POINT1_SIDE
-BM_Downmix/14      10245 ns        10199 ns        67486 AUDIO_CHANNEL_OUT_6POINT1
-BM_Downmix/15      10975 ns        10929 ns        61359 AUDIO_CHANNEL_OUT_5POINT1POINT2
-BM_Downmix/16       3796 ns         3780 ns       184728 AUDIO_CHANNEL_OUT_7POINT1
-BM_Downmix/17      13562 ns        13503 ns        51823 AUDIO_CHANNEL_OUT_5POINT1POINT4
-BM_Downmix/18      13573 ns        13516 ns        51800 AUDIO_CHANNEL_OUT_7POINT1POINT2
-BM_Downmix/19      15502 ns        15435 ns        47147 AUDIO_CHANNEL_OUT_7POINT1POINT4
-BM_Downmix/20      16693 ns        16624 ns        42109 AUDIO_CHANNEL_OUT_13POINT_360RA
-BM_Downmix/21      28267 ns        28116 ns        24982 AUDIO_CHANNEL_OUT_22POINT2
+downmix_benchmark:
+  #BM_Downmix/0     2216 ns    2208 ns       308323
+  #BM_Downmix/1     2237 ns    2228 ns       314730
+  #BM_Downmix/2      270 ns     268 ns      2681469
+  #BM_Downmix/3     3016 ns    2999 ns       234146
+  #BM_Downmix/4     3331 ns    3313 ns       212026
+  #BM_Downmix/5      816 ns     809 ns       864395
+  #BM_Downmix/6      813 ns     809 ns       863876
+  #BM_Downmix/7     3336 ns    3319 ns       211938
+  #BM_Downmix/8     3786 ns    3762 ns       185047
+  #BM_Downmix/9     3810 ns    3797 ns       186840
+  #BM_Downmix/10    3767 ns    3746 ns       187015
+  #BM_Downmix/11    4212 ns    4191 ns       166119
+  #BM_Downmix/12    1245 ns    1231 ns       574388
+  #BM_Downmix/13    1234 ns    1228 ns       574743
+  #BM_Downmix/14    4795 ns    4771 ns       147157
+  #BM_Downmix/15    1334 ns    1327 ns       527728
+  #BM_Downmix/16    1346 ns    1332 ns       525444
+  #BM_Downmix/17    2144 ns    2121 ns       333343
+  #BM_Downmix/18    2133 ns    2118 ns       330391
+  #BM_Downmix/19    2527 ns    2513 ns       278553
+  #BM_Downmix/20    8148 ns    8113 ns        86136
+  #BM_Downmix/21    6332 ns    6301 ns       111134
 */
 
 static void BM_Downmix(benchmark::State& state) {
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 569a25f..ec6a00a 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -79,6 +79,7 @@
     },
 }
 
+// this library gets wrapped into libstagefright as well as modules
 cc_library_static {
     name: "libstagefright_mpeg2extractor",
     apex_available: [
@@ -241,7 +242,6 @@
         "CodecErrorLog.cpp",
         "CryptoAsync.cpp",
         "FrameDecoder.cpp",
-        "HevcUtils.cpp",
         "InterfaceUtils.cpp",
         "JPEGSource.cpp",
         "MPEG2TSWriter.cpp",
@@ -255,7 +255,6 @@
         "MediaCodecSource.cpp",
         "MediaExtractor.cpp",
         "MediaExtractorFactory.cpp",
-        "MediaSource.cpp",
         "MediaSync.cpp",
         "MediaTrack.cpp",
         "MediaMuxer.cpp",
@@ -269,7 +268,6 @@
         "StagefrightMediaScanner.cpp",
         "SurfaceUtils.cpp",
         "ThrottledSource.cpp",
-        "Utils.cpp",
         "VideoFrameSchedulerBase.cpp",
         "VideoFrameScheduler.cpp",
     ],
@@ -328,6 +326,11 @@
         "libmedia_ndkformatpriv",
     ],
 
+    // to get Utils, MediaSource, HevcUtils
+    whole_static_libs: [
+        "libstagefright_mpeg2extractor",
+    ],
+
     header_libs:[
         "libmediadrm_headers",
         "libnativeloader-headers",
diff --git a/media/utils/include/mediautils/SharedMemoryAllocator.h b/media/utils/include/mediautils/SharedMemoryAllocator.h
index 17c1ac9..79621e2 100644
--- a/media/utils/include/mediautils/SharedMemoryAllocator.h
+++ b/media/utils/include/mediautils/SharedMemoryAllocator.h
@@ -22,6 +22,7 @@
 
 #include <iomanip>
 #include <limits>
+#include <mutex>
 #include <sstream>
 #include <string>
 #include <type_traits>
@@ -109,13 +110,14 @@
 // TODO is there some way to avoid paying this cost?
 template <typename Allocator>
 class ScopedAllocator;
-template <typename AllocationT, typename AllocatorHandleType>
+
 class ScopedAllocation : public BnMemory {
   public:
     template <typename T>
     friend class ScopedAllocator;
-    ScopedAllocation(const AllocationT& allocation, const AllocatorHandleType& handle)
-        : mAllocation(allocation), mHandle(handle) {}
+    template <typename Deallocator>
+    ScopedAllocation(const AllocationType& allocation, Deallocator&& deallocator)
+        : mAllocation(allocation), mDeallocator(std::forward<Deallocator>(deallocator)) {}
 
     // Defer the implementation to the underlying mAllocation
 
@@ -125,10 +127,10 @@
     }
 
   private:
-    ~ScopedAllocation() override { mHandle->deallocate(mAllocation); }
+    ~ScopedAllocation() override { mDeallocator(mAllocation); }
 
-    const AllocationT mAllocation;
-    const AllocatorHandleType mHandle;
+    const AllocationType mAllocation;
+    const std::function<void(const AllocationType&)> mDeallocator;
 };
 
 // Allocations are only deallocated when going out of scope.
@@ -136,7 +138,6 @@
 template <typename Allocator>
 class ScopedAllocator {
   public:
-    using HandleT = std::shared_ptr<Allocator>;
     static constexpr size_t alignment() { return Allocator::alignment(); }
 
     explicit ScopedAllocator(const std::shared_ptr<Allocator>& allocator) : mAllocator(allocator) {}
@@ -145,11 +146,16 @@
 
     template <typename T>
     auto allocate(T&& request) {
+        std::lock_guard l{*mLock};
         const auto allocation = mAllocator->allocate(std::forward<T>(request));
         if (!allocation) {
-            return sp<ScopedAllocation<AllocationType, HandleT>>{};
+            return sp<ScopedAllocation>{};
         }
-        return sp<ScopedAllocation<AllocationType, HandleT>>::make(allocation, mAllocator);
+        return sp<ScopedAllocation>::make(allocation,
+                [allocator = mAllocator, lock = mLock] (const AllocationType& allocation) {
+                    std::lock_guard l{*lock};
+                    allocator->deallocate(allocation);
+                });
     }
 
     // Deallocate and deallocate_all are implicitly unsafe due to double
@@ -159,20 +165,23 @@
     //
     // Owns is only safe to pseudo-impl due to static cast reqs
     template <typename Enable = bool>
-    auto owns(const sp<ScopedAllocation<AllocationType, HandleT>>& allocation) const
+    auto owns(const sp<ScopedAllocation>& allocation) const
             -> std::enable_if_t<shared_allocator_impl::has_owns<Allocator>, Enable> {
+        std::lock_guard l{*mLock};
         return mAllocator->owns(allocation->mAllocation);
     }
 
     template <typename Enable = std::string>
     auto dump() const -> std::enable_if_t<shared_allocator_impl::has_dump<Allocator>, Enable> {
+        std::lock_guard l{*mLock};
         return mAllocator->dump();
     }
 
   private:
     // We store a shared pointer in order to ensure that the allocator outlives
     // allocations (which call back to become dereferenced).
-    const HandleT mAllocator;
+    const std::shared_ptr<Allocator> mAllocator;
+    const std::shared_ptr<std::mutex> mLock = std::make_shared<std::mutex>();
 };
 
 // A simple policy for PolicyAllocator which enforces a pool size and an allocation
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 077fa26..323ce0e 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -425,6 +425,8 @@
 
     bool        btNrecIsOff() const { return mBtNrecIsOff.load(); }
 
+    void             lock() ACQUIRE(mLock) { mLock.lock(); }
+    void             unlock() RELEASE(mLock) { mLock.unlock(); }
 
 private:
 
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index 3d5aae2..496aedc 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -92,7 +92,8 @@
     switch (device) {
         case AUDIO_DEVICE_OUT_WIRED_HEADSET:
         case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
+        // TODO(b/278265907): enable A2DP when we can distinguish A2DP headsets
+        // case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
         case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
         case AUDIO_DEVICE_OUT_HEARING_AID:
         case AUDIO_DEVICE_OUT_USB_HEADSET:
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 3b428bb..d25d46f 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -135,6 +135,10 @@
 status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *patch,
                                    audio_patch_handle_t *handle,
                                    bool endpointPatch)
+ //unlocks AudioFlinger::mLock when calling ThreadBase::sendCreateAudioPatchConfigEvent
+ //to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock
+ //before processing the create patch request.
+ NO_THREAD_SAFETY_ANALYSIS
 {
     if (handle == NULL || patch == NULL) {
         return BAD_VALUE;
@@ -245,7 +249,6 @@
                         status = INVALID_OPERATION;
                         goto exit;
                     }
-
                     sp<ThreadBase> thread =
                             mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
                     if (thread == 0) {
@@ -356,11 +359,12 @@
                             goto exit;
                         }
                     }
+                    mAudioFlinger.unlock();
                     status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
+                    mAudioFlinger.lock();
                     if (status == NO_ERROR) {
                         newPatch.setThread(thread);
                     }
-
                     // remove stale audio patch with same input as sink if any
                     for (auto& iter : mPatches) {
                         if (iter.second.mAudioPatch.sinks[0].ext.mix.handle == thread->id()) {
@@ -422,7 +426,9 @@
                 mAudioFlinger.updateOutDevicesForRecordThreads_l(devices);
             }
 
+            mAudioFlinger.unlock();
             status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
+            mAudioFlinger.lock();
             if (status == NO_ERROR) {
                 newPatch.setThread(thread);
             }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 76c9ad8..de0abf0 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4976,7 +4976,7 @@
         const NBAIO_Format offersFast[1] = {format};
         size_t numCounterOffersFast = 0;
 #if !LOG_NDEBUG
-        ssize_t index =
+        index =
 #else
         (void)
 #endif
@@ -7874,15 +7874,15 @@
         Pipe *pipe = new Pipe(pipeFramesP2, format, pipeBuffer);
         const NBAIO_Format offersFast[1] = {format};
         size_t numCounterOffersFast = 0;
-        [[maybe_unused]] ssize_t index = pipe->negotiate(offersFast, std::size(offersFast),
+        [[maybe_unused]] ssize_t index2 = pipe->negotiate(offersFast, std::size(offersFast),
                 nullptr /* counterOffers */, numCounterOffersFast);
-        ALOG_ASSERT(index == 0);
+        ALOG_ASSERT(index2 == 0);
         mPipeSink = pipe;
         PipeReader *pipeReader = new PipeReader(*pipe);
         numCounterOffersFast = 0;
-        index = pipeReader->negotiate(offersFast, std::size(offersFast),
+        index2 = pipeReader->negotiate(offersFast, std::size(offersFast),
                 nullptr /* counterOffers */, numCounterOffersFast);
-        ALOG_ASSERT(index == 0);
+        ALOG_ASSERT(index2 == 0);
         mPipeSource = pipeReader;
         mPipeFramesP2 = pipeFramesP2;
         mPipeMemory = pipeMemory;
@@ -9297,7 +9297,7 @@
     if (stepCount == 0) {
         return;
     }
-    ALOG_ASSERT(stepCount <= mRsmpInUnrel);
+    ALOG_ASSERT(stepCount <= (int32_t)mRsmpInUnrel);
     mRsmpInUnrel -= stepCount;
     mRsmpInFront = audio_utils::safe_add_overflow(mRsmpInFront, stepCount);
     buffer->raw = NULL;
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index de8e77f..d266e63 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -218,12 +218,15 @@
         return *(deviceTypes.begin());
     } else {
         // Multiple device selection is either:
+        //  - dock + one other device: give priority to dock in this case.
         //  - speaker + one other device: give priority to speaker in this case.
         //  - one A2DP device + another device: happens with duplicated output. In this case
         // retain the device on the A2DP output as the other must not correspond to an active
         // selection if not the speaker.
         //  - HDMI-CEC system audio mode only output: give priority to available item in order.
-        if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER) != 0) {
+        if (deviceTypes.count(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) != 0) {
+            return AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
+        } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER) != 0) {
             return AUDIO_DEVICE_OUT_SPEAKER;
         } else if (deviceTypes.count(AUDIO_DEVICE_OUT_SPEAKER_SAFE) != 0) {
             return AUDIO_DEVICE_OUT_SPEAKER_SAFE;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index cc8b1a1..56a692b 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -6471,6 +6471,14 @@
     }
 
     if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+        // first call getAudioPort to get the supported attributes from the HAL
+        struct audio_port_v7 port = {};
+        device->toAudioPort(&port);
+        status_t status = mpClientInterface->getAudioPort(&port);
+        if (status == NO_ERROR) {
+            device->importAudioPort(port);
+        }
+
         // look for input profiles that can be routed to this device
         SortedVector< sp<IOProfile> > profiles;
         for (const auto& hwModule : mHwModules) {
@@ -6522,11 +6530,7 @@
 
             desc = new AudioInputDescriptor(profile, mpClientInterface);
             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
-            status_t status = desc->open(nullptr,
-                                         device,
-                                         AUDIO_SOURCE_MIC,
-                                         AUDIO_INPUT_FLAG_NONE,
-                                         &input);
+            status = desc->open(nullptr, device, AUDIO_SOURCE_MIC, AUDIO_INPUT_FLAG_NONE, &input);
 
             if (status == NO_ERROR) {
                 const String8& address = String8(device->address().c_str());
@@ -8073,12 +8077,17 @@
                 ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
         ALOGV("%s: supported formats %d, %s", __FUNCTION__, ioHandle, reply.string());
         AudioParameter repliedParameters(reply);
+        FormatVector formats;
         if (repliedParameters.get(
-                String8(AudioParameter::keyStreamSupportedFormats), reply) != NO_ERROR) {
-            ALOGE("%s: failed to retrieve format, bailing out", __FUNCTION__);
+                String8(AudioParameter::keyStreamSupportedFormats), reply) == NO_ERROR) {
+            formats = formatsFromString(reply.string());
+        } else if (devDesc->hasValidAudioProfile()) {
+            ALOGD("%s: using the device profiles", __func__);
+            formats = devDesc->getAudioProfiles().getSupportedFormats();
+        } else {
+            ALOGE("%s: failed to retrieve format, bailing out", __func__);
             return;
         }
-        FormatVector formats = formatsFromString(reply.string());
         mReportedFormatsMap[devDesc] = formats;
         if (device == AUDIO_DEVICE_OUT_HDMI
                 || isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD)) {
@@ -8088,7 +8097,7 @@
     }
 
     for (audio_format_t format : profiles.getSupportedFormats()) {
-        ChannelMaskSet channelMasks;
+        std::optional<ChannelMaskSet> channelMasks;
         SampleRateSet samplingRates;
         AudioParameter requestedParameters;
         requestedParameters.addInt(String8(AudioParameter::keyFormat), format);
@@ -8103,6 +8112,8 @@
             if (repliedParameters.get(
                     String8(AudioParameter::keyStreamSupportedSamplingRates), reply) == NO_ERROR) {
                 samplingRates = samplingRatesFromString(reply.string());
+            } else {
+                samplingRates = devDesc->getAudioProfiles().getSampleRatesFor(format);
             }
         }
         if (profiles.hasDynamicChannelsFor(format)) {
@@ -8114,14 +8125,17 @@
             if (repliedParameters.get(
                     String8(AudioParameter::keyStreamSupportedChannels), reply) == NO_ERROR) {
                 channelMasks = channelMasksFromString(reply.string());
-                if (device == AUDIO_DEVICE_OUT_HDMI
-                        || isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD)) {
-                    modifySurroundChannelMasks(&channelMasks);
-                }
+            } else {
+                channelMasks = devDesc->getAudioProfiles().getChannelMasksFor(format);
+            }
+            if (channelMasks.has_value() && (device == AUDIO_DEVICE_OUT_HDMI
+                    || isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD))) {
+                modifySurroundChannelMasks(&channelMasks.value());
             }
         }
         addDynamicAudioProfileAndSort(
-                profiles, new AudioProfile(format, channelMasks, samplingRates));
+                profiles, new AudioProfile(
+                        format, channelMasks.value_or(ChannelMaskSet()), samplingRates));
     }
 }
 
diff --git a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
index 5794747..8a65a67 100644
--- a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
@@ -299,14 +299,11 @@
     p010.height = inputFrame.p010Buffer.height;
     p010.width = inputFrame.p010Buffer.width;
     p010.colorGamut = jpegrecoverymap::jpegr_color_gamut::JPEGR_COLORGAMUT_BT2100;
-    size_t yChannelSizeInByte = p010.width * p010.height * 2;
-    size_t uvChannelSizeInByte = p010.width * p010.height;
-    p010.data = new uint8_t[yChannelSizeInByte + uvChannelSizeInByte];
-    std::unique_ptr<uint8_t[]> p010_data;
-    p010_data.reset(reinterpret_cast<uint8_t*>(p010.data));
-    memcpy((uint8_t*)p010.data, inputFrame.p010Buffer.data, yChannelSizeInByte);
-    memcpy((uint8_t*)p010.data + yChannelSizeInByte, inputFrame.p010Buffer.dataCb,
-           uvChannelSizeInByte);
+    p010.data = inputFrame.p010Buffer.data;
+    p010.chroma_data = inputFrame.p010Buffer.dataCb;
+    // Strides are expected to be in pixels not bytes
+    p010.luma_stride = inputFrame.p010Buffer.stride / 2;
+    p010.chroma_stride = inputFrame.p010Buffer.chromaStride / 2;
 
     jpegR.data = dstBuffer;
     jpegR.maxLength = maxJpegRBufferSize;
@@ -367,7 +364,6 @@
     }
 
     actualJpegRSize = jpegR.length;
-    p010_data.release();
 
     size_t finalJpegRSize = actualJpegRSize + sizeof(CameraBlob);
     if (finalJpegRSize > maxJpegRBufferSize) {