diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 1689365..fb1cc34 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -319,6 +319,7 @@
         "ConversionHelperAidl.cpp",
         "DeviceHalAidl.cpp",
         "DevicesFactoryHalAidl.cpp",
+        "Hal2AidlMapper.cpp",
         "StreamHalAidl.cpp",
     ],
 }
diff --git a/media/libaudiohal/impl/Cleanups.h b/media/libaudiohal/impl/Cleanups.h
new file mode 100644
index 0000000..a313da1
--- /dev/null
+++ b/media/libaudiohal/impl/Cleanups.h
@@ -0,0 +1,107 @@
+/*
+ * 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
+
+#include <forward_list>
+#include <mutex>
+#include <utility>
+
+namespace android {
+
+// This class implements the "monitor" idiom for providing locked access to a class instance.
+// This is how it is intended to be used. Let's assume there is a "Main" class which owns
+// an instance of a "Resource" class, which is protected by a mutex. We add an instance of
+// "LockedAccessor<Resource>" as a member of "Main":
+//
+// class Resource;
+//
+// class Main {
+//     Main() : mAccessor(mResource, mLock) {}
+//   private:
+//     std::mutex mLock;
+//     Resource mResource GUARDED_BY(mLock);  // owns the resource
+//     LockedAccessor<Resource> mAccessor;
+// };
+//
+// The accessor is initialized in the constructor when no locking is needed. The accessor
+// defers locking until the resource is accessed.
+//
+// Although "mAccessor" can be used by the methods of "Main" for scoped access to the resource,
+// its main role is for granting access to the resource to other classes. This is achieved by
+// making a copy of "mAccessor" and giving it away to another class. This obviously does not
+// transfer ownership of the resource. The intent is to allow another class to use the resource
+// with proper locking in a "lazy" fashion:
+//
+// class Another {
+//   public:
+//     Another(const LockedAccessor<Resource>& accessor) : mAccessor(accessor) {}
+//     void doItLater() {  // Use explicit 'lock' / 'unlock'
+//         auto resource = mAccessor.lock();
+//         resource.use();
+//         mAccessor.unlock();
+//     }
+//     void doItLaterScoped() {  // Rely on the scoped accessor do perform unlocking.
+//         LockedAccessor<Resource> scopedAccessor(mAccessor);
+//         auto resource = scopedAccessor.lock();
+//         resource.use();
+//     }
+//   private:
+//     LockedAccessor<Resource> mAccessor;
+// };
+//
+template<class C>
+class LockedAccessor {
+  public:
+    LockedAccessor(C& instance, std::mutex& mutex)
+            : mInstance(instance), mMutex(mutex), mLock(mMutex, std::defer_lock) {}
+    LockedAccessor(const LockedAccessor& other)
+            : mInstance(other.mInstance), mMutex(other.mMutex), mLock(mMutex, std::defer_lock) {}
+    ~LockedAccessor() { if (mLock.owns_lock()) mLock.unlock(); }
+    C& lock() { mLock.lock(); return mInstance; }
+    void unlock() { mLock.unlock(); }
+  private:
+    C& mInstance;
+    std::mutex& mMutex;
+    std::unique_lock<std::mutex> mLock;
+};
+
+// This class implements scoped cleanups. A "cleanup" is a call to a method of class "C" which
+// takes an integer parameter. Cleanups are executed in the reverse order to how they were added.
+// For executing cleanups, the instance of "C" is retrieved via the provided "LockedAccessor".
+template<class C>
+class Cleanups {
+  public:
+    typedef void (C::*Cleaner)(int32_t);  // A member function of "C" performing a cleanup action.
+    explicit Cleanups(const LockedAccessor<C>& accessor) : mAccessor(accessor) {}
+    ~Cleanups() {
+        if (!mCleanups.empty()) {
+            C& c = mAccessor.lock();
+            for (auto& cleanup : mCleanups) (c.*cleanup.first)(cleanup.second);
+            mAccessor.unlock();
+        }
+    }
+    void add(Cleaner cleaner, int32_t id) {
+        mCleanups.emplace_front(cleaner, id);
+    }
+    void disarmAll() { mCleanups.clear(); }
+  private:
+    using Cleanup = std::pair<Cleaner, int32_t>;
+    LockedAccessor<C> mAccessor;
+    std::forward_list<Cleanup> mCleanups;
+};
+
+}  // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalAidl.cpp b/media/libaudiohal/impl/DeviceHalAidl.cpp
index 5bc25ae..bd95e9d 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalAidl.cpp
@@ -18,7 +18,6 @@
 // #define LOG_NDEBUG 0
 
 #include <algorithm>
-#include <forward_list>
 
 #include <aidl/android/hardware/audio/core/BnStreamCallback.h>
 #include <aidl/android/hardware/audio/core/BnStreamOutEventCallback.h>
@@ -38,15 +37,9 @@
 
 using aidl::android::aidl_utils::statusTFromBinderStatus;
 using aidl::android::media::audio::common::Boolean;
-using aidl::android::media::audio::common::AudioChannelLayout;
 using aidl::android::media::audio::common::AudioConfig;
 using aidl::android::media::audio::common::AudioDevice;
-using aidl::android::media::audio::common::AudioDeviceAddress;
-using aidl::android::media::audio::common::AudioDeviceDescription;
 using aidl::android::media::audio::common::AudioDeviceType;
-using aidl::android::media::audio::common::AudioFormatDescription;
-using aidl::android::media::audio::common::AudioFormatType;
-using aidl::android::media::audio::common::AudioInputFlags;
 using aidl::android::media::audio::common::AudioIoFlags;
 using aidl::android::media::audio::common::AudioLatencyMode;
 using aidl::android::media::audio::common::AudioMMapPolicy;
@@ -56,11 +49,7 @@
 using aidl::android::media::audio::common::AudioOutputFlags;
 using aidl::android::media::audio::common::AudioPort;
 using aidl::android::media::audio::common::AudioPortConfig;
-using aidl::android::media::audio::common::AudioPortDeviceExt;
 using aidl::android::media::audio::common::AudioPortExt;
-using aidl::android::media::audio::common::AudioPortMixExt;
-using aidl::android::media::audio::common::AudioPortMixExtUseCase;
-using aidl::android::media::audio::common::AudioProfile;
 using aidl::android::media::audio::common::AudioSource;
 using aidl::android::media::audio::common::Float;
 using aidl::android::media::audio::common::Int;
@@ -69,9 +58,8 @@
 using aidl::android::media::audio::IHalAdapterVendorExtension;
 using aidl::android::hardware::audio::common::getFrameSizeInBytes;
 using aidl::android::hardware::audio::common::isBitPositionFlagSet;
-using aidl::android::hardware::audio::common::isDefaultAudioFormat;
-using aidl::android::hardware::audio::common::makeBitPositionFlagMask;
 using aidl::android::hardware::audio::common::RecordTrackMetadata;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
 using aidl::android::hardware::audio::core::AudioPatch;
 using aidl::android::hardware::audio::core::AudioRoute;
 using aidl::android::hardware::audio::core::IBluetooth;
@@ -80,37 +68,12 @@
 using aidl::android::hardware::audio::core::IModule;
 using aidl::android::hardware::audio::core::ITelephony;
 using aidl::android::hardware::audio::core::ModuleDebug;
-using aidl::android::hardware::audio::core::StreamDescriptor;
 using aidl::android::hardware::audio::core::VendorParameter;
 
 namespace android {
 
 namespace {
 
-bool isConfigEqualToPortConfig(const AudioConfig& config, const AudioPortConfig& portConfig) {
-    return portConfig.sampleRate.value().value == config.base.sampleRate &&
-            portConfig.channelMask.value() == config.base.channelMask &&
-            portConfig.format.value() == config.base.format;
-}
-
-void setConfigFromPortConfig(AudioConfig* config, const AudioPortConfig& portConfig) {
-    config->base.sampleRate = portConfig.sampleRate.value().value;
-    config->base.channelMask = portConfig.channelMask.value();
-    config->base.format = portConfig.format.value();
-}
-
-void setPortConfigFromConfig(AudioPortConfig* portConfig, const AudioConfig& config) {
-    if (config.base.sampleRate != 0) {
-        portConfig->sampleRate = Int{ .value = config.base.sampleRate };
-    }
-    if (config.base.channelMask != AudioChannelLayout{}) {
-        portConfig->channelMask = config.base.channelMask;
-    }
-    if (config.base.format != AudioFormatDescription{}) {
-        portConfig->format = config.base.format;
-    }
-}
-
 // Note: these converters are for types defined in different AIDL files. Although these
 // AIDL files are copies of each other, however formally these are different types
 // thus we don't use a conversion via a parcelable.
@@ -144,28 +107,29 @@
           mTelephony(retrieveSubInterface<ITelephony>(module, &IModule::getTelephony)),
           mBluetooth(retrieveSubInterface<IBluetooth>(module, &IModule::getBluetooth)),
           mBluetoothA2dp(retrieveSubInterface<IBluetoothA2dp>(module, &IModule::getBluetoothA2dp)),
-          mBluetoothLe(retrieveSubInterface<IBluetoothLe>(module, &IModule::getBluetoothLe)) {
+          mBluetoothLe(retrieveSubInterface<IBluetoothLe>(module, &IModule::getBluetoothLe)),
+          mSoundDose(retrieveSubInterface<ISoundDose>(module, &IModule::getSoundDose)),
+          mMapper(instance, module), mMapperAccessor(mMapper, mLock) {
 }
 
 status_t DeviceHalAidl::getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) {
-    return ::aidl::android::convertContainer(mPorts, ports,
-            [](const Ports::value_type& pair) { return ndk2cpp_AudioPort(pair.second); });
+    std::lock_guard l(mLock);
+    return mMapper.getAudioPorts(ports, ndk2cpp_AudioPort);
 }
 
 status_t DeviceHalAidl::getAudioRoutes(std::vector<media::AudioRoute> *routes) {
-    *routes = VALUE_OR_RETURN_STATUS(
-            ::aidl::android::convertContainer<std::vector<media::AudioRoute>>(
-                    mRoutes, ndk2cpp_AudioRoute));
-    return OK;
+    std::lock_guard l(mLock);
+    return mMapper.getAudioRoutes(routes, ndk2cpp_AudioRoute);
 }
 
 status_t DeviceHalAidl::getSupportedModes(std::vector<media::audio::common::AudioMode> *modes) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
+    if (mModule == nullptr) return NO_INIT;
+    if (mTelephony == nullptr) return INVALID_OPERATION;
     if (modes == nullptr) {
         return BAD_VALUE;
     }
-    if (mModule == nullptr) return NO_INIT;
-    if (mTelephony == nullptr) return INVALID_OPERATION;
     std::vector<AudioMode> aidlModes;
     RETURN_STATUS_IF_ERROR(
             statusTFromBinderStatus(mTelephony->getSupportedAudioModes(&aidlModes)));
@@ -181,105 +145,17 @@
 }
 
 status_t DeviceHalAidl::initCheck() {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
     if (mModule == nullptr) return NO_INIT;
-    std::vector<AudioPort> ports;
-    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
-    ALOGW_IF(ports.empty(), "%s: module %s returned an empty list of audio ports",
-            __func__, mInstance.c_str());
-    mDefaultInputPortId = mDefaultOutputPortId = -1;
-    const int defaultDeviceFlag = 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
-    for (auto it = ports.begin(); it != ports.end(); ) {
-        const auto& port = *it;
-        if (port.ext.getTag() != AudioPortExt::Tag::device) {
-            ++it;
-            continue;
-        }
-        const AudioPortDeviceExt& deviceExt = port.ext.get<AudioPortExt::Tag::device>();
-        if ((deviceExt.flags & defaultDeviceFlag) != 0) {
-            if (port.flags.getTag() == AudioIoFlags::Tag::input) {
-                mDefaultInputPortId = port.id;
-            } else if (port.flags.getTag() == AudioIoFlags::Tag::output) {
-                mDefaultOutputPortId = port.id;
-            }
-        }
-        // For compatibility with HIDL, hide "template" remote submix ports from ports list.
-        if (const auto& devDesc = deviceExt.device;
-                (devDesc.type.type == AudioDeviceType::IN_SUBMIX ||
-                        devDesc.type.type == AudioDeviceType::OUT_SUBMIX) &&
-                devDesc.type.connection == AudioDeviceDescription::CONNECTION_VIRTUAL) {
-            if (devDesc.type.type == AudioDeviceType::IN_SUBMIX) {
-                mRemoteSubmixIn = port;
-            } else {
-                mRemoteSubmixOut = port;
-            }
-            it = ports.erase(it);
-        } else {
-            ++it;
-        }
-    }
-    if (mRemoteSubmixIn.has_value() != mRemoteSubmixOut.has_value()) {
-        ALOGE("%s: The configuration only has input or output remote submix device, must have both",
-                __func__);
-        mRemoteSubmixIn.reset();
-        mRemoteSubmixOut.reset();
-    }
-    if (mRemoteSubmixIn.has_value()) {
-        AudioPort connectedRSubmixIn = *mRemoteSubmixIn;
-        connectedRSubmixIn.ext.get<AudioPortExt::Tag::device>().device.address =
-                AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS;
-        ALOGD("%s: connecting remote submix input", __func__);
-        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->connectExternalDevice(
-                                connectedRSubmixIn, &connectedRSubmixIn)));
-        // The template port for the remote submix input couldn't be "default" because it is not
-        // attached. The connected port can now be made default because we never disconnect it.
-        if (mDefaultInputPortId == -1) {
-            mDefaultInputPortId = connectedRSubmixIn.id;
-        }
-        ports.push_back(std::move(connectedRSubmixIn));
-
-        // Remote submix output must not be connected until the framework actually starts
-        // using it, however for legacy compatibility we need to provide an "augmented template"
-        // port with an address and profiles. It is obtained by connecting the output and then
-        // immediately disconnecting it. This is a cheap operation as we don't open any streams.
-        AudioPort tempConnectedRSubmixOut = *mRemoteSubmixOut;
-        tempConnectedRSubmixOut.ext.get<AudioPortExt::Tag::device>().device.address =
-                AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS;
-        ALOGD("%s: temporarily connecting and disconnecting remote submix output", __func__);
-        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->connectExternalDevice(
-                                tempConnectedRSubmixOut, &tempConnectedRSubmixOut)));
-        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->disconnectExternalDevice(
-                                tempConnectedRSubmixOut.id)));
-        tempConnectedRSubmixOut.id = mRemoteSubmixOut->id;
-        ports.push_back(std::move(tempConnectedRSubmixOut));
-    }
-
-    ALOGI("%s: module %s default port ids: input %d, output %d",
-            __func__, mInstance.c_str(), mDefaultInputPortId, mDefaultOutputPortId);
-    std::transform(ports.begin(), ports.end(), std::inserter(mPorts, mPorts.end()),
-            [](const auto& p) { return std::make_pair(p.id, p); });
-    RETURN_STATUS_IF_ERROR(updateRoutes());
-    std::vector<AudioPortConfig> portConfigs;
-    RETURN_STATUS_IF_ERROR(
-            statusTFromBinderStatus(mModule->getAudioPortConfigs(&portConfigs)));  // OK if empty
-    std::transform(portConfigs.begin(), portConfigs.end(),
-            std::inserter(mPortConfigs, mPortConfigs.end()),
-            [](const auto& p) { return std::make_pair(p.id, p); });
-    std::transform(mPortConfigs.begin(), mPortConfigs.end(),
-            std::inserter(mInitialPortConfigIds, mInitialPortConfigIds.end()),
-            [](const auto& pcPair) { return pcPair.first; });
-    std::vector<AudioPatch> patches;
-    RETURN_STATUS_IF_ERROR(
-            statusTFromBinderStatus(mModule->getAudioPatches(&patches)));  // OK if empty
-    std::transform(patches.begin(), patches.end(),
-            std::inserter(mPatches, mPatches.end()),
-            [](const auto& p) { return std::make_pair(p.id, p); });
-    return OK;
+    std::lock_guard l(mLock);
+    return mMapper.initialize();
 }
 
 status_t DeviceHalAidl::setVoiceVolume(float volume) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     if (mTelephony == nullptr) return INVALID_OPERATION;
     ITelephony::TelecomConfig inConfig{ .voiceVolume = Float{volume} }, outConfig;
     RETURN_STATUS_IF_ERROR(
@@ -291,20 +167,26 @@
 }
 
 status_t DeviceHalAidl::setMasterVolume(float volume) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     return statusTFromBinderStatus(mModule->setMasterVolume(volume));
 }
 
 status_t DeviceHalAidl::getMasterVolume(float *volume) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
+    if (volume == nullptr) {
+        return BAD_VALUE;
+    }
     return statusTFromBinderStatus(mModule->getMasterVolume(volume));
 }
 
 status_t DeviceHalAidl::setMode(audio_mode_t mode) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     AudioMode audioMode = VALUE_OR_FATAL(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
     if (mTelephony != nullptr) {
         RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mTelephony->switchAudioMode(audioMode)));
@@ -313,31 +195,43 @@
 }
 
 status_t DeviceHalAidl::setMicMute(bool state) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     return statusTFromBinderStatus(mModule->setMicMute(state));
 }
 
 status_t DeviceHalAidl::getMicMute(bool *state) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
+    if (state == nullptr) {
+        return BAD_VALUE;
+    }
     return statusTFromBinderStatus(mModule->getMicMute(state));
 }
 
 status_t DeviceHalAidl::setMasterMute(bool state) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     return statusTFromBinderStatus(mModule->setMasterMute(state));
 }
 
 status_t DeviceHalAidl::getMasterMute(bool *state) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
+    if (state == nullptr) {
+        return BAD_VALUE;
+    }
     return statusTFromBinderStatus(mModule->getMasterMute(state));
 }
 
 status_t DeviceHalAidl::setParameters(const String8& kvPairs) {
-    if (!mModule) return NO_INIT;
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
+    TIME_CHECK();
+    if (mModule == nullptr) return NO_INIT;
     AudioParameter parameters(kvPairs);
     ALOGD("%s: parameters: \"%s\"", __func__, parameters.toString().c_str());
 
@@ -363,8 +257,9 @@
 }
 
 status_t DeviceHalAidl::getParameters(const String8& keys, String8 *values) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     if (values == nullptr) {
         return BAD_VALUE;
     }
@@ -376,44 +271,13 @@
     return parseAndGetVendorParameters(mVendorExt, mModule, parameterKeys, values);
 }
 
-namespace {
-
-class Cleanup {
-  public:
-    typedef void (DeviceHalAidl::*Cleaner)(int32_t);
-
-    Cleanup(DeviceHalAidl* device, Cleaner cleaner, int32_t id) :
-            mDevice(device), mCleaner(cleaner), mId(id) {}
-    ~Cleanup() { clean(); }
-    void clean() {
-        if (mDevice != nullptr) (mDevice->*mCleaner)(mId);
-        disarm();
-    }
-    void disarm() { mDevice = nullptr; }
-
-  private:
-    DeviceHalAidl* mDevice;
-    const Cleaner mCleaner;
-    const int32_t mId;
-};
-
-}  // namespace
-
-// Since the order of container elements destruction is unspecified,
-// ensure that cleanups are performed from the most recent one and upwards.
-// This is the same as if there were individual Cleanup instances on the stack,
-// however the bonus is that we can disarm all of them with just one statement.
-class DeviceHalAidl::Cleanups : public std::forward_list<Cleanup> {
-  public:
-    ~Cleanups() { for (auto& c : *this) c.clean(); }
-    void disarmAll() { for (auto& c : *this) c.disarm(); }
-};
-
 status_t DeviceHalAidl::getInputBufferSize(const struct audio_config* config, size_t* size) {
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
-    if (size == nullptr) return BAD_VALUE;
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
+    if (config == nullptr || size == nullptr) {
+        return BAD_VALUE;
+    }
     AudioConfig aidlConfig = VALUE_OR_RETURN_STATUS(
             ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, true /*isInput*/));
     AudioDevice aidlDevice;
@@ -421,61 +285,20 @@
     AudioSource aidlSource = AudioSource::DEFAULT;
     AudioIoFlags aidlFlags = AudioIoFlags::make<AudioIoFlags::Tag::input>(0);
     AudioPortConfig mixPortConfig;
-    Cleanups cleanups;
-    audio_config writableConfig = *config;
+    Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
     AudioPatch aidlPatch;
-    RETURN_STATUS_IF_ERROR(prepareToOpenStream(0 /*handle*/, aidlDevice, aidlFlags, aidlSource,
-                    &writableConfig, &cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
+    {
+        std::lock_guard l(mLock);
+        RETURN_STATUS_IF_ERROR(mMapper.prepareToOpenStream(
+                        0 /*handle*/, aidlDevice, aidlFlags, aidlSource,
+                        &cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
+    }
     *size = aidlConfig.frameCount *
             getFrameSizeInBytes(aidlConfig.base.format, aidlConfig.base.channelMask);
     // Do not disarm cleanups to release temporary port configs.
     return OK;
 }
 
-status_t DeviceHalAidl::prepareToOpenStream(
-        int32_t aidlHandle, const AudioDevice& aidlDevice, const AudioIoFlags& aidlFlags,
-        AudioSource aidlSource, struct audio_config* config,
-        Cleanups* cleanups, AudioConfig* aidlConfig, AudioPortConfig* mixPortConfig,
-        AudioPatch* aidlPatch) {
-    ALOGD("%p %s::%s: handle %d, device %s, flags %s, source %s, config %s, mix port config %s",
-            this, getClassName().c_str(), __func__, aidlHandle, aidlDevice.toString().c_str(),
-            aidlFlags.toString().c_str(), toString(aidlSource).c_str(),
-            aidlConfig->toString().c_str(), mixPortConfig->toString().c_str());
-    resetUnusedPatchesAndPortConfigs();
-    const bool isInput = aidlFlags.getTag() == AudioIoFlags::Tag::input;
-    // Find / create AudioPortConfigs for the device port and the mix port,
-    // then find / create a patch between them, and open a stream on the mix port.
-    AudioPortConfig devicePortConfig;
-    bool created = false;
-    RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(aidlDevice, aidlConfig,
-                                                  &devicePortConfig, &created));
-    if (created) {
-        cleanups->emplace_front(this, &DeviceHalAidl::resetPortConfig, devicePortConfig.id);
-    }
-    RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(*aidlConfig, aidlFlags, aidlHandle, aidlSource,
-                    std::set<int32_t>{devicePortConfig.portId}, mixPortConfig, &created));
-    if (created) {
-        cleanups->emplace_front(this, &DeviceHalAidl::resetPortConfig, mixPortConfig->id);
-    }
-    setConfigFromPortConfig(aidlConfig, *mixPortConfig);
-    if (isInput) {
-        RETURN_STATUS_IF_ERROR(findOrCreatePatch(
-                        {devicePortConfig.id}, {mixPortConfig->id}, aidlPatch, &created));
-    } else {
-        RETURN_STATUS_IF_ERROR(findOrCreatePatch(
-                        {mixPortConfig->id}, {devicePortConfig.id}, aidlPatch, &created));
-    }
-    if (created) {
-        cleanups->emplace_front(this, &DeviceHalAidl::resetPatch, aidlPatch->id);
-    }
-    if (aidlConfig->frameCount <= 0) {
-        aidlConfig->frameCount = aidlPatch->minimumStreamBufferSizeFrames;
-    }
-    *config = VALUE_OR_RETURN_STATUS(
-            ::aidl::android::aidl2legacy_AudioConfig_audio_config_t(*aidlConfig, isInput));
-    return OK;
-}
-
 namespace {
 
 class StreamCallbackBase {
@@ -599,26 +422,32 @@
         const char* address,
         sp<StreamOutHalInterface>* outStream) {
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
-    if (!outStream || !config) {
+    TIME_CHECK();
+    if (mModule == nullptr) return NO_INIT;
+    if (outStream == nullptr || config == nullptr) {
         return BAD_VALUE;
     }
-    TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    constexpr bool isInput = false;
     int32_t aidlHandle = VALUE_OR_RETURN_STATUS(
             ::aidl::android::legacy2aidl_audio_io_handle_t_int32_t(handle));
     AudioConfig aidlConfig = VALUE_OR_RETURN_STATUS(
-            ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, false /*isInput*/));
+            ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, isInput));
     AudioDevice aidlDevice = VALUE_OR_RETURN_STATUS(
             ::aidl::android::legacy2aidl_audio_device_AudioDevice(devices, address));
     int32_t aidlOutputFlags = VALUE_OR_RETURN_STATUS(
             ::aidl::android::legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
     AudioIoFlags aidlFlags = AudioIoFlags::make<AudioIoFlags::Tag::output>(aidlOutputFlags);
     AudioPortConfig mixPortConfig;
-    Cleanups cleanups;
     AudioPatch aidlPatch;
-    RETURN_STATUS_IF_ERROR(prepareToOpenStream(aidlHandle, aidlDevice, aidlFlags,
-                    AudioSource::SYS_RESERVED_INVALID /*only needed for input*/,
-                    config, &cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
+    Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
+    {
+        std::lock_guard l(mLock);
+        RETURN_STATUS_IF_ERROR(mMapper.prepareToOpenStream(aidlHandle, aidlDevice, aidlFlags,
+                        AudioSource::SYS_RESERVED_INVALID /*only needed for input*/,
+                        &cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
+    }
+    *config = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::aidl2legacy_AudioConfig_audio_config_t(aidlConfig, isInput));
     ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
     args.portConfigId = mixPortConfig.id;
     const bool isOffload = isBitPositionFlagSet(
@@ -644,11 +473,11 @@
     }
     *outStream = sp<StreamOutHalAidl>::make(*config, std::move(context), aidlPatch.latenciesMs[0],
             std::move(ret.stream), mVendorExt, this /*callbackBroker*/);
-    mStreams.insert(std::pair(*outStream, aidlPatch.id));
     void* cbCookie = (*outStream).get();
     {
         std::lock_guard l(mLock);
         mCallbacks.emplace(cbCookie, Callbacks{});
+        mMapper.addStream(*outStream, aidlPatch.id);
     }
     if (streamCb) streamCb->setCookie(cbCookie);
     eventCb->setCookie(cbCookie);
@@ -663,15 +492,16 @@
         audio_devices_t outputDevice, const char* outputDeviceAddress,
         sp<StreamInHalInterface>* inStream) {
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
-    if (!inStream || !config) {
+    TIME_CHECK();
+    if (mModule == nullptr) return NO_INIT;
+    if (inStream == nullptr || config == nullptr) {
         return BAD_VALUE;
     }
-    TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    constexpr bool isInput = true;
     int32_t aidlHandle = VALUE_OR_RETURN_STATUS(
             ::aidl::android::legacy2aidl_audio_io_handle_t_int32_t(handle));
     AudioConfig aidlConfig = VALUE_OR_RETURN_STATUS(
-            ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, true /*isInput*/));
+            ::aidl::android::legacy2aidl_audio_config_t_AudioConfig(*config, isInput));
     AudioDevice aidlDevice = VALUE_OR_RETURN_STATUS(
             ::aidl::android::legacy2aidl_audio_device_AudioDevice(devices, address));
     int32_t aidlInputFlags = VALUE_OR_RETURN_STATUS(
@@ -680,10 +510,16 @@
     AudioSource aidlSource = VALUE_OR_RETURN_STATUS(
             ::aidl::android::legacy2aidl_audio_source_t_AudioSource(source));
     AudioPortConfig mixPortConfig;
-    Cleanups cleanups;
     AudioPatch aidlPatch;
-    RETURN_STATUS_IF_ERROR(prepareToOpenStream(aidlHandle, aidlDevice, aidlFlags, aidlSource,
-                    config, &cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
+    Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
+    {
+        std::lock_guard l(mLock);
+        RETURN_STATUS_IF_ERROR(mMapper.prepareToOpenStream(
+                        aidlHandle, aidlDevice, aidlFlags, aidlSource,
+                        &cleanups, &aidlConfig, &mixPortConfig, &aidlPatch));
+    }
+    *config = VALUE_OR_RETURN_STATUS(
+            ::aidl::android::aidl2legacy_AudioConfig_audio_config_t(aidlConfig, isInput));
     ::aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments args;
     args.portConfigId = mixPortConfig.id;
     RecordTrackMetadata aidlTrackMetadata{
@@ -705,12 +541,18 @@
     }
     *inStream = sp<StreamInHalAidl>::make(*config, std::move(context), aidlPatch.latenciesMs[0],
             std::move(ret.stream), mVendorExt, this /*micInfoProvider*/);
-    mStreams.insert(std::pair(*inStream, aidlPatch.id));
+    {
+        std::lock_guard l(mLock);
+        mMapper.addStream(*inStream, aidlPatch.id);
+    }
     cleanups.disarmAll();
     return OK;
 }
 
 status_t DeviceHalAidl::supportsAudioPatches(bool* supportsPatches) {
+    if (supportsPatches == nullptr) {
+        return BAD_VALUE;
+    }
     *supportsPatches = true;
     return OK;
 }
@@ -722,7 +564,7 @@
                                          audio_patch_handle_t* patch) {
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     if (num_sinks > AUDIO_PATCH_PORTS_MAX || num_sources > AUDIO_PATCH_PORTS_MAX ||
         sources == nullptr || sinks == nullptr || patch == nullptr) {
         return BAD_VALUE;
@@ -739,7 +581,7 @@
     // that the HAL module uses `int32_t` for patch IDs. The following assert ensures
     // that both the framework and the HAL use the same value for "no ID":
     static_assert(AUDIO_PATCH_HANDLE_NONE == 0);
-    int32_t halPatchId = static_cast<int32_t>(*patch);
+    int32_t aidlPatchId = static_cast<int32_t>(*patch);
 
     // Upon conversion, mix port configs contain audio configuration, while
     // device port configs contain device address. This data is used to find
@@ -761,68 +603,13 @@
                         ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
                                 sinks[i], isInput, 0)));
     }
-    Cleanups cleanups;
-    auto existingPatchIt = halPatchId != 0 ? mPatches.find(halPatchId): mPatches.end();
-    AudioPatch aidlPatch;
-    if (existingPatchIt != mPatches.end()) {
-        aidlPatch = existingPatchIt->second;
-        aidlPatch.sourcePortConfigIds.clear();
-        aidlPatch.sinkPortConfigIds.clear();
+    Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
+    {
+        std::lock_guard l(mLock);
+        RETURN_STATUS_IF_ERROR(mMapper.createOrUpdatePatch(
+                        aidlSources, aidlSinks, &aidlPatchId, &cleanups));
     }
-    // The IDs will be found by 'fillPortConfigs', however the original 'aidlSources' and
-    // 'aidlSinks' will not be updated because 'setAudioPatch' only needs IDs. Here we log
-    // the source arguments, where only the audio configuration and device specifications
-    // are relevant.
-    ALOGD("%s: [disregard IDs] sources: %s, sinks: %s",
-            __func__, ::android::internal::ToString(aidlSources).c_str(),
-            ::android::internal::ToString(aidlSinks).c_str());
-    auto fillPortConfigs = [&](
-            const std::vector<AudioPortConfig>& configs,
-            const std::set<int32_t>& destinationPortIds,
-            std::vector<int32_t>* ids, std::set<int32_t>* portIds) -> status_t {
-        for (const auto& s : configs) {
-            AudioPortConfig portConfig;
-            bool created = false;
-            RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(
-                            s, destinationPortIds, &portConfig, &created));
-            if (created) {
-                cleanups.emplace_front(this, &DeviceHalAidl::resetPortConfig, portConfig.id);
-            }
-            ids->push_back(portConfig.id);
-            if (portIds != nullptr) {
-                portIds->insert(portConfig.portId);
-            }
-        }
-        return OK;
-    };
-    // When looking up port configs, the destinationPortId is only used for mix ports.
-    // Thus, we process device port configs first, and look up the destination port ID from them.
-    bool sourceIsDevice = std::any_of(aidlSources.begin(), aidlSources.end(),
-            [](const auto& config) { return config.ext.getTag() == AudioPortExt::device; });
-    const std::vector<AudioPortConfig>& devicePortConfigs =
-            sourceIsDevice ? aidlSources : aidlSinks;
-    std::vector<int32_t>* devicePortConfigIds =
-            sourceIsDevice ? &aidlPatch.sourcePortConfigIds : &aidlPatch.sinkPortConfigIds;
-    const std::vector<AudioPortConfig>& mixPortConfigs =
-            sourceIsDevice ? aidlSinks : aidlSources;
-    std::vector<int32_t>* mixPortConfigIds =
-            sourceIsDevice ? &aidlPatch.sinkPortConfigIds : &aidlPatch.sourcePortConfigIds;
-    std::set<int32_t> devicePortIds;
-    RETURN_STATUS_IF_ERROR(fillPortConfigs(
-                    devicePortConfigs, std::set<int32_t>(), devicePortConfigIds, &devicePortIds));
-    RETURN_STATUS_IF_ERROR(fillPortConfigs(
-                    mixPortConfigs, devicePortIds, mixPortConfigIds, nullptr));
-    if (existingPatchIt != mPatches.end()) {
-        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
-                        mModule->setAudioPatch(aidlPatch, &aidlPatch)));
-        existingPatchIt->second = aidlPatch;
-    } else {
-        bool created = false;
-        RETURN_STATUS_IF_ERROR(findOrCreatePatch(aidlPatch, &aidlPatch, &created));
-        // Since no cleanup of the patch is needed, 'created' is ignored.
-        halPatchId = aidlPatch.id;
-        *patch = static_cast<audio_patch_handle_t>(halPatchId);
-    }
+    *patch = static_cast<audio_patch_handle_t>(aidlPatchId);
     cleanups.disarmAll();
     return OK;
 }
@@ -830,26 +617,17 @@
 status_t DeviceHalAidl::releaseAudioPatch(audio_patch_handle_t patch) {
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     static_assert(AUDIO_PATCH_HANDLE_NONE == 0);
     if (patch == AUDIO_PATCH_HANDLE_NONE) {
         return BAD_VALUE;
     }
-    int32_t halPatchId = static_cast<int32_t>(patch);
-    auto patchIt = mPatches.find(halPatchId);
-    if (patchIt == mPatches.end()) {
-        ALOGE("%s: patch with id %d not found", __func__, halPatchId);
-        return BAD_VALUE;
-    }
-    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->resetAudioPatch(halPatchId)));
-    mPatches.erase(patchIt);
+    std::lock_guard l(mLock);
+    RETURN_STATUS_IF_ERROR(mMapper.releaseAudioPatch(static_cast<int32_t>(patch)));
     return OK;
 }
 
 status_t DeviceHalAidl::getAudioPort(struct audio_port* port) {
-    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
-    TIME_CHECK();
-    if (!mModule) return NO_INIT;
     if (port == nullptr) {
         return BAD_VALUE;
     }
@@ -862,7 +640,7 @@
 status_t DeviceHalAidl::getAudioPort(struct audio_port_v7 *port) {
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     if (port == nullptr) {
         return BAD_VALUE;
     }
@@ -878,14 +656,11 @@
     const auto& matchDevice = aidlPort.ext.get<AudioPortExt::device>().device;
     // It seems that we don't have to call HAL since all valid ports have been added either
     // during initialization, or while handling connection of an external device.
-    auto portsIt = findPort(matchDevice);
-    if (portsIt == mPorts.end()) {
-        ALOGE("%s: device port for device %s is not found in the module %s",
-                __func__, matchDevice.toString().c_str(), mInstance.c_str());
-        return BAD_VALUE;
-    }
     const int32_t fwkId = aidlPort.id;
-    aidlPort = portsIt->second;
+    {
+        std::lock_guard l(mLock);
+        RETURN_STATUS_IF_ERROR(mMapper.getAudioPortCached(matchDevice, &aidlPort));
+    }
     aidlPort.id = fwkId;
     *port = VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioPort_audio_port_v7(
                     aidlPort, isInput));
@@ -895,34 +670,30 @@
 status_t DeviceHalAidl::getAudioMixPort(const struct audio_port_v7 *devicePort,
                                         struct audio_port_v7 *mixPort) {
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
-    if (devicePort->type != AUDIO_PORT_TYPE_DEVICE) {
-        return BAD_VALUE;
-    }
-    if (mixPort->type != AUDIO_PORT_TYPE_MIX) {
+    TIME_CHECK();
+    if (mModule == nullptr) return NO_INIT;
+    if (devicePort == nullptr || mixPort == nullptr ||
+            devicePort->type != AUDIO_PORT_TYPE_DEVICE || mixPort->type != AUDIO_PORT_TYPE_MIX) {
         return BAD_VALUE;
     }
     const int32_t aidlHandle = VALUE_OR_RETURN_STATUS(
             ::aidl::android::legacy2aidl_audio_io_handle_t_int32_t(mixPort->ext.mix.handle));
-    auto it = findPortConfig(std::nullopt /*config*/, std::nullopt/*flags*/, aidlHandle);
-    if (it == mPortConfigs.end()) {
-        ALOGE("%s, cannot find mix port config for handle=%u", __func__, aidlHandle);
-        return BAD_VALUE;
-    }
     AudioPort port;
-    if (status_t status = getAudioPort(it->second.portId, &port); status != NO_ERROR) {
-        return status;
+    {
+        std::lock_guard l(mLock);
+        RETURN_STATUS_IF_ERROR(mMapper.getAudioMixPort(aidlHandle, &port));
     }
     const bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
             mixPort->role, mixPort->type)) == ::aidl::android::AudioPortDirection::INPUT;
     *mixPort = VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioPort_audio_port_v7(
             port, isInput));
-    return NO_ERROR;
+    return OK;
 }
 
 status_t DeviceHalAidl::setAudioPortConfig(const struct audio_port_config* config) {
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     if (config == nullptr) {
         return BAD_VALUE;
     }
@@ -932,13 +703,16 @@
             ::aidl::android::legacy2aidl_audio_port_config_AudioPortConfig(
                     *config, isInput, 0 /*portId*/));
     AudioPortConfig portConfig;
-    bool created = false;
-    RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(
-                    requestedPortConfig, std::set<int32_t>(), &portConfig, &created));
-    return OK;
+    std::lock_guard l(mLock);
+    return mMapper.findOrCreatePortConfig(
+            requestedPortConfig, std::set<int32_t>(), &portConfig);
 }
 
 MicrophoneInfoProvider::Info const* DeviceHalAidl::getMicrophoneInfo() {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
+    TIME_CHECK();
+    if (!mModule) return {};
+    std::lock_guard l(mLock);
     if (mMicrophones.status == Microphones::Status::UNKNOWN) {
         TIME_CHECK();
         std::vector<MicrophoneInfo> aidlInfo;
@@ -961,11 +735,12 @@
 
 status_t DeviceHalAidl::getMicrophones(
         std::vector<audio_microphone_characteristic_t>* microphones) {
-    if (!microphones) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
+    TIME_CHECK();
+    if (mModule == nullptr) return NO_INIT;
+    if (microphones == nullptr) {
         return BAD_VALUE;
     }
-    TIME_CHECK();
-    if (!mModule) return NO_INIT;
     auto staticInfo = getMicrophoneInfo();
     if (!staticInfo) return INVALID_OPERATION;
     std::vector<MicrophoneDynamicInfo> emptyDynamicInfo;
@@ -982,9 +757,10 @@
 
 status_t DeviceHalAidl::addDeviceEffect(
         const struct audio_port_config *device, sp<EffectHalInterface> effect) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
-    if (!effect) {
+    if (mModule == nullptr) return NO_INIT;
+    if (device == nullptr || effect == nullptr) {
         return BAD_VALUE;
     }
     bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
@@ -998,12 +774,11 @@
         return BAD_VALUE;
     }
     AudioPortConfig devicePortConfig;
-    bool created;
-    RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(
-                    requestedPortConfig, {} /*destinationPortIds*/, &devicePortConfig, &created));
-    Cleanups cleanups;
-    if (created) {
-        cleanups.emplace_front(this, &DeviceHalAidl::resetPortConfig, devicePortConfig.id);
+    Hal2AidlMapper::Cleanups cleanups(mMapperAccessor);
+    {
+        std::lock_guard l(mLock);
+        RETURN_STATUS_IF_ERROR(mMapper.findOrCreatePortConfig(
+                    requestedPortConfig, {} /*destinationPortIds*/, &devicePortConfig, &cleanups));
     }
     auto aidlEffect = sp<effect::EffectHalAidl>::cast(effect);
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->addDeviceEffect(
@@ -1013,9 +788,10 @@
 }
 status_t DeviceHalAidl::removeDeviceEffect(
         const struct audio_port_config *device, sp<EffectHalInterface> effect) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
-    if (!effect) {
+    if (mModule == nullptr) return NO_INIT;
+    if (device == nullptr || effect == nullptr) {
         return BAD_VALUE;
     }
     bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(
@@ -1028,22 +804,24 @@
                 __func__, requestedPortConfig.toString().c_str());
         return BAD_VALUE;
     }
-    auto existingPortConfigIt = findPortConfig(
-            requestedPortConfig.ext.get<AudioPortExt::Tag::device>().device);
-    if (existingPortConfigIt == mPortConfigs.end()) {
-        ALOGE("%s: could not find a configured device port for the config %s",
-                __func__, requestedPortConfig.toString().c_str());
-        return BAD_VALUE;
+    AudioPortConfig devicePortConfig;
+    {
+        std::lock_guard l(mLock);
+        RETURN_STATUS_IF_ERROR(mMapper.findPortConfig(
+                        requestedPortConfig.ext.get<AudioPortExt::Tag::device>().device,
+                        &devicePortConfig));
     }
     auto aidlEffect = sp<effect::EffectHalAidl>::cast(effect);
     return statusTFromBinderStatus(mModule->removeDeviceEffect(
-                    existingPortConfigIt->first, aidlEffect->getIEffect()));
+                    devicePortConfig.id, aidlEffect->getIEffect()));
 }
 
 status_t DeviceHalAidl::getMmapPolicyInfos(
         media::audio::common::AudioMMapPolicyType policyType,
         std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
+    if (mModule == nullptr) return NO_INIT;
     AudioMMapPolicyType mmapPolicyType = VALUE_OR_RETURN_STATUS(
             cpp2ndk_AudioMMapPolicyType(policyType));
 
@@ -1061,7 +839,9 @@
 }
 
 int32_t DeviceHalAidl::getAAudioMixerBurstCount() {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
+    if (mModule == nullptr) return NO_INIT;
     int32_t mixerBurstCount = 0;
     if (mModule->getAAudioMixerBurstCount(&mixerBurstCount).isOk()) {
         return mixerBurstCount;
@@ -1070,7 +850,9 @@
 }
 
 int32_t DeviceHalAidl::getAAudioHardwareBurstMinUsec() {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
+    if (mModule == nullptr) return NO_INIT;
     int32_t hardwareBurstMinUsec = 0;
     if (mModule->getAAudioHardwareBurstMinUsec(&hardwareBurstMinUsec).isOk()) {
         return hardwareBurstMinUsec;
@@ -1079,8 +861,9 @@
 }
 
 error::Result<audio_hw_sync_t> DeviceHalAidl::getHwAvSync() {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     int32_t aidlHwAvSync;
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->generateHwAvSyncId(&aidlHwAvSync)));
     return VALUE_OR_RETURN_STATUS(
@@ -1089,13 +872,14 @@
 
 status_t DeviceHalAidl::dump(int fd, const Vector<String16>& args) {
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     return mModule->dump(fd, Args(args).args(), args.size());
 }
 
 status_t DeviceHalAidl::supportsBluetoothVariableLatency(bool* supports) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     if (supports == nullptr) {
         return BAD_VALUE;
     }
@@ -1104,21 +888,16 @@
 
 status_t DeviceHalAidl::getSoundDoseInterface(const std::string& module,
                                               ::ndk::SpAIBinder* soundDoseBinder)  {
-    TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (soundDoseBinder == nullptr) {
+        return BAD_VALUE;
+    }
     if (mSoundDose == nullptr) {
-        ndk::ScopedAStatus status = mModule->getSoundDose(&mSoundDose);
-        if (!status.isOk()) {
-            ALOGE("%s failed to return the sound dose interface for module %s: %s",
-                  __func__,
-                  module.c_str(),
-                  status.getDescription().c_str());
-            return BAD_VALUE;
-        }
+        ALOGE("%s failed to retrieve the sound dose interface for module %s",
+                __func__, module.c_str());
+        return BAD_VALUE;
     }
     *soundDoseBinder = mSoundDose->asBinder();
     ALOGI("%s using audio AIDL HAL sound dose interface", __func__);
-
     return OK;
 }
 
@@ -1126,29 +905,32 @@
     // There is not AIDL API defined for `prepareToDisconnectExternalDevice`.
     // Call `setConnectedState` instead.
     // TODO(b/279824103): call prepareToDisconnectExternalDevice when it is added.
-    if (const status_t status = setConnectedState(port, false /*connected*/); status == NO_ERROR) {
-        mDeviceDisconnectionNotified.insert(port->id);
-    }
+    RETURN_STATUS_IF_ERROR(setConnectedState(port, false /*connected*/));
+    std::lock_guard l(mLock);
+    mDeviceDisconnectionNotified.insert(port->id);
     // Return that there was no error as otherwise the disconnection procedure will not be
-    // considered complete for upper layers, and 'setConnectedState' will not be called again.
-    return NO_ERROR;
+    // considered complete for upper layers, and 'setConnectedState' will not be called again
+    return OK;
 }
 
 status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
     ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
+    if (mModule == nullptr) return NO_INIT;
     if (port == nullptr) {
         return BAD_VALUE;
     }
-    if (!connected && mDeviceDisconnectionNotified.erase(port->id) > 0) {
-        // For device disconnection, APM will first call `prepareToDisconnectExternalDevice`
-        // and then call `setConnectedState`. However, there is no API for
-        // `prepareToDisconnectExternalDevice` yet. In that case, `setConnectedState` will be
-        // called when calling `prepareToDisconnectExternalDevice`. Do not call to the HAL if
-        // previous call is successful. Also remove the cache here to avoid a large cache after
-        // a long run.
-        return NO_ERROR;
+    if (!connected) {
+        std::lock_guard l(mLock);
+        if (mDeviceDisconnectionNotified.erase(port->id) > 0) {
+            // For device disconnection, APM will first call `prepareToDisconnectExternalDevice`
+            // and then call `setConnectedState`. However, there is no API for
+            // `prepareToDisconnectExternalDevice` yet. In that case, `setConnectedState` will be
+            // called when calling `prepareToDisconnectExternalDevice`. Do not call to the HAL if
+            // previous call is successful. Also remove the cache here to avoid a large cache after
+            // a long run.
+            return OK;
+        }
     }
     bool isInput = VALUE_OR_RETURN_STATUS(::aidl::android::portDirection(port->role, port->type)) ==
             ::aidl::android::AudioPortDirection::INPUT;
@@ -1159,100 +941,17 @@
                 __func__, mInstance.c_str(), aidlPort.toString().c_str());
         return BAD_VALUE;
     }
-    if (connected) {
-        AudioDevice matchDevice = aidlPort.ext.get<AudioPortExt::device>().device;
-        std::optional<AudioPort> templatePort;
-        auto erasePortAfterConnectionIt = mPorts.end();
-        // Connection of remote submix out with address "0" is a special case. Since there is
-        // already an "augmented template" port with this address in mPorts, we need to replace
-        // it with a connected port.
-        // Connection of remote submix outs with any other address is done as usual except that
-        // the template port is in `mRemoteSubmixOut`.
-        if (mRemoteSubmixOut.has_value() &&
-                matchDevice.type.type == AudioDeviceType::OUT_SUBMIX) {
-            if (matchDevice.address == AudioDeviceAddress::make<AudioDeviceAddress::id>(
-                            AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS)) {
-                erasePortAfterConnectionIt = findPort(matchDevice);
-            }
-            templatePort = mRemoteSubmixOut;
-        } else if (mRemoteSubmixIn.has_value() &&
-                matchDevice.type.type == AudioDeviceType::IN_SUBMIX) {
-            templatePort = mRemoteSubmixIn;
-        } else {
-            // Reset the device address to find the "template" port.
-            matchDevice.address = AudioDeviceAddress::make<AudioDeviceAddress::id>();
-        }
-        if (!templatePort.has_value()) {
-            auto portsIt = findPort(matchDevice);
-            if (portsIt == mPorts.end()) {
-                // Since 'setConnectedState' is called for all modules, it is normal when the device
-                // port not found in every one of them.
-                return BAD_VALUE;
-            } else {
-                ALOGD("%s: device port for device %s found in the module %s",
-                        __func__, matchDevice.toString().c_str(), mInstance.c_str());
-            }
-            templatePort = portsIt->second;
-        }
-        resetUnusedPatchesAndPortConfigs();
-
-        // Use the ID of the "template" port, use all the information from the provided port.
-        aidlPort.id = templatePort->id;
-        AudioPort connectedPort;
-        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->connectExternalDevice(
-                                aidlPort, &connectedPort)));
-        const auto [it, inserted] = mPorts.insert(std::make_pair(connectedPort.id, connectedPort));
-        LOG_ALWAYS_FATAL_IF(!inserted,
-                "%s: module %s, duplicate port ID received from HAL: %s, existing port: %s",
-                __func__, mInstance.c_str(), connectedPort.toString().c_str(),
-                it->second.toString().c_str());
-        mConnectedPorts[connectedPort.id] = false;
-        if (erasePortAfterConnectionIt != mPorts.end()) {
-            mPorts.erase(erasePortAfterConnectionIt);
-        }
-    } else {  // !connected
-        AudioDevice matchDevice = aidlPort.ext.get<AudioPortExt::device>().device;
-        auto portsIt = findPort(matchDevice);
-        if (portsIt == mPorts.end()) {
-            // Since 'setConnectedState' is called for all modules, it is normal when the device
-            // port not found in every one of them.
-            return BAD_VALUE;
-        } else {
-            ALOGD("%s: device port for device %s found in the module %s",
-                    __func__, matchDevice.toString().c_str(), mInstance.c_str());
-        }
-        resetUnusedPatchesAndPortConfigs();
-
-        // Disconnection of remote submix out with address "0" is a special case. We need to replace
-        // the connected port entry with the "augmented template".
-        const int32_t portId = portsIt->second.id;
-        if (mRemoteSubmixOut.has_value() && matchDevice.type.type == AudioDeviceType::OUT_SUBMIX &&
-                matchDevice.address == AudioDeviceAddress::make<AudioDeviceAddress::id>(
-                        AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS)) {
-            mDisconnectedPortReplacement = std::make_pair(portId, *mRemoteSubmixOut);
-            auto& port = mDisconnectedPortReplacement.second;
-            port.ext.get<AudioPortExt::Tag::device>().device = matchDevice;
-            port.profiles = portsIt->second.profiles;
-        }
-        // Streams are closed by AudioFlinger independently from device disconnections.
-        // It is possible that the stream has not been closed yet.
-        if (!isPortHeldByAStream(portId)) {
-            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
-                            mModule->disconnectExternalDevice(portId)));
-            eraseConnectedPort(portId);
-        } else {
-            ALOGD("%s: since device port ID %d is used by a stream, "
-                    "external device disconnection postponed", __func__, portId);
-            mConnectedPorts[portId] = true;
-        }
-    }
-    return updateRoutes();
+    std::lock_guard l(mLock);
+    return mMapper.setDevicePortConnectedState(aidlPort, connected);
 }
 
 status_t DeviceHalAidl::setSimulateDeviceConnections(bool enabled) {
     TIME_CHECK();
-    if (!mModule) return NO_INIT;
-    resetUnusedPatchesAndPortConfigs();
+    if (mModule == nullptr) return NO_INIT;
+    {
+        std::lock_guard l(mLock);
+        mMapper.resetUnusedPatchesAndPortConfigs();
+    }
     ModuleDebug debug{ .simulateDeviceConnections = enabled };
     status_t status = statusTFromBinderStatus(mModule->setModuleDebug(debug));
     // This is important to log as it affects HAL behavior.
@@ -1264,65 +963,8 @@
     return status;
 }
 
-bool DeviceHalAidl::audioDeviceMatches(const AudioDevice& device, const AudioPort& p) {
-    if (p.ext.getTag() != AudioPortExt::Tag::device) return false;
-    return p.ext.get<AudioPortExt::Tag::device>().device == device;
-}
-
-bool DeviceHalAidl::audioDeviceMatches(const AudioDevice& device, const AudioPortConfig& p) {
-    if (p.ext.getTag() != AudioPortExt::Tag::device) return false;
-    if (device.type.type == AudioDeviceType::IN_DEFAULT) {
-        return p.portId == mDefaultInputPortId;
-    } else if (device.type.type == AudioDeviceType::OUT_DEFAULT) {
-        return p.portId == mDefaultOutputPortId;
-    }
-    return p.ext.get<AudioPortExt::Tag::device>().device == device;
-}
-
-status_t DeviceHalAidl::createOrUpdatePortConfig(
-        const AudioPortConfig& requestedPortConfig, PortConfigs::iterator* result, bool* created) {
-    TIME_CHECK();
-    AudioPortConfig appliedPortConfig;
-    bool applied = false;
-    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPortConfig(
-                            requestedPortConfig, &appliedPortConfig, &applied)));
-    if (!applied) {
-        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPortConfig(
-                                appliedPortConfig, &appliedPortConfig, &applied)));
-        if (!applied) {
-            ALOGE("%s: module %s did not apply suggested config %s",
-                    __func__, mInstance.c_str(), appliedPortConfig.toString().c_str());
-            return NO_INIT;
-        }
-    }
-
-    int32_t id = appliedPortConfig.id;
-    if (requestedPortConfig.id != 0 && requestedPortConfig.id != id) {
-        LOG_ALWAYS_FATAL("%s: requested port config id %d changed to %d", __func__,
-                requestedPortConfig.id, id);
-    }
-
-    auto [it, inserted] = mPortConfigs.insert_or_assign(std::move(id),
-            std::move(appliedPortConfig));
-    *result = it;
-    *created = inserted;
-    return OK;
-}
-
-void DeviceHalAidl::eraseConnectedPort(int32_t portId) {
-    mPorts.erase(portId);
-    mConnectedPorts.erase(portId);
-    if (mDisconnectedPortReplacement.first == portId) {
-        const auto& port = mDisconnectedPortReplacement.second;
-        mPorts.insert(std::make_pair(port.id, port));
-        ALOGD("%s: disconnected port replacement: %s", __func__, port.toString().c_str());
-        mDisconnectedPortReplacement = std::pair<int32_t, AudioPort>();
-    }
-}
-
 status_t DeviceHalAidl::filterAndRetrieveBtA2dpParameters(
         AudioParameter &keys, AudioParameter *result) {
-    TIME_CHECK();
     if (String8 key = String8(AudioParameter::keyReconfigA2dpSupported); keys.containsKey(key)) {
         keys.remove(key);
         if (mBluetoothA2dp != nullptr) {
@@ -1339,7 +981,6 @@
 }
 
 status_t DeviceHalAidl::filterAndUpdateBtA2dpParameters(AudioParameter &parameters) {
-    TIME_CHECK();
     std::optional<bool> a2dpEnabled;
     std::optional<std::vector<VendorParameter>> reconfigureOffload;
     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
@@ -1381,7 +1022,6 @@
 }
 
 status_t DeviceHalAidl::filterAndUpdateBtHfpParameters(AudioParameter &parameters) {
-    TIME_CHECK();
     IBluetooth::HfpConfig hfpConfig;
     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
                     parameters, String8(AudioParameter::keyBtHfpEnable),
@@ -1420,7 +1060,6 @@
 }
 
 status_t DeviceHalAidl::filterAndUpdateBtLeParameters(AudioParameter &parameters) {
-    TIME_CHECK();
     std::optional<bool> leEnabled;
     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
                     parameters, String8(AudioParameter::keyBtLeSuspended),
@@ -1443,7 +1082,6 @@
 }
 
 status_t DeviceHalAidl::filterAndUpdateBtScoParameters(AudioParameter &parameters) {
-    TIME_CHECK();
     IBluetooth::ScoConfig scoConfig;
     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
                     parameters, String8(AudioParameter::keyBtSco),
@@ -1501,7 +1139,6 @@
 }
 
 status_t DeviceHalAidl::filterAndUpdateScreenParameters(AudioParameter &parameters) {
-    TIME_CHECK();
     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
                     parameters, String8(AudioParameter::keyScreenState),
                     [&](const String8& onOrOff) -> status_t {
@@ -1539,7 +1176,6 @@
 }
 
 status_t DeviceHalAidl::filterAndUpdateTelephonyParameters(AudioParameter &parameters) {
-    TIME_CHECK();
     using TtyMode = ITelephony::TelecomConfig::TtyMode;
     ITelephony::TelecomConfig telConfig;
     (void)VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<String8>(
@@ -1584,443 +1220,6 @@
     return OK;
 }
 
-status_t DeviceHalAidl::findOrCreatePatch(
-        const AudioPatch& requestedPatch, AudioPatch* patch, bool* created) {
-    std::set<int32_t> sourcePortConfigIds(requestedPatch.sourcePortConfigIds.begin(),
-            requestedPatch.sourcePortConfigIds.end());
-    std::set<int32_t> sinkPortConfigIds(requestedPatch.sinkPortConfigIds.begin(),
-            requestedPatch.sinkPortConfigIds.end());
-    return findOrCreatePatch(sourcePortConfigIds, sinkPortConfigIds, patch, created);
-}
-
-status_t DeviceHalAidl::findOrCreatePatch(
-        const std::set<int32_t>& sourcePortConfigIds, const std::set<int32_t>& sinkPortConfigIds,
-        AudioPatch* patch, bool* created) {
-    auto patchIt = findPatch(sourcePortConfigIds, sinkPortConfigIds);
-    if (patchIt == mPatches.end()) {
-        TIME_CHECK();
-        AudioPatch requestedPatch, appliedPatch;
-        requestedPatch.sourcePortConfigIds.insert(requestedPatch.sourcePortConfigIds.end(),
-                sourcePortConfigIds.begin(), sourcePortConfigIds.end());
-        requestedPatch.sinkPortConfigIds.insert(requestedPatch.sinkPortConfigIds.end(),
-                sinkPortConfigIds.begin(), sinkPortConfigIds.end());
-        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPatch(
-                                requestedPatch, &appliedPatch)));
-        patchIt = mPatches.insert(mPatches.end(), std::make_pair(appliedPatch.id, appliedPatch));
-        *created = true;
-    } else {
-        *created = false;
-    }
-    *patch = patchIt->second;
-    return OK;
-}
-
-status_t DeviceHalAidl::findOrCreatePortConfig(const AudioDevice& device, const AudioConfig* config,
-        AudioPortConfig* portConfig, bool* created) {
-    auto portConfigIt = findPortConfig(device);
-    if (portConfigIt == mPortConfigs.end()) {
-        auto portsIt = findPort(device);
-        if (portsIt == mPorts.end()) {
-            ALOGE("%s: device port for device %s is not found in the module %s",
-                    __func__, device.toString().c_str(), mInstance.c_str());
-            return BAD_VALUE;
-        }
-        AudioPortConfig requestedPortConfig;
-        requestedPortConfig.portId = portsIt->first;
-        if (config != nullptr) {
-            setPortConfigFromConfig(&requestedPortConfig, *config);
-        }
-        RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig, &portConfigIt,
-                created));
-    } else {
-        *created = false;
-    }
-    *portConfig = portConfigIt->second;
-    return OK;
-}
-
-status_t DeviceHalAidl::findOrCreatePortConfig(
-        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 };
-    auto portConfigIt = findPortConfig(config, flags, ioHandle);
-    if (portConfigIt == mPortConfigs.end() && flags.has_value()) {
-        auto optionalInputFlagsIt = kOptionalInputFlags.begin();
-        AudioIoFlags matchFlags = flags.value();
-        auto portsIt = findPort(config, matchFlags, destinationPortIds);
-        while (portsIt == mPorts.end() && matchFlags.getTag() == AudioIoFlags::Tag::input
-                && optionalInputFlagsIt != kOptionalInputFlags.end()) {
-            if (!isBitPositionFlagSet(
-                            matchFlags.get<AudioIoFlags::Tag::input>(), *optionalInputFlagsIt)) {
-                ++optionalInputFlagsIt;
-                continue;
-            }
-            matchFlags.set<AudioIoFlags::Tag::input>(matchFlags.get<AudioIoFlags::Tag::input>() &
-                    ~makeBitPositionFlagMask(*optionalInputFlagsIt++));
-            portsIt = findPort(config, matchFlags, destinationPortIds);
-            ALOGI("%s: mix port for config %s, flags %s was not found in the module %s, "
-                    "retried with flags %s", __func__, config.toString().c_str(),
-                    flags.value().toString().c_str(), mInstance.c_str(),
-                    matchFlags.toString().c_str());
-        }
-        if (portsIt == mPorts.end()) {
-            ALOGE("%s: mix port for config %s, flags %s is not found in the module %s",
-                    __func__, config.toString().c_str(), matchFlags.toString().c_str(),
-                    mInstance.c_str());
-            return BAD_VALUE;
-        }
-        AudioPortConfig requestedPortConfig;
-        requestedPortConfig.portId = portsIt->first;
-        setPortConfigFromConfig(&requestedPortConfig, config);
-        requestedPortConfig.ext = AudioPortMixExt{ .handle = ioHandle };
-        if (matchFlags.getTag() == AudioIoFlags::Tag::input
-                && source != AudioSource::SYS_RESERVED_INVALID) {
-            requestedPortConfig.ext.get<AudioPortExt::Tag::mix>().usecase =
-                    AudioPortMixExtUseCase::make<AudioPortMixExtUseCase::Tag::source>(source);
-        }
-        RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig, &portConfigIt,
-                created));
-    } else if (portConfigIt == mPortConfigs.end() && !flags.has_value()) {
-        ALOGW("%s: mix port config for %s, handle %d not found in the module %s, "
-                "and was not created as flags are not specified",
-                __func__, config.toString().c_str(), ioHandle, mInstance.c_str());
-        return BAD_VALUE;
-    } else {
-        AudioPortConfig requestedPortConfig = portConfigIt->second;
-        if (requestedPortConfig.ext.getTag() == AudioPortExt::Tag::mix) {
-            AudioPortMixExt& mixExt = requestedPortConfig.ext.get<AudioPortExt::Tag::mix>();
-            if (mixExt.usecase.getTag() == AudioPortMixExtUseCase::Tag::source &&
-                    source != AudioSource::SYS_RESERVED_INVALID) {
-                mixExt.usecase.get<AudioPortMixExtUseCase::Tag::source>() = source;
-            }
-        }
-
-        if (requestedPortConfig != portConfigIt->second) {
-            RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig, &portConfigIt,
-                    created));
-        } else {
-            *created = false;
-        }
-    }
-    *portConfig = portConfigIt->second;
-    return OK;
-}
-
-status_t DeviceHalAidl::findOrCreatePortConfig(
-        const AudioPortConfig& requestedPortConfig, const std::set<int32_t>& destinationPortIds,
-        AudioPortConfig* portConfig, bool* created) {
-    using Tag = AudioPortExt::Tag;
-    if (requestedPortConfig.ext.getTag() == Tag::mix) {
-        if (const auto& p = requestedPortConfig;
-                !p.sampleRate.has_value() || !p.channelMask.has_value() ||
-                !p.format.has_value()) {
-            ALOGW("%s: provided mix port config is not fully specified: %s",
-                    __func__, p.toString().c_str());
-            return BAD_VALUE;
-        }
-        AudioConfig config;
-        setConfigFromPortConfig(&config, requestedPortConfig);
-        AudioSource source = requestedPortConfig.ext.get<Tag::mix>().usecase.getTag() ==
-                AudioPortMixExtUseCase::Tag::source ?
-                requestedPortConfig.ext.get<Tag::mix>().usecase.
-                get<AudioPortMixExtUseCase::Tag::source>() : AudioSource::SYS_RESERVED_INVALID;
-        return findOrCreatePortConfig(config, requestedPortConfig.flags,
-                requestedPortConfig.ext.get<Tag::mix>().handle, source, destinationPortIds,
-                portConfig, created);
-    } else if (requestedPortConfig.ext.getTag() == Tag::device) {
-        return findOrCreatePortConfig(
-                requestedPortConfig.ext.get<Tag::device>().device, nullptr /*config*/,
-                portConfig, created);
-    }
-    ALOGW("%s: unsupported audio port config: %s",
-            __func__, requestedPortConfig.toString().c_str());
-    return BAD_VALUE;
-}
-
-DeviceHalAidl::Patches::iterator DeviceHalAidl::findPatch(
-        const std::set<int32_t>& sourcePortConfigIds, const std::set<int32_t>& sinkPortConfigIds) {
-    return std::find_if(mPatches.begin(), mPatches.end(),
-            [&](const auto& pair) {
-                const auto& p = pair.second;
-                std::set<int32_t> patchSrcs(
-                        p.sourcePortConfigIds.begin(), p.sourcePortConfigIds.end());
-                std::set<int32_t> patchSinks(
-                        p.sinkPortConfigIds.begin(), p.sinkPortConfigIds.end());
-                return sourcePortConfigIds == patchSrcs && sinkPortConfigIds == patchSinks; });
-}
-
-DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(const AudioDevice& device) {
-    if (device.type.type == AudioDeviceType::IN_DEFAULT) {
-        return mPorts.find(mDefaultInputPortId);
-    } else if (device.type.type == AudioDeviceType::OUT_DEFAULT) {
-        return mPorts.find(mDefaultOutputPortId);
-    }
-    if (device.address.getTag() != AudioDeviceAddress::id ||
-            !device.address.get<AudioDeviceAddress::id>().empty()) {
-        return std::find_if(mPorts.begin(), mPorts.end(),
-                [&](const auto& pair) { return audioDeviceMatches(device, pair.second); });
-    }
-    // For connection w/o an address, two ports can be found: the template port,
-    // and a connected port (if exists). Make sure we return the connected port.
-    DeviceHalAidl::Ports::iterator portIt = mPorts.end();
-    for (auto it = mPorts.begin(); it != mPorts.end(); ++it) {
-        if (audioDeviceMatches(device, it->second)) {
-            if (mConnectedPorts.find(it->first) != mConnectedPorts.end()) {
-                return it;
-            } else {
-                // Will return 'it' if there is no connected port.
-                portIt = it;
-            }
-        }
-    }
-    return portIt;
-}
-
-DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(
-            const AudioConfig& config, const AudioIoFlags& flags,
-            const std::set<int32_t>& destinationPortIds) {
-    auto belongsToProfile = [&config](const AudioProfile& prof) {
-        return (isDefaultAudioFormat(config.base.format) || prof.format == config.base.format) &&
-                (config.base.channelMask.getTag() == AudioChannelLayout::none ||
-                        std::find(prof.channelMasks.begin(), prof.channelMasks.end(),
-                                config.base.channelMask) != prof.channelMasks.end()) &&
-                (config.base.sampleRate == 0 ||
-                        std::find(prof.sampleRates.begin(), prof.sampleRates.end(),
-                                config.base.sampleRate) != prof.sampleRates.end());
-    };
-    static const std::vector<AudioOutputFlags> kOptionalOutputFlags{AudioOutputFlags::BIT_PERFECT};
-    int optionalFlags = 0;
-    auto flagMatches = [&flags, &optionalFlags](const AudioIoFlags& portFlags) {
-        // Ports should be able to match if the optional flags are not requested.
-        return portFlags == flags ||
-               (portFlags.getTag() == AudioIoFlags::Tag::output &&
-                        AudioIoFlags::make<AudioIoFlags::Tag::output>(
-                                portFlags.get<AudioIoFlags::Tag::output>() &
-                                        ~optionalFlags) == flags);
-    };
-    auto matcher = [&](const auto& pair) {
-        const auto& p = pair.second;
-        return p.ext.getTag() == AudioPortExt::Tag::mix &&
-                flagMatches(p.flags) &&
-                (destinationPortIds.empty() ||
-                        std::any_of(destinationPortIds.begin(), destinationPortIds.end(),
-                                [&](const int32_t destId) { return mRoutingMatrix.count(
-                                            std::make_pair(p.id, destId)) != 0; })) &&
-                (p.profiles.empty() ||
-                        std::find_if(p.profiles.begin(), p.profiles.end(), belongsToProfile) !=
-                        p.profiles.end()); };
-    auto result = std::find_if(mPorts.begin(), mPorts.end(), matcher);
-    if (result == mPorts.end() && flags.getTag() == AudioIoFlags::Tag::output) {
-        auto optionalOutputFlagsIt = kOptionalOutputFlags.begin();
-        while (result == mPorts.end() && optionalOutputFlagsIt != kOptionalOutputFlags.end()) {
-            if (isBitPositionFlagSet(
-                        flags.get<AudioIoFlags::Tag::output>(), *optionalOutputFlagsIt)) {
-                // If the flag is set by the request, it must be matched.
-                ++optionalOutputFlagsIt;
-                continue;
-            }
-            optionalFlags |= makeBitPositionFlagMask(*optionalOutputFlagsIt++);
-            result = std::find_if(mPorts.begin(), mPorts.end(), matcher);
-            ALOGI("%s: port for config %s, flags %s was not found in the module %s, "
-                  "retried with excluding optional flags %#x", __func__, config.toString().c_str(),
-                    flags.toString().c_str(), mInstance.c_str(), optionalFlags);
-        }
-    }
-    return result;
-}
-
-DeviceHalAidl::PortConfigs::iterator DeviceHalAidl::findPortConfig(const AudioDevice& device) {
-    return std::find_if(mPortConfigs.begin(), mPortConfigs.end(),
-            [&](const auto& pair) { return audioDeviceMatches(device, pair.second); });
-}
-
-DeviceHalAidl::PortConfigs::iterator DeviceHalAidl::findPortConfig(
-            const std::optional<AudioConfig>& config,
-            const std::optional<AudioIoFlags>& flags,
-            int32_t ioHandle) {
-    using Tag = AudioPortExt::Tag;
-    return std::find_if(mPortConfigs.begin(), mPortConfigs.end(),
-            [&](const auto& pair) {
-                const auto& p = pair.second;
-                LOG_ALWAYS_FATAL_IF(p.ext.getTag() == Tag::mix &&
-                        (!p.sampleRate.has_value() || !p.channelMask.has_value() ||
-                                !p.format.has_value() || !p.flags.has_value()),
-                        "%s: stored mix port config is not fully specified: %s",
-                        __func__, p.toString().c_str());
-                return p.ext.getTag() == Tag::mix &&
-                        (!config.has_value() ||
-                                isConfigEqualToPortConfig(config.value(), p)) &&
-                        (!flags.has_value() || p.flags.value() == flags.value()) &&
-                        p.ext.template get<Tag::mix>().handle == ioHandle; });
-}
-
-bool DeviceHalAidl::isPortHeldByAStream(int32_t portId) {
-    // It is assumed that mStreams has already been cleaned up.
-    for (const auto& streamPair : mStreams) {
-        int32_t patchId = streamPair.second;
-        auto patchIt = mPatches.find(patchId);
-        if (patchIt == mPatches.end()) continue;
-        for (int32_t id : patchIt->second.sourcePortConfigIds) {
-            auto portConfigIt = mPortConfigs.find(id);
-            if (portConfigIt != mPortConfigs.end() && portConfigIt->second.portId == portId) {
-                return true;
-            }
-        }
-        for (int32_t id : patchIt->second.sinkPortConfigIds) {
-            auto portConfigIt = mPortConfigs.find(id);
-            if (portConfigIt != mPortConfigs.end() && portConfigIt->second.portId == portId) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-void DeviceHalAidl::resetPatch(int32_t patchId) {
-    if (auto it = mPatches.find(patchId); it != mPatches.end()) {
-        mPatches.erase(it);
-        TIME_CHECK();
-        if (ndk::ScopedAStatus status = mModule->resetAudioPatch(patchId); !status.isOk()) {
-            ALOGE("%s: error while resetting patch %d: %s",
-                    __func__, patchId, status.getDescription().c_str());
-        }
-        return;
-    }
-    ALOGE("%s: patch id %d not found", __func__, patchId);
-}
-
-void DeviceHalAidl::resetPortConfig(int32_t portConfigId) {
-    if (auto it = mPortConfigs.find(portConfigId); it != mPortConfigs.end()) {
-        mPortConfigs.erase(it);
-        TIME_CHECK();
-        if (ndk::ScopedAStatus status = mModule->resetAudioPortConfig(portConfigId);
-                !status.isOk()) {
-            ALOGE("%s: error while resetting port config %d: %s",
-                    __func__, portConfigId, status.getDescription().c_str());
-        }
-        return;
-    }
-    ALOGE("%s: port config id %d not found", __func__, portConfigId);
-}
-
-void DeviceHalAidl::resetUnusedPatches() {
-    // Since patches can be created independently of streams via 'createAudioPatch',
-    // here we only clean up patches for released streams.
-    for (auto it = mStreams.begin(); it != mStreams.end(); ) {
-        if (auto streamSp = it->first.promote(); streamSp) {
-            ++it;
-        } else {
-            resetPatch(it->second);
-            it = mStreams.erase(it);
-        }
-    }
-}
-
-void DeviceHalAidl::resetUnusedPatchesAndPortConfigs() {
-    resetUnusedPatches();
-    resetUnusedPortConfigs();
-}
-
-void DeviceHalAidl::resetUnusedPortConfigs() {
-    // The assumption is that port configs are used to create patches
-    // (or to open streams, but that involves creation of patches, too). Thus,
-    // orphaned port configs can and should be reset.
-    std::map<int32_t, int32_t /*portID*/> portConfigIds;
-    std::transform(mPortConfigs.begin(), mPortConfigs.end(),
-            std::inserter(portConfigIds, portConfigIds.end()),
-            [](const auto& pcPair) { return std::make_pair(pcPair.first, pcPair.second.portId); });
-    for (const auto& p : mPatches) {
-        for (int32_t id : p.second.sourcePortConfigIds) portConfigIds.erase(id);
-        for (int32_t id : p.second.sinkPortConfigIds) portConfigIds.erase(id);
-    }
-    for (int32_t id : mInitialPortConfigIds) {
-        portConfigIds.erase(id);
-    }
-    std::set<int32_t> retryDeviceDisconnection;
-    for (const auto& portConfigAndIdPair : portConfigIds) {
-        resetPortConfig(portConfigAndIdPair.first);
-        if (const auto it = mConnectedPorts.find(portConfigAndIdPair.second);
-                it != mConnectedPorts.end() && it->second) {
-            retryDeviceDisconnection.insert(portConfigAndIdPair.second);
-        }
-    }
-    for (int32_t portId : retryDeviceDisconnection) {
-        if (!isPortHeldByAStream(portId)) {
-            TIME_CHECK();
-            if (auto status = mModule->disconnectExternalDevice(portId); status.isOk()) {
-                eraseConnectedPort(portId);
-                ALOGD("%s: executed postponed external device disconnection for port ID %d",
-                        __func__, portId);
-            }
-        }
-    }
-    if (!retryDeviceDisconnection.empty()) {
-        updateRoutes();
-    }
-}
-
-status_t DeviceHalAidl::updateRoutes() {
-    TIME_CHECK();
-    RETURN_STATUS_IF_ERROR(
-            statusTFromBinderStatus(mModule->getAudioRoutes(&mRoutes)));
-    ALOGW_IF(mRoutes.empty(), "%s: module %s returned an empty list of audio routes",
-            __func__, mInstance.c_str());
-    if (mRemoteSubmixIn.has_value()) {
-        // Remove mentions of the template remote submix input from routes.
-        int32_t rSubmixInId = mRemoteSubmixIn->id;
-        // Remove mentions of the template remote submix out only if it is not in mPorts
-        // (that means there is a connected port in mPorts).
-        int32_t rSubmixOutId = mPorts.find(mRemoteSubmixOut->id) == mPorts.end() ?
-                mRemoteSubmixOut->id : -1;
-        for (auto it = mRoutes.begin(); it != mRoutes.end();) {
-            auto& route = *it;
-            if (route.sinkPortId == rSubmixOutId) {
-                it = mRoutes.erase(it);
-                continue;
-            }
-            if (auto sourceIt = std::find(route.sourcePortIds.begin(), route.sourcePortIds.end(),
-                            rSubmixInId); sourceIt != route.sourcePortIds.end()) {
-                route.sourcePortIds.erase(sourceIt);
-                if (route.sourcePortIds.empty()) {
-                    it = mRoutes.erase(it);
-                    continue;
-                }
-            }
-            ++it;
-        }
-    }
-    mRoutingMatrix.clear();
-    for (const auto& r : mRoutes) {
-        for (auto portId : r.sourcePortIds) {
-            mRoutingMatrix.emplace(r.sinkPortId, portId);
-            mRoutingMatrix.emplace(portId, r.sinkPortId);
-        }
-    }
-    return OK;
-}
-
-status_t DeviceHalAidl::getAudioPort(int32_t portId, AudioPort* port) {
-    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
-    TIME_CHECK();
-    if (!mModule) {
-        return NO_INIT;
-    }
-    const status_t status = statusTFromBinderStatus(mModule->getAudioPort(portId, port));
-    if (status == OK) {
-        auto portIt = mPorts.find(portId);
-        if (portIt != mPorts.end()) {
-            portIt->second = *port;
-        } else {
-            ALOGW("%s, port(%d) returned successfully from the HAL but not it is not cached",
-                  __func__, portId);
-        }
-    }
-    return status;
-}
-
 void DeviceHalAidl::clearCallbacks(void* cookie) {
     std::lock_guard l(mLock);
     mCallbacks.erase(cookie);
diff --git a/media/libaudiohal/impl/DeviceHalAidl.h b/media/libaudiohal/impl/DeviceHalAidl.h
index 99e8503..9493e47 100644
--- a/media/libaudiohal/impl/DeviceHalAidl.h
+++ b/media/libaudiohal/impl/DeviceHalAidl.h
@@ -17,7 +17,9 @@
 #pragma once
 
 #include <map>
-#include <set>
+#include <memory>
+#include <mutex>
+#include <string>
 #include <vector>
 
 #include <aidl/android/media/audio/IHalAdapterVendorExtension.h>
@@ -26,9 +28,10 @@
 #include <android-base/thread_annotations.h>
 #include <media/audiohal/DeviceHalInterface.h>
 #include <media/audiohal/EffectHalInterface.h>
-#include <media/audiohal/StreamHalInterface.h>
 
+#include "Cleanups.h"
 #include "ConversionHelperAidl.h"
+#include "Hal2AidlMapper.h"
 
 namespace android {
 
@@ -194,19 +197,6 @@
         Status status = Status::UNKNOWN;
         MicrophoneInfoProvider::Info info;
     };
-    // IDs of ports for connected external devices, and whether they are held by streams.
-    using ConnectedPorts = std::map<int32_t /*port ID*/, bool>;
-    using Patches = std::map<int32_t /*patch ID*/,
-            ::aidl::android::hardware::audio::core::AudioPatch>;
-    using PortConfigs = std::map<int32_t /*port config ID*/,
-            ::aidl::android::media::audio::common::AudioPortConfig>;
-    using Ports = std::map<int32_t /*port ID*/, ::aidl::android::media::audio::common::AudioPort>;
-    using Routes = std::vector<::aidl::android::hardware::audio::core::AudioRoute>;
-    // Answers the question "whether portID 'first' is reachable from portID 'second'?"
-    // It's not a map because both portIDs are known. The matrix is symmetric.
-    using RoutingMatrix = std::set<std::pair<int32_t, int32_t>>;
-    using Streams = std::map<wp<StreamHalInterface>, int32_t /*patch ID*/>;
-    class Cleanups;
 
     // Must not be constructed directly by clients.
     DeviceHalAidl(
@@ -216,14 +206,6 @@
 
     ~DeviceHalAidl() override = default;
 
-    bool audioDeviceMatches(const ::aidl::android::media::audio::common::AudioDevice& device,
-            const ::aidl::android::media::audio::common::AudioPort& p);
-    bool audioDeviceMatches(const ::aidl::android::media::audio::common::AudioDevice& device,
-            const ::aidl::android::media::audio::common::AudioPortConfig& p);
-    status_t createOrUpdatePortConfig(
-            const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
-            PortConfigs::iterator* result, bool *created);
-    void eraseConnectedPort(int32_t portId);
     status_t filterAndRetrieveBtA2dpParameters(AudioParameter &keys, AudioParameter *result);
     status_t filterAndUpdateBtA2dpParameters(AudioParameter &parameters);
     status_t filterAndUpdateBtHfpParameters(AudioParameter &parameters);
@@ -231,60 +213,6 @@
     status_t filterAndUpdateBtScoParameters(AudioParameter &parameters);
     status_t filterAndUpdateScreenParameters(AudioParameter &parameters);
     status_t filterAndUpdateTelephonyParameters(AudioParameter &parameters);
-    status_t findOrCreatePatch(
-        const std::set<int32_t>& sourcePortConfigIds,
-        const std::set<int32_t>& sinkPortConfigIds,
-        ::aidl::android::hardware::audio::core::AudioPatch* patch, bool* created);
-    status_t findOrCreatePatch(
-        const ::aidl::android::hardware::audio::core::AudioPatch& requestedPatch,
-        ::aidl::android::hardware::audio::core::AudioPatch* patch, bool* created);
-    status_t findOrCreatePortConfig(
-            const ::aidl::android::media::audio::common::AudioDevice& device,
-            const ::aidl::android::media::audio::common::AudioConfig* config,
-            ::aidl::android::media::audio::common::AudioPortConfig* portConfig,
-            bool* created);
-    status_t findOrCreatePortConfig(
-            const ::aidl::android::media::audio::common::AudioConfig& config,
-            const std::optional<::aidl::android::media::audio::common::AudioIoFlags>& flags,
-            int32_t ioHandle,
-            ::aidl::android::media::audio::common::AudioSource aidlSource,
-            const std::set<int32_t>& destinationPortIds,
-            ::aidl::android::media::audio::common::AudioPortConfig* portConfig, bool* created);
-    status_t findOrCreatePortConfig(
-        const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
-        const std::set<int32_t>& destinationPortIds,
-        ::aidl::android::media::audio::common::AudioPortConfig* portConfig, bool* created);
-    Patches::iterator findPatch(const std::set<int32_t>& sourcePortConfigIds,
-            const std::set<int32_t>& sinkPortConfigIds);
-    Ports::iterator findPort(const ::aidl::android::media::audio::common::AudioDevice& device);
-    Ports::iterator findPort(
-            const ::aidl::android::media::audio::common::AudioConfig& config,
-            const ::aidl::android::media::audio::common::AudioIoFlags& flags,
-            const std::set<int32_t>& destinationPortIds);
-    PortConfigs::iterator findPortConfig(
-            const ::aidl::android::media::audio::common::AudioDevice& device);
-    PortConfigs::iterator findPortConfig(
-            const std::optional<::aidl::android::media::audio::common::AudioConfig>& config,
-            const std::optional<::aidl::android::media::audio::common::AudioIoFlags>& flags,
-            int32_t ioHandle);
-    bool isPortHeldByAStream(int32_t portId);
-    status_t prepareToOpenStream(
-        int32_t aidlHandle,
-        const ::aidl::android::media::audio::common::AudioDevice& aidlDevice,
-        const ::aidl::android::media::audio::common::AudioIoFlags& aidlFlags,
-        ::aidl::android::media::audio::common::AudioSource aidlSource,
-        struct audio_config* config,
-        Cleanups* cleanups,
-        ::aidl::android::media::audio::common::AudioConfig* aidlConfig,
-        ::aidl::android::media::audio::common::AudioPortConfig* mixPortConfig,
-        ::aidl::android::hardware::audio::core::AudioPatch* aidlPatch);
-    void resetPatch(int32_t patchId);
-    void resetPortConfig(int32_t portConfigId);
-    void resetUnusedPatches();
-    void resetUnusedPatchesAndPortConfigs();
-    void resetUnusedPortConfigs();
-    status_t updateRoutes();
-    status_t getAudioPort(int32_t portId, ::aidl::android::media::audio::common::AudioPort* port);
 
     // CallbackBroker implementation
     void clearCallbacks(void* cookie) override;
@@ -311,28 +239,14 @@
     const std::shared_ptr<::aidl::android::hardware::audio::core::IBluetooth> mBluetooth;
     const std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothA2dp> mBluetoothA2dp;
     const std::shared_ptr<::aidl::android::hardware::audio::core::IBluetoothLe> mBluetoothLe;
-    std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose>
-        mSoundDose = nullptr;
-    Ports mPorts;
-    // Remote submix "template" ports (no address specified, no profiles).
-    // They are excluded from `mPorts` as their presence confuses the framework code.
-    std::optional<::aidl::android::media::audio::common::AudioPort> mRemoteSubmixIn;
-    std::optional<::aidl::android::media::audio::common::AudioPort> mRemoteSubmixOut;
-    int32_t mDefaultInputPortId = -1;
-    int32_t mDefaultOutputPortId = -1;
-    PortConfigs mPortConfigs;
-    std::set<int32_t> mInitialPortConfigIds;
-    Patches mPatches;
-    Routes mRoutes;
-    RoutingMatrix mRoutingMatrix;
-    Streams mStreams;
-    Microphones mMicrophones;
+    const std::shared_ptr<::aidl::android::hardware::audio::core::sounddose::ISoundDose> mSoundDose;
+
     std::mutex mLock;
     std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock);
-    std::set<audio_port_handle_t> mDeviceDisconnectionNotified;
-    ConnectedPorts mConnectedPorts;
-    std::pair<int32_t, ::aidl::android::media::audio::common::AudioPort>
-            mDisconnectedPortReplacement;
+    std::set<audio_port_handle_t> mDeviceDisconnectionNotified GUARDED_BY(mLock);
+    Hal2AidlMapper mMapper GUARDED_BY(mLock);
+    LockedAccessor<Hal2AidlMapper> mMapperAccessor;
+    Microphones mMicrophones GUARDED_BY(mLock);
 };
 
 } // namespace android
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.cpp b/media/libaudiohal/impl/Hal2AidlMapper.cpp
new file mode 100644
index 0000000..28b12c2
--- /dev/null
+++ b/media/libaudiohal/impl/Hal2AidlMapper.cpp
@@ -0,0 +1,917 @@
+/*
+ * Copyright (C) 2022 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 "Hal2AidlMapper"
+// #define LOG_NDEBUG 0
+
+#include <algorithm>
+
+#include <media/audiohal/StreamHalInterface.h>
+#include <error/expected_utils.h>
+#include <system/audio.h>  // For AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS
+#include <Utils.h>
+#include <utils/Log.h>
+
+#include "Hal2AidlMapper.h"
+
+using aidl::android::aidl_utils::statusTFromBinderStatus;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioConfig;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioInputFlags;
+using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioOutputFlags;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortDeviceExt;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioPortMixExt;
+using aidl::android::media::audio::common::AudioPortMixExtUseCase;
+using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::Int;
+using aidl::android::hardware::audio::common::isBitPositionFlagSet;
+using aidl::android::hardware::audio::common::isDefaultAudioFormat;
+using aidl::android::hardware::audio::common::makeBitPositionFlagMask;
+using aidl::android::hardware::audio::core::AudioPatch;
+using aidl::android::hardware::audio::core::AudioRoute;
+using aidl::android::hardware::audio::core::IModule;
+
+namespace android {
+
+namespace {
+
+bool isConfigEqualToPortConfig(const AudioConfig& config, const AudioPortConfig& portConfig) {
+    return portConfig.sampleRate.value().value == config.base.sampleRate &&
+            portConfig.channelMask.value() == config.base.channelMask &&
+            portConfig.format.value() == config.base.format;
+}
+
+void setConfigFromPortConfig(AudioConfig* config, const AudioPortConfig& portConfig) {
+    config->base.sampleRate = portConfig.sampleRate.value().value;
+    config->base.channelMask = portConfig.channelMask.value();
+    config->base.format = portConfig.format.value();
+}
+
+void setPortConfigFromConfig(AudioPortConfig* portConfig, const AudioConfig& config) {
+    if (config.base.sampleRate != 0) {
+        portConfig->sampleRate = Int{ .value = config.base.sampleRate };
+    }
+    if (config.base.channelMask != AudioChannelLayout{}) {
+        portConfig->channelMask = config.base.channelMask;
+    }
+    if (config.base.format != AudioFormatDescription{}) {
+        portConfig->format = config.base.format;
+    }
+}
+
+}  // namespace
+
+Hal2AidlMapper::Hal2AidlMapper(const std::string& instance, const std::shared_ptr<IModule>& module)
+        : mInstance(instance), mModule(module) {
+}
+
+void Hal2AidlMapper::addStream(const sp<StreamHalInterface>& stream, int32_t patchId) {
+    mStreams.insert(std::pair(stream, patchId));
+}
+
+bool Hal2AidlMapper::audioDeviceMatches(const AudioDevice& device, const AudioPort& p) {
+    if (p.ext.getTag() != AudioPortExt::Tag::device) return false;
+    return p.ext.get<AudioPortExt::Tag::device>().device == device;
+}
+
+bool Hal2AidlMapper::audioDeviceMatches(const AudioDevice& device, const AudioPortConfig& p) {
+    if (p.ext.getTag() != AudioPortExt::Tag::device) return false;
+    if (device.type.type == AudioDeviceType::IN_DEFAULT) {
+        return p.portId == mDefaultInputPortId;
+    } else if (device.type.type == AudioDeviceType::OUT_DEFAULT) {
+        return p.portId == mDefaultOutputPortId;
+    }
+    return p.ext.get<AudioPortExt::Tag::device>().device == device;
+}
+
+status_t Hal2AidlMapper::createOrUpdatePatch(
+        const std::vector<AudioPortConfig>& sources,
+        const std::vector<AudioPortConfig>& sinks,
+        int32_t* patchId, Cleanups* cleanups) {
+    auto existingPatchIt = *patchId != 0 ? mPatches.find(*patchId): mPatches.end();
+    AudioPatch patch;
+    if (existingPatchIt != mPatches.end()) {
+        patch = existingPatchIt->second;
+        patch.sourcePortConfigIds.clear();
+        patch.sinkPortConfigIds.clear();
+    }
+    // The IDs will be found by 'fillPortConfigs', however the original 'sources' and
+    // 'sinks' will not be updated because 'setAudioPatch' only needs IDs. Here we log
+    // the source arguments, where only the audio configuration and device specifications
+    // are relevant.
+    ALOGD("%s: [disregard IDs] sources: %s, sinks: %s",
+            __func__, ::android::internal::ToString(sources).c_str(),
+            ::android::internal::ToString(sinks).c_str());
+    auto fillPortConfigs = [&](
+            const std::vector<AudioPortConfig>& configs,
+            const std::set<int32_t>& destinationPortIds,
+            std::vector<int32_t>* ids, std::set<int32_t>* portIds) -> status_t {
+        for (const auto& s : configs) {
+            AudioPortConfig portConfig;
+            RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(
+                            s, destinationPortIds, &portConfig, cleanups));
+            ids->push_back(portConfig.id);
+            if (portIds != nullptr) {
+                portIds->insert(portConfig.portId);
+            }
+        }
+        return OK;
+    };
+    // When looking up port configs, the destinationPortId is only used for mix ports.
+    // Thus, we process device port configs first, and look up the destination port ID from them.
+    bool sourceIsDevice = std::any_of(sources.begin(), sources.end(),
+            [](const auto& config) { return config.ext.getTag() == AudioPortExt::device; });
+    const std::vector<AudioPortConfig>& devicePortConfigs =
+            sourceIsDevice ? sources : sinks;
+    std::vector<int32_t>* devicePortConfigIds =
+            sourceIsDevice ? &patch.sourcePortConfigIds : &patch.sinkPortConfigIds;
+    const std::vector<AudioPortConfig>& mixPortConfigs =
+            sourceIsDevice ? sinks : sources;
+    std::vector<int32_t>* mixPortConfigIds =
+            sourceIsDevice ? &patch.sinkPortConfigIds : &patch.sourcePortConfigIds;
+    std::set<int32_t> devicePortIds;
+    RETURN_STATUS_IF_ERROR(fillPortConfigs(
+                    devicePortConfigs, std::set<int32_t>(), devicePortConfigIds, &devicePortIds));
+    RETURN_STATUS_IF_ERROR(fillPortConfigs(
+                    mixPortConfigs, devicePortIds, mixPortConfigIds, nullptr));
+    if (existingPatchIt != mPatches.end()) {
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+                        mModule->setAudioPatch(patch, &patch)));
+        existingPatchIt->second = patch;
+    } else {
+        bool created = false;
+        RETURN_STATUS_IF_ERROR(findOrCreatePatch(patch, &patch, &created));
+        // Since no cleanup of the patch is needed, 'created' is ignored.
+        *patchId = patch.id;
+    }
+    return OK;
+}
+
+status_t Hal2AidlMapper::createOrUpdatePortConfig(
+        const AudioPortConfig& requestedPortConfig, PortConfigs::iterator* result, bool* created) {
+    AudioPortConfig appliedPortConfig;
+    bool applied = false;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPortConfig(
+                            requestedPortConfig, &appliedPortConfig, &applied)));
+    if (!applied) {
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPortConfig(
+                                appliedPortConfig, &appliedPortConfig, &applied)));
+        if (!applied) {
+            ALOGE("%s: module %s did not apply suggested config %s",
+                    __func__, mInstance.c_str(), appliedPortConfig.toString().c_str());
+            return NO_INIT;
+        }
+    }
+
+    int32_t id = appliedPortConfig.id;
+    if (requestedPortConfig.id != 0 && requestedPortConfig.id != id) {
+        LOG_ALWAYS_FATAL("%s: requested port config id %d changed to %d", __func__,
+                requestedPortConfig.id, id);
+    }
+
+    auto [it, inserted] = mPortConfigs.insert_or_assign(std::move(id),
+            std::move(appliedPortConfig));
+    *result = it;
+    *created = inserted;
+    return OK;
+}
+
+void Hal2AidlMapper::eraseConnectedPort(int32_t portId) {
+    mPorts.erase(portId);
+    mConnectedPorts.erase(portId);
+    if (mDisconnectedPortReplacement.first == portId) {
+        const auto& port = mDisconnectedPortReplacement.second;
+        mPorts.insert(std::make_pair(port.id, port));
+        ALOGD("%s: disconnected port replacement: %s", __func__, port.toString().c_str());
+        mDisconnectedPortReplacement = std::pair<int32_t, AudioPort>();
+    }
+}
+
+status_t Hal2AidlMapper::findOrCreatePatch(
+        const AudioPatch& requestedPatch, AudioPatch* patch, bool* created) {
+    std::set<int32_t> sourcePortConfigIds(requestedPatch.sourcePortConfigIds.begin(),
+            requestedPatch.sourcePortConfigIds.end());
+    std::set<int32_t> sinkPortConfigIds(requestedPatch.sinkPortConfigIds.begin(),
+            requestedPatch.sinkPortConfigIds.end());
+    return findOrCreatePatch(sourcePortConfigIds, sinkPortConfigIds, patch, created);
+}
+
+status_t Hal2AidlMapper::findOrCreatePatch(
+        const std::set<int32_t>& sourcePortConfigIds, const std::set<int32_t>& sinkPortConfigIds,
+        AudioPatch* patch, bool* created) {
+    auto patchIt = findPatch(sourcePortConfigIds, sinkPortConfigIds);
+    if (patchIt == mPatches.end()) {
+        AudioPatch requestedPatch, appliedPatch;
+        requestedPatch.sourcePortConfigIds.insert(requestedPatch.sourcePortConfigIds.end(),
+                sourcePortConfigIds.begin(), sourcePortConfigIds.end());
+        requestedPatch.sinkPortConfigIds.insert(requestedPatch.sinkPortConfigIds.end(),
+                sinkPortConfigIds.begin(), sinkPortConfigIds.end());
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->setAudioPatch(
+                                requestedPatch, &appliedPatch)));
+        patchIt = mPatches.insert(mPatches.end(), std::make_pair(appliedPatch.id, appliedPatch));
+        *created = true;
+    } else {
+        *created = false;
+    }
+    *patch = patchIt->second;
+    return OK;
+}
+
+status_t Hal2AidlMapper::findOrCreatePortConfig(
+        const AudioDevice& device, const AudioConfig* config, AudioPortConfig* portConfig,
+        bool* created) {
+    auto portConfigIt = findPortConfig(device);
+    if (portConfigIt == mPortConfigs.end()) {
+        auto portsIt = findPort(device);
+        if (portsIt == mPorts.end()) {
+            ALOGE("%s: device port for device %s is not found in the module %s",
+                    __func__, device.toString().c_str(), mInstance.c_str());
+            return BAD_VALUE;
+        }
+        AudioPortConfig requestedPortConfig;
+        requestedPortConfig.portId = portsIt->first;
+        if (config != nullptr) {
+            setPortConfigFromConfig(&requestedPortConfig, *config);
+        }
+        RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig, &portConfigIt,
+                created));
+    } else {
+        *created = false;
+    }
+    *portConfig = portConfigIt->second;
+    return OK;
+}
+
+status_t Hal2AidlMapper::findOrCreatePortConfig(
+        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 };
+    auto portConfigIt = findPortConfig(config, flags, ioHandle);
+    if (portConfigIt == mPortConfigs.end() && flags.has_value()) {
+        auto optionalInputFlagsIt = kOptionalInputFlags.begin();
+        AudioIoFlags matchFlags = flags.value();
+        auto portsIt = findPort(config, matchFlags, destinationPortIds);
+        while (portsIt == mPorts.end() && matchFlags.getTag() == AudioIoFlags::Tag::input
+                && optionalInputFlagsIt != kOptionalInputFlags.end()) {
+            if (!isBitPositionFlagSet(
+                            matchFlags.get<AudioIoFlags::Tag::input>(), *optionalInputFlagsIt)) {
+                ++optionalInputFlagsIt;
+                continue;
+            }
+            matchFlags.set<AudioIoFlags::Tag::input>(matchFlags.get<AudioIoFlags::Tag::input>() &
+                    ~makeBitPositionFlagMask(*optionalInputFlagsIt++));
+            portsIt = findPort(config, matchFlags, destinationPortIds);
+            ALOGI("%s: mix port for config %s, flags %s was not found in the module %s, "
+                    "retried with flags %s", __func__, config.toString().c_str(),
+                    flags.value().toString().c_str(), mInstance.c_str(),
+                    matchFlags.toString().c_str());
+        }
+        if (portsIt == mPorts.end()) {
+            ALOGE("%s: mix port for config %s, flags %s is not found in the module %s",
+                    __func__, config.toString().c_str(), matchFlags.toString().c_str(),
+                    mInstance.c_str());
+            return BAD_VALUE;
+        }
+        AudioPortConfig requestedPortConfig;
+        requestedPortConfig.portId = portsIt->first;
+        setPortConfigFromConfig(&requestedPortConfig, config);
+        requestedPortConfig.ext = AudioPortMixExt{ .handle = ioHandle };
+        if (matchFlags.getTag() == AudioIoFlags::Tag::input
+                && source != AudioSource::SYS_RESERVED_INVALID) {
+            requestedPortConfig.ext.get<AudioPortExt::Tag::mix>().usecase =
+                    AudioPortMixExtUseCase::make<AudioPortMixExtUseCase::Tag::source>(source);
+        }
+        RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig, &portConfigIt,
+                created));
+    } else if (portConfigIt == mPortConfigs.end() && !flags.has_value()) {
+        ALOGW("%s: mix port config for %s, handle %d not found in the module %s, "
+                "and was not created as flags are not specified",
+                __func__, config.toString().c_str(), ioHandle, mInstance.c_str());
+        return BAD_VALUE;
+    } else {
+        AudioPortConfig requestedPortConfig = portConfigIt->second;
+        if (requestedPortConfig.ext.getTag() == AudioPortExt::Tag::mix) {
+            AudioPortMixExt& mixExt = requestedPortConfig.ext.get<AudioPortExt::Tag::mix>();
+            if (mixExt.usecase.getTag() == AudioPortMixExtUseCase::Tag::source &&
+                    source != AudioSource::SYS_RESERVED_INVALID) {
+                mixExt.usecase.get<AudioPortMixExtUseCase::Tag::source>() = source;
+            }
+        }
+
+        if (requestedPortConfig != portConfigIt->second) {
+            RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig, &portConfigIt,
+                    created));
+        } else {
+            *created = false;
+        }
+    }
+    *portConfig = portConfigIt->second;
+    return OK;
+}
+
+status_t Hal2AidlMapper::findOrCreatePortConfig(
+        const AudioPortConfig& requestedPortConfig, const std::set<int32_t>& destinationPortIds,
+        AudioPortConfig* portConfig, bool* created) {
+    using Tag = AudioPortExt::Tag;
+    if (requestedPortConfig.ext.getTag() == Tag::mix) {
+        if (const auto& p = requestedPortConfig;
+                !p.sampleRate.has_value() || !p.channelMask.has_value() ||
+                !p.format.has_value()) {
+            ALOGW("%s: provided mix port config is not fully specified: %s",
+                    __func__, p.toString().c_str());
+            return BAD_VALUE;
+        }
+        AudioConfig config;
+        setConfigFromPortConfig(&config, requestedPortConfig);
+        AudioSource source = requestedPortConfig.ext.get<Tag::mix>().usecase.getTag() ==
+                AudioPortMixExtUseCase::Tag::source ?
+                requestedPortConfig.ext.get<Tag::mix>().usecase.
+                get<AudioPortMixExtUseCase::Tag::source>() : AudioSource::SYS_RESERVED_INVALID;
+        return findOrCreatePortConfig(config, requestedPortConfig.flags,
+                requestedPortConfig.ext.get<Tag::mix>().handle, source, destinationPortIds,
+                portConfig, created);
+    } else if (requestedPortConfig.ext.getTag() == Tag::device) {
+        return findOrCreatePortConfig(
+                requestedPortConfig.ext.get<Tag::device>().device, nullptr /*config*/,
+                portConfig, created);
+    }
+    ALOGW("%s: unsupported audio port config: %s",
+            __func__, requestedPortConfig.toString().c_str());
+    return BAD_VALUE;
+}
+
+status_t Hal2AidlMapper::findOrCreatePortConfig(
+        const AudioPortConfig& requestedPortConfig, const std::set<int32_t>& destinationPortIds,
+        AudioPortConfig* portConfig, Cleanups* cleanups) {
+    bool created = false;
+    RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(
+                    requestedPortConfig, destinationPortIds, portConfig, &created));
+    if (created && cleanups != nullptr) {
+        cleanups->add(&Hal2AidlMapper::resetPortConfig, portConfig->id);
+    }
+    return OK;
+}
+
+status_t Hal2AidlMapper::findPortConfig(const AudioDevice& device, AudioPortConfig* portConfig) {
+    if (auto it = findPortConfig(device); it != mPortConfigs.end()) {
+        *portConfig = it->second;
+        return OK;
+    }
+    ALOGE("%s: could not find a configured device port for device %s",
+            __func__, device.toString().c_str());
+    return BAD_VALUE;
+}
+
+Hal2AidlMapper::Patches::iterator Hal2AidlMapper::findPatch(
+        const std::set<int32_t>& sourcePortConfigIds, const std::set<int32_t>& sinkPortConfigIds) {
+    return std::find_if(mPatches.begin(), mPatches.end(),
+            [&](const auto& pair) {
+                const auto& p = pair.second;
+                std::set<int32_t> patchSrcs(
+                        p.sourcePortConfigIds.begin(), p.sourcePortConfigIds.end());
+                std::set<int32_t> patchSinks(
+                        p.sinkPortConfigIds.begin(), p.sinkPortConfigIds.end());
+                return sourcePortConfigIds == patchSrcs && sinkPortConfigIds == patchSinks; });
+}
+
+Hal2AidlMapper::Ports::iterator Hal2AidlMapper::findPort(const AudioDevice& device) {
+    if (device.type.type == AudioDeviceType::IN_DEFAULT) {
+        return mPorts.find(mDefaultInputPortId);
+    } else if (device.type.type == AudioDeviceType::OUT_DEFAULT) {
+        return mPorts.find(mDefaultOutputPortId);
+    }
+    if (device.address.getTag() != AudioDeviceAddress::id ||
+            !device.address.get<AudioDeviceAddress::id>().empty()) {
+        return std::find_if(mPorts.begin(), mPorts.end(),
+                [&](const auto& pair) { return audioDeviceMatches(device, pair.second); });
+    }
+    // For connection w/o an address, two ports can be found: the template port,
+    // and a connected port (if exists). Make sure we return the connected port.
+    Hal2AidlMapper::Ports::iterator portIt = mPorts.end();
+    for (auto it = mPorts.begin(); it != mPorts.end(); ++it) {
+        if (audioDeviceMatches(device, it->second)) {
+            if (mConnectedPorts.find(it->first) != mConnectedPorts.end()) {
+                return it;
+            } else {
+                // Will return 'it' if there is no connected port.
+                portIt = it;
+            }
+        }
+    }
+    return portIt;
+}
+
+Hal2AidlMapper::Ports::iterator Hal2AidlMapper::findPort(
+            const AudioConfig& config, const AudioIoFlags& flags,
+            const std::set<int32_t>& destinationPortIds) {
+    auto belongsToProfile = [&config](const AudioProfile& prof) {
+        return (isDefaultAudioFormat(config.base.format) || prof.format == config.base.format) &&
+                (config.base.channelMask.getTag() == AudioChannelLayout::none ||
+                        std::find(prof.channelMasks.begin(), prof.channelMasks.end(),
+                                config.base.channelMask) != prof.channelMasks.end()) &&
+                (config.base.sampleRate == 0 ||
+                        std::find(prof.sampleRates.begin(), prof.sampleRates.end(),
+                                config.base.sampleRate) != prof.sampleRates.end());
+    };
+    static const std::vector<AudioOutputFlags> kOptionalOutputFlags{AudioOutputFlags::BIT_PERFECT};
+    int optionalFlags = 0;
+    auto flagMatches = [&flags, &optionalFlags](const AudioIoFlags& portFlags) {
+        // Ports should be able to match if the optional flags are not requested.
+        return portFlags == flags ||
+               (portFlags.getTag() == AudioIoFlags::Tag::output &&
+                        AudioIoFlags::make<AudioIoFlags::Tag::output>(
+                                portFlags.get<AudioIoFlags::Tag::output>() &
+                                        ~optionalFlags) == flags);
+    };
+    auto matcher = [&](const auto& pair) {
+        const auto& p = pair.second;
+        return p.ext.getTag() == AudioPortExt::Tag::mix &&
+                flagMatches(p.flags) &&
+                (destinationPortIds.empty() ||
+                        std::any_of(destinationPortIds.begin(), destinationPortIds.end(),
+                                [&](const int32_t destId) { return mRoutingMatrix.count(
+                                            std::make_pair(p.id, destId)) != 0; })) &&
+                (p.profiles.empty() ||
+                        std::find_if(p.profiles.begin(), p.profiles.end(), belongsToProfile) !=
+                        p.profiles.end()); };
+    auto result = std::find_if(mPorts.begin(), mPorts.end(), matcher);
+    if (result == mPorts.end() && flags.getTag() == AudioIoFlags::Tag::output) {
+        auto optionalOutputFlagsIt = kOptionalOutputFlags.begin();
+        while (result == mPorts.end() && optionalOutputFlagsIt != kOptionalOutputFlags.end()) {
+            if (isBitPositionFlagSet(
+                        flags.get<AudioIoFlags::Tag::output>(), *optionalOutputFlagsIt)) {
+                // If the flag is set by the request, it must be matched.
+                ++optionalOutputFlagsIt;
+                continue;
+            }
+            optionalFlags |= makeBitPositionFlagMask(*optionalOutputFlagsIt++);
+            result = std::find_if(mPorts.begin(), mPorts.end(), matcher);
+            ALOGI("%s: port for config %s, flags %s was not found in the module %s, "
+                  "retried with excluding optional flags %#x", __func__, config.toString().c_str(),
+                    flags.toString().c_str(), mInstance.c_str(), optionalFlags);
+        }
+    }
+    return result;
+}
+
+Hal2AidlMapper::PortConfigs::iterator Hal2AidlMapper::findPortConfig(const AudioDevice& device) {
+    return std::find_if(mPortConfigs.begin(), mPortConfigs.end(),
+            [&](const auto& pair) { return audioDeviceMatches(device, pair.second); });
+}
+
+Hal2AidlMapper::PortConfigs::iterator Hal2AidlMapper::findPortConfig(
+            const std::optional<AudioConfig>& config,
+            const std::optional<AudioIoFlags>& flags,
+            int32_t ioHandle) {
+    using Tag = AudioPortExt::Tag;
+    return std::find_if(mPortConfigs.begin(), mPortConfigs.end(),
+            [&](const auto& pair) {
+                const auto& p = pair.second;
+                LOG_ALWAYS_FATAL_IF(p.ext.getTag() == Tag::mix &&
+                        (!p.sampleRate.has_value() || !p.channelMask.has_value() ||
+                                !p.format.has_value() || !p.flags.has_value()),
+                        "%s: stored mix port config is not fully specified: %s",
+                        __func__, p.toString().c_str());
+                return p.ext.getTag() == Tag::mix &&
+                        (!config.has_value() ||
+                                isConfigEqualToPortConfig(config.value(), p)) &&
+                        (!flags.has_value() || p.flags.value() == flags.value()) &&
+                        p.ext.template get<Tag::mix>().handle == ioHandle; });
+}
+
+status_t Hal2AidlMapper::getAudioMixPort(int32_t ioHandle, AudioPort* port) {
+    auto it = findPortConfig(std::nullopt /*config*/, std::nullopt /*flags*/, ioHandle);
+    if (it == mPortConfigs.end()) {
+        ALOGE("%s, cannot find mix port config for handle %u", __func__, ioHandle);
+        return BAD_VALUE;
+    }
+    return updateAudioPort(it->second.portId, port);
+}
+
+status_t Hal2AidlMapper::getAudioPortCached(
+        const ::aidl::android::media::audio::common::AudioDevice& device,
+        ::aidl::android::media::audio::common::AudioPort* port) {
+
+    if (auto portsIt = findPort(device); portsIt != mPorts.end()) {
+        *port = portsIt->second;
+        return OK;
+    }
+    ALOGE("%s: device port for device %s is not found in the module %s",
+            __func__, device.toString().c_str(), mInstance.c_str());
+    return BAD_VALUE;
+}
+
+status_t Hal2AidlMapper::initialize() {
+    std::vector<AudioPort> ports;
+    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
+    ALOGW_IF(ports.empty(), "%s: module %s returned an empty list of audio ports",
+            __func__, mInstance.c_str());
+    mDefaultInputPortId = mDefaultOutputPortId = -1;
+    const int defaultDeviceFlag = 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
+    for (auto it = ports.begin(); it != ports.end(); ) {
+        const auto& port = *it;
+        if (port.ext.getTag() != AudioPortExt::Tag::device) {
+            ++it;
+            continue;
+        }
+        const AudioPortDeviceExt& deviceExt = port.ext.get<AudioPortExt::Tag::device>();
+        if ((deviceExt.flags & defaultDeviceFlag) != 0) {
+            if (port.flags.getTag() == AudioIoFlags::Tag::input) {
+                mDefaultInputPortId = port.id;
+            } else if (port.flags.getTag() == AudioIoFlags::Tag::output) {
+                mDefaultOutputPortId = port.id;
+            }
+        }
+        // For compatibility with HIDL, hide "template" remote submix ports from ports list.
+        if (const auto& devDesc = deviceExt.device;
+                (devDesc.type.type == AudioDeviceType::IN_SUBMIX ||
+                        devDesc.type.type == AudioDeviceType::OUT_SUBMIX) &&
+                devDesc.type.connection == AudioDeviceDescription::CONNECTION_VIRTUAL) {
+            if (devDesc.type.type == AudioDeviceType::IN_SUBMIX) {
+                mRemoteSubmixIn = port;
+            } else {
+                mRemoteSubmixOut = port;
+            }
+            it = ports.erase(it);
+        } else {
+            ++it;
+        }
+    }
+    if (mRemoteSubmixIn.has_value() != mRemoteSubmixOut.has_value()) {
+        ALOGE("%s: The configuration only has input or output remote submix device, must have both",
+                __func__);
+        mRemoteSubmixIn.reset();
+        mRemoteSubmixOut.reset();
+    }
+    if (mRemoteSubmixIn.has_value()) {
+        AudioPort connectedRSubmixIn = *mRemoteSubmixIn;
+        connectedRSubmixIn.ext.get<AudioPortExt::Tag::device>().device.address =
+                AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS;
+        ALOGD("%s: connecting remote submix input", __func__);
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->connectExternalDevice(
+                                connectedRSubmixIn, &connectedRSubmixIn)));
+        // The template port for the remote submix input couldn't be "default" because it is not
+        // attached. The connected port can now be made default because we never disconnect it.
+        if (mDefaultInputPortId == -1) {
+            mDefaultInputPortId = connectedRSubmixIn.id;
+        }
+        ports.push_back(std::move(connectedRSubmixIn));
+
+        // Remote submix output must not be connected until the framework actually starts
+        // using it, however for legacy compatibility we need to provide an "augmented template"
+        // port with an address and profiles. It is obtained by connecting the output and then
+        // immediately disconnecting it. This is a cheap operation as we don't open any streams.
+        AudioPort tempConnectedRSubmixOut = *mRemoteSubmixOut;
+        tempConnectedRSubmixOut.ext.get<AudioPortExt::Tag::device>().device.address =
+                AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS;
+        ALOGD("%s: temporarily connecting and disconnecting remote submix output", __func__);
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->connectExternalDevice(
+                                tempConnectedRSubmixOut, &tempConnectedRSubmixOut)));
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->disconnectExternalDevice(
+                                tempConnectedRSubmixOut.id)));
+        tempConnectedRSubmixOut.id = mRemoteSubmixOut->id;
+        ports.push_back(std::move(tempConnectedRSubmixOut));
+    }
+
+    ALOGI("%s: module %s default port ids: input %d, output %d",
+            __func__, mInstance.c_str(), mDefaultInputPortId, mDefaultOutputPortId);
+    std::transform(ports.begin(), ports.end(), std::inserter(mPorts, mPorts.end()),
+            [](const auto& p) { return std::make_pair(p.id, p); });
+    RETURN_STATUS_IF_ERROR(updateRoutes());
+    std::vector<AudioPortConfig> portConfigs;
+    RETURN_STATUS_IF_ERROR(
+            statusTFromBinderStatus(mModule->getAudioPortConfigs(&portConfigs)));  // OK if empty
+    std::transform(portConfigs.begin(), portConfigs.end(),
+            std::inserter(mPortConfigs, mPortConfigs.end()),
+            [](const auto& p) { return std::make_pair(p.id, p); });
+    std::transform(mPortConfigs.begin(), mPortConfigs.end(),
+            std::inserter(mInitialPortConfigIds, mInitialPortConfigIds.end()),
+            [](const auto& pcPair) { return pcPair.first; });
+    std::vector<AudioPatch> patches;
+    RETURN_STATUS_IF_ERROR(
+            statusTFromBinderStatus(mModule->getAudioPatches(&patches)));  // OK if empty
+    std::transform(patches.begin(), patches.end(),
+            std::inserter(mPatches, mPatches.end()),
+            [](const auto& p) { return std::make_pair(p.id, p); });
+    return OK;
+}
+
+bool Hal2AidlMapper::isPortHeldByAStream(int32_t portId) {
+    // It is assumed that mStreams has already been cleaned up.
+    for (const auto& streamPair : mStreams) {
+        int32_t patchId = streamPair.second;
+        auto patchIt = mPatches.find(patchId);
+        if (patchIt == mPatches.end()) continue;
+        for (int32_t id : patchIt->second.sourcePortConfigIds) {
+            auto portConfigIt = mPortConfigs.find(id);
+            if (portConfigIt != mPortConfigs.end() && portConfigIt->second.portId == portId) {
+                return true;
+            }
+        }
+        for (int32_t id : patchIt->second.sinkPortConfigIds) {
+            auto portConfigIt = mPortConfigs.find(id);
+            if (portConfigIt != mPortConfigs.end() && portConfigIt->second.portId == portId) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+status_t Hal2AidlMapper::prepareToOpenStream(
+        int32_t ioHandle, const AudioDevice& device, const AudioIoFlags& flags,
+        AudioSource source, Cleanups* cleanups, AudioConfig* config,
+        AudioPortConfig* mixPortConfig, AudioPatch* patch) {
+    ALOGD("%p %s: handle %d, device %s, flags %s, source %s, config %s, mix port config %s",
+            this, __func__, ioHandle, device.toString().c_str(),
+            flags.toString().c_str(), toString(source).c_str(),
+            config->toString().c_str(), mixPortConfig->toString().c_str());
+    resetUnusedPatchesAndPortConfigs();
+    const bool isInput = flags.getTag() == AudioIoFlags::Tag::input;
+    // Find / create AudioPortConfigs for the device port and the mix port,
+    // then find / create a patch between them, and open a stream on the mix port.
+    AudioPortConfig devicePortConfig;
+    bool created = false;
+    RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(device, config,
+                                                  &devicePortConfig, &created));
+    if (created) {
+        cleanups->add(&Hal2AidlMapper::resetPortConfig, devicePortConfig.id);
+    }
+    RETURN_STATUS_IF_ERROR(findOrCreatePortConfig(*config, flags, ioHandle, source,
+                    std::set<int32_t>{devicePortConfig.portId}, mixPortConfig, &created));
+    if (created) {
+        cleanups->add(&Hal2AidlMapper::resetPortConfig, mixPortConfig->id);
+    }
+    setConfigFromPortConfig(config, *mixPortConfig);
+    if (isInput) {
+        RETURN_STATUS_IF_ERROR(findOrCreatePatch(
+                        {devicePortConfig.id}, {mixPortConfig->id}, patch, &created));
+    } else {
+        RETURN_STATUS_IF_ERROR(findOrCreatePatch(
+                        {mixPortConfig->id}, {devicePortConfig.id}, patch, &created));
+    }
+    if (created) {
+        cleanups->add(&Hal2AidlMapper::resetPatch, patch->id);
+    }
+    if (config->frameCount <= 0) {
+        config->frameCount = patch->minimumStreamBufferSizeFrames;
+    }
+    return OK;
+}
+
+status_t Hal2AidlMapper::releaseAudioPatch(int32_t patchId) {
+    if (auto it = mPatches.find(patchId); it != mPatches.end()) {
+        mPatches.erase(it);
+        if (ndk::ScopedAStatus status = mModule->resetAudioPatch(patchId); !status.isOk()) {
+            ALOGE("%s: error while resetting patch %d: %s",
+                    __func__, patchId, status.getDescription().c_str());
+            return statusTFromBinderStatus(status);
+        }
+        return OK;
+    }
+    ALOGE("%s: patch id %d not found", __func__, patchId);
+    return BAD_VALUE;
+}
+
+void Hal2AidlMapper::resetPatch(int32_t patchId) {
+    (void)releaseAudioPatch(patchId);
+}
+
+void Hal2AidlMapper::resetPortConfig(int32_t portConfigId) {
+    if (auto it = mPortConfigs.find(portConfigId); it != mPortConfigs.end()) {
+        mPortConfigs.erase(it);
+        if (ndk::ScopedAStatus status = mModule->resetAudioPortConfig(portConfigId);
+                !status.isOk()) {
+            ALOGE("%s: error while resetting port config %d: %s",
+                    __func__, portConfigId, status.getDescription().c_str());
+        }
+        return;
+    }
+    ALOGE("%s: port config id %d not found", __func__, portConfigId);
+}
+
+void Hal2AidlMapper::resetUnusedPatches() {
+    // Since patches can be created independently of streams via 'createAudioPatch',
+    // here we only clean up patches for released streams.
+    for (auto it = mStreams.begin(); it != mStreams.end(); ) {
+        if (auto streamSp = it->first.promote(); streamSp) {
+            ++it;
+        } else {
+            resetPatch(it->second);
+            it = mStreams.erase(it);
+        }
+    }
+}
+
+void Hal2AidlMapper::resetUnusedPatchesAndPortConfigs() {
+    resetUnusedPatches();
+    resetUnusedPortConfigs();
+}
+
+void Hal2AidlMapper::resetUnusedPortConfigs() {
+    // The assumption is that port configs are used to create patches
+    // (or to open streams, but that involves creation of patches, too). Thus,
+    // orphaned port configs can and should be reset.
+    std::map<int32_t, int32_t /*portID*/> portConfigIds;
+    std::transform(mPortConfigs.begin(), mPortConfigs.end(),
+            std::inserter(portConfigIds, portConfigIds.end()),
+            [](const auto& pcPair) { return std::make_pair(pcPair.first, pcPair.second.portId); });
+    for (const auto& p : mPatches) {
+        for (int32_t id : p.second.sourcePortConfigIds) portConfigIds.erase(id);
+        for (int32_t id : p.second.sinkPortConfigIds) portConfigIds.erase(id);
+    }
+    for (int32_t id : mInitialPortConfigIds) {
+        portConfigIds.erase(id);
+    }
+    std::set<int32_t> retryDeviceDisconnection;
+    for (const auto& portConfigAndIdPair : portConfigIds) {
+        resetPortConfig(portConfigAndIdPair.first);
+        if (const auto it = mConnectedPorts.find(portConfigAndIdPair.second);
+                it != mConnectedPorts.end() && it->second) {
+            retryDeviceDisconnection.insert(portConfigAndIdPair.second);
+        }
+    }
+    for (int32_t portId : retryDeviceDisconnection) {
+        if (!isPortHeldByAStream(portId)) {
+            if (auto status = mModule->disconnectExternalDevice(portId); status.isOk()) {
+                eraseConnectedPort(portId);
+                ALOGD("%s: executed postponed external device disconnection for port ID %d",
+                        __func__, portId);
+            }
+        }
+    }
+    if (!retryDeviceDisconnection.empty()) {
+        updateRoutes();
+    }
+}
+
+status_t Hal2AidlMapper::setDevicePortConnectedState(const AudioPort& devicePort, bool connected) {
+    if (connected) {
+        AudioDevice matchDevice = devicePort.ext.get<AudioPortExt::device>().device;
+        std::optional<AudioPort> templatePort;
+        auto erasePortAfterConnectionIt = mPorts.end();
+        // Connection of remote submix out with address "0" is a special case. Since there is
+        // already an "augmented template" port with this address in mPorts, we need to replace
+        // it with a connected port.
+        // Connection of remote submix outs with any other address is done as usual except that
+        // the template port is in `mRemoteSubmixOut`.
+        if (mRemoteSubmixOut.has_value() && matchDevice.type.type == AudioDeviceType::OUT_SUBMIX) {
+            if (matchDevice.address == AudioDeviceAddress::make<AudioDeviceAddress::id>(
+                            AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS)) {
+                erasePortAfterConnectionIt = findPort(matchDevice);
+            }
+            templatePort = mRemoteSubmixOut;
+        } else if (mRemoteSubmixIn.has_value() &&
+                matchDevice.type.type == AudioDeviceType::IN_SUBMIX) {
+            templatePort = mRemoteSubmixIn;
+        } else {
+            // Reset the device address to find the "template" port.
+            matchDevice.address = AudioDeviceAddress::make<AudioDeviceAddress::id>();
+        }
+        if (!templatePort.has_value()) {
+            auto portsIt = findPort(matchDevice);
+            if (portsIt == mPorts.end()) {
+                // Since 'setConnectedState' is called for all modules, it is normal when the device
+                // port not found in every one of them.
+                return BAD_VALUE;
+            } else {
+                ALOGD("%s: device port for device %s found in the module %s",
+                        __func__, matchDevice.toString().c_str(), mInstance.c_str());
+            }
+            templatePort = portsIt->second;
+        }
+        resetUnusedPatchesAndPortConfigs();
+
+        // Use the ID of the "template" port, use all the information from the provided port.
+        AudioPort connectedPort = devicePort;
+        connectedPort.id = templatePort->id;
+        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->connectExternalDevice(
+                                connectedPort, &connectedPort)));
+        const auto [it, inserted] = mPorts.insert(std::make_pair(connectedPort.id, connectedPort));
+        LOG_ALWAYS_FATAL_IF(!inserted,
+                "%s: module %s, duplicate port ID received from HAL: %s, existing port: %s",
+                __func__, mInstance.c_str(), connectedPort.toString().c_str(),
+                it->second.toString().c_str());
+        mConnectedPorts[connectedPort.id] = false;
+        if (erasePortAfterConnectionIt != mPorts.end()) {
+            mPorts.erase(erasePortAfterConnectionIt);
+        }
+    } else {  // !connected
+        AudioDevice matchDevice = devicePort.ext.get<AudioPortExt::device>().device;
+        auto portsIt = findPort(matchDevice);
+        if (portsIt == mPorts.end()) {
+            // Since 'setConnectedState' is called for all modules, it is normal when the device
+            // port not found in every one of them.
+            return BAD_VALUE;
+        } else {
+            ALOGD("%s: device port for device %s found in the module %s",
+                    __func__, matchDevice.toString().c_str(), mInstance.c_str());
+        }
+        resetUnusedPatchesAndPortConfigs();
+
+        // Disconnection of remote submix out with address "0" is a special case. We need to replace
+        // the connected port entry with the "augmented template".
+        const int32_t portId = portsIt->second.id;
+        if (mRemoteSubmixOut.has_value() && matchDevice.type.type == AudioDeviceType::OUT_SUBMIX &&
+                matchDevice.address == AudioDeviceAddress::make<AudioDeviceAddress::id>(
+                        AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS)) {
+            mDisconnectedPortReplacement = std::make_pair(portId, *mRemoteSubmixOut);
+            auto& port = mDisconnectedPortReplacement.second;
+            port.ext.get<AudioPortExt::Tag::device>().device = matchDevice;
+            port.profiles = portsIt->second.profiles;
+        }
+        // Streams are closed by AudioFlinger independently from device disconnections.
+        // It is possible that the stream has not been closed yet.
+        if (!isPortHeldByAStream(portId)) {
+            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+                            mModule->disconnectExternalDevice(portId)));
+            eraseConnectedPort(portId);
+        } else {
+            ALOGD("%s: since device port ID %d is used by a stream, "
+                    "external device disconnection postponed", __func__, portId);
+            mConnectedPorts[portId] = true;
+        }
+    }
+    return updateRoutes();
+}
+
+status_t Hal2AidlMapper::updateAudioPort(int32_t portId, AudioPort* port) {
+    const status_t status = statusTFromBinderStatus(mModule->getAudioPort(portId, port));
+    if (status == OK) {
+        auto portIt = mPorts.find(portId);
+        if (portIt != mPorts.end()) {
+            portIt->second = *port;
+        } else {
+            ALOGW("%s, port(%d) returned successfully from the HAL but not it is not cached",
+                  __func__, portId);
+        }
+    }
+    return status;
+}
+
+status_t Hal2AidlMapper::updateRoutes() {
+    RETURN_STATUS_IF_ERROR(
+            statusTFromBinderStatus(mModule->getAudioRoutes(&mRoutes)));
+    ALOGW_IF(mRoutes.empty(), "%s: module %s returned an empty list of audio routes",
+            __func__, mInstance.c_str());
+    if (mRemoteSubmixIn.has_value()) {
+        // Remove mentions of the template remote submix input from routes.
+        int32_t rSubmixInId = mRemoteSubmixIn->id;
+        // Remove mentions of the template remote submix out only if it is not in mPorts
+        // (that means there is a connected port in mPorts).
+        int32_t rSubmixOutId = mPorts.find(mRemoteSubmixOut->id) == mPorts.end() ?
+                mRemoteSubmixOut->id : -1;
+        for (auto it = mRoutes.begin(); it != mRoutes.end();) {
+            auto& route = *it;
+            if (route.sinkPortId == rSubmixOutId) {
+                it = mRoutes.erase(it);
+                continue;
+            }
+            if (auto routeIt = std::find(route.sourcePortIds.begin(), route.sourcePortIds.end(),
+                            rSubmixInId); routeIt != route.sourcePortIds.end()) {
+                route.sourcePortIds.erase(routeIt);
+                if (route.sourcePortIds.empty()) {
+                    it = mRoutes.erase(it);
+                    continue;
+                }
+            }
+            ++it;
+        }
+    }
+    mRoutingMatrix.clear();
+    for (const auto& r : mRoutes) {
+        for (auto portId : r.sourcePortIds) {
+            mRoutingMatrix.emplace(r.sinkPortId, portId);
+            mRoutingMatrix.emplace(portId, r.sinkPortId);
+        }
+    }
+    return OK;
+}
+
+} // namespace android
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.h b/media/libaudiohal/impl/Hal2AidlMapper.h
new file mode 100644
index 0000000..9283fb4
--- /dev/null
+++ b/media/libaudiohal/impl/Hal2AidlMapper.h
@@ -0,0 +1,177 @@
+/*
+ * 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
+
+#include <memory>
+#include <map>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include <aidl/android/hardware/audio/core/IModule.h>
+#include <media/AidlConversionUtil.h>
+
+#include "Cleanups.h"
+
+namespace android {
+
+class Hal2AidlMapper;
+class StreamHalInterface;
+
+// The mapper class is needed because the framework was not yet updated to operate on AIDL-based
+// structures directly. Mapper does the job of translating the "legacy" way of identifying ports
+// and port configs (by device addresses and I/O handles) into AIDL IDs. Once the framework will
+// be updated to provide these IDs directly to libaudiohal, the need for the mapper will cease.
+class Hal2AidlMapper {
+  public:
+    using Cleanups = Cleanups<Hal2AidlMapper>;
+
+    Hal2AidlMapper(
+            const std::string& instance,
+            const std::shared_ptr<::aidl::android::hardware::audio::core::IModule>& module);
+
+    void addStream(const sp<StreamHalInterface>& stream, int32_t patchId);
+    status_t createOrUpdatePatch(
+            const std::vector<::aidl::android::media::audio::common::AudioPortConfig>& sources,
+            const std::vector<::aidl::android::media::audio::common::AudioPortConfig>& sinks,
+            int32_t* patchId, Cleanups* cleanups);
+    status_t findOrCreatePortConfig(
+            const ::aidl::android::media::audio::common::AudioDevice& device,
+            const ::aidl::android::media::audio::common::AudioConfig* config,
+            ::aidl::android::media::audio::common::AudioPortConfig* portConfig,
+            bool* created);
+    status_t findOrCreatePortConfig(
+            const ::aidl::android::media::audio::common::AudioConfig& config,
+            const std::optional<::aidl::android::media::audio::common::AudioIoFlags>& flags,
+            int32_t ioHandle,
+            ::aidl::android::media::audio::common::AudioSource source,
+            const std::set<int32_t>& destinationPortIds,
+            ::aidl::android::media::audio::common::AudioPortConfig* portConfig, bool* created);
+    status_t findOrCreatePortConfig(
+        const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
+        const std::set<int32_t>& destinationPortIds,
+        ::aidl::android::media::audio::common::AudioPortConfig* portConfig, bool* created);
+    status_t findOrCreatePortConfig(
+        const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
+        const std::set<int32_t>& destinationPortIds,
+        ::aidl::android::media::audio::common::AudioPortConfig* portConfig,
+        Cleanups* cleanups = nullptr);
+    status_t findPortConfig(
+            const ::aidl::android::media::audio::common::AudioDevice& device,
+            ::aidl::android::media::audio::common::AudioPortConfig* portConfig);
+    status_t getAudioMixPort(
+            int32_t ioHandle, ::aidl::android::media::audio::common::AudioPort* port);
+    status_t getAudioPortCached(
+            const ::aidl::android::media::audio::common::AudioDevice& device,
+            ::aidl::android::media::audio::common::AudioPort* port);
+    template<typename OutputContainer, typename Func>
+    status_t getAudioPorts(OutputContainer* ports, Func converter) {
+        return ::aidl::android::convertContainer(mPorts, ports,
+                [&converter](const auto& pair) { return converter(pair.second); });
+    }
+    template<typename OutputContainer, typename Func>
+    status_t getAudioRoutes(OutputContainer* routes, Func converter) {
+        return ::aidl::android::convertContainer(mRoutes, routes, converter);
+    }
+    status_t initialize();
+    status_t prepareToOpenStream(
+        int32_t ioHandle,
+        const ::aidl::android::media::audio::common::AudioDevice& device,
+        const ::aidl::android::media::audio::common::AudioIoFlags& flags,
+        ::aidl::android::media::audio::common::AudioSource source,
+        Cleanups* cleanups,
+        ::aidl::android::media::audio::common::AudioConfig* config,
+        ::aidl::android::media::audio::common::AudioPortConfig* mixPortConfig,
+        ::aidl::android::hardware::audio::core::AudioPatch* patch);
+    status_t releaseAudioPatch(int32_t patchId);
+    void resetUnusedPatchesAndPortConfigs();
+    status_t setDevicePortConnectedState(
+            const ::aidl::android::media::audio::common::AudioPort& devicePort, bool connected);
+
+  private:
+    // IDs of ports for connected external devices, and whether they are held by streams.
+    using ConnectedPorts = std::map<int32_t /*port ID*/, bool>;
+    using Patches = std::map<int32_t /*patch ID*/,
+            ::aidl::android::hardware::audio::core::AudioPatch>;
+    using PortConfigs = std::map<int32_t /*port config ID*/,
+            ::aidl::android::media::audio::common::AudioPortConfig>;
+    using Ports = std::map<int32_t /*port ID*/, ::aidl::android::media::audio::common::AudioPort>;
+    using Routes = std::vector<::aidl::android::hardware::audio::core::AudioRoute>;
+    // Answers the question "whether portID 'first' is reachable from portID 'second'?"
+    // It's not a map because both portIDs are known. The matrix is symmetric.
+    using RoutingMatrix = std::set<std::pair<int32_t, int32_t>>;
+    using Streams = std::map<wp<StreamHalInterface>, int32_t /*patch ID*/>;
+
+    const std::string mInstance;
+    const std::shared_ptr<::aidl::android::hardware::audio::core::IModule> mModule;
+
+    bool audioDeviceMatches(const ::aidl::android::media::audio::common::AudioDevice& device,
+            const ::aidl::android::media::audio::common::AudioPort& p);
+    bool audioDeviceMatches(const ::aidl::android::media::audio::common::AudioDevice& device,
+            const ::aidl::android::media::audio::common::AudioPortConfig& p);
+    status_t createOrUpdatePortConfig(
+            const ::aidl::android::media::audio::common::AudioPortConfig& requestedPortConfig,
+            PortConfigs::iterator* result, bool *created);
+    void eraseConnectedPort(int32_t portId);
+    status_t findOrCreatePatch(
+        const std::set<int32_t>& sourcePortConfigIds,
+        const std::set<int32_t>& sinkPortConfigIds,
+        ::aidl::android::hardware::audio::core::AudioPatch* patch, bool* created);
+    status_t findOrCreatePatch(
+        const ::aidl::android::hardware::audio::core::AudioPatch& requestedPatch,
+        ::aidl::android::hardware::audio::core::AudioPatch* patch, bool* created);
+    Patches::iterator findPatch(const std::set<int32_t>& sourcePortConfigIds,
+            const std::set<int32_t>& sinkPortConfigIds);
+    Ports::iterator findPort(const ::aidl::android::media::audio::common::AudioDevice& device);
+    Ports::iterator findPort(
+            const ::aidl::android::media::audio::common::AudioConfig& config,
+            const ::aidl::android::media::audio::common::AudioIoFlags& flags,
+            const std::set<int32_t>& destinationPortIds);
+    PortConfigs::iterator findPortConfig(
+            const ::aidl::android::media::audio::common::AudioDevice& device);
+    PortConfigs::iterator findPortConfig(
+            const std::optional<::aidl::android::media::audio::common::AudioConfig>& config,
+            const std::optional<::aidl::android::media::audio::common::AudioIoFlags>& flags,
+            int32_t ioHandle);
+    bool isPortHeldByAStream(int32_t portId);
+    void resetPatch(int32_t patchId);
+    void resetPortConfig(int32_t portConfigId);
+    void resetUnusedPatches();
+    void resetUnusedPortConfigs();
+    status_t updateAudioPort(
+            int32_t portId, ::aidl::android::media::audio::common::AudioPort* port);
+    status_t updateRoutes();
+
+    Ports mPorts;
+    // Remote submix "template" ports (no address specified, no profiles).
+    // They are excluded from `mPorts` as their presence confuses the framework code.
+    std::optional<::aidl::android::media::audio::common::AudioPort> mRemoteSubmixIn;
+    std::optional<::aidl::android::media::audio::common::AudioPort> mRemoteSubmixOut;
+    int32_t mDefaultInputPortId = -1;
+    int32_t mDefaultOutputPortId = -1;
+    PortConfigs mPortConfigs;
+    std::set<int32_t> mInitialPortConfigIds;
+    Patches mPatches;
+    Routes mRoutes;
+    RoutingMatrix mRoutingMatrix;
+    Streams mStreams;
+    ConnectedPorts mConnectedPorts;
+    std::pair<int32_t, ::aidl::android::media::audio::common::AudioPort>
+            mDisconnectedPortReplacement;
+};
+
+}  // namespace android
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index e74fc16..378d919 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -83,6 +83,7 @@
           mContext(std::move(context)),
           mStream(stream),
           mVendorExt(vext) {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     {
         std::lock_guard l(mLock);
         mLastReply.latencyMs = nominalLatency;
@@ -97,6 +98,7 @@
 }
 
 StreamHalAidl::~StreamHalAidl() {
+    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
     if (mStream != nullptr) {
         ndk::ScopedAStatus status = mStream->close();
         ALOGE_IF(!status.isOk(), "%s: status %s", __func__, status.getDescription().c_str());
