Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2336de89 authored by jiabin's avatar jiabin
Browse files

Allow to set/get/remove disabled devices for strategy/capture preset.

Cache the disabled devices as a list for strategy/capture preset. The
preferred devices list and disabled devices list are mutually exclusive.
Once a device is in a list, it must be removed from the other list.

Bug: 184065221
Test: atest AudioServiceHostTest, audiopolicy_tests
Change-Id: I3477c089f8a1c89f82c692637295c1cf25a91593
parent a4bfdc34
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -170,11 +170,13 @@ private:
    status_t getMediaDevicesForRole(device_role_t role, const DeviceVector& availableDevices,
    status_t getMediaDevicesForRole(device_role_t role, const DeviceVector& availableDevices,
            DeviceVector& devices) const;
            DeviceVector& devices) const;


    void dumpCapturePresetDevicesRoleMap(String8 *dst, int spaces) const;

    AudioPolicyManagerObserver *mApmObserver = nullptr;
    AudioPolicyManagerObserver *mApmObserver = nullptr;


    ProductStrategyMap mProductStrategies;
    ProductStrategyMap mProductStrategies;
    ProductStrategyPreferredRoutingMap mProductStrategyPreferredDevices;
    ProductStrategyDevicesRoleMap mProductStrategyDeviceRoleMap;
    CapturePresetDevicesRoleMap mCapturePresetDevicesRole;
    CapturePresetDevicesRoleMap mCapturePresetDevicesRoleMap;
    VolumeGroupMap mVolumeGroups;
    VolumeGroupMap mVolumeGroups;
    LastRemovableMediaDevices mLastRemovableMediaDevices;
    LastRemovableMediaDevices mLastRemovableMediaDevices;
    audio_mode_t mPhoneState = AUDIO_MODE_NORMAL;  /**< current phone state. */
    audio_mode_t mPhoneState = AUDIO_MODE_NORMAL;  /**< current phone state. */
+15 −14
Original line number Original line Diff line number Diff line
@@ -18,20 +18,20 @@


#include "VolumeGroup.h"
#include "VolumeGroup.h"


#include <system/audio.h>
#include <map>
#include <utils/RefBase.h>
#include <HandleGenerator.h>
#include <string>
#include <string>
#include <utility>
#include <vector>
#include <vector>
#include <map>

#include <utils/Errors.h>
#include <HandleGenerator.h>
#include <utils/String8.h>
#include <media/AudioAttributes.h>
#include <media/AudioAttributes.h>
#include <media/AudioContainers.h>
#include <media/AudioContainers.h>
#include <media/AudioDeviceTypeAddr.h>
#include <media/AudioDeviceTypeAddr.h>
#include <media/AudioPolicy.h>
#include <media/AudioPolicy.h>

#include <system/audio.h>
#include <vector>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/String8.h>


namespace android {
namespace android {


@@ -170,11 +170,12 @@ private:
    product_strategy_t mDefaultStrategy = PRODUCT_STRATEGY_NONE;
    product_strategy_t mDefaultStrategy = PRODUCT_STRATEGY_NONE;
};
};


class ProductStrategyPreferredRoutingMap : public std::map<product_strategy_t,
using ProductStrategyDevicesRoleMap =
                                                           AudioDeviceTypeAddrVector>
        std::map<std::pair<product_strategy_t, device_role_t>, AudioDeviceTypeAddrVector>;
{

public:
void dumpProductStrategyDevicesRoleMap(
    void dump(String8 *dst, int spaces = 0) const;
        const ProductStrategyDevicesRoleMap& productStrategyDeviceRoleMap,
};
        String8 *dst,
        int spaces);


} // namespace android
} // namespace android
+125 −133
Original line number Original line Diff line number Diff line
@@ -17,6 +17,8 @@
#define LOG_TAG "APM::AudioPolicyEngine/Base"
#define LOG_TAG "APM::AudioPolicyEngine/Base"
//#define LOG_NDEBUG 0
//#define LOG_NDEBUG 0


#include <functional>
#include <string>
#include <sys/stat.h>
#include <sys/stat.h>


#include "EngineBase.h"
#include "EngineBase.h"
@@ -349,23 +351,33 @@ status_t EngineBase::listAudioVolumeGroups(AudioVolumeGroupVector &groups) const
    return NO_ERROR;
    return NO_ERROR;
}
}


status_t EngineBase::setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role,
namespace {
            const AudioDeviceTypeAddrVector &devices)
template <typename T>
{
status_t setDevicesRoleForT(
    // verify strategy exists
        std::map<std::pair<T, device_role_t>, AudioDeviceTypeAddrVector>& tDevicesRoleMap,
    if (mProductStrategies.find(strategy) == mProductStrategies.end()) {
        T t, device_role_t role, const AudioDeviceTypeAddrVector &devices,
        ALOGE("%s invalid strategy %u", __func__, strategy);
        const std::string& logStr, std::function<bool(T)> p) {
    if (!p(t)) {
        ALOGE("%s invalid %s %u", __func__, logStr.c_str(), t);
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    switch (role) {
    switch (role) {
    case DEVICE_ROLE_PREFERRED:
    case DEVICE_ROLE_PREFERRED:
        mProductStrategyPreferredDevices[strategy] = devices;
    case DEVICE_ROLE_DISABLED: {
        break;
        tDevicesRoleMap[std::make_pair(t, role)] = devices;
    case DEVICE_ROLE_DISABLED:
        // The preferred devices and disabled devices are mutually exclusive. Once a device is added
        // TODO (b/184065221): support set devices role as disabled for strategy.
        // the a list, it must be removed from the other one.
        ALOGI("%s no implemented for role as %d", __func__, role);
        const device_role_t roleToRemove = role == DEVICE_ROLE_PREFERRED ? DEVICE_ROLE_DISABLED
        break;
                                                                         : DEVICE_ROLE_PREFERRED;
        auto it = tDevicesRoleMap.find(std::make_pair(t, roleToRemove));
        if (it != tDevicesRoleMap.end()) {
            it->second = excludeDeviceTypeAddrsFrom(it->second, devices);
            if (it->second.empty()) {
                tDevicesRoleMap.erase(it);
            }
        }
    } break;
    case DEVICE_ROLE_NONE:
    case DEVICE_ROLE_NONE:
        // Intentionally fall-through as it is no need to set device role as none for a strategy.
        // Intentionally fall-through as it is no need to set device role as none for a strategy.
    default:
    default:
@@ -375,28 +387,26 @@ status_t EngineBase::setDevicesRoleForStrategy(product_strategy_t strategy, devi
    return NO_ERROR;
    return NO_ERROR;
}
}


status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role)
template <typename T>
{
status_t removeAllDevicesRoleForT(
    // verify strategy exists
        std::map<std::pair<T, device_role_t>, AudioDeviceTypeAddrVector>& tDevicesRoleMap,
    if (mProductStrategies.find(strategy) == mProductStrategies.end()) {
        T t, device_role_t role, const std::string& logStr, std::function<bool(T)> p) {
        ALOGE("%s invalid strategy %u", __func__, strategy);
    if (!p(t)) {
        ALOGE("%s invalid %s %u", __func__, logStr.c_str(), t);
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    switch (role) {
    switch (role) {
    case DEVICE_ROLE_PREFERRED:
    case DEVICE_ROLE_PREFERRED:
        if (mProductStrategyPreferredDevices.erase(strategy) == 0) {
    case DEVICE_ROLE_DISABLED:
            // no preferred device was set
        if (tDevicesRoleMap.erase(std::make_pair(t, role)) == 0) {
            // no preferred/disabled device was set
            return NAME_NOT_FOUND;
            return NAME_NOT_FOUND;
        }
        }
        break;
        break;
    case DEVICE_ROLE_DISABLED:
        // TODO (b/184065221): support remove devices role as disabled for strategy.
        ALOGI("%s no implemented for role as %d", __func__, role);
        break;
    case DEVICE_ROLE_NONE:
    case DEVICE_ROLE_NONE:
        // Intentionally fall-through as it makes no sense to remove devices with
        // Intentionally fall-through as it makes no sense to remove devices with
        // role as DEVICE_ROLE_NONE for a strategy
        // role as DEVICE_ROLE_NONE
    default:
    default:
        ALOGE("%s invalid role %d", __func__, role);
        ALOGE("%s invalid role %d", __func__, role);
        return BAD_VALUE;
        return BAD_VALUE;
@@ -404,30 +414,27 @@ status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, d
    return NO_ERROR;
    return NO_ERROR;
}
}


status_t EngineBase::getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role,
template <typename T>
            AudioDeviceTypeAddrVector &devices) const
status_t getDevicesRoleForT(
{
        const std::map<std::pair<T, device_role_t>, AudioDeviceTypeAddrVector>& tDevicesRoleMap,
    // verify strategy exists
        T t, device_role_t role, AudioDeviceTypeAddrVector &devices, const std::string& logStr,
    if (mProductStrategies.find(strategy) == mProductStrategies.end()) {
        std::function<bool(T)> p) {
        ALOGE("%s unknown strategy %u", __func__, strategy);
    if (!p(t)) {
        ALOGE("%s invalid %s %u", __func__, logStr.c_str(), t);
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    switch (role) {
    switch (role) {
    case DEVICE_ROLE_PREFERRED: {
    case DEVICE_ROLE_PREFERRED:
        // preferred device for this strategy?
    case DEVICE_ROLE_DISABLED: {
        auto devIt = mProductStrategyPreferredDevices.find(strategy);
        auto it = tDevicesRoleMap.find(std::make_pair(t, role));
        if (devIt == mProductStrategyPreferredDevices.end()) {
        if (it == tDevicesRoleMap.end()) {
            ALOGV("%s no preferred device for strategy %u", __func__, strategy);
            ALOGV("%s no device as role %u for %s %u", __func__, role, logStr.c_str(), t);
            return NAME_NOT_FOUND;
            return NAME_NOT_FOUND;
        }
        }


        devices = devIt->second;
        devices = it->second;
    } break;
    } break;
    case DEVICE_ROLE_DISABLED:
        // TODO (b/184065221): support devices role as disabled for strategy.
        ALOGV("%s no implemented for role as %d", __func__, role);
        break;
    case DEVICE_ROLE_NONE:
    case DEVICE_ROLE_NONE:
        // Intentionally fall-through as the DEVICE_ROLE_NONE is never set
        // Intentionally fall-through as the DEVICE_ROLE_NONE is never set
    default:
    default:
@@ -437,32 +444,45 @@ status_t EngineBase::getDevicesForRoleAndStrategy(product_strategy_t strategy, d
    return NO_ERROR;
    return NO_ERROR;
}
}


status_t EngineBase::setDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
} // namespace

status_t EngineBase::setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role,
            const AudioDeviceTypeAddrVector &devices)
            const AudioDeviceTypeAddrVector &devices)
{
{
    // verify if the audio source is valid
    std::function<bool(product_strategy_t)> p = [this](product_strategy_t strategy) {
    if (!audio_is_valid_audio_source(audioSource)) {
        return mProductStrategies.find(strategy) != mProductStrategies.end();
        ALOGE("%s unknown audio source %u", __func__, audioSource);
    };
    return setDevicesRoleForT(
            mProductStrategyDeviceRoleMap, strategy, role, devices, "strategy" /*logStr*/, p);
}
}


    switch (role) {
status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role)
    case DEVICE_ROLE_PREFERRED:
{
        mCapturePresetDevicesRole[audioSource][role] = devices;
    std::function<bool(product_strategy_t)> p = [this](product_strategy_t strategy) {
        // When the devices are set as preferred devices, remove them from the disabled devices.
        return mProductStrategies.find(strategy) != mProductStrategies.end();
        doRemoveDevicesRoleForCapturePreset(
    };
                audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/);
    return removeAllDevicesRoleForT(
        break;
            mProductStrategyDeviceRoleMap, strategy, role, "strategy" /*logStr*/, p);
    case DEVICE_ROLE_DISABLED:
        // TODO: support setting devices role as disabled for capture preset.
        ALOGI("%s no implemented for role as %d", __func__, role);
        break;
    case DEVICE_ROLE_NONE:
        // Intentionally fall-through as it is no need to set device role as none
    default:
        ALOGE("%s invalid role %d", __func__, role);
        return BAD_VALUE;
}
}
    return NO_ERROR;

status_t EngineBase::getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role,
            AudioDeviceTypeAddrVector &devices) const
{
    std::function<bool(product_strategy_t)> p = [this](product_strategy_t strategy) {
        return mProductStrategies.find(strategy) != mProductStrategies.end();
    };
    return getDevicesRoleForT(
            mProductStrategyDeviceRoleMap, strategy, role, devices, "strategy" /*logStr*/, p);
}

status_t EngineBase::setDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
        const AudioDeviceTypeAddrVector &devices)
{
    std::function<bool(audio_source_t)> p = [](audio_source_t audioSource) {
        return audio_is_valid_audio_source(audioSource);
    };
    return setDevicesRoleForT(
            mCapturePresetDevicesRoleMap, audioSource, role, devices, "audio source" /*logStr*/, p);
}
}


status_t EngineBase::addDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
status_t EngineBase::addDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
@@ -475,19 +495,20 @@ status_t EngineBase::addDevicesRoleForCapturePreset(audio_source_t audioSource,


    switch (role) {
    switch (role) {
    case DEVICE_ROLE_PREFERRED:
    case DEVICE_ROLE_PREFERRED:
        mCapturePresetDevicesRole[audioSource][role] = excludeDeviceTypeAddrsFrom(
    case DEVICE_ROLE_DISABLED: {
                mCapturePresetDevicesRole[audioSource][role], devices);
        const auto audioSourceRole = std::make_pair(audioSource, role);
        mCapturePresetDevicesRoleMap[audioSourceRole] = excludeDeviceTypeAddrsFrom(
                mCapturePresetDevicesRoleMap[audioSourceRole], devices);
        for (const auto &device : devices) {
        for (const auto &device : devices) {
            mCapturePresetDevicesRole[audioSource][role].push_back(device);
            mCapturePresetDevicesRoleMap[audioSourceRole].push_back(device);
        }
        }
        // When the devices are set as preferred devices, remove them from the disabled devices.
        // When the devices are set as preferred devices, remove them from the disabled devices.
        doRemoveDevicesRoleForCapturePreset(
        doRemoveDevicesRoleForCapturePreset(
                audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/);
                audioSource,
        break;
                role == DEVICE_ROLE_PREFERRED ? DEVICE_ROLE_DISABLED : DEVICE_ROLE_PREFERRED,
    case DEVICE_ROLE_DISABLED:
                devices,
        // TODO: support setting devices role as disabled for capture preset.
                false /*forceMatched*/);
        ALOGI("%s no implemented for role as %d", __func__, role);
    } break;
        break;
    case DEVICE_ROLE_NONE:
    case DEVICE_ROLE_NONE:
        // Intentionally fall-through as it is no need to set device role as none
        // Intentionally fall-through as it is no need to set device role as none
    default:
    default:
@@ -513,21 +534,22 @@ status_t EngineBase::doRemoveDevicesRoleForCapturePreset(audio_source_t audioSou
    switch (role) {
    switch (role) {
    case DEVICE_ROLE_PREFERRED:
    case DEVICE_ROLE_PREFERRED:
    case DEVICE_ROLE_DISABLED: {
    case DEVICE_ROLE_DISABLED: {
        if (mCapturePresetDevicesRole.count(audioSource) == 0 ||
        const auto audioSourceRole = std::make_pair(audioSource, role);
                mCapturePresetDevicesRole[audioSource].count(role) == 0) {
        if (mCapturePresetDevicesRoleMap.find(audioSourceRole) ==
                mCapturePresetDevicesRoleMap.end()) {
            return NAME_NOT_FOUND;
            return NAME_NOT_FOUND;
        }
        }
        AudioDeviceTypeAddrVector remainingDevices = excludeDeviceTypeAddrsFrom(
        AudioDeviceTypeAddrVector remainingDevices = excludeDeviceTypeAddrsFrom(
                mCapturePresetDevicesRole[audioSource][role], devices);
                mCapturePresetDevicesRoleMap[audioSourceRole], devices);
        if (forceMatched && remainingDevices.size() !=
        if (forceMatched && remainingDevices.size() !=
                mCapturePresetDevicesRole[audioSource][role].size() - devices.size()) {
                mCapturePresetDevicesRoleMap[audioSourceRole].size() - devices.size()) {
            // There are some devices from `devicesToRemove` that are not shown in the cached record
            // There are some devices from `devicesToRemove` that are not shown in the cached record
            return BAD_VALUE;
            return BAD_VALUE;
        }
        }
        mCapturePresetDevicesRole[audioSource][role] = remainingDevices;
        mCapturePresetDevicesRoleMap[audioSourceRole] = remainingDevices;
        if (mCapturePresetDevicesRole[audioSource][role].empty()) {
        if (mCapturePresetDevicesRoleMap[audioSourceRole].empty()) {
            // Remove the role when device list is empty
            // Remove the role when device list is empty
            mCapturePresetDevicesRole[audioSource].erase(role);
            mCapturePresetDevicesRoleMap.erase(audioSourceRole);
        }
        }
    } break;
    } break;
    case DEVICE_ROLE_NONE:
    case DEVICE_ROLE_NONE:
@@ -543,63 +565,21 @@ status_t EngineBase::doRemoveDevicesRoleForCapturePreset(audio_source_t audioSou
status_t EngineBase::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
status_t EngineBase::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
                                                      device_role_t role)
                                                      device_role_t role)
{
{
    // verify if the audio source is valid
    std::function<bool(audio_source_t)> p = [](audio_source_t audioSource) {
    if (!audio_is_valid_audio_source(audioSource)) {
        return audio_is_valid_audio_source(audioSource);
        ALOGE("%s unknown audio source %u", __func__, audioSource);
    };
    }
    return removeAllDevicesRoleForT(

            mCapturePresetDevicesRoleMap, audioSource, role, "audio source" /*logStr*/, p);
    switch (role) {
    case DEVICE_ROLE_PREFERRED:
        if (mCapturePresetDevicesRole.count(audioSource) == 0 ||
                mCapturePresetDevicesRole[audioSource].erase(role) == 0) {
            // no preferred device for the given audio source
            return NAME_NOT_FOUND;
        }
        break;
    case DEVICE_ROLE_DISABLED:
        // TODO: support remove devices role as disabled for strategy.
        ALOGI("%s no implemented for role as %d", __func__, role);
        break;
    case DEVICE_ROLE_NONE:
        // Intentionally fall-through as it makes no sense to remove devices with
        // role as DEVICE_ROLE_NONE for a strategy
    default:
        ALOGE("%s invalid role %d", __func__, role);
        return BAD_VALUE;
    }
    return NO_ERROR;
}
}


status_t EngineBase::getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
status_t EngineBase::getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
        device_role_t role, AudioDeviceTypeAddrVector &devices) const
        device_role_t role, AudioDeviceTypeAddrVector &devices) const
{
{
    // verify if the audio source is valid
    std::function<bool(audio_source_t)> p = [](audio_source_t audioSource) {
    if (!audio_is_valid_audio_source(audioSource)) {
        return audio_is_valid_audio_source(audioSource);
        ALOGE("%s unknown audio source %u", __func__, audioSource);
    };
        return BAD_VALUE;
    return getDevicesRoleForT(
    }
            mCapturePresetDevicesRoleMap, audioSource, role, devices, "audio source" /*logStr*/, p);

    switch (role) {
    case DEVICE_ROLE_PREFERRED:
    case DEVICE_ROLE_DISABLED: {
        if (mCapturePresetDevicesRole.count(audioSource) == 0) {
            return NAME_NOT_FOUND;
        }
        auto devIt = mCapturePresetDevicesRole.at(audioSource).find(role);
        if (devIt == mCapturePresetDevicesRole.at(audioSource).end()) {
            ALOGV("%s no devices role(%d) for capture preset %u", __func__, role, audioSource);
            return NAME_NOT_FOUND;
        }

        devices = devIt->second;
    } break;
    case DEVICE_ROLE_NONE:
        // Intentionally fall-through as the DEVICE_ROLE_NONE is never set
    default:
        ALOGE("%s invalid role %d", __func__, role);
        return BAD_VALUE;
    }
    return NO_ERROR;
}
}


status_t EngineBase::getMediaDevicesForRole(device_role_t role,
status_t EngineBase::getMediaDevicesForRole(device_role_t role,
@@ -641,10 +621,22 @@ DeviceVector EngineBase::getActiveMediaDevices(const DeviceVector& availableDevi
    return activeDevices;
    return activeDevices;
}
}


void EngineBase::dumpCapturePresetDevicesRoleMap(String8 *dst, int spaces) const
{
    dst->appendFormat("\n%*sDevice role per capture preset dump:", spaces, "");
    for (const auto& [capturePresetRolePair, devices] : mCapturePresetDevicesRoleMap) {
        dst->appendFormat("\n%*sCapture preset(%u) Device Role(%u) Devices(%s)", spaces + 2, "",
                capturePresetRolePair.first, capturePresetRolePair.second,
                dumpAudioDeviceTypeAddrVector(devices, true /*includeSensitiveInfo*/).c_str());
    }
    dst->appendFormat("\n");
}

void EngineBase::dump(String8 *dst) const
void EngineBase::dump(String8 *dst) const
{
{
    mProductStrategies.dump(dst, 2);
    mProductStrategies.dump(dst, 2);
    mProductStrategyPreferredDevices.dump(dst, 2);
    dumpProductStrategyDevicesRoleMap(mProductStrategyDeviceRoleMap, dst, 2);
    dumpCapturePresetDevicesRoleMap(dst, 2);
    mVolumeGroups.dump(dst, 2);
    mVolumeGroups.dump(dst, 2);
}
}


+9 −8
Original line number Original line Diff line number Diff line
@@ -320,14 +320,15 @@ void ProductStrategyMap::dump(String8 *dst, int spaces) const
    }
    }
}
}


void ProductStrategyPreferredRoutingMap::dump(android::String8* dst, int spaces) const {
void dumpProductStrategyDevicesRoleMap(
    dst->appendFormat("\n%*sPreferred devices per product strategy dump:", spaces, "");
        const ProductStrategyDevicesRoleMap& productStrategyDeviceRoleMap,
    for (const auto& iter : *this) {
        String8 *dst,
        dst->appendFormat("\n%*sStrategy %u %s",
        int spaces) {
                          spaces + 2, "",
    dst->appendFormat("\n%*sDevice role per product strategy dump:", spaces, "");
                          (uint32_t) iter.first,
    for (const auto& [strategyRolePair, devices] : productStrategyDeviceRoleMap) {
                          dumpAudioDeviceTypeAddrVector(iter.second, true /*includeSensitiveInfo*/)
        dst->appendFormat("\n%*sStrategy(%u) Device Role(%u) Devices(%s)", spaces + 2, "",
                                  .c_str());
                strategyRolePair.first, strategyRolePair.second,
                dumpAudioDeviceTypeAddrVector(devices, true /*includeSensitiveInfo*/).c_str());
    }
    }
    dst->appendFormat("\n");
    dst->appendFormat("\n");
}
}
+3 −1
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


#pragma once
#pragma once


#include <utility>

#include <AudioPolicyManagerObserver.h>
#include <AudioPolicyManagerObserver.h>
#include <media/AudioProductStrategy.h>
#include <media/AudioProductStrategy.h>
#include <media/AudioVolumeGroup.h>
#include <media/AudioVolumeGroup.h>
@@ -35,7 +37,7 @@ using DeviceStrategyMap = std::map<product_strategy_t, DeviceVector>;
using StrategyVector = std::vector<product_strategy_t>;
using StrategyVector = std::vector<product_strategy_t>;
using VolumeGroupVector = std::vector<volume_group_t>;
using VolumeGroupVector = std::vector<volume_group_t>;
using CapturePresetDevicesRoleMap =
using CapturePresetDevicesRoleMap =
        std::map<audio_source_t, std::map<device_role_t, AudioDeviceTypeAddrVector>>;
        std::map<std::pair<audio_source_t, device_role_t>, AudioDeviceTypeAddrVector>;


/**
/**
 * This interface is dedicated to the policy manager that a Policy Engine shall implement.
 * This interface is dedicated to the policy manager that a Policy Engine shall implement.