Loading services/audiopolicy/engine/common/include/EngineBase.h +6 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,12 @@ public: void updateDeviceSelectionCache() override; protected: DeviceVector getPreferredAvailableDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const; DeviceVector getDisabledDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const; private: /** * Get media devices as the given role Loading services/audiopolicy/engine/common/src/EngineBase.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -705,6 +705,38 @@ void EngineBase::updateDeviceSelectionCache() { } } DeviceVector EngineBase::getPreferredAvailableDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const { DeviceVector preferredAvailableDevVec = {}; AudioDeviceTypeAddrVector preferredStrategyDevices; const status_t status = getDevicesForRoleAndStrategy( strategy, DEVICE_ROLE_PREFERRED, preferredStrategyDevices); if (status == NO_ERROR) { // there is a preferred device, is it available? preferredAvailableDevVec = availableOutputDevices.getDevicesFromDeviceTypeAddrVec(preferredStrategyDevices); if (preferredAvailableDevVec.size() == preferredStrategyDevices.size()) { ALOGV("%s using pref device %s for strategy %u", __func__, preferredAvailableDevVec.toString().c_str(), strategy); return preferredAvailableDevVec; } } return preferredAvailableDevVec; } DeviceVector EngineBase::getDisabledDevicesForProductStrategy( const DeviceVector &availableOutputDevices, product_strategy_t strategy) const { DeviceVector disabledDevices = {}; AudioDeviceTypeAddrVector disabledDevicesTypeAddr; const status_t status = getDevicesForRoleAndStrategy( strategy, DEVICE_ROLE_DISABLED, disabledDevicesTypeAddr); if (status == NO_ERROR) { disabledDevices = availableOutputDevices.getDevicesFromDeviceTypeAddrVec(disabledDevicesTypeAddr); } return disabledDevices; } void EngineBase::dumpCapturePresetDevicesRoleMap(String8 *dst, int spaces) const { dst->appendFormat("\n%*sDevice role per capture preset dump:", spaces, ""); Loading services/audiopolicy/engineconfigurable/src/Engine.cpp +144 −16 Original line number Diff line number Diff line Loading @@ -165,6 +165,21 @@ audio_policy_forced_cfg_t Engine::getForceUse(audio_policy_force_use_t usage) co return mPolicyParameterMgr->getForceUse(usage); } status_t Engine::setOutputDevicesConnectionState(const DeviceVector &devices, audio_policy_dev_state_t state) { for (const auto &device : devices) { mPolicyParameterMgr->setDeviceConnectionState(device->type(), device->address(), state); } DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) { availableOutputDevices.remove(devices); } else { availableOutputDevices.add(devices); } return mPolicyParameterMgr->setAvailableOutputDevices(availableOutputDevices.types()); } status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> device, audio_policy_dev_state_t state) { Loading Loading @@ -205,17 +220,126 @@ status_t Engine::loadAudioPolicyEngineConfig() return result.nbSkippedElement == 0? NO_ERROR : BAD_VALUE; } status_t Engine::setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) { DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); DeviceVector prevDisabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, strategy); status_t status = EngineBase::setDevicesRoleForStrategy(strategy, role, devices); if (status != NO_ERROR) { return status; } DeviceVector newDisabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, strategy); if (role == DEVICE_ROLE_PREFERRED) { DeviceVector reenabledDevices = prevDisabledDevices; reenabledDevices.remove(newDisabledDevices); if (reenabledDevices.empty()) { ALOGD("%s DEVICE_ROLE_PREFERRED empty renabled devices", __func__); return status; } // some devices were moved from disabled to preferred, need to force a resync for these enableDevicesForStrategy(strategy, prevDisabledDevices); } if (newDisabledDevices.empty()) { return status; } return disableDevicesForStrategy(strategy, newDisabledDevices); } status_t Engine::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) { const auto productStrategies = getProductStrategies(); if (productStrategies.find(strategy) == end(productStrategies)) { ALOGE("%s invalid %d", __func__, strategy); return BAD_VALUE; } DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); DeviceVector prevDisabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, strategy); status_t status = EngineBase::removeDevicesRoleForStrategy(strategy, role, devices); if (status != NO_ERROR || role == DEVICE_ROLE_PREFERRED) { return status; } // Removing ROLE_DISABLED for given devices, need to force a resync for these enableDevicesForStrategy(strategy, prevDisabledDevices); DeviceVector remainingDisabledDevices = getDisabledDevicesForProductStrategy( availableOutputDevices, strategy); if (remainingDisabledDevices.empty()) { return status; } return disableDevicesForStrategy(strategy, remainingDisabledDevices); } status_t Engine::clearDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) { const auto productStrategies = getProductStrategies(); if (productStrategies.find(strategy) == end(productStrategies)) { ALOGE("%s invalid %d", __func__, strategy); return BAD_VALUE; } DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); DeviceVector prevDisabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, strategy); status_t status = EngineBase::clearDevicesRoleForStrategy(strategy, role); if (status != NO_ERROR || role == DEVICE_ROLE_PREFERRED || prevDisabledDevices.empty()) { return status; } // Disabled devices were removed, need to force a resync for these enableDevicesForStrategy(strategy, prevDisabledDevices); return NO_ERROR; } void Engine::enableDevicesForStrategy(product_strategy_t strategy __unused, const DeviceVector &devicesToEnable) { // devices were (re)enabled, need to force a resync for these setOutputDevicesConnectionState(devicesToEnable, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE); setOutputDevicesConnectionState(devicesToEnable, AUDIO_POLICY_DEVICE_STATE_AVAILABLE); } status_t Engine::disableDevicesForStrategy(product_strategy_t strategy, const DeviceVector &devicesToDisable) { // Filter out disabled devices for this strategy. // However, to update the output device decision, availability criterion shall be updated, // which may impact other strategies. So, as a WA, reconsider now and later to prevent from // altering decision for other strategies; setOutputDevicesConnectionState(devicesToDisable, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE); DeviceTypeSet deviceTypes = getProductStrategies().getDeviceTypesForProductStrategy(strategy); const std::string address(getProductStrategies().getDeviceAddressForProductStrategy(strategy)); setOutputDevicesConnectionState(devicesToDisable, AUDIO_POLICY_DEVICE_STATE_AVAILABLE); // Force reapply devices for given strategy getProductStrategies().at(strategy)->setDeviceTypes(deviceTypes); setDeviceAddressForProductStrategy(strategy, address); return NO_ERROR; } DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t ps) const { DeviceVector selectedDevices = {}; DeviceVector disabledDevices = {}; const auto productStrategies = getProductStrategies(); if (productStrategies.find(ps) == productStrategies.end()) { ALOGE("%s: Trying to get device on invalid strategy %d", __FUNCTION__, ps); return {}; return selectedDevices; } const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs(); DeviceTypeSet availableOutputDevicesTypes = availableOutputDevices.types(); // check if this strategy has a preferred device that is available, // if yes, give priority to it. DeviceVector preferredAvailableDevVec = getPreferredAvailableDevicesForProductStrategy(availableOutputDevices, ps); if (!preferredAvailableDevVec.isEmpty()) { return preferredAvailableDevVec; } /** This is the only case handled programmatically because the PFW is unable to know the * activity of streams. * Loading @@ -227,33 +351,34 @@ DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t ps) const * -When media is not playing anymore, fall back on the sonification behavior */ DeviceTypeSet deviceTypes; product_strategy_t psOrFallback = ps; if (ps == getProductStrategyForStream(AUDIO_STREAM_NOTIFICATION) && !is_state_in_call(getPhoneState()) && !outputs.isActiveRemotely(toVolumeSource(AUDIO_STREAM_MUSIC), SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY) && outputs.isActive(toVolumeSource(AUDIO_STREAM_MUSIC), SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { product_strategy_t strategyForMedia = getProductStrategyForStream(AUDIO_STREAM_MUSIC); deviceTypes = productStrategies.getDeviceTypesForProductStrategy(strategyForMedia); psOrFallback = getProductStrategyForStream(AUDIO_STREAM_MUSIC); } else if (ps == getProductStrategyForStream(AUDIO_STREAM_ACCESSIBILITY) && (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) || outputs.isActive(toVolumeSource(AUDIO_STREAM_ALARM)))) { // do not route accessibility prompts to a digital output currently configured with a // compressed format as they would likely not be mixed and dropped. // Device For Sonification conf file has HDMI, SPDIF and HDMI ARC unreacheable. product_strategy_t strategyNotification = getProductStrategyForStream(AUDIO_STREAM_RING); deviceTypes = productStrategies.getDeviceTypesForProductStrategy(strategyNotification); } else { deviceTypes = productStrategies.getDeviceTypesForProductStrategy(ps); psOrFallback = getProductStrategyForStream(AUDIO_STREAM_RING); } disabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, psOrFallback); deviceTypes = productStrategies.getDeviceTypesForProductStrategy(psOrFallback); // In case a fallback is decided on other strategy, prevent from selecting this device if // disabled for current strategy. availableOutputDevices.remove(disabledDevices); if (deviceTypes.empty() || Intersection(deviceTypes, availableOutputDevicesTypes).empty()) { auto defaultDevice = getApmObserver()->getDefaultOutputDevice(); ALOG_ASSERT(defaultDevice != nullptr, "no valid default device defined"); return DeviceVector(defaultDevice); } if (/*device_distinguishes_on_address(*deviceTypes.begin())*/ isSingleDeviceType( selectedDevices = DeviceVector(defaultDevice); } else if (/*device_distinguishes_on_address(*deviceTypes.begin())*/ isSingleDeviceType( deviceTypes, AUDIO_DEVICE_OUT_BUS)) { // We do expect only one device for these types of devices // Criterion device address garantee this one is available Loading @@ -268,12 +393,15 @@ DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t ps) const dumpDeviceTypes(deviceTypes).c_str(), address.c_str()); auto defaultDevice = getApmObserver()->getDefaultOutputDevice(); ALOG_ASSERT(defaultDevice != nullptr, "Default Output Device NOT available"); return DeviceVector(defaultDevice); } return DeviceVector(busDevice); selectedDevices = DeviceVector(defaultDevice); } else { selectedDevices = DeviceVector(busDevice); } } else { ALOGV("%s:device %s %d", __FUNCTION__, dumpDeviceTypes(deviceTypes).c_str(), ps); return availableOutputDevices.getDevicesFromTypes(deviceTypes); selectedDevices = availableOutputDevices.getDevicesFromTypes(deviceTypes); } return selectedDevices; } DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes, Loading services/audiopolicy/engineconfigurable/src/Engine.h +13 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,13 @@ public: sp<AudioPolicyMix> *mix = nullptr) const override; status_t setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) override; status_t removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) override; status_t clearDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) override; /// /// from AudioPolicyPluginInterface /// Loading Loading @@ -94,6 +101,12 @@ public: } private: android::status_t disableDevicesForStrategy(product_strategy_t strategy, const DeviceVector &devicesToDisable); void enableDevicesForStrategy(product_strategy_t strategy, const DeviceVector &devicesToEnable); android::status_t setOutputDevicesConnectionState(const DeviceVector &devices, audio_policy_dev_state_t state); /* Copy facilities are put private to disable copy. */ Engine(const Engine &object); Engine &operator=(const Engine &object); Loading services/audiopolicy/enginedefault/src/Engine.cpp +0 −32 Original line number Diff line number Diff line Loading @@ -730,38 +730,6 @@ audio_devices_t Engine::getPreferredDeviceTypeForLegacyStrategy( return AUDIO_DEVICE_NONE; } DeviceVector Engine::getPreferredAvailableDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const { DeviceVector preferredAvailableDevVec = {}; AudioDeviceTypeAddrVector preferredStrategyDevices; const status_t status = getDevicesForRoleAndStrategy( strategy, DEVICE_ROLE_PREFERRED, preferredStrategyDevices); if (status == NO_ERROR) { // there is a preferred device, is it available? preferredAvailableDevVec = availableOutputDevices.getDevicesFromDeviceTypeAddrVec(preferredStrategyDevices); if (preferredAvailableDevVec.size() == preferredStrategyDevices.size()) { ALOGVV("%s using pref device %s for strategy %u", __func__, preferredAvailableDevVec.toString().c_str(), strategy); return preferredAvailableDevVec; } } return preferredAvailableDevVec; } DeviceVector Engine::getDisabledDevicesForProductStrategy( const DeviceVector &availableOutputDevices, product_strategy_t strategy) const { DeviceVector disabledDevices = {}; AudioDeviceTypeAddrVector disabledDevicesTypeAddr; const status_t status = getDevicesForRoleAndStrategy( strategy, DEVICE_ROLE_DISABLED, disabledDevicesTypeAddr); if (status == NO_ERROR) { disabledDevices = availableOutputDevices.getDevicesFromDeviceTypeAddrVec(disabledDevicesTypeAddr); } return disabledDevices; } DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const { const SwAudioOutputCollection& outputs = getApmObserver()->getOutputs(); Loading Loading
services/audiopolicy/engine/common/include/EngineBase.h +6 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,12 @@ public: void updateDeviceSelectionCache() override; protected: DeviceVector getPreferredAvailableDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const; DeviceVector getDisabledDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const; private: /** * Get media devices as the given role Loading
services/audiopolicy/engine/common/src/EngineBase.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -705,6 +705,38 @@ void EngineBase::updateDeviceSelectionCache() { } } DeviceVector EngineBase::getPreferredAvailableDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const { DeviceVector preferredAvailableDevVec = {}; AudioDeviceTypeAddrVector preferredStrategyDevices; const status_t status = getDevicesForRoleAndStrategy( strategy, DEVICE_ROLE_PREFERRED, preferredStrategyDevices); if (status == NO_ERROR) { // there is a preferred device, is it available? preferredAvailableDevVec = availableOutputDevices.getDevicesFromDeviceTypeAddrVec(preferredStrategyDevices); if (preferredAvailableDevVec.size() == preferredStrategyDevices.size()) { ALOGV("%s using pref device %s for strategy %u", __func__, preferredAvailableDevVec.toString().c_str(), strategy); return preferredAvailableDevVec; } } return preferredAvailableDevVec; } DeviceVector EngineBase::getDisabledDevicesForProductStrategy( const DeviceVector &availableOutputDevices, product_strategy_t strategy) const { DeviceVector disabledDevices = {}; AudioDeviceTypeAddrVector disabledDevicesTypeAddr; const status_t status = getDevicesForRoleAndStrategy( strategy, DEVICE_ROLE_DISABLED, disabledDevicesTypeAddr); if (status == NO_ERROR) { disabledDevices = availableOutputDevices.getDevicesFromDeviceTypeAddrVec(disabledDevicesTypeAddr); } return disabledDevices; } void EngineBase::dumpCapturePresetDevicesRoleMap(String8 *dst, int spaces) const { dst->appendFormat("\n%*sDevice role per capture preset dump:", spaces, ""); Loading
services/audiopolicy/engineconfigurable/src/Engine.cpp +144 −16 Original line number Diff line number Diff line Loading @@ -165,6 +165,21 @@ audio_policy_forced_cfg_t Engine::getForceUse(audio_policy_force_use_t usage) co return mPolicyParameterMgr->getForceUse(usage); } status_t Engine::setOutputDevicesConnectionState(const DeviceVector &devices, audio_policy_dev_state_t state) { for (const auto &device : devices) { mPolicyParameterMgr->setDeviceConnectionState(device->type(), device->address(), state); } DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) { availableOutputDevices.remove(devices); } else { availableOutputDevices.add(devices); } return mPolicyParameterMgr->setAvailableOutputDevices(availableOutputDevices.types()); } status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> device, audio_policy_dev_state_t state) { Loading Loading @@ -205,17 +220,126 @@ status_t Engine::loadAudioPolicyEngineConfig() return result.nbSkippedElement == 0? NO_ERROR : BAD_VALUE; } status_t Engine::setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) { DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); DeviceVector prevDisabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, strategy); status_t status = EngineBase::setDevicesRoleForStrategy(strategy, role, devices); if (status != NO_ERROR) { return status; } DeviceVector newDisabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, strategy); if (role == DEVICE_ROLE_PREFERRED) { DeviceVector reenabledDevices = prevDisabledDevices; reenabledDevices.remove(newDisabledDevices); if (reenabledDevices.empty()) { ALOGD("%s DEVICE_ROLE_PREFERRED empty renabled devices", __func__); return status; } // some devices were moved from disabled to preferred, need to force a resync for these enableDevicesForStrategy(strategy, prevDisabledDevices); } if (newDisabledDevices.empty()) { return status; } return disableDevicesForStrategy(strategy, newDisabledDevices); } status_t Engine::removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) { const auto productStrategies = getProductStrategies(); if (productStrategies.find(strategy) == end(productStrategies)) { ALOGE("%s invalid %d", __func__, strategy); return BAD_VALUE; } DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); DeviceVector prevDisabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, strategy); status_t status = EngineBase::removeDevicesRoleForStrategy(strategy, role, devices); if (status != NO_ERROR || role == DEVICE_ROLE_PREFERRED) { return status; } // Removing ROLE_DISABLED for given devices, need to force a resync for these enableDevicesForStrategy(strategy, prevDisabledDevices); DeviceVector remainingDisabledDevices = getDisabledDevicesForProductStrategy( availableOutputDevices, strategy); if (remainingDisabledDevices.empty()) { return status; } return disableDevicesForStrategy(strategy, remainingDisabledDevices); } status_t Engine::clearDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) { const auto productStrategies = getProductStrategies(); if (productStrategies.find(strategy) == end(productStrategies)) { ALOGE("%s invalid %d", __func__, strategy); return BAD_VALUE; } DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); DeviceVector prevDisabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, strategy); status_t status = EngineBase::clearDevicesRoleForStrategy(strategy, role); if (status != NO_ERROR || role == DEVICE_ROLE_PREFERRED || prevDisabledDevices.empty()) { return status; } // Disabled devices were removed, need to force a resync for these enableDevicesForStrategy(strategy, prevDisabledDevices); return NO_ERROR; } void Engine::enableDevicesForStrategy(product_strategy_t strategy __unused, const DeviceVector &devicesToEnable) { // devices were (re)enabled, need to force a resync for these setOutputDevicesConnectionState(devicesToEnable, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE); setOutputDevicesConnectionState(devicesToEnable, AUDIO_POLICY_DEVICE_STATE_AVAILABLE); } status_t Engine::disableDevicesForStrategy(product_strategy_t strategy, const DeviceVector &devicesToDisable) { // Filter out disabled devices for this strategy. // However, to update the output device decision, availability criterion shall be updated, // which may impact other strategies. So, as a WA, reconsider now and later to prevent from // altering decision for other strategies; setOutputDevicesConnectionState(devicesToDisable, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE); DeviceTypeSet deviceTypes = getProductStrategies().getDeviceTypesForProductStrategy(strategy); const std::string address(getProductStrategies().getDeviceAddressForProductStrategy(strategy)); setOutputDevicesConnectionState(devicesToDisable, AUDIO_POLICY_DEVICE_STATE_AVAILABLE); // Force reapply devices for given strategy getProductStrategies().at(strategy)->setDeviceTypes(deviceTypes); setDeviceAddressForProductStrategy(strategy, address); return NO_ERROR; } DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t ps) const { DeviceVector selectedDevices = {}; DeviceVector disabledDevices = {}; const auto productStrategies = getProductStrategies(); if (productStrategies.find(ps) == productStrategies.end()) { ALOGE("%s: Trying to get device on invalid strategy %d", __FUNCTION__, ps); return {}; return selectedDevices; } const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs(); DeviceTypeSet availableOutputDevicesTypes = availableOutputDevices.types(); // check if this strategy has a preferred device that is available, // if yes, give priority to it. DeviceVector preferredAvailableDevVec = getPreferredAvailableDevicesForProductStrategy(availableOutputDevices, ps); if (!preferredAvailableDevVec.isEmpty()) { return preferredAvailableDevVec; } /** This is the only case handled programmatically because the PFW is unable to know the * activity of streams. * Loading @@ -227,33 +351,34 @@ DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t ps) const * -When media is not playing anymore, fall back on the sonification behavior */ DeviceTypeSet deviceTypes; product_strategy_t psOrFallback = ps; if (ps == getProductStrategyForStream(AUDIO_STREAM_NOTIFICATION) && !is_state_in_call(getPhoneState()) && !outputs.isActiveRemotely(toVolumeSource(AUDIO_STREAM_MUSIC), SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY) && outputs.isActive(toVolumeSource(AUDIO_STREAM_MUSIC), SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { product_strategy_t strategyForMedia = getProductStrategyForStream(AUDIO_STREAM_MUSIC); deviceTypes = productStrategies.getDeviceTypesForProductStrategy(strategyForMedia); psOrFallback = getProductStrategyForStream(AUDIO_STREAM_MUSIC); } else if (ps == getProductStrategyForStream(AUDIO_STREAM_ACCESSIBILITY) && (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) || outputs.isActive(toVolumeSource(AUDIO_STREAM_ALARM)))) { // do not route accessibility prompts to a digital output currently configured with a // compressed format as they would likely not be mixed and dropped. // Device For Sonification conf file has HDMI, SPDIF and HDMI ARC unreacheable. product_strategy_t strategyNotification = getProductStrategyForStream(AUDIO_STREAM_RING); deviceTypes = productStrategies.getDeviceTypesForProductStrategy(strategyNotification); } else { deviceTypes = productStrategies.getDeviceTypesForProductStrategy(ps); psOrFallback = getProductStrategyForStream(AUDIO_STREAM_RING); } disabledDevices = getDisabledDevicesForProductStrategy(availableOutputDevices, psOrFallback); deviceTypes = productStrategies.getDeviceTypesForProductStrategy(psOrFallback); // In case a fallback is decided on other strategy, prevent from selecting this device if // disabled for current strategy. availableOutputDevices.remove(disabledDevices); if (deviceTypes.empty() || Intersection(deviceTypes, availableOutputDevicesTypes).empty()) { auto defaultDevice = getApmObserver()->getDefaultOutputDevice(); ALOG_ASSERT(defaultDevice != nullptr, "no valid default device defined"); return DeviceVector(defaultDevice); } if (/*device_distinguishes_on_address(*deviceTypes.begin())*/ isSingleDeviceType( selectedDevices = DeviceVector(defaultDevice); } else if (/*device_distinguishes_on_address(*deviceTypes.begin())*/ isSingleDeviceType( deviceTypes, AUDIO_DEVICE_OUT_BUS)) { // We do expect only one device for these types of devices // Criterion device address garantee this one is available Loading @@ -268,12 +393,15 @@ DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t ps) const dumpDeviceTypes(deviceTypes).c_str(), address.c_str()); auto defaultDevice = getApmObserver()->getDefaultOutputDevice(); ALOG_ASSERT(defaultDevice != nullptr, "Default Output Device NOT available"); return DeviceVector(defaultDevice); } return DeviceVector(busDevice); selectedDevices = DeviceVector(defaultDevice); } else { selectedDevices = DeviceVector(busDevice); } } else { ALOGV("%s:device %s %d", __FUNCTION__, dumpDeviceTypes(deviceTypes).c_str(), ps); return availableOutputDevices.getDevicesFromTypes(deviceTypes); selectedDevices = availableOutputDevices.getDevicesFromTypes(deviceTypes); } return selectedDevices; } DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes, Loading
services/audiopolicy/engineconfigurable/src/Engine.h +13 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,13 @@ public: sp<AudioPolicyMix> *mix = nullptr) const override; status_t setDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) override; status_t removeDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role, const AudioDeviceTypeAddrVector &devices) override; status_t clearDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) override; /// /// from AudioPolicyPluginInterface /// Loading Loading @@ -94,6 +101,12 @@ public: } private: android::status_t disableDevicesForStrategy(product_strategy_t strategy, const DeviceVector &devicesToDisable); void enableDevicesForStrategy(product_strategy_t strategy, const DeviceVector &devicesToEnable); android::status_t setOutputDevicesConnectionState(const DeviceVector &devices, audio_policy_dev_state_t state); /* Copy facilities are put private to disable copy. */ Engine(const Engine &object); Engine &operator=(const Engine &object); Loading
services/audiopolicy/enginedefault/src/Engine.cpp +0 −32 Original line number Diff line number Diff line Loading @@ -730,38 +730,6 @@ audio_devices_t Engine::getPreferredDeviceTypeForLegacyStrategy( return AUDIO_DEVICE_NONE; } DeviceVector Engine::getPreferredAvailableDevicesForProductStrategy( const DeviceVector& availableOutputDevices, product_strategy_t strategy) const { DeviceVector preferredAvailableDevVec = {}; AudioDeviceTypeAddrVector preferredStrategyDevices; const status_t status = getDevicesForRoleAndStrategy( strategy, DEVICE_ROLE_PREFERRED, preferredStrategyDevices); if (status == NO_ERROR) { // there is a preferred device, is it available? preferredAvailableDevVec = availableOutputDevices.getDevicesFromDeviceTypeAddrVec(preferredStrategyDevices); if (preferredAvailableDevVec.size() == preferredStrategyDevices.size()) { ALOGVV("%s using pref device %s for strategy %u", __func__, preferredAvailableDevVec.toString().c_str(), strategy); return preferredAvailableDevVec; } } return preferredAvailableDevVec; } DeviceVector Engine::getDisabledDevicesForProductStrategy( const DeviceVector &availableOutputDevices, product_strategy_t strategy) const { DeviceVector disabledDevices = {}; AudioDeviceTypeAddrVector disabledDevicesTypeAddr; const status_t status = getDevicesForRoleAndStrategy( strategy, DEVICE_ROLE_DISABLED, disabledDevicesTypeAddr); if (status == NO_ERROR) { disabledDevices = availableOutputDevices.getDevicesFromDeviceTypeAddrVec(disabledDevicesTypeAddr); } return disabledDevices; } DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const { const SwAudioOutputCollection& outputs = getApmObserver()->getOutputs(); Loading