AudioPolicyManager: update getDevicesForAttributes
Add forVolume parameter to enable special volume handling.
This is the first step to remove getDevicesForStream.
Test: volume changes; adb shell dumpsys audio
Bug: 219974551
Merged-In: If0886e6e885a06d927befadb02830cead421fabd
Change-Id: If0886e6e885a06d927befadb02830cead421fabd
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 4c2284b..dd729c4 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1270,7 +1270,8 @@
}
status_t AudioSystem::getDevicesForAttributes(const AudioAttributes& aa,
- AudioDeviceTypeAddrVector* devices) {
+ AudioDeviceTypeAddrVector* devices,
+ bool forVolume) {
if (devices == nullptr) {
return BAD_VALUE;
}
@@ -1281,7 +1282,7 @@
legacy2aidl_AudioAttributes_AudioAttributesEx(aa));
std::vector<AudioDevice> retAidl;
RETURN_STATUS_IF_ERROR(
- statusTFromBinderStatus(aps->getDevicesForAttributes(aaAidl, &retAidl)));
+ statusTFromBinderStatus(aps->getDevicesForAttributes(aaAidl, forVolume, &retAidl)));
*devices = VALUE_OR_RETURN_STATUS(
convertContainer<AudioDeviceTypeAddrVector>(
retAidl,
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index f10c5d0..748a10b 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -139,7 +139,7 @@
AudioDeviceDescription[] getDevicesForStream(AudioStreamType stream);
- AudioDevice[] getDevicesForAttributes(in AudioAttributesEx attr);
+ AudioDevice[] getDevicesForAttributes(in AudioAttributesEx attr, boolean forVolume);
int /* audio_io_handle_t */ getOutputForEffect(in EffectDescriptor desc);
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index a1fb125..f1fcd3f 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -330,7 +330,8 @@
static product_strategy_t getStrategyForStream(audio_stream_type_t stream);
static DeviceTypeSet getDevicesForStream(audio_stream_type_t stream);
static status_t getDevicesForAttributes(const AudioAttributes &aa,
- AudioDeviceTypeAddrVector *devices);
+ AudioDeviceTypeAddrVector *devices,
+ bool forVolume);
static audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc);
static status_t registerEffect(const effect_descriptor_t *desc,
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 5b2b87e..0ccc963 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -215,7 +215,8 @@
// retrieves the list of enabled output devices for the given audio attributes
virtual status_t getDevicesForAttributes(const audio_attributes_t &attr,
- AudioDeviceTypeAddrVector *devices) = 0;
+ AudioDeviceTypeAddrVector *devices,
+ bool forVolume) = 0;
// Audio effect management
virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc) = 0;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index fd42229..f981b26 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3919,7 +3919,7 @@
status_t AudioPolicyManager::getDirectProfilesForAttributes(const audio_attributes_t* attr,
AudioProfileVector& audioProfilesVector) {
AudioDeviceTypeAddrVector devices;
- status_t status = getDevicesForAttributes(*attr, &devices);
+ status_t status = getDevicesForAttributes(*attr, &devices, false /* forVolume */);
if (status != OK) {
return status;
}
@@ -6472,24 +6472,69 @@
// TODO - consider MSD routes b/214971780
status_t AudioPolicyManager::getDevicesForAttributes(
- const audio_attributes_t &attr, AudioDeviceTypeAddrVector *devices) {
+ const audio_attributes_t &attr, AudioDeviceTypeAddrVector *devices, bool forVolume) {
if (devices == nullptr) {
return BAD_VALUE;
}
+
+ // Devices are determined in the following precedence:
+ //
+ // 1) Devices associated with a dynamic policy matching the attributes. This is often
+ // a remote submix from MIX_ROUTE_FLAG_LOOP_BACK.
+ //
+ // If no such dynamic policy then
+ // 2) Devices containing an active client using setPreferredDevice
+ // with same strategy as the attributes.
+ // (from the default Engine::getOutputDevicesForAttributes() implementation).
+ //
+ // If no corresponding active client with setPreferredDevice then
+ // 3) Devices associated with the strategy determined by the attributes
+ // (from the default Engine::getOutputDevicesForAttributes() implementation).
+ //
+ // See related getOutputForAttrInt().
+
// check dynamic policies but only for primary descriptors (secondary not used for audible
// audio routing, only used for duplication for playback capture)
sp<AudioPolicyMix> policyMix;
status_t status = mPolicyMixes.getOutputForAttr(attr, 0 /*uid unknown here*/,
- AUDIO_OUTPUT_FLAG_NONE, policyMix, nullptr);
+ AUDIO_OUTPUT_FLAG_NONE, policyMix, nullptr /* secondaryMixes */);
if (status != OK) {
return status;
}
- if (policyMix != nullptr && policyMix->getOutput() != nullptr) {
- AudioDeviceTypeAddr device(policyMix->mDeviceType, policyMix->mDeviceAddress.c_str());
- devices->push_back(device);
- return NO_ERROR;
+
+ DeviceVector curDevices;
+ if (policyMix != nullptr && policyMix->getOutput() != nullptr &&
+ // For volume control, skip LOOPBACK mixes which use AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+ // as they are unaffected by device/stream volume
+ // (per SwAudioOutputDescriptor::isFixedVolume()).
+ (!forVolume || policyMix->mDeviceType != AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
+ ) {
+ sp<DeviceDescriptor> deviceDesc = mAvailableOutputDevices.getDevice(
+ policyMix->mDeviceType, policyMix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
+ curDevices.add(deviceDesc);
+ } else {
+ // The default Engine::getOutputDevicesForAttributes() uses findPreferredDevice()
+ // which selects setPreferredDevice if active. This means forVolume call
+ // will take an active setPreferredDevice, if such exists.
+
+ curDevices = mEngine->getOutputDevicesForAttributes(
+ attr, nullptr /* preferredDevice */, false /* fromCache */);
}
- DeviceVector curDevices = mEngine->getOutputDevicesForAttributes(attr, nullptr, false);
+
+ if (forVolume) {
+ // We alias the device AUDIO_DEVICE_OUT_SPEAKER_SAFE to AUDIO_DEVICE_OUT_SPEAKER
+ // for single volume control in AudioService (such relationship should exist if
+ // SPEAKER_SAFE is present).
+ //
+ // (This is unrelated to a different device grouping as Volume::getDeviceCategory)
+ DeviceVector speakerSafeDevices =
+ curDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER_SAFE);
+ if (!speakerSafeDevices.isEmpty()) {
+ curDevices.merge(
+ mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
+ curDevices.remove(speakerSafeDevices);
+ }
+ }
for (const auto& device : curDevices) {
devices->push_back(device->getDeviceTypeAddr());
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index daa4faf..ac8b625 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -193,9 +193,37 @@
// return the enabled output devices for the given stream type
virtual DeviceTypeSet getDevicesForStream(audio_stream_type_t stream);
+ /**
+ * Returns a vector of devices associated with attributes.
+ *
+ * An AudioTrack opened with specified attributes should play on the returned devices.
+ * If forVolume is set to true, the caller is AudioService, determining the proper
+ * device volume to adjust.
+ *
+ * Devices are determined in the following precedence:
+ * 1) Devices associated with a dynamic policy matching the attributes. This is often
+ * a remote submix from MIX_ROUTE_FLAG_LOOP_BACK. Secondary mixes from a
+ * dynamic policy are not included.
+ *
+ * If no such dynamic policy then
+ * 2) Devices containing an active client using setPreferredDevice
+ * with same strategy as the attributes.
+ * (from the default Engine::getOutputDevicesForAttributes() implementation).
+ *
+ * If no corresponding active client with setPreferredDevice then
+ * 3) Devices associated with the strategy determined by the attributes
+ * (from the default Engine::getOutputDevicesForAttributes() implementation).
+ *
+ * @param attributes to be considered
+ * @param devices an AudioDeviceTypeAddrVector container passed in that
+ * will be filled on success.
+ * @param forVolume true if the devices are to be associated with current device volume.
+ * @return NO_ERROR on success.
+ */
virtual status_t getDevicesForAttributes(
const audio_attributes_t &attributes,
- AudioDeviceTypeAddrVector *devices);
+ AudioDeviceTypeAddrVector *devices,
+ bool forVolume);
virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc = NULL);
virtual status_t registerEffect(const effect_descriptor_t *desc,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 391d60a..82d28ca 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1184,6 +1184,7 @@
}
Status AudioPolicyService::getDevicesForAttributes(const media::AudioAttributesEx& attrAidl,
+ bool forVolume,
std::vector<AudioDevice>* _aidl_return)
{
AudioAttributes aa = VALUE_OR_RETURN_BINDER_STATUS(
@@ -1196,7 +1197,8 @@
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
- mAudioPolicyManager->getDevicesForAttributes(aa.getAttributes(), &devices)));
+ mAudioPolicyManager->getDevicesForAttributes(
+ aa.getAttributes(), &devices, forVolume)));
*_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(
convertContainer<std::vector<AudioDevice>>(devices,
legacy2aidl_AudioDeviceTypeAddress));
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 0a01b7b..f482886 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -138,6 +138,7 @@
AudioStreamType stream,
std::vector<AudioDeviceDescription>* _aidl_return) override;
binder::Status getDevicesForAttributes(const media::AudioAttributesEx& attr,
+ bool forVolume,
std::vector<AudioDevice>* _aidl_return) override;
binder::Status getOutputForEffect(const media::EffectDescriptor& desc,
int32_t* _aidl_return) override;