diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
new file mode 100644
index 0000000..51ac5f5
--- /dev/null
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2015 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 "APM::Devices"
+//#define LOG_NDEBUG 0
+
+#include <audio_utils/string.h>
+#include <media/TypeConverter.h>
+#include <set>
+#include "DeviceDescriptor.h"
+#include "TypeConverter.h"
+#include "HwModule.h"
+
+namespace android {
+
+DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const std::string &tagName) :
+        DeviceDescriptor(type, FormatVector{}, tagName)
+{
+}
+
+DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats,
+        const std::string &tagName) :
+    AudioPort("", AUDIO_PORT_TYPE_DEVICE,
+              audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
+                                             AUDIO_PORT_ROLE_SOURCE),
+    mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats)
+{
+    mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
+    if (audio_is_remote_submix_device(type)) {
+        mAddress = String8("0");
+    }
+    /* If framework runs against a pre 5.0 Audio HAL, encoded formats are absent from the config.
+     * FIXME: APM should know the version of the HAL and don't add the formats for V5.0.
+     * For now, the workaround to remove AC3 and IEC61937 support on HDMI is to declare
+     * something like 'encodedFormats="AUDIO_FORMAT_PCM_16_BIT"' on the HDMI devicePort.
+     */
+    if (type == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.empty()) {
+        mEncodedFormats.push_back(AUDIO_FORMAT_AC3);
+        mEncodedFormats.push_back(AUDIO_FORMAT_IEC61937);
+    }
+}
+
+void DeviceDescriptor::attach(const sp<HwModule>& module)
+{
+    PolicyAudioPort::attach(module);
+    mId = getNextUniqueId();
+}
+
+void DeviceDescriptor::detach() {
+    mId = AUDIO_PORT_HANDLE_NONE;
+    PolicyAudioPort::detach();
+}
+
+template<typename T>
+bool checkEqual(const T& f1, const T& f2)
+{
+    std::set<typename T::value_type> s1(f1.begin(), f1.end());
+    std::set<typename T::value_type> s2(f2.begin(), f2.end());
+    return s1 == s2;
+}
+
+bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
+{
+    // Devices are considered equal if they:
+    // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
+    // - have the same address
+    // - have the same encodingFormats (if device supports encoding)
+    if (other == 0) {
+        return false;
+    }
+
+    return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress) &&
+           checkEqual(mEncodedFormats, other->mEncodedFormats);
+}
+
+bool DeviceDescriptor::hasCurrentEncodedFormat() const
+{
+    if (!device_has_encoding_capability(type())) {
+        return true;
+    }
+    if (mEncodedFormats.empty()) {
+        return true;
+    }
+
+    return (mCurrentEncodedFormat != AUDIO_FORMAT_DEFAULT);
+}
+
+bool DeviceDescriptor::supportsFormat(audio_format_t format)
+{
+    if (mEncodedFormats.empty()) {
+        return true;
+    }
+
+    for (const auto& devFormat : mEncodedFormats) {
+        if (devFormat == format) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void DeviceVector::refreshTypes()
+{
+    mDeviceTypes = AUDIO_DEVICE_NONE;
+    for (size_t i = 0; i < size(); i++) {
+        mDeviceTypes |= itemAt(i)->type();
+    }
+    ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
+}
+
+ssize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
+{
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->equals(item)) { // item may be null sp<>, i.e. AUDIO_DEVICE_NONE
+            return i;
+        }
+    }
+    return -1;
+}
+
+void DeviceVector::add(const DeviceVector &devices)
+{
+    bool added = false;
+    for (const auto& device : devices) {
+        if (indexOf(device) < 0 && SortedVector::add(device) >= 0) {
+            added = true;
+        }
+    }
+    if (added) {
+        refreshTypes();
+    }
+}
+
+ssize_t DeviceVector::add(const sp<DeviceDescriptor>& item)
+{
+    ssize_t ret = indexOf(item);
+
+    if (ret < 0) {
+        ret = SortedVector::add(item);
+        if (ret >= 0) {
+            refreshTypes();
+        }
+    } else {
+        ALOGW("DeviceVector::add device %08x already in", item->type());
+        ret = -1;
+    }
+    return ret;
+}
+
+ssize_t DeviceVector::remove(const sp<DeviceDescriptor>& item)
+{
+    ssize_t ret = indexOf(item);
+
+    if (ret < 0) {
+        ALOGW("DeviceVector::remove device %08x not in", item->type());
+    } else {
+        ret = SortedVector::removeAt(ret);
+        if (ret >= 0) {
+            refreshTypes();
+        }
+    }
+    return ret;
+}
+
+void DeviceVector::remove(const DeviceVector &devices)
+{
+    for (const auto& device : devices) {
+        remove(device);
+    }
+}
+
+DeviceVector DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
+{
+    DeviceVector devices;
+    for (const auto& device : *this) {
+        if (device->getModuleHandle() == moduleHandle) {
+            devices.add(device);
+        }
+    }
+    return devices;
+}
+
+audio_devices_t DeviceVector::getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const
+{
+    audio_devices_t deviceTypes = AUDIO_DEVICE_NONE;
+    for (const auto& device : *this) {
+        if (device->getModuleHandle() == moduleHandle) {
+            deviceTypes |= device->type();
+        }
+    }
+    return deviceTypes;
+}
+
+sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address,
+                                             audio_format_t format) const
+{
+    sp<DeviceDescriptor> device;
+    for (size_t i = 0; i < size(); i++) {
+        if (itemAt(i)->type() == type) {
+            // If format is specified, match it and ignore address
+            // Otherwise if address is specified match it
+            // Otherwise always match
+            if (((address == "" || itemAt(i)->address() == address) &&
+                 format == AUDIO_FORMAT_DEFAULT) ||
+                (itemAt(i)->supportsFormat(format) && format != AUDIO_FORMAT_DEFAULT)) {
+                device = itemAt(i);
+                if (itemAt(i)->address() == address) {
+                    break;
+                }
+            }
+        }
+    }
+    ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p format %08x",
+            __func__, type, address.string(), device.get(), format);
+    return device;
+}
+
+sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
+{
+    if (id != AUDIO_PORT_HANDLE_NONE) {
+        for (const auto& device : *this) {
+            if (device->getId() == id) {
+                return device;
+            }
+        }
+    }
+    return nullptr;
+}
+
+DeviceVector DeviceVector::getDevicesFromTypeMask(audio_devices_t type) const
+{
+    DeviceVector devices;
+    bool isOutput = audio_is_output_devices(type);
+    type &= ~AUDIO_DEVICE_BIT_IN;
+    for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
+        bool curIsOutput = audio_is_output_devices(itemAt(i)->type());
+        audio_devices_t curType = itemAt(i)->type() & ~AUDIO_DEVICE_BIT_IN;
+        if ((isOutput == curIsOutput) && ((type & curType) != 0)) {
+            devices.add(itemAt(i));
+            ALOGV("DeviceVector::%s() for type %08x found %p",
+                    __func__, itemAt(i)->type(), itemAt(i).get());
+        }
+    }
+    return devices;
+}
+
+sp<DeviceDescriptor> DeviceVector::getDeviceFromTagName(const std::string &tagName) const
+{
+    for (const auto& device : *this) {
+        if (device->getTagName() == tagName) {
+            return device;
+        }
+    }
+    return nullptr;
+}
+
+DeviceVector DeviceVector::getFirstDevicesFromTypes(
+        std::vector<audio_devices_t> orderedTypes) const
+{
+    DeviceVector devices;
+    for (auto deviceType : orderedTypes) {
+        if (!(devices = getDevicesFromTypeMask(deviceType)).isEmpty()) {
+            break;
+        }
+    }
+    return devices;
+}
+
+sp<DeviceDescriptor> DeviceVector::getFirstExistingDevice(
+        std::vector<audio_devices_t> orderedTypes) const {
+    sp<DeviceDescriptor> device;
+    for (auto deviceType : orderedTypes) {
+        if ((device = getDevice(deviceType, String8(""), AUDIO_FORMAT_DEFAULT)) != nullptr) {
+            break;
+        }
+    }
+    return device;
+}
+
+void DeviceVector::replaceDevicesByType(
+        audio_devices_t typeToRemove, const DeviceVector &devicesToAdd) {
+    DeviceVector devicesToRemove = getDevicesFromTypeMask(typeToRemove);
+    if (!devicesToRemove.isEmpty() && !devicesToAdd.isEmpty()) {
+        remove(devicesToRemove);
+        add(devicesToAdd);
+    }
+}
+
+void DeviceVector::dump(String8 *dst, const String8 &tag, int spaces, bool verbose) const
+{
+    if (isEmpty()) {
+        return;
+    }
+    dst->appendFormat("%*s- %s devices:\n", spaces, "", tag.string());
+    for (size_t i = 0; i < size(); i++) {
+        itemAt(i)->dump(dst, spaces + 2, i, verbose);
+    }
+}
+
+status_t DeviceDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
+                                                audio_port_config *backupConfig)
+{
+    struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
+    status_t status = NO_ERROR;
+
+    toAudioPortConfig(&localBackupConfig);
+    if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
+        AudioPortConfig::applyAudioPortConfig(config, backupConfig);
+        applyPolicyAudioPortConfig(config);
+    }
+
+    if (backupConfig != NULL) {
+        *backupConfig = localBackupConfig;
+    }
+    return status;
+}
+
+void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
+                                         const struct audio_port_config *srcConfig) const
+{
+    dstConfig->config_mask = AUDIO_PORT_CONFIG_GAIN;
+    if (mSamplingRate != 0) {
+        dstConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
+    }
+    if (mChannelMask != AUDIO_CHANNEL_NONE) {
+        dstConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
+    }
+    if (mFormat != AUDIO_FORMAT_INVALID) {
+        dstConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
+    }
+
+    if (srcConfig != NULL) {
+        dstConfig->config_mask |= srcConfig->config_mask;
+    }
+
+    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
+    toPolicyAudioPortConfig(dstConfig, srcConfig);
+
+    dstConfig->role = audio_is_output_device(mDeviceType) ?
+                        AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
+    dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
+    dstConfig->ext.device.type = mDeviceType;
+
+    //TODO Understand why this test is necessary. i.e. why at boot time does it crash
+    // without the test?
+    // This has been demonstrated to NOT be true (at start up)
+    // ALOG_ASSERT(mModule != NULL);
+    dstConfig->ext.device.hw_module = getModuleHandle();
+    (void)audio_utils_strlcpy_zerofill(dstConfig->ext.device.address, mAddress.string());
+}
+
+void DeviceDescriptor::toAudioPort(struct audio_port *port) const
+{
+    ALOGV("DeviceDescriptor::toAudioPort() handle %d type %08x", mId, mDeviceType);
+    AudioPort::toAudioPort(port);
+    port->id = mId;
+    toAudioPortConfig(&port->active_config);
+    port->ext.device.type = mDeviceType;
+    port->ext.device.hw_module = getModuleHandle();
+    (void)audio_utils_strlcpy_zerofill(port->ext.device.address, mAddress.string());
+}
+
+void DeviceDescriptor::importAudioPortAndPickAudioProfile(
+        const sp<PolicyAudioPort>& policyPort, bool force) {
+    if (!force && !policyPort->asAudioPort()->hasDynamicAudioProfile()) {
+        return;
+    }
+    AudioPort::importAudioPort(policyPort->asAudioPort());
+    policyPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
+}
+
+void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) const
+{
+    dst->appendFormat("%*sDevice %d:\n", spaces, "", index + 1);
+    if (mId != 0) {
+        dst->appendFormat("%*s- id: %2d\n", spaces, "", mId);
+    }
+    if (!mTagName.empty()) {
+        dst->appendFormat("%*s- tag name: %s\n", spaces, "", mTagName.c_str());
+    }
+
+    dst->appendFormat("%*s- type: %-48s\n", spaces, "", ::android::toString(mDeviceType).c_str());
+
+    if (mAddress.size() != 0) {
+        dst->appendFormat("%*s- address: %-32s\n", spaces, "", mAddress.string());
+    }
+    std::string portStr;
+    AudioPort::dump(&portStr, spaces, verbose);
+    dst->append(portStr.c_str());
+}
+
+std::string DeviceDescriptor::toString() const
+{
+    std::stringstream sstream;
+    sstream << "type:0x" << std::hex << type() << ",@:" << mAddress;
+    return sstream.str();
+}
+
+std::string DeviceVector::toString() const
+{
+    if (isEmpty()) {
+        return {"AUDIO_DEVICE_NONE"};
+    }
+    std::string result = {"{"};
+    for (const auto &device : *this) {
+        if (device != *begin()) {
+           result += ";";
+        }
+        result += device->toString();
+    }
+    return result + "}";
+}
+
+DeviceVector DeviceVector::filter(const DeviceVector &devices) const
+{
+    DeviceVector filteredDevices;
+    for (const auto &device : *this) {
+        if (devices.contains(device)) {
+            filteredDevices.add(device);
+        }
+    }
+    return filteredDevices;
+}
+
+bool DeviceVector::containsAtLeastOne(const DeviceVector &devices) const
+{
+    return !filter(devices).isEmpty();
+}
+
+bool DeviceVector::containsAllDevices(const DeviceVector &devices) const
+{
+    return filter(devices).size() == devices.size();
+}
+
+DeviceVector DeviceVector::filterForEngine() const
+{
+    DeviceVector filteredDevices;
+    for (const auto &device : *this) {
+        if (audio_is_remote_submix_device(device->type()) && device->address() != "0") {
+            continue;
+        }
+        filteredDevices.add(device);
+    }
+    return filteredDevices;
+}
+
+void DeviceDescriptor::log() const
+{
+    ALOGI("Device id:%d type:0x%08X:%s, addr:%s", mId,  mDeviceType,
+          ::android::toString(mDeviceType).c_str(),
+          mAddress.string());
+
+    AudioPort::log("  ");
+}
+
+} // namespace android
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
new file mode 100644
index 0000000..6c1035c
--- /dev/null
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2015 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 "PolicyAudioPort.h"
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/SortedVector.h>
+#include <cutils/config_utils.h>
+#include <system/audio.h>
+#include <system/audio_policy.h>
+
+namespace android {
+
+class DeviceDescriptor : public AudioPort, public AudioPortConfig,
+                         public PolicyAudioPort, public PolicyAudioPortConfig
+{
+public:
+     // Note that empty name refers by convention to a generic device.
+    explicit DeviceDescriptor(audio_devices_t type, const std::string &tagName = "");
+    DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats,
+            const std::string &tagName = "");
+
+    virtual ~DeviceDescriptor() {}
+
+    virtual void addAudioProfile(const sp<AudioProfile> &profile) {
+        addAudioProfileAndSort(mProfiles, profile);
+    }
+
+    virtual const std::string getTagName() const { return mTagName; }
+
+    audio_devices_t type() const { return mDeviceType; }
+    String8 address() const { return mAddress; }
+    void setAddress(const String8 &address) { mAddress = address; }
+
+    const FormatVector& encodedFormats() const { return mEncodedFormats; }
+
+    audio_format_t getEncodedFormat() { return mCurrentEncodedFormat; }
+
+    void setEncodedFormat(audio_format_t format) {
+        mCurrentEncodedFormat = format;
+    }
+
+    bool equals(const sp<DeviceDescriptor>& other) const;
+
+    bool hasCurrentEncodedFormat() const;
+
+    bool supportsFormat(audio_format_t format);
+
+    // PolicyAudioPortConfig
+    virtual sp<PolicyAudioPort> getPolicyAudioPort() const {
+        return static_cast<PolicyAudioPort*>(const_cast<DeviceDescriptor*>(this));
+    }
+
+    // AudioPortConfig
+    virtual sp<AudioPort> getAudioPort() const {
+        return static_cast<AudioPort*>(const_cast<DeviceDescriptor*>(this));
+    }
+    virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
+                                          struct audio_port_config *backupConfig = NULL);
+    virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
+            const struct audio_port_config *srcConfig = NULL) const;
+
+    // PolicyAudioPort
+    virtual sp<AudioPort> asAudioPort() const {
+        return static_cast<AudioPort*>(const_cast<DeviceDescriptor*>(this));
+    }
+    virtual void attach(const sp<HwModule>& module);
+    virtual void detach();
+
+    // AudioPort
+    virtual void toAudioPort(struct audio_port *port) const;
+
+    void importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort>& policyPort,
+                                            bool force = false);
+
+    void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
+    void log() const;
+    std::string toString() const;
+
+private:
+    String8 mAddress{""};
+    std::string mTagName; // Unique human readable identifier for a device port found in conf file.
+    audio_devices_t     mDeviceType;
+    FormatVector        mEncodedFormats;
+    audio_format_t      mCurrentEncodedFormat;
+};
+
+class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
+{
+public:
+    DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
+    explicit DeviceVector(const sp<DeviceDescriptor>& item) : DeviceVector()
+    {
+        add(item);
+    }
+
+    ssize_t add(const sp<DeviceDescriptor>& item);
+    void add(const DeviceVector &devices);
+    ssize_t remove(const sp<DeviceDescriptor>& item);
+    void remove(const DeviceVector &devices);
+    ssize_t indexOf(const sp<DeviceDescriptor>& item) const;
+
+    audio_devices_t types() const { return mDeviceTypes; }
+
+    // If 'address' is empty and 'codec' is AUDIO_FORMAT_DEFAULT, a device with a non-empty
+    // address may be returned if there is no device with the specified 'type' and empty address.
+    sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address,
+                                   audio_format_t codec) const;
+    DeviceVector getDevicesFromTypeMask(audio_devices_t types) const;
+
+    /**
+     * @brief getDeviceFromId
+     * @param id of the DeviceDescriptor to seach (aka Port handle).
+     * @return DeviceDescriptor associated to port id if found, nullptr otherwise. If the id is
+     * equal to AUDIO_PORT_HANDLE_NONE, it also returns a nullptr.
+     */
+    sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
+    sp<DeviceDescriptor> getDeviceFromTagName(const std::string &tagName) const;
+    DeviceVector getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
+    audio_devices_t getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const;
+
+    DeviceVector getFirstDevicesFromTypes(std::vector<audio_devices_t> orderedTypes) const;
+    sp<DeviceDescriptor> getFirstExistingDevice(std::vector<audio_devices_t> orderedTypes) const;
+
+    // If there are devices with the given type and the devices to add is not empty,
+    // remove all the devices with the given type and add all the devices to add.
+    void replaceDevicesByType(audio_devices_t typeToRemove, const DeviceVector &devicesToAdd);
+
+    bool contains(const sp<DeviceDescriptor>& item) const { return indexOf(item) >= 0; }
+
+    /**
+     * @brief containsAtLeastOne
+     * @param devices vector of devices to check against.
+     * @return true if the DeviceVector contains at list one of the devices from the given vector.
+     */
+    bool containsAtLeastOne(const DeviceVector &devices) const;
+
+    /**
+     * @brief containsAllDevices
+     * @param devices vector of devices to check against.
+     * @return true if the DeviceVector contains all the devices from the given vector
+     */
+    bool containsAllDevices(const DeviceVector &devices) const;
+
+    /**
+     * @brief filter the devices supported by this collection against another collection
+     * @param devices to filter against
+     * @return a filtered DeviceVector
+     */
+    DeviceVector filter(const DeviceVector &devices) const;
+
+    /**
+     * @brief filter the devices supported by this collection before sending
+     * then to the Engine via AudioPolicyManagerObserver interface
+     * @return a filtered DeviceVector
+     */
+    DeviceVector filterForEngine() const;
+
+    /**
+     * @brief merge two vectors. As SortedVector Implementation is buggy (it does not check the size
+     * of the destination vector, only of the source, it provides a safe implementation
+     * @param devices source device vector to merge with
+     * @return size of the merged vector.
+     */
+    ssize_t merge(const DeviceVector &devices)
+    {
+        if (isEmpty()) {
+            add(devices);
+            return size();
+        }
+        return SortedVector::merge(devices);
+    }
+
+    /**
+     * @brief operator == DeviceVector are equals if all the DeviceDescriptor can be found (aka
+     * DeviceDescriptor with same type and address) and the vector has same size.
+     * @param right DeviceVector to compare to.
+     * @return true if right contains the same device and has the same size.
+     */
+    bool operator==(const DeviceVector &right) const
+    {
+        if (size() != right.size()) {
+            return false;
+        }
+        for (const auto &device : *this) {
+            if (right.indexOf(device) < 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    bool operator!=(const DeviceVector &right) const
+    {
+        return !operator==(right);
+    }
+
+    /**
+     * @brief getFirstValidAddress
+     * @return the first valid address of a list of device, "" if no device with valid address
+     * found.
+     * This helper function helps maintaining compatibility with legacy where we used to have a
+     * devices mask and an address.
+     */
+    String8 getFirstValidAddress() const
+    {
+        for (const auto &device : *this) {
+            if (device->address() != "") {
+                return device->address();
+            }
+        }
+        return String8("");
+    }
+
+    std::string toString() const;
+
+    void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;
+
+private:
+    void refreshTypes();
+    audio_devices_t mDeviceTypes;
+};
+
+} // namespace android
