Loading services/audiopolicy/engine/common/include/EngineBase.h +4 −2 Original line number Diff line number Diff line Loading @@ -170,11 +170,13 @@ private: status_t getMediaDevicesForRole(device_role_t role, const DeviceVector& availableDevices, DeviceVector& devices) const; void dumpCapturePresetDevicesRoleMap(String8 *dst, int spaces) const; AudioPolicyManagerObserver *mApmObserver = nullptr; ProductStrategyMap mProductStrategies; ProductStrategyPreferredRoutingMap mProductStrategyPreferredDevices; CapturePresetDevicesRoleMap mCapturePresetDevicesRole; ProductStrategyDevicesRoleMap mProductStrategyDeviceRoleMap; CapturePresetDevicesRoleMap mCapturePresetDevicesRoleMap; VolumeGroupMap mVolumeGroups; LastRemovableMediaDevices mLastRemovableMediaDevices; audio_mode_t mPhoneState = AUDIO_MODE_NORMAL; /**< current phone state. */ Loading services/audiopolicy/engine/common/include/ProductStrategy.h +15 −14 Original line number Diff line number Diff line Loading @@ -18,20 +18,20 @@ #include "VolumeGroup.h" #include <system/audio.h> #include <utils/RefBase.h> #include <HandleGenerator.h> #include <map> #include <string> #include <utility> #include <vector> #include <map> #include <utils/Errors.h> #include <utils/String8.h> #include <HandleGenerator.h> #include <media/AudioAttributes.h> #include <media/AudioContainers.h> #include <media/AudioDeviceTypeAddr.h> #include <media/AudioPolicy.h> #include <vector> #include <system/audio.h> #include <utils/Errors.h> #include <utils/RefBase.h> #include <utils/String8.h> namespace android { Loading Loading @@ -170,11 +170,12 @@ private: product_strategy_t mDefaultStrategy = PRODUCT_STRATEGY_NONE; }; class ProductStrategyPreferredRoutingMap : public std::map<product_strategy_t, AudioDeviceTypeAddrVector> { public: void dump(String8 *dst, int spaces = 0) const; }; using ProductStrategyDevicesRoleMap = std::map<std::pair<product_strategy_t, device_role_t>, AudioDeviceTypeAddrVector>; void dumpProductStrategyDevicesRoleMap( const ProductStrategyDevicesRoleMap& productStrategyDeviceRoleMap, String8 *dst, int spaces); } // namespace android services/audiopolicy/engine/common/src/EngineBase.cpp +125 −133 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #define LOG_TAG "APM::AudioPolicyEngine/Base" //#define LOG_NDEBUG 0 #include <functional> #include <string> #include <sys/stat.h> #include "EngineBase.h" Loading Loading @@ -349,23 +351,33 @@ status_t EngineBase::listAudioVolumeGroups(AudioVolumeGroupVector &groups) const return NO_ERROR; } status_t EngineBase::setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) { // verify strategy exists if (mProductStrategies.find(strategy) == mProductStrategies.end()) { ALOGE("%s invalid strategy %u", __func__, strategy); namespace { template <typename T> status_t setDevicesRoleForT( std::map<std::pair<T, device_role_t>, AudioDeviceTypeAddrVector>& tDevicesRoleMap, T t, device_role_t role, const AudioDeviceTypeAddrVector &devices, 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; } switch (role) { case DEVICE_ROLE_PREFERRED: mProductStrategyPreferredDevices[strategy] = devices; break; case DEVICE_ROLE_DISABLED: // TODO (b/184065221): support set devices role as disabled for strategy. ALOGI("%s no implemented for role as %d", __func__, role); break; case DEVICE_ROLE_DISABLED: { tDevicesRoleMap[std::make_pair(t, role)] = devices; // The preferred devices and disabled devices are mutually exclusive. Once a device is added // the a list, it must be removed from the other one. const device_role_t roleToRemove = role == DEVICE_ROLE_PREFERRED ? DEVICE_ROLE_DISABLED : 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: // Intentionally fall-through as it is no need to set device role as none for a strategy. default: Loading @@ -375,28 +387,26 @@ status_t EngineBase::setDevicesRoleForStrategy(product_strategy_t strategy, devi return NO_ERROR; } status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) { // verify strategy exists if (mProductStrategies.find(strategy) == mProductStrategies.end()) { ALOGE("%s invalid strategy %u", __func__, strategy); template <typename T> status_t removeAllDevicesRoleForT( std::map<std::pair<T, device_role_t>, AudioDeviceTypeAddrVector>& tDevicesRoleMap, T t, device_role_t role, 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; } switch (role) { case DEVICE_ROLE_PREFERRED: if (mProductStrategyPreferredDevices.erase(strategy) == 0) { // no preferred device was set case DEVICE_ROLE_DISABLED: if (tDevicesRoleMap.erase(std::make_pair(t, role)) == 0) { // no preferred/disabled device was set return NAME_NOT_FOUND; } 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: // 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: ALOGE("%s invalid role %d", __func__, role); return BAD_VALUE; Loading @@ -404,30 +414,27 @@ status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, d return NO_ERROR; } status_t EngineBase::getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role, AudioDeviceTypeAddrVector &devices) const { // verify strategy exists if (mProductStrategies.find(strategy) == mProductStrategies.end()) { ALOGE("%s unknown strategy %u", __func__, strategy); template <typename T> status_t getDevicesRoleForT( const std::map<std::pair<T, device_role_t>, AudioDeviceTypeAddrVector>& tDevicesRoleMap, T t, device_role_t role, AudioDeviceTypeAddrVector &devices, 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; } switch (role) { case DEVICE_ROLE_PREFERRED: { // preferred device for this strategy? auto devIt = mProductStrategyPreferredDevices.find(strategy); if (devIt == mProductStrategyPreferredDevices.end()) { ALOGV("%s no preferred device for strategy %u", __func__, strategy); case DEVICE_ROLE_PREFERRED: case DEVICE_ROLE_DISABLED: { auto it = tDevicesRoleMap.find(std::make_pair(t, role)); if (it == tDevicesRoleMap.end()) { ALOGV("%s no device as role %u for %s %u", __func__, role, logStr.c_str(), t); return NAME_NOT_FOUND; } devices = devIt->second; devices = it->second; } 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: // Intentionally fall-through as the DEVICE_ROLE_NONE is never set default: Loading @@ -437,32 +444,45 @@ status_t EngineBase::getDevicesForRoleAndStrategy(product_strategy_t strategy, d 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) { // verify if the audio source is valid if (!audio_is_valid_audio_source(audioSource)) { ALOGE("%s unknown audio source %u", __func__, audioSource); std::function<bool(product_strategy_t)> p = [this](product_strategy_t strategy) { return mProductStrategies.find(strategy) != mProductStrategies.end(); }; return setDevicesRoleForT( mProductStrategyDeviceRoleMap, strategy, role, devices, "strategy" /*logStr*/, p); } switch (role) { case DEVICE_ROLE_PREFERRED: mCapturePresetDevicesRole[audioSource][role] = devices; // When the devices are set as preferred devices, remove them from the disabled devices. doRemoveDevicesRoleForCapturePreset( audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/); break; 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; status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) { std::function<bool(product_strategy_t)> p = [this](product_strategy_t strategy) { return mProductStrategies.find(strategy) != mProductStrategies.end(); }; return removeAllDevicesRoleForT( mProductStrategyDeviceRoleMap, strategy, role, "strategy" /*logStr*/, p); } 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, Loading @@ -475,19 +495,20 @@ status_t EngineBase::addDevicesRoleForCapturePreset(audio_source_t audioSource, switch (role) { case DEVICE_ROLE_PREFERRED: mCapturePresetDevicesRole[audioSource][role] = excludeDeviceTypeAddrsFrom( mCapturePresetDevicesRole[audioSource][role], devices); case DEVICE_ROLE_DISABLED: { const auto audioSourceRole = std::make_pair(audioSource, role); mCapturePresetDevicesRoleMap[audioSourceRole] = excludeDeviceTypeAddrsFrom( mCapturePresetDevicesRoleMap[audioSourceRole], 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. doRemoveDevicesRoleForCapturePreset( audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/); break; 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; audioSource, role == DEVICE_ROLE_PREFERRED ? DEVICE_ROLE_DISABLED : DEVICE_ROLE_PREFERRED, devices, false /*forceMatched*/); } break; case DEVICE_ROLE_NONE: // Intentionally fall-through as it is no need to set device role as none default: Loading @@ -513,21 +534,22 @@ status_t EngineBase::doRemoveDevicesRoleForCapturePreset(audio_source_t audioSou switch (role) { case DEVICE_ROLE_PREFERRED: case DEVICE_ROLE_DISABLED: { if (mCapturePresetDevicesRole.count(audioSource) == 0 || mCapturePresetDevicesRole[audioSource].count(role) == 0) { const auto audioSourceRole = std::make_pair(audioSource, role); if (mCapturePresetDevicesRoleMap.find(audioSourceRole) == mCapturePresetDevicesRoleMap.end()) { return NAME_NOT_FOUND; } AudioDeviceTypeAddrVector remainingDevices = excludeDeviceTypeAddrsFrom( mCapturePresetDevicesRole[audioSource][role], devices); mCapturePresetDevicesRoleMap[audioSourceRole], devices); 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 return BAD_VALUE; } mCapturePresetDevicesRole[audioSource][role] = remainingDevices; if (mCapturePresetDevicesRole[audioSource][role].empty()) { mCapturePresetDevicesRoleMap[audioSourceRole] = remainingDevices; if (mCapturePresetDevicesRoleMap[audioSourceRole].empty()) { // Remove the role when device list is empty mCapturePresetDevicesRole[audioSource].erase(role); mCapturePresetDevicesRoleMap.erase(audioSourceRole); } } break; case DEVICE_ROLE_NONE: Loading @@ -543,63 +565,21 @@ status_t EngineBase::doRemoveDevicesRoleForCapturePreset(audio_source_t audioSou status_t EngineBase::clearDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role) { // verify if the audio source is valid if (!audio_is_valid_audio_source(audioSource)) { ALOGE("%s unknown audio source %u", __func__, audioSource); } 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; std::function<bool(audio_source_t)> p = [](audio_source_t audioSource) { return audio_is_valid_audio_source(audioSource); }; return removeAllDevicesRoleForT( mCapturePresetDevicesRoleMap, audioSource, role, "audio source" /*logStr*/, p); } status_t EngineBase::getDevicesForRoleAndCapturePreset(audio_source_t audioSource, device_role_t role, AudioDeviceTypeAddrVector &devices) const { // verify if the audio source is valid if (!audio_is_valid_audio_source(audioSource)) { ALOGE("%s unknown audio source %u", __func__, audioSource); return BAD_VALUE; } 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; std::function<bool(audio_source_t)> p = [](audio_source_t audioSource) { return audio_is_valid_audio_source(audioSource); }; return getDevicesRoleForT( mCapturePresetDevicesRoleMap, audioSource, role, devices, "audio source" /*logStr*/, p); } status_t EngineBase::getMediaDevicesForRole(device_role_t role, Loading Loading @@ -641,10 +621,22 @@ DeviceVector EngineBase::getActiveMediaDevices(const DeviceVector& availableDevi 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 { mProductStrategies.dump(dst, 2); mProductStrategyPreferredDevices.dump(dst, 2); dumpProductStrategyDevicesRoleMap(mProductStrategyDeviceRoleMap, dst, 2); dumpCapturePresetDevicesRoleMap(dst, 2); mVolumeGroups.dump(dst, 2); } Loading services/audiopolicy/engine/common/src/ProductStrategy.cpp +9 −8 Original line number Diff line number Diff line Loading @@ -320,14 +320,15 @@ void ProductStrategyMap::dump(String8 *dst, int spaces) const } } void ProductStrategyPreferredRoutingMap::dump(android::String8* dst, int spaces) const { dst->appendFormat("\n%*sPreferred devices per product strategy dump:", spaces, ""); for (const auto& iter : *this) { dst->appendFormat("\n%*sStrategy %u %s", spaces + 2, "", (uint32_t) iter.first, dumpAudioDeviceTypeAddrVector(iter.second, true /*includeSensitiveInfo*/) .c_str()); void dumpProductStrategyDevicesRoleMap( const ProductStrategyDevicesRoleMap& productStrategyDeviceRoleMap, String8 *dst, int spaces) { dst->appendFormat("\n%*sDevice role per product strategy dump:", spaces, ""); for (const auto& [strategyRolePair, devices] : productStrategyDeviceRoleMap) { dst->appendFormat("\n%*sStrategy(%u) Device Role(%u) Devices(%s)", spaces + 2, "", strategyRolePair.first, strategyRolePair.second, dumpAudioDeviceTypeAddrVector(devices, true /*includeSensitiveInfo*/).c_str()); } dst->appendFormat("\n"); } Loading services/audiopolicy/engine/interface/EngineInterface.h +3 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #pragma once #include <utility> #include <AudioPolicyManagerObserver.h> #include <media/AudioProductStrategy.h> #include <media/AudioVolumeGroup.h> Loading @@ -35,7 +37,7 @@ using DeviceStrategyMap = std::map<product_strategy_t, DeviceVector>; using StrategyVector = std::vector<product_strategy_t>; using VolumeGroupVector = std::vector<volume_group_t>; 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. Loading Loading
services/audiopolicy/engine/common/include/EngineBase.h +4 −2 Original line number Diff line number Diff line Loading @@ -170,11 +170,13 @@ private: status_t getMediaDevicesForRole(device_role_t role, const DeviceVector& availableDevices, DeviceVector& devices) const; void dumpCapturePresetDevicesRoleMap(String8 *dst, int spaces) const; AudioPolicyManagerObserver *mApmObserver = nullptr; ProductStrategyMap mProductStrategies; ProductStrategyPreferredRoutingMap mProductStrategyPreferredDevices; CapturePresetDevicesRoleMap mCapturePresetDevicesRole; ProductStrategyDevicesRoleMap mProductStrategyDeviceRoleMap; CapturePresetDevicesRoleMap mCapturePresetDevicesRoleMap; VolumeGroupMap mVolumeGroups; LastRemovableMediaDevices mLastRemovableMediaDevices; audio_mode_t mPhoneState = AUDIO_MODE_NORMAL; /**< current phone state. */ Loading
services/audiopolicy/engine/common/include/ProductStrategy.h +15 −14 Original line number Diff line number Diff line Loading @@ -18,20 +18,20 @@ #include "VolumeGroup.h" #include <system/audio.h> #include <utils/RefBase.h> #include <HandleGenerator.h> #include <map> #include <string> #include <utility> #include <vector> #include <map> #include <utils/Errors.h> #include <utils/String8.h> #include <HandleGenerator.h> #include <media/AudioAttributes.h> #include <media/AudioContainers.h> #include <media/AudioDeviceTypeAddr.h> #include <media/AudioPolicy.h> #include <vector> #include <system/audio.h> #include <utils/Errors.h> #include <utils/RefBase.h> #include <utils/String8.h> namespace android { Loading Loading @@ -170,11 +170,12 @@ private: product_strategy_t mDefaultStrategy = PRODUCT_STRATEGY_NONE; }; class ProductStrategyPreferredRoutingMap : public std::map<product_strategy_t, AudioDeviceTypeAddrVector> { public: void dump(String8 *dst, int spaces = 0) const; }; using ProductStrategyDevicesRoleMap = std::map<std::pair<product_strategy_t, device_role_t>, AudioDeviceTypeAddrVector>; void dumpProductStrategyDevicesRoleMap( const ProductStrategyDevicesRoleMap& productStrategyDeviceRoleMap, String8 *dst, int spaces); } // namespace android
services/audiopolicy/engine/common/src/EngineBase.cpp +125 −133 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #define LOG_TAG "APM::AudioPolicyEngine/Base" //#define LOG_NDEBUG 0 #include <functional> #include <string> #include <sys/stat.h> #include "EngineBase.h" Loading Loading @@ -349,23 +351,33 @@ status_t EngineBase::listAudioVolumeGroups(AudioVolumeGroupVector &groups) const return NO_ERROR; } status_t EngineBase::setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) { // verify strategy exists if (mProductStrategies.find(strategy) == mProductStrategies.end()) { ALOGE("%s invalid strategy %u", __func__, strategy); namespace { template <typename T> status_t setDevicesRoleForT( std::map<std::pair<T, device_role_t>, AudioDeviceTypeAddrVector>& tDevicesRoleMap, T t, device_role_t role, const AudioDeviceTypeAddrVector &devices, 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; } switch (role) { case DEVICE_ROLE_PREFERRED: mProductStrategyPreferredDevices[strategy] = devices; break; case DEVICE_ROLE_DISABLED: // TODO (b/184065221): support set devices role as disabled for strategy. ALOGI("%s no implemented for role as %d", __func__, role); break; case DEVICE_ROLE_DISABLED: { tDevicesRoleMap[std::make_pair(t, role)] = devices; // The preferred devices and disabled devices are mutually exclusive. Once a device is added // the a list, it must be removed from the other one. const device_role_t roleToRemove = role == DEVICE_ROLE_PREFERRED ? DEVICE_ROLE_DISABLED : 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: // Intentionally fall-through as it is no need to set device role as none for a strategy. default: Loading @@ -375,28 +387,26 @@ status_t EngineBase::setDevicesRoleForStrategy(product_strategy_t strategy, devi return NO_ERROR; } status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) { // verify strategy exists if (mProductStrategies.find(strategy) == mProductStrategies.end()) { ALOGE("%s invalid strategy %u", __func__, strategy); template <typename T> status_t removeAllDevicesRoleForT( std::map<std::pair<T, device_role_t>, AudioDeviceTypeAddrVector>& tDevicesRoleMap, T t, device_role_t role, 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; } switch (role) { case DEVICE_ROLE_PREFERRED: if (mProductStrategyPreferredDevices.erase(strategy) == 0) { // no preferred device was set case DEVICE_ROLE_DISABLED: if (tDevicesRoleMap.erase(std::make_pair(t, role)) == 0) { // no preferred/disabled device was set return NAME_NOT_FOUND; } 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: // 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: ALOGE("%s invalid role %d", __func__, role); return BAD_VALUE; Loading @@ -404,30 +414,27 @@ status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, d return NO_ERROR; } status_t EngineBase::getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role, AudioDeviceTypeAddrVector &devices) const { // verify strategy exists if (mProductStrategies.find(strategy) == mProductStrategies.end()) { ALOGE("%s unknown strategy %u", __func__, strategy); template <typename T> status_t getDevicesRoleForT( const std::map<std::pair<T, device_role_t>, AudioDeviceTypeAddrVector>& tDevicesRoleMap, T t, device_role_t role, AudioDeviceTypeAddrVector &devices, 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; } switch (role) { case DEVICE_ROLE_PREFERRED: { // preferred device for this strategy? auto devIt = mProductStrategyPreferredDevices.find(strategy); if (devIt == mProductStrategyPreferredDevices.end()) { ALOGV("%s no preferred device for strategy %u", __func__, strategy); case DEVICE_ROLE_PREFERRED: case DEVICE_ROLE_DISABLED: { auto it = tDevicesRoleMap.find(std::make_pair(t, role)); if (it == tDevicesRoleMap.end()) { ALOGV("%s no device as role %u for %s %u", __func__, role, logStr.c_str(), t); return NAME_NOT_FOUND; } devices = devIt->second; devices = it->second; } 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: // Intentionally fall-through as the DEVICE_ROLE_NONE is never set default: Loading @@ -437,32 +444,45 @@ status_t EngineBase::getDevicesForRoleAndStrategy(product_strategy_t strategy, d 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) { // verify if the audio source is valid if (!audio_is_valid_audio_source(audioSource)) { ALOGE("%s unknown audio source %u", __func__, audioSource); std::function<bool(product_strategy_t)> p = [this](product_strategy_t strategy) { return mProductStrategies.find(strategy) != mProductStrategies.end(); }; return setDevicesRoleForT( mProductStrategyDeviceRoleMap, strategy, role, devices, "strategy" /*logStr*/, p); } switch (role) { case DEVICE_ROLE_PREFERRED: mCapturePresetDevicesRole[audioSource][role] = devices; // When the devices are set as preferred devices, remove them from the disabled devices. doRemoveDevicesRoleForCapturePreset( audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/); break; 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; status_t EngineBase::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) { std::function<bool(product_strategy_t)> p = [this](product_strategy_t strategy) { return mProductStrategies.find(strategy) != mProductStrategies.end(); }; return removeAllDevicesRoleForT( mProductStrategyDeviceRoleMap, strategy, role, "strategy" /*logStr*/, p); } 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, Loading @@ -475,19 +495,20 @@ status_t EngineBase::addDevicesRoleForCapturePreset(audio_source_t audioSource, switch (role) { case DEVICE_ROLE_PREFERRED: mCapturePresetDevicesRole[audioSource][role] = excludeDeviceTypeAddrsFrom( mCapturePresetDevicesRole[audioSource][role], devices); case DEVICE_ROLE_DISABLED: { const auto audioSourceRole = std::make_pair(audioSource, role); mCapturePresetDevicesRoleMap[audioSourceRole] = excludeDeviceTypeAddrsFrom( mCapturePresetDevicesRoleMap[audioSourceRole], 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. doRemoveDevicesRoleForCapturePreset( audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/); break; 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; audioSource, role == DEVICE_ROLE_PREFERRED ? DEVICE_ROLE_DISABLED : DEVICE_ROLE_PREFERRED, devices, false /*forceMatched*/); } break; case DEVICE_ROLE_NONE: // Intentionally fall-through as it is no need to set device role as none default: Loading @@ -513,21 +534,22 @@ status_t EngineBase::doRemoveDevicesRoleForCapturePreset(audio_source_t audioSou switch (role) { case DEVICE_ROLE_PREFERRED: case DEVICE_ROLE_DISABLED: { if (mCapturePresetDevicesRole.count(audioSource) == 0 || mCapturePresetDevicesRole[audioSource].count(role) == 0) { const auto audioSourceRole = std::make_pair(audioSource, role); if (mCapturePresetDevicesRoleMap.find(audioSourceRole) == mCapturePresetDevicesRoleMap.end()) { return NAME_NOT_FOUND; } AudioDeviceTypeAddrVector remainingDevices = excludeDeviceTypeAddrsFrom( mCapturePresetDevicesRole[audioSource][role], devices); mCapturePresetDevicesRoleMap[audioSourceRole], devices); 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 return BAD_VALUE; } mCapturePresetDevicesRole[audioSource][role] = remainingDevices; if (mCapturePresetDevicesRole[audioSource][role].empty()) { mCapturePresetDevicesRoleMap[audioSourceRole] = remainingDevices; if (mCapturePresetDevicesRoleMap[audioSourceRole].empty()) { // Remove the role when device list is empty mCapturePresetDevicesRole[audioSource].erase(role); mCapturePresetDevicesRoleMap.erase(audioSourceRole); } } break; case DEVICE_ROLE_NONE: Loading @@ -543,63 +565,21 @@ status_t EngineBase::doRemoveDevicesRoleForCapturePreset(audio_source_t audioSou status_t EngineBase::clearDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role) { // verify if the audio source is valid if (!audio_is_valid_audio_source(audioSource)) { ALOGE("%s unknown audio source %u", __func__, audioSource); } 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; std::function<bool(audio_source_t)> p = [](audio_source_t audioSource) { return audio_is_valid_audio_source(audioSource); }; return removeAllDevicesRoleForT( mCapturePresetDevicesRoleMap, audioSource, role, "audio source" /*logStr*/, p); } status_t EngineBase::getDevicesForRoleAndCapturePreset(audio_source_t audioSource, device_role_t role, AudioDeviceTypeAddrVector &devices) const { // verify if the audio source is valid if (!audio_is_valid_audio_source(audioSource)) { ALOGE("%s unknown audio source %u", __func__, audioSource); return BAD_VALUE; } 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; std::function<bool(audio_source_t)> p = [](audio_source_t audioSource) { return audio_is_valid_audio_source(audioSource); }; return getDevicesRoleForT( mCapturePresetDevicesRoleMap, audioSource, role, devices, "audio source" /*logStr*/, p); } status_t EngineBase::getMediaDevicesForRole(device_role_t role, Loading Loading @@ -641,10 +621,22 @@ DeviceVector EngineBase::getActiveMediaDevices(const DeviceVector& availableDevi 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 { mProductStrategies.dump(dst, 2); mProductStrategyPreferredDevices.dump(dst, 2); dumpProductStrategyDevicesRoleMap(mProductStrategyDeviceRoleMap, dst, 2); dumpCapturePresetDevicesRoleMap(dst, 2); mVolumeGroups.dump(dst, 2); } Loading
services/audiopolicy/engine/common/src/ProductStrategy.cpp +9 −8 Original line number Diff line number Diff line Loading @@ -320,14 +320,15 @@ void ProductStrategyMap::dump(String8 *dst, int spaces) const } } void ProductStrategyPreferredRoutingMap::dump(android::String8* dst, int spaces) const { dst->appendFormat("\n%*sPreferred devices per product strategy dump:", spaces, ""); for (const auto& iter : *this) { dst->appendFormat("\n%*sStrategy %u %s", spaces + 2, "", (uint32_t) iter.first, dumpAudioDeviceTypeAddrVector(iter.second, true /*includeSensitiveInfo*/) .c_str()); void dumpProductStrategyDevicesRoleMap( const ProductStrategyDevicesRoleMap& productStrategyDeviceRoleMap, String8 *dst, int spaces) { dst->appendFormat("\n%*sDevice role per product strategy dump:", spaces, ""); for (const auto& [strategyRolePair, devices] : productStrategyDeviceRoleMap) { dst->appendFormat("\n%*sStrategy(%u) Device Role(%u) Devices(%s)", spaces + 2, "", strategyRolePair.first, strategyRolePair.second, dumpAudioDeviceTypeAddrVector(devices, true /*includeSensitiveInfo*/).c_str()); } dst->appendFormat("\n"); } Loading
services/audiopolicy/engine/interface/EngineInterface.h +3 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ #pragma once #include <utility> #include <AudioPolicyManagerObserver.h> #include <media/AudioProductStrategy.h> #include <media/AudioVolumeGroup.h> Loading @@ -35,7 +37,7 @@ using DeviceStrategyMap = std::map<product_strategy_t, DeviceVector>; using StrategyVector = std::vector<product_strategy_t>; using VolumeGroupVector = std::vector<volume_group_t>; 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. Loading