Use DeviceIdVector for outputs in Audio Policy
Use DeviceIdVector for output in Audio Policy.
Bug: 367816690
Test: atest audiopolicy_tests
Test: adb shell /data/fuzz/arm64/audiopolicy_fuzzer/audiopolicy_fuzzer
Flag: android.media.audio.routed_device_ids
Change-Id: If2144348ff69e75fd4e6c339848d7d161ef5611d
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 54ef5d5..083b81b 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1262,7 +1262,7 @@
uid_t uid,
audio_config_t *config,
audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId,
+ DeviceIdVector *selectedDeviceIds,
bool *isRequestedDeviceForExclusiveUse,
std::vector<sp<AudioPolicyMix>> *secondaryMixes,
output_type_t *outputType,
@@ -1270,7 +1270,8 @@
bool *isBitPerfect)
{
DeviceVector outputDevices;
- const audio_port_handle_t requestedPortId = *selectedDeviceId;
+ audio_port_handle_t requestedPortId = getFirstDeviceId(*selectedDeviceIds);
+ selectedDeviceIds->clear();
DeviceVector msdDevices = getMsdAudioOutDevices();
const sp<DeviceDescriptor> requestedDevice =
mAvailableOutputDevices.getDeviceFromId(requestedPortId);
@@ -1347,8 +1348,9 @@
if (policyDesc != nullptr) {
policyDesc->mPolicyMix = primaryMix;
*output = policyDesc->mIoHandle;
- *selectedDeviceId = policyMixDevice != nullptr ? policyMixDevice->getId()
- : AUDIO_PORT_HANDLE_NONE;
+ if (policyMixDevice != nullptr) {
+ selectedDeviceIds->push_back(policyMixDevice->getId());
+ }
if ((policyDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != AUDIO_OUTPUT_FLAG_DIRECT) {
// Remove direct flag as it is not on a direct output.
*flags = (audio_output_flags_t) (*flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
@@ -1485,11 +1487,13 @@
return INVALID_OPERATION;
}
- *selectedDeviceId = getFirstDeviceId(outputDevices);
for (auto &outputDevice : outputDevices) {
- if (outputDevice->getId() == mConfig->getDefaultOutputDevice()->getId()) {
- *selectedDeviceId = outputDevice->getId();
- break;
+ if (std::find(selectedDeviceIds->begin(), selectedDeviceIds->end(),
+ outputDevice->getId()) == selectedDeviceIds->end()) {
+ selectedDeviceIds->push_back(outputDevice->getId());
+ if (outputDevice->getId() == mConfig->getDefaultOutputDevice()->getId()) {
+ std::swap(selectedDeviceIds->front(), selectedDeviceIds->back());
+ }
}
}
@@ -1499,7 +1503,8 @@
*outputType = API_OUTPUT_LEGACY;
}
- ALOGV("%s returns output %d selectedDeviceId %d", __func__, *output, *selectedDeviceId);
+ ALOGV("%s returns output %d selectedDeviceIds %s", __func__, *output,
+ toString(*selectedDeviceIds).c_str());
return NO_ERROR;
}
@@ -1511,7 +1516,7 @@
const AttributionSourceState& attributionSource,
audio_config_t *config,
audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId,
+ DeviceIdVector *selectedDeviceIds,
audio_port_handle_t *portId,
std::vector<audio_io_handle_t> *secondaryOutputs,
output_type_t *outputType,
@@ -1526,20 +1531,22 @@
}
const uid_t uid = VALUE_OR_RETURN_STATUS(
aidl2legacy_int32_t_uid_t(attributionSource.uid));
- const audio_port_handle_t requestedPortId = *selectedDeviceId;
audio_attributes_t resultAttr;
bool isRequestedDeviceForExclusiveUse = false;
std::vector<sp<AudioPolicyMix>> secondaryMixes;
- const sp<DeviceDescriptor> requestedDevice =
- mAvailableOutputDevices.getDeviceFromId(requestedPortId);
+ DeviceIdVector requestedDeviceIds = *selectedDeviceIds;
// Prevent from storing invalid requested device id in clients
- const audio_port_handle_t sanitizedRequestedPortId =
- requestedDevice != nullptr ? requestedPortId : AUDIO_PORT_HANDLE_NONE;
- *selectedDeviceId = sanitizedRequestedPortId;
+ DeviceIdVector sanitizedRequestedPortIds;
+ for (auto deviceId : *selectedDeviceIds) {
+ if (mAvailableOutputDevices.getDeviceFromId(deviceId) != nullptr) {
+ sanitizedRequestedPortIds.push_back(deviceId);
+ }
+ }
+ *selectedDeviceIds = sanitizedRequestedPortIds;
status_t status = getOutputForAttrInt(&resultAttr, output, session, attr, stream, uid,
- config, flags, selectedDeviceId, &isRequestedDeviceForExclusiveUse,
+ config, flags, selectedDeviceIds, &isRequestedDeviceForExclusiveUse,
secondaryOutputs != nullptr ? &secondaryMixes : nullptr, outputType, isSpatialized,
isBitPerfect);
if (status != NO_ERROR) {
@@ -1564,9 +1571,10 @@
*portId = PolicyAudioPort::getNextUniqueId();
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(*output);
+ // TODO(b/367816690): Add device id sets to TrackClientDescriptor
sp<TrackClientDescriptor> clientDesc =
new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
- sanitizedRequestedPortId, *stream,
+ getFirstDeviceId(sanitizedRequestedPortIds), *stream,
mEngine->getProductStrategyForAttributes(resultAttr),
toVolumeSource(resultAttr),
*flags, isRequestedDeviceForExclusiveUse,
@@ -1577,8 +1585,9 @@
*volume = Volume::DbToAmpl(outputDesc->getCurVolume(toVolumeSource(resultAttr)));
*muted = outputDesc->isMutedByGroup(toVolumeSource(resultAttr));
- ALOGV("%s() returns output %d requestedPortId %d selectedDeviceId %d for port ID %d", __func__,
- *output, requestedPortId, *selectedDeviceId, *portId);
+ ALOGV("%s() returns output %d requestedPortIds %s selectedDeviceIds %s for port ID %d",
+ __func__, *output, toString(requestedDeviceIds).c_str(),
+ toString(*selectedDeviceIds).c_str(), *portId);
return NO_ERROR;
}
@@ -5596,14 +5605,14 @@
: audio_channel_mask_in_to_out(sourceMask);
config.format = sourceDesc->config().format;
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
bool isRequestedDeviceForExclusiveUse = false;
output_type_t outputType;
bool isSpatialized;
bool isBitPerfect;
getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE, &attributes,
&stream, sourceDesc->uid(), &config, &flags,
- &selectedDeviceId, &isRequestedDeviceForExclusiveUse,
+ &selectedDeviceIds, &isRequestedDeviceForExclusiveUse,
nullptr, &outputType, &isSpatialized, &isBitPerfect);
if (output == AUDIO_IO_HANDLE_NONE) {
ALOGV("%s no output for device %s",
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 1ca0c32..e0cafd4 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -123,7 +123,7 @@
const AttributionSourceState& attributionSource,
audio_config_t *config,
audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId,
+ DeviceIdVector *selectedDeviceIds,
audio_port_handle_t *portId,
std::vector<audio_io_handle_t> *secondaryOutputs,
output_type_t *outputType,
@@ -893,15 +893,7 @@
return mAvailableInputDevices.getDevicesFromHwModule(
mPrimaryOutput->getModuleHandle());
}
- /**
- * @brief getFirstDeviceId of the Device Vector
- * @return if the collection is not empty, it returns the first device Id,
- * otherwise AUDIO_PORT_HANDLE_NONE
- */
- audio_port_handle_t getFirstDeviceId(const DeviceVector &devices) const
- {
- return (devices.size() > 0) ? devices.itemAt(0)->getId() : AUDIO_PORT_HANDLE_NONE;
- }
+
String8 getFirstDeviceAddress(const DeviceVector &devices) const
{
return (devices.size() > 0) ?
@@ -1142,7 +1134,7 @@
uid_t uid,
audio_config_t *config,
audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId,
+ DeviceIdVector *selectedDeviceIds,
bool *isRequestedDeviceForExclusiveUse,
std::vector<sp<AudioPolicyMix>> *secondaryMixes,
output_type_t *outputType,