diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp index 6665c43c63..cb9c7ba920 100644 --- a/media/libaudioclient/AudioSystem.cpp +++ b/media/libaudioclient/AudioSystem.cpp @@ -1525,6 +1525,35 @@ status_t AudioSystem::setRttEnabled(bool enabled) return aps->setRttEnabled(enabled); } +status_t AudioSystem::setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) { + return PERMISSION_DENIED; + } + return aps->setPreferredDeviceForStrategy(strategy, device); +} + +status_t AudioSystem::removePreferredDeviceForStrategy(product_strategy_t strategy) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) { + return PERMISSION_DENIED; + } + return aps->removePreferredDeviceForStrategy(strategy); +} + +status_t AudioSystem::getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) { + return PERMISSION_DENIED; + } + return aps->getPreferredDeviceForStrategy(strategy, device); +} + // --------------------------------------------------------------------------- int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback( diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp index 7cc95e5e60..0facaf8f88 100644 --- a/media/libaudioclient/IAudioPolicyService.cpp +++ b/media/libaudioclient/IAudioPolicyService.cpp @@ -104,7 +104,10 @@ enum { GET_VOLUME_GROUP_FOR_ATTRIBUTES, SET_ALLOWED_CAPTURE_POLICY, MOVE_EFFECTS_TO_IO, - SET_RTT_ENABLED + SET_RTT_ENABLED, + SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY, + REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY, + GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY, }; #define MAX_ITEMS_PER_LIST 1024 @@ -1284,6 +1287,55 @@ public: } return static_cast(reply.readInt32()); } + + virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.writeUint32(static_cast(strategy)); + status_t status = device.writeToParcel(&data); + if (status != NO_ERROR) { + return BAD_VALUE; + } + status = remote()->transact(SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY, + data, &reply); + if (status != NO_ERROR) { + return status; + } + return static_cast(reply.readInt32()); + } + + virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.writeUint32(static_cast(strategy)); + status_t status = remote()->transact(REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY, + data, &reply); + if (status != NO_ERROR) { + return status; + } + return static_cast(reply.readInt32()); + } + + virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.writeUint32(static_cast(strategy)); + status_t status = remote()->transact(GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY, + data, &reply); + if (status != NO_ERROR) { + return status; + } + status = device.readFromParcel(&reply); + if (status != NO_ERROR) { + return status; + } + return static_cast(reply.readInt32()); + } }; IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); @@ -1346,7 +1398,10 @@ status_t BnAudioPolicyService::onTransact( case GET_OFFLOAD_FORMATS_A2DP: case LIST_AUDIO_VOLUME_GROUPS: case GET_VOLUME_GROUP_FOR_ATTRIBUTES: - case SET_RTT_ENABLED: { + case SET_RTT_ENABLED: + case SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: + case REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: + case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: { if (!isServiceUid(IPCThreadState::self()->getCallingUid())) { ALOGW("%s: transaction %d received from PID %d unauthorized UID %d", __func__, code, IPCThreadState::self()->getCallingPid(), @@ -2369,6 +2424,40 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } + case SET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + product_strategy_t strategy = (product_strategy_t) data.readUint32(); + AudioDeviceTypeAddr device; + status_t status = device.readFromParcel((Parcel*)&data); + if (status != NO_ERROR) { + return status; + } + status = setPreferredDeviceForStrategy(strategy, device); + reply->writeInt32(status); + return NO_ERROR; + } + + case REMOVE_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + product_strategy_t strategy = (product_strategy_t) data.readUint32(); + status_t status = removePreferredDeviceForStrategy(strategy); + reply->writeInt32(status); + return NO_ERROR; + } + + case GET_PREFERRED_DEVICE_FOR_PRODUCT_STRATEGY: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + product_strategy_t strategy = (product_strategy_t) data.readUint32(); + AudioDeviceTypeAddr device; + status_t status = getPreferredDeviceForStrategy(strategy, device); + status_t marshall_status = device.writeToParcel(reply); + if (marshall_status != NO_ERROR) { + return marshall_status; + } + reply->writeInt32(status); + return NO_ERROR; + } + default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h index f29a775dac..a86297d5cc 100644 --- a/media/libaudioclient/include/media/AudioSystem.h +++ b/media/libaudioclient/include/media/AudioSystem.h @@ -403,6 +403,17 @@ public: */ static status_t setAudioHalPids(const std::vector& pids); + static status_t setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device); + + static status_t removePreferredDeviceForStrategy(product_strategy_t strategy); + + static status_t getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device); + + static status_t getDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device); + // ---------------------------------------------------------------------------- class AudioVolumeGroupCallback : public RefBase diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h index 8669ee6b88..9b91d6dfcb 100644 --- a/media/libaudioclient/include/media/IAudioPolicyService.h +++ b/media/libaudioclient/include/media/IAudioPolicyService.h @@ -223,6 +223,14 @@ public: volume_group_t &volumeGroup) = 0; virtual status_t setRttEnabled(bool enabled) = 0; + + virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device) = 0; + + virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) = 0; + + virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device) = 0; }; diff --git a/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h b/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h index 5e5e7622ec..acc37ca964 100644 --- a/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h +++ b/media/libaudiofoundation/include/media/AudioDeviceTypeAddr.h @@ -37,6 +37,8 @@ struct AudioDeviceTypeAddr : public Parcelable { bool equals(const AudioDeviceTypeAddr& other) const; + AudioDeviceTypeAddr& operator= (const AudioDeviceTypeAddr&) = default; + void reset(); status_t readFromParcel(const Parcel *parcel) override; diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index 1155987db4..1fe60d4975 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -271,6 +271,14 @@ public: virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa, volume_group_t &volumeGroup) = 0; + + virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device) = 0; + + virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) = 0; + + virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device) = 0; }; diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h index 4cf0b904c2..7f339dcfe4 100755 --- a/services/audiopolicy/engine/common/include/EngineBase.h +++ b/services/audiopolicy/engine/common/include/EngineBase.h @@ -93,6 +93,13 @@ public: void dump(String8 *dst) const override; + status_t setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device) override; + + status_t removePreferredDeviceForStrategy(product_strategy_t strategy) override; + + status_t getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device) const override; engineConfig::ParsingResult loadAudioPolicyEngineConfig(); @@ -124,6 +131,7 @@ private: AudioPolicyManagerObserver *mApmObserver = nullptr; ProductStrategyMap mProductStrategies; + ProductStrategyPreferredRoutingMap mProductStrategyPreferredDevices; VolumeGroupMap mVolumeGroups; LastRemovableMediaDevices mLastRemovableMediaDevices; audio_mode_t mPhoneState = AUDIO_MODE_NORMAL; /**< current phone state. */ diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h index ab8eff3d10..3ebe7d1960 100644 --- a/services/audiopolicy/engine/common/include/ProductStrategy.h +++ b/services/audiopolicy/engine/common/include/ProductStrategy.h @@ -28,6 +28,7 @@ #include #include #include +#include namespace android { @@ -163,4 +164,10 @@ private: product_strategy_t mDefaultStrategy = PRODUCT_STRATEGY_NONE; }; +class ProductStrategyPreferredRoutingMap : public std::map +{ +public: + void dump(String8 *dst, int spaces = 0) const; +}; + } // namespace android diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp index 45c43d8387..01efc7a041 100644 --- a/services/audiopolicy/engine/common/src/EngineBase.cpp +++ b/services/audiopolicy/engine/common/src/EngineBase.cpp @@ -283,9 +283,57 @@ status_t EngineBase::listAudioVolumeGroups(AudioVolumeGroupVector &groups) const return NO_ERROR; } +status_t EngineBase::setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device) +{ + // verify strategy exists + if (mProductStrategies.find(strategy) == mProductStrategies.end()) { + ALOGE("%s invalid strategy %u", __func__, strategy); + return BAD_VALUE; + } + + mProductStrategyPreferredDevices[strategy] = device; + return NO_ERROR; +} + +status_t EngineBase::removePreferredDeviceForStrategy(product_strategy_t strategy) +{ + // verify strategy exists + if (mProductStrategies.find(strategy) == mProductStrategies.end()) { + ALOGE("%s invalid strategy %u", __func__, strategy); + return BAD_VALUE; + } + + if (mProductStrategyPreferredDevices.erase(strategy) == 0) { + // no preferred device was set + return NAME_NOT_FOUND; + } + return NO_ERROR; +} + +status_t EngineBase::getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device) const +{ + // verify strategy exists + if (mProductStrategies.find(strategy) == mProductStrategies.end()) { + ALOGE("%s unknown strategy %u", __func__, strategy); + return BAD_VALUE; + } + // preferred device for this strategy? + auto devIt = mProductStrategyPreferredDevices.find(strategy); + if (devIt == mProductStrategyPreferredDevices.end()) { + ALOGV("%s no preferred device for strategy %u", __func__, strategy); + return NAME_NOT_FOUND; + } + + device = devIt->second; + return NO_ERROR; +} + void EngineBase::dump(String8 *dst) const { mProductStrategies.dump(dst, 2); + mProductStrategyPreferredDevices.dump(dst, 2); mVolumeGroups.dump(dst, 2); } diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp index 14c9dd1205..fe15ff698f 100644 --- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp +++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp @@ -310,5 +310,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 dev:%08x addr:%s", + spaces + 2, "", + (uint32_t) iter.first, + iter.second.mType, iter.second.mAddress.c_str()); + } + dst->appendFormat("\n"); +} } diff --git a/services/audiopolicy/engine/interface/EngineInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h index 0c58a7ca5f..dfb20b5274 100644 --- a/services/audiopolicy/engine/interface/EngineInterface.h +++ b/services/audiopolicy/engine/interface/EngineInterface.h @@ -292,6 +292,39 @@ public: */ virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const = 0; + /** + * @brief setPreferredDeviceForStrategy sets the default device to be used for a + * strategy when available + * @param strategy the audio strategy whose routing will be affected + * @param device the audio device to route to when available + * @return BAD_VALUE if the strategy is invalid, + * or NO_ERROR if the preferred device was set + */ + virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device) = 0; + + /** + * @brief removePreferredDeviceForStrategy removes the preferred device previously set + * for the given strategy + * @param strategy the audio strategy whose routing will be affected + * @return BAD_VALUE if the strategy is invalid, + * or NO_ERROR if the preferred device was removed + */ + virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy) = 0; + + /** + * @brief getPreferredDeviceForStrategy queries which device is set as the + * preferred device for the given strategy + * @param strategy the strategy to query + * @param device returns configured as the preferred device if one was set + * @return BAD_VALUE if the strategy is invalid, + * or NAME_NOT_FOUND if no preferred device was set + * or NO_ERROR if the device parameter was initialized to the preferred device + */ + virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device) const = 0; + + virtual void dump(String8 *dst) const = 0; protected: diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp index de7e7cea3d..02b99d0c90 100755 --- a/services/audiopolicy/enginedefault/src/Engine.cpp +++ b/services/audiopolicy/enginedefault/src/Engine.cpp @@ -604,7 +604,7 @@ sp Engine::getDeviceForInputSource(audio_source_t inputSource) void Engine::updateDeviceSelectionCache() { for (const auto &iter : getProductStrategies()) { - const auto &strategy = iter.second; + const auto& strategy = iter.second; auto devices = getDevicesForProductStrategy(strategy->getId()); mDevicesForStrategies[strategy->getId()] = devices; strategy->setDeviceTypes(devices.types()); @@ -612,14 +612,30 @@ void Engine::updateDeviceSelectionCache() } } -DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const -{ +DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const { DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); - DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices(); - const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs(); + // check if this strategy has a preferred device that is available, + // if yes, give priority to it + AudioDeviceTypeAddr preferredStrategyDevice; + const status_t status = getPreferredDeviceForStrategy(strategy, preferredStrategyDevice); + if (status == NO_ERROR) { + // there is a preferred device, is it available? + sp preferredAvailableDevDescr = availableOutputDevices.getDevice( + preferredStrategyDevice.mType, + String8(preferredStrategyDevice.mAddress.c_str()), + AUDIO_FORMAT_DEFAULT); + if (preferredAvailableDevDescr != nullptr) { + ALOGVV("%s using pref device 0x%08x/%s for strategy %u", __FUNCTION__, + preferredStrategyDevice.mType, preferredStrategyDevice.mAddress, strategy); + return DeviceVector(preferredAvailableDevDescr); + } + } + + DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices(); + const SwAudioOutputCollection& outputs = getApmObserver()->getOutputs(); auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ? - mLegacyStrategyMap.at(strategy) : STRATEGY_NONE; + mLegacyStrategyMap.at(strategy) : STRATEGY_NONE; return getDevicesForStrategyInt(legacyStrategy, availableOutputDevices, availableInputDevices, outputs); diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index 718142f1d2..23c0a12b15 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -794,27 +794,11 @@ void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage, //FIXME: workaround for truncated touch sounds // to be removed when the problem is handled by system UI uint32_t delayMs = 0; - uint32_t waitMs = 0; if (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) { delayMs = TOUCH_SOUND_FIXED_DELAY_MS; } - if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) { - DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, true /*fromCache*/); - waitMs = updateCallRouting(newDevices, delayMs); - } - for (size_t i = 0; i < mOutputs.size(); i++) { - sp outputDesc = mOutputs.valueAt(i); - DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/); - if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) { - // As done in setDeviceConnectionState, we could also fix default device issue by - // preventing the force re-routing in case of default dev that distinguishes on address. - // Let's give back to engine full device choice decision however. - waitMs = setOutputDevices(outputDesc, newDevices, !newDevices.isEmpty(), delayMs); - } - if (forceVolumeReeval && !newDevices.isEmpty()) { - applyStreamVolumes(outputDesc, newDevices.types(), waitMs, true); - } - } + + updateCallAndOutputRouting(forceVolumeReeval, delayMs); for (const auto& activeDesc : mInputs.getActiveInputs()) { auto newDevice = getNewInputDevice(activeDesc); @@ -3084,6 +3068,72 @@ status_t AudioPolicyManager::removeUidDeviceAffinities(uid_t uid) { return res; } +status_t AudioPolicyManager::setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device) { + ALOGI("%s() strategy=%d device=%08x addr=%s", __FUNCTION__, + strategy, device.mType, device.mAddress.c_str()); + // strategy preferred device is only for output devices + if (!audio_is_output_device(device.mType)) { + ALOGE("%s() device=%08x is NOT an output device", __FUNCTION__, device.mType); + return BAD_VALUE; + } + + status_t status = mEngine->setPreferredDeviceForStrategy(strategy, device); + if (status != NO_ERROR) { + ALOGW("Engine could not set preferred device %08x %s for strategy %d", + device.mType, device.mAddress.c_str(), strategy); + return status; + } + + checkForDeviceAndOutputChanges(); + updateCallAndOutputRouting(); + + return NO_ERROR; +} + +void AudioPolicyManager::updateCallAndOutputRouting(bool forceVolumeReeval, uint32_t delayMs) +{ + uint32_t waitMs = 0; + if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) { + DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, true /*fromCache*/); + waitMs = updateCallRouting(newDevices, delayMs); + } + for (size_t i = 0; i < mOutputs.size(); i++) { + sp outputDesc = mOutputs.valueAt(i); + DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/); + if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) { + // As done in setDeviceConnectionState, we could also fix default device issue by + // preventing the force re-routing in case of default dev that distinguishes on address. + // Let's give back to engine full device choice decision however. + waitMs = setOutputDevices(outputDesc, newDevices, !newDevices.isEmpty(), delayMs); + } + if (forceVolumeReeval && !newDevices.isEmpty()) { + applyStreamVolumes(outputDesc, newDevices.types(), waitMs, true); + } + } +} + +status_t AudioPolicyManager::removePreferredDeviceForStrategy(product_strategy_t strategy) +{ + ALOGI("%s() strategy=%d", __FUNCTION__, strategy); + + status_t status = mEngine->removePreferredDeviceForStrategy(strategy); + if (status != NO_ERROR) { + ALOGW("Engine could not remove preferred device for strategy %d", strategy); + return status; + } + + checkForDeviceAndOutputChanges(); + updateCallAndOutputRouting(); + + return NO_ERROR; +} + +status_t AudioPolicyManager::getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device) { + return mEngine->getPreferredDeviceForStrategy(strategy, device); +} + void AudioPolicyManager::dump(String8 *dst) const { dst->appendFormat("\nAudioPolicyManager Dump: %p\n", this); @@ -5056,6 +5106,7 @@ void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr DeviceVector oldDevices = mEngine->getOutputDevicesForAttributes(attr, 0, true /*fromCache*/); DeviceVector newDevices = mEngine->getOutputDevicesForAttributes(attr, 0, false /*fromCache*/); + SortedVector srcOutputs = getOutputsForDevices(oldDevices, mPreviousOutputs); SortedVector dstOutputs = getOutputsForDevices(newDevices, mOutputs); diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h index cff6983d77..d516d7ba28 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.h +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h @@ -258,6 +258,12 @@ public: const Vector& devices); virtual status_t removeUidDeviceAffinities(uid_t uid); + virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device); + virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy); + virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device); + virtual status_t startAudioSource(const struct audio_port_config *source, const audio_attributes_t *attributes, audio_port_handle_t *portId, @@ -496,12 +502,18 @@ protected: // close an input. void closeInput(audio_io_handle_t input); - // runs all the checks required for accomodating changes in devices and outputs + // runs all the checks required for accommodating changes in devices and outputs // if 'onOutputsChecked' callback is provided, it is executed after the outputs // check via 'checkOutputForAllStrategies'. If the callback returns 'true', // A2DP suspend status is rechecked. void checkForDeviceAndOutputChanges(std::function onOutputsChecked = nullptr); + /** + * @brief updates routing for all outputs (including call if call in progress). + * @param delayMs delay for unmuting if required + */ + void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0); + /** * @brief checkOutputForAttributes checks and if necessary changes outputs used for the * given audio attributes. diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index fa8da8916e..47a103b0bd 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -1325,4 +1325,33 @@ status_t AudioPolicyService::setRttEnabled(bool enabled) return NO_ERROR; } +status_t AudioPolicyService::setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device) +{ + if (mAudioPolicyManager == NULL) { + return NO_INIT; + } + Mutex::Autolock _l(mLock); + return mAudioPolicyManager->setPreferredDeviceForStrategy(strategy, device); +} + +status_t AudioPolicyService::removePreferredDeviceForStrategy(product_strategy_t strategy) +{ + if (mAudioPolicyManager == NULL) { + return NO_INIT; + } + Mutex::Autolock _l(mLock); + return mAudioPolicyManager->removePreferredDeviceForStrategy(strategy); +} + +status_t AudioPolicyService::getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device) +{ + if (mAudioPolicyManager == NULL) { + return NO_INIT; + } + Mutex::Autolock _l(mLock); + return mAudioPolicyManager->getPreferredDeviceForStrategy(strategy, device); +} + } // namespace android diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index bed1b0417f..7b72dc198e 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -224,6 +224,15 @@ public: virtual status_t removeUidDeviceAffinities(uid_t uid); + virtual status_t setPreferredDeviceForStrategy(product_strategy_t strategy, + const AudioDeviceTypeAddr &device); + + virtual status_t removePreferredDeviceForStrategy(product_strategy_t strategy); + + + virtual status_t getPreferredDeviceForStrategy(product_strategy_t strategy, + AudioDeviceTypeAddr &device); + virtual status_t startAudioSource(const struct audio_port_config *source, const audio_attributes_t *attributes, audio_port_handle_t *portId);