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/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 483a1ef..f68b506 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1224,7 +1224,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,
bool *isSpatialized,
@@ -1239,8 +1239,8 @@
ALOGE("%s NULL output - shouldn't happen", __func__);
return BAD_VALUE;
}
- if (selectedDeviceId == nullptr) {
- ALOGE("%s NULL selectedDeviceId - shouldn't happen", __func__);
+ if (selectedDeviceIds == nullptr) {
+ ALOGE("%s NULL selectedDeviceIds - shouldn't happen", __func__);
return BAD_VALUE;
}
if (portId == nullptr) {
@@ -1262,20 +1262,20 @@
legacy2aidl_audio_config_t_AudioConfig(*config, false /*isInput*/));
int32_t flagsAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
- int32_t selectedDeviceIdAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_port_handle_t_int32_t(*selectedDeviceId));
+ auto selectedDeviceIdsAidl = VALUE_OR_RETURN_STATUS(convertContainer<std::vector<int32_t>>(
+ *selectedDeviceIds, legacy2aidl_audio_port_handle_t_int32_t));
media::GetOutputForAttrResponse responseAidl;
status_t status = statusTFromBinderStatus(
aps->getOutputForAttr(attrAidl, sessionAidl, attributionSource, configAidl, flagsAidl,
- selectedDeviceIdAidl, &responseAidl));
+ selectedDeviceIdsAidl, &responseAidl));
if (status != NO_ERROR) {
config->format = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioFormatDescription_audio_format_t(responseAidl.configBase.format));
+ aidl2legacy_AudioFormatDescription_audio_format_t(responseAidl.configBase.format));
config->channel_mask = VALUE_OR_RETURN_STATUS(
- aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
- responseAidl.configBase.channelMask, false /*isInput*/));
+ aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+ responseAidl.configBase.channelMask, false /*isInput*/));
config->sample_rate = responseAidl.configBase.sampleRate;
return status;
}
@@ -1287,8 +1287,8 @@
*stream = VALUE_OR_RETURN_STATUS(
aidl2legacy_AudioStreamType_audio_stream_type_t(responseAidl.stream));
}
- *selectedDeviceId = VALUE_OR_RETURN_STATUS(
- aidl2legacy_int32_t_audio_port_handle_t(responseAidl.selectedDeviceId));
+ *selectedDeviceIds = VALUE_OR_RETURN_STATUS(convertContainer<DeviceIdVector>(
+ responseAidl.selectedDeviceIds, aidl2legacy_int32_t_audio_port_handle_t));
*portId = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_port_handle_t(responseAidl.portId));
*secondaryOutputs = VALUE_OR_RETURN_STATUS(convertContainer<std::vector<audio_io_handle_t>>(
responseAidl.secondaryOutputs, aidl2legacy_int32_t_audio_io_handle_t));
diff --git a/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl b/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
index d3975c0..5d066bb 100644
--- a/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/GetOutputForAttrResponse.aidl
@@ -26,8 +26,8 @@
/** Interpreted as audio_io_handle_t. */
int output;
AudioStreamType stream;
- /** Interpreted as audio_port_handle_t. */
- int selectedDeviceId;
+ /** Interpreted as audio_port_handle_t[]. */
+ int[] selectedDeviceIds;
/** Interpreted as audio_port_handle_t. */
int portId;
/** Interpreted as audio_io_handle_t[]. */
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 956acce..7f4a7dd 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -94,7 +94,7 @@
in AttributionSourceState attributionSource,
in AudioConfig config,
int /* Bitmask, indexed by AudioOutputFlags */ flags,
- int /* audio_port_handle_t */ selectedDeviceId);
+ in int[] /* audio_port_handle_t */ selectedDeviceIds);
void startOutput(int /* audio_port_handle_t */ portId);
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 5565281..fbc7629 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -342,7 +342,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,
bool *isSpatialized,
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
index 6727562..d0f77e8 100644
--- a/media/libaudiofoundation/AudioContainers.cpp
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -130,7 +130,7 @@
return ss.str();
}
-std::string toString(const DeviceIdSet& deviceIds) {
+std::string toString(const DeviceIdVector& deviceIds) {
if (deviceIds.empty()) {
return "Empty device ids";
}
@@ -144,11 +144,11 @@
return ss.str();
}
-audio_port_handle_t getFirstDeviceId(const DeviceIdSet& deviceIds) {
+audio_port_handle_t getFirstDeviceId(const DeviceIdVector& deviceIds) {
if (deviceIds.empty()) {
return AUDIO_PORT_HANDLE_NONE;
}
- return *(deviceIds.begin());
+ return deviceIds[0];
}
AudioProfileAttributesMultimap createAudioProfilesAttrMap(audio_profile profiles[],
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 3673871..8d4665e 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -33,8 +33,8 @@
using FormatSet = std::set<audio_format_t>;
using SampleRateSet = std::set<uint32_t>;
using MixerBehaviorSet = std::set<audio_mixer_behavior_t>;
-using DeviceIdSet = std::set<audio_port_handle_t>;
+using DeviceIdVector = std::vector<audio_port_handle_t>;
using FormatVector = std::vector<audio_format_t>;
using AudioProfileAttributesMultimap =
std::multimap<audio_format_t, std::pair<SampleRateSet, ChannelMaskSet>>;
@@ -142,12 +142,12 @@
/**
* Returns human readable string for a set of device ids.
*/
-std::string toString(const DeviceIdSet& deviceIds);
+std::string toString(const DeviceIdVector& deviceIds);
/**
* Returns the first device id of a set of device ids or AUDIO_PORT_HANDLE_NONE when its empty.
*/
-audio_port_handle_t getFirstDeviceId(const DeviceIdSet& deviceIds);
+audio_port_handle_t getFirstDeviceId(const DeviceIdVector& deviceIds);
/**
* Create audio profile attributes map by given audio profile array from the range of [first, last).
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a1a0634..5fb326f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -630,16 +630,22 @@
bool isBitPerfect;
float volume;
bool muted;
+ DeviceIdVector selectedDeviceIds;
+ if (*deviceId != AUDIO_PORT_HANDLE_NONE) {
+ selectedDeviceIds.push_back(*deviceId);
+ }
ret = AudioSystem::getOutputForAttr(&localAttr, &io,
actualSessionId,
&streamType, adjAttributionSource,
&fullConfig,
(audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
AUDIO_OUTPUT_FLAG_DIRECT),
- deviceId, &portId, &secondaryOutputs, &isSpatialized,
+ &selectedDeviceIds, &portId, &secondaryOutputs,
+ &isSpatialized,
&isBitPerfect,
&volume,
&muted);
+ *deviceId = getFirstDeviceId(selectedDeviceIds);
if (ret != NO_ERROR) {
config->sample_rate = fullConfig.sample_rate;
config->channel_mask = fullConfig.channel_mask;
@@ -1166,6 +1172,7 @@
adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
}
+ DeviceIdVector selectedDeviceIds;
audio_session_t sessionId = input.sessionId;
if (sessionId == AUDIO_SESSION_ALLOCATE) {
sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
@@ -1176,11 +1183,14 @@
output.sessionId = sessionId;
output.outputId = AUDIO_IO_HANDLE_NONE;
- output.selectedDeviceId = input.selectedDeviceId;
+ if (input.selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
+ selectedDeviceIds.push_back(input.selectedDeviceId);
+ }
lStatus = AudioSystem::getOutputForAttr(&localAttr, &output.outputId, sessionId, &streamType,
adjAttributionSource, &input.config, input.flags,
- &output.selectedDeviceId, &portId, &secondaryOutputs,
+ &selectedDeviceIds, &portId, &secondaryOutputs,
&isSpatialized, &isBitPerfect, &volume, &muted);
+ output.selectedDeviceId = getFirstDeviceId(selectedDeviceIds);
if (lStatus != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) {
ALOGE("createTrack() getOutputForAttr() return error %d or invalid output handle", lStatus);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 060c72b..db01cff 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -10492,7 +10492,12 @@
audio_stream_type_t stream = streamType_l();
audio_output_flags_t flags =
(audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
- audio_port_handle_t deviceId = mDeviceId;
+ DeviceIdVector deviceIds;
+ if (mDeviceId != AUDIO_PORT_HANDLE_NONE) {
+ deviceIds.push_back(mDeviceId);
+ } else {
+ ALOGW("%s no device id set", __func__);
+ }
std::vector<audio_io_handle_t> secondaryOutputs;
bool isSpatialized;
bool isBitPerfect;
@@ -10503,7 +10508,7 @@
adjAttributionSource,
&config,
flags,
- &deviceId,
+ &deviceIds,
&portId,
&secondaryOutputs,
&isSpatialized,
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index c047a89..8dd247a 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -144,7 +144,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,
diff --git a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
index a5f37b0..1c6248a 100644
--- a/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
+++ b/services/audiopolicy/fuzzer/audiopolicy_fuzzer.cpp
@@ -198,7 +198,7 @@
virtual ~AudioPolicyManagerFuzzer() = default;
virtual bool initialize();
virtual void SetUpManagerConfig();
- bool getOutputForAttr(audio_port_handle_t *selectedDeviceId, audio_format_t format,
+ bool getOutputForAttr(DeviceIdVector *selectedDeviceIds, audio_format_t format,
audio_channel_mask_t channelMask, int sampleRate,
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
audio_io_handle_t *output = nullptr,
@@ -248,7 +248,7 @@
void AudioPolicyManagerFuzzer::SetUpManagerConfig() { mConfig->setDefault(); }
bool AudioPolicyManagerFuzzer::getOutputForAttr(
- audio_port_handle_t *selectedDeviceId, audio_format_t format, audio_channel_mask_t channelMask,
+ DeviceIdVector *selectedDeviceIds, audio_format_t format, audio_channel_mask_t channelMask,
int sampleRate, audio_output_flags_t flags, audio_io_handle_t *output,
audio_port_handle_t *portId, audio_attributes_t attr) {
audio_io_handle_t localOutput;
@@ -273,7 +273,7 @@
attributionSource.uid = 0;
attributionSource.token = sp<BBinder>::make();
if (mManager->getOutputForAttr(&attr, output, AUDIO_SESSION_NONE, &stream, attributionSource,
- &config, &flags, selectedDeviceId, portId, {}, &outputType, &isSpatialized,
+ &config, &flags, selectedDeviceIds, portId, {}, &outputType, &isSpatialized,
&isBitPerfect, &volume, &muted) != OK) {
return false;
}
@@ -726,8 +726,8 @@
std::string tags(mFdp->ConsumeBool() ? "" : "addr=remote_submix_media");
strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
- audio_port_handle_t playbackRoutedPortId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&playbackRoutedPortId, mAudioConfig.format, mAudioConfig.channel_mask,
+ DeviceIdVector playbackRoutedPortIds;
+ getOutputForAttr(&playbackRoutedPortIds, mAudioConfig.format, mAudioConfig.channel_mask,
mAudioConfig.sample_rate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/,
nullptr /*portId*/, attr);
}
@@ -807,13 +807,13 @@
findDevicePort(AUDIO_PORT_ROLE_SINK, getValueFromVector<audio_devices_t>(mFdp, kAudioDevices),
mMixAddress, &injectionPort);
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_usage_t usage = getValueFromVector<audio_usage_t>(mFdp, kAudioUsages);
audio_attributes_t attr = {AUDIO_CONTENT_TYPE_UNKNOWN, usage, AUDIO_SOURCE_DEFAULT,
AUDIO_FLAG_NONE, ""};
std::string tags = std::string("addr=") + mMixAddress;
strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
- getOutputForAttr(&selectedDeviceId, mAudioConfig.format, mAudioConfig.channel_mask,
+ getOutputForAttr(&selectedDeviceIds, mAudioConfig.format, mAudioConfig.channel_mask,
mAudioConfig.sample_rate /*sampleRate*/, AUDIO_OUTPUT_FLAG_NONE,
nullptr /*output*/, &mPortId, attr);
ret = mManager->startOutput(mPortId);
@@ -903,15 +903,17 @@
audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
findDevicePort(role, type, address, &devicePort);
- audio_port_handle_t routedPortId = devicePort.id;
// Try start input or output according to the device type
if (audio_is_output_devices(type)) {
- getOutputForAttr(&routedPortId, getValueFromVector<audio_format_t>(mFdp, kAudioFormats),
+ DeviceIdVector routedPortIds = { devicePort.id };
+ getOutputForAttr(&routedPortIds,
+ getValueFromVector<audio_format_t>(mFdp, kAudioFormats),
getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelOutMasks),
getValueFromVector<uint32_t>(mFdp, kSamplingRates),
AUDIO_OUTPUT_FLAG_NONE);
} else if (audio_is_input_device(type)) {
RecordingActivityTracker tracker;
+ audio_port_handle_t routedPortId = devicePort.id;
getInputForAttr({}, tracker.getRiid(), &routedPortId,
getValueFromVector<audio_format_t>(mFdp, kAudioFormats),
getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelInMasks),
@@ -984,10 +986,10 @@
if (ret != NO_ERROR) {
return;
}
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_io_handle_t output;
audio_port_handle_t portId;
- getOutputForAttr(&selectedDeviceId, getValueFromVector<audio_format_t>(mFdp, kAudioFormats),
+ getOutputForAttr(&selectedDeviceIds, getValueFromVector<audio_format_t>(mFdp, kAudioFormats),
getValueFromVector<audio_channel_mask_t>(mFdp, kAudioChannelOutMasks),
getValueFromVector<uint32_t>(mFdp, kSamplingRates), flags, &output, &portId);
sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
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,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 1ffa176..babc80e 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -369,7 +369,7 @@
const AttributionSourceState& attributionSource,
const AudioConfig& configAidl,
int32_t flagsAidl,
- int32_t selectedDeviceIdAidl,
+ const std::vector<int32_t>& selectedDeviceIdsAidl,
media::GetOutputForAttrResponse* _aidl_return)
{
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
@@ -381,8 +381,9 @@
aidl2legacy_AudioConfig_audio_config_t(configAidl, false /*isInput*/));
audio_output_flags_t flags = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_output_flags_t_mask(flagsAidl));
- audio_port_handle_t selectedDeviceId = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_int32_t_audio_port_handle_t(selectedDeviceIdAidl));
+ DeviceIdVector selectedDeviceIds = VALUE_OR_RETURN_BINDER_STATUS(
+ convertContainer<DeviceIdVector>(selectedDeviceIdsAidl,
+ aidl2legacy_int32_t_audio_port_handle_t));
audio_io_handle_t output;
audio_port_handle_t portId;
@@ -435,7 +436,7 @@
&stream,
attributionSource,
&config,
- &flags, &selectedDeviceId, &portId,
+ &flags, &selectedDeviceIds, &portId,
&secondaryOutputs,
&outputType,
&isSpatialized,
@@ -487,15 +488,16 @@
sp<AudioPlaybackClient> client =
new AudioPlaybackClient(attr, output, attributionSource, session,
- portId, selectedDeviceId, stream, isSpatialized, config.channel_mask);
+ portId, selectedDeviceIds, stream, isSpatialized, config.channel_mask);
mAudioPlaybackClients.add(portId, client);
_aidl_return->output = VALUE_OR_RETURN_BINDER_STATUS(
legacy2aidl_audio_io_handle_t_int32_t(output));
_aidl_return->stream = VALUE_OR_RETURN_BINDER_STATUS(
legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
- _aidl_return->selectedDeviceId = VALUE_OR_RETURN_BINDER_STATUS(
- legacy2aidl_audio_port_handle_t_int32_t(selectedDeviceId));
+ _aidl_return->selectedDeviceIds = VALUE_OR_RETURN_BINDER_STATUS(
+ convertContainer<std::vector<int32_t>>(selectedDeviceIds,
+ legacy2aidl_audio_port_handle_t_int32_t));
_aidl_return->portId = VALUE_OR_RETURN_BINDER_STATUS(
legacy2aidl_audio_port_handle_t_int32_t(portId));
_aidl_return->secondaryOutputs = VALUE_OR_RETURN_BINDER_STATUS(
@@ -853,8 +855,9 @@
return binderStatusFromStatusT(status);
}
+ DeviceIdVector selectedDeviceIds = { selectedDeviceId };
sp<AudioRecordClient> client = new AudioRecordClient(attr, input, session, portId,
- selectedDeviceId, attributionSource,
+ selectedDeviceIds, attributionSource,
virtualDeviceId,
canCaptureOutput, canCaptureHotword,
mOutputCommandThread);
@@ -888,6 +891,17 @@
return {};
}
+std::string AudioPolicyService::getDeviceTypeStrForPortIds(DeviceIdVector portIds) {
+ std::string output = {};
+ for (auto it = portIds.begin(); it != portIds.end(); ++it) {
+ if (it != portIds.begin()) {
+ output += ", ";
+ }
+ output += getDeviceTypeStrForPortId(*it);
+ }
+ return output;
+}
+
Status AudioPolicyService::startInput(int32_t portIdAidl)
{
audio_port_handle_t portId = VALUE_OR_RETURN_BINDER_STATUS(
@@ -978,6 +992,8 @@
"android.media.audiopolicy.active.session";
static constexpr char kAudioPolicyActiveDevice[] =
"android.media.audiopolicy.active.device";
+ static constexpr char kAudioPolicyActiveDevices[] =
+ "android.media.audiopolicy.active.devices";
mediametrics::Item *item = mediametrics::Item::create(kAudioPolicy);
if (item != NULL) {
@@ -995,8 +1011,8 @@
item->setCString(kAudioPolicyRqstPkg,
std::to_string(client->attributionSource.uid).c_str());
}
- item->setCString(
- kAudioPolicyRqstDevice, getDeviceTypeStrForPortId(client->deviceId).c_str());
+ item->setCString(kAudioPolicyRqstDevice,
+ getDeviceTypeStrForPortId(getFirstDeviceId(client->deviceIds)).c_str());
int count = mAudioRecordClients.size();
for (int i = 0; i < count ; i++) {
@@ -1018,7 +1034,9 @@
other->attributionSource.uid).c_str());
}
item->setCString(kAudioPolicyActiveDevice,
- getDeviceTypeStrForPortId(other->deviceId).c_str());
+ getDeviceTypeStrForPortId(getFirstDeviceId(other->deviceIds)).c_str());
+ item->setCString(kAudioPolicyActiveDevices,
+ getDeviceTypeStrForPortIds(other->deviceIds).c_str());
}
}
item->selfrecord();
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 44a0e7d..eeac9a6 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -117,7 +117,7 @@
int32_t session,
const AttributionSourceState &attributionSource,
const AudioConfig& config,
- int32_t flags, int32_t selectedDeviceId,
+ int32_t flags, const std::vector<int32_t>& selectedDeviceIds,
media::GetOutputForAttrResponse* _aidl_return) override;
binder::Status startOutput(int32_t portId) override;
binder::Status stopOutput(int32_t portId) override;
@@ -474,6 +474,8 @@
std::string getDeviceTypeStrForPortId(audio_port_handle_t portId);
+ std::string getDeviceTypeStrForPortIds(DeviceIdVector portIds);
+
status_t getAudioPolicyEffects(sp<AudioPolicyEffects>& audioPolicyEffects);
app_state_t apmStatFromAmState(int amState);
@@ -1015,10 +1017,10 @@
const audio_io_handle_t io,
const AttributionSourceState& attributionSource,
const audio_session_t session, audio_port_handle_t portId,
- const audio_port_handle_t deviceId) :
+ const DeviceIdVector deviceIds) :
attributes(attributes), io(io), attributionSource(
attributionSource), session(session), portId(portId),
- deviceId(deviceId), active(false) {}
+ deviceIds(deviceIds), active(false) {}
~AudioClient() override = default;
@@ -1027,7 +1029,7 @@
const AttributionSourceState attributionSource; //client attributionsource
const audio_session_t session; // audio session ID
const audio_port_handle_t portId;
- const audio_port_handle_t deviceId; // selected input device port ID
+ const DeviceIdVector deviceIds; // selected input device port IDs
bool active; // Playback/Capture is active or inactive
};
private:
@@ -1042,10 +1044,10 @@
AudioPlaybackClient(const audio_attributes_t attributes,
const audio_io_handle_t io, AttributionSourceState attributionSource,
const audio_session_t session, audio_port_handle_t portId,
- audio_port_handle_t deviceId, audio_stream_type_t stream,
+ DeviceIdVector deviceIds, audio_stream_type_t stream,
bool isSpatialized, audio_channel_mask_t channelMask) :
AudioClient(attributes, io, attributionSource, session, portId,
- deviceId), stream(stream), isSpatialized(isSpatialized),
+ deviceIds), stream(stream), isSpatialized(isSpatialized),
channelMask(channelMask) {}
~AudioPlaybackClient() override = default;
diff --git a/services/audiopolicy/service/AudioRecordClient.h b/services/audiopolicy/service/AudioRecordClient.h
index 76aff41..8167950 100644
--- a/services/audiopolicy/service/AudioRecordClient.h
+++ b/services/audiopolicy/service/AudioRecordClient.h
@@ -85,13 +85,13 @@
AudioRecordClient(const audio_attributes_t attributes,
const audio_io_handle_t io,
const audio_session_t session, audio_port_handle_t portId,
- const audio_port_handle_t deviceId,
+ const DeviceIdVector deviceIds,
const AttributionSourceState& attributionSource,
const uint32_t virtualDeviceId,
bool canCaptureOutput, bool canCaptureHotword,
wp<AudioPolicyService::AudioCommandThread> commandThread) :
AudioClient(attributes, io, attributionSource,
- session, portId, deviceId), attributionSource(attributionSource),
+ session, portId, deviceIds), attributionSource(attributionSource),
virtualDeviceId(virtualDeviceId),
startTimeNs(0), canCaptureOutput(canCaptureOutput),
canCaptureHotword(canCaptureHotword), silenced(false),
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index e901cfd..c37540c 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -191,7 +191,7 @@
// When explicit routing is needed, selectedDeviceId needs to be set as the wanted port
// id. Otherwise, selectedDeviceId needs to be initialized as AUDIO_PORT_HANDLE_NONE.
void getOutputForAttr(
- audio_port_handle_t *selectedDeviceId,
+ DeviceIdVector *selectedDeviceIds,
audio_format_t format,
audio_channel_mask_t channelMask,
int sampleRate,
@@ -284,7 +284,7 @@
}
void AudioPolicyManagerTest::getOutputForAttr(
- audio_port_handle_t *selectedDeviceId,
+ DeviceIdVector *selectedDeviceIds,
audio_format_t format,
audio_channel_mask_t channelMask,
int sampleRate,
@@ -314,7 +314,7 @@
AttributionSourceState attributionSource = createAttributionSourceState(uid);
ASSERT_EQ(OK, mManager->getOutputForAttr(
&attr, output, session, &stream, attributionSource, &config, &flags,
- selectedDeviceId, portId, {}, &outputType, &isSpatialized,
+ selectedDeviceIds, portId, {}, &outputType, &isSpatialized,
isBitPerfect == nullptr ? &isBitPerfectInternal : isBitPerfect, &volume,
&muted));
ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
@@ -648,42 +648,42 @@
TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedRoutesToMsd) {
const PatchCountCheck patchCount = snapshotPatchCount();
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
+ DeviceIdVector selectedDeviceIds;
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
- ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
+ ASSERT_EQ(mDefaultOutputDevice->getId(), selectedDeviceIds[0]);
ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
}
TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrPcmRoutesToMsd) {
const PatchCountCheck patchCount = snapshotPatchCount();
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&selectedDeviceId,
+ DeviceIdVector selectedDeviceIds;
+ getOutputForAttr(&selectedDeviceIds,
AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
- ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
+ ASSERT_EQ(mDefaultOutputDevice->getId(), selectedDeviceIds[0]);
ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
}
TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrEncodedPlusPcmRoutesToMsd) {
const PatchCountCheck patchCount = snapshotPatchCount();
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
+ DeviceIdVector selectedDeviceIds;
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
- ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
+ ASSERT_EQ(mDefaultOutputDevice->getId(), selectedDeviceIds[0]);
ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
- selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&selectedDeviceId,
+ selectedDeviceIds.clear();
+ getOutputForAttr(&selectedDeviceIds,
AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate);
- ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
+ ASSERT_EQ(mDefaultOutputDevice->getId(), selectedDeviceIds[0]);
ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
}
TEST_P(AudioPolicyManagerTestMsd, GetOutputForAttrUnsupportedFormatBypassesMsd) {
const PatchCountCheck patchCount = snapshotPatchCount();
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
+ DeviceIdVector selectedDeviceIds;
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
- ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
+ ASSERT_NE(mMsdOutputDevice->getId(), selectedDeviceIds[0]);
ASSERT_EQ(1, patchCount.deltaFromSnapshot());
}
@@ -691,32 +691,33 @@
// Switch between formats that are supported and not supported by MSD.
{
const PatchCountCheck patchCount = snapshotPatchCount();
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_port_handle_t portId;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, nullptr /*output*/, &portId);
- ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
+ ASSERT_EQ(mDefaultOutputDevice->getId(), selectedDeviceIds[0]);
ASSERT_EQ(mExpectedAudioPatchCount, patchCount.deltaFromSnapshot());
mManager->releaseOutput(portId);
ASSERT_EQ(mExpectedAudioPatchCount - 1, patchCount.deltaFromSnapshot());
}
{
const PatchCountCheck patchCount = snapshotPatchCount();
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_port_handle_t portId;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, nullptr /*output*/, &portId);
- ASSERT_NE(selectedDeviceId, mMsdOutputDevice->getId());
+ ASSERT_GT(selectedDeviceIds.size(), 0);
+ ASSERT_NE(mMsdOutputDevice->getId(), selectedDeviceIds[0]);
ASSERT_EQ(-static_cast<int>(mExpectedAudioPatchCount) + 2, patchCount.deltaFromSnapshot());
mManager->releaseOutput(portId);
ASSERT_EQ(0, patchCount.deltaFromSnapshot());
}
{
const PatchCountCheck patchCount = snapshotPatchCount();
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
+ DeviceIdVector selectedDeviceIds;
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_AC3, AUDIO_CHANNEL_OUT_5POINT1,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT);
- ASSERT_EQ(selectedDeviceId, mDefaultOutputDevice->getId());
+ ASSERT_EQ(mDefaultOutputDevice->getId(), selectedDeviceIds[0]);
ASSERT_EQ(1, patchCount.deltaFromSnapshot());
}
}
@@ -1138,14 +1139,14 @@
&mediaAttr, usbPortId, uid, &mixerAttributes[0]));
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, mediaAttr,
AUDIO_SESSION_NONE, uid);
status_t status = mManager->startOutput(portId);
if (status == DEAD_OBJECT) {
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, mediaAttr,
AUDIO_SESSION_NONE, uid);
status = mManager->startOutput(portId);
@@ -1172,6 +1173,56 @@
"", "", AUDIO_FORMAT_LDAC));
}
+template <typename T>
+bool hasDuplicates(const T& container) {
+ return std::unordered_set<typename T::value_type>(container.begin(),
+ container.end()).size() != container.size();
+}
+
+TEST_F(AudioPolicyManagerTestWithConfigurationFile, UniqueSelectedDeviceIds) {
+ mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
+ mClient->addSupportedChannelMask(AUDIO_CHANNEL_OUT_STEREO);
+ ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ "", "", AUDIO_FORMAT_DEFAULT));
+ auto devices = mManager->getAvailableOutputDevices();
+ audio_port_handle_t usbPortId = AUDIO_PORT_HANDLE_NONE;
+ audio_port_handle_t speakerPortId = AUDIO_PORT_HANDLE_NONE;
+ for (auto device : devices) {
+ if (device->type() == AUDIO_DEVICE_OUT_USB_DEVICE) {
+ usbPortId = device->getId();
+ }
+ if (device->type() == AUDIO_DEVICE_OUT_SPEAKER) {
+ speakerPortId = device->getId();
+ }
+ }
+ EXPECT_NE(AUDIO_PORT_HANDLE_NONE, usbPortId);
+ EXPECT_NE(AUDIO_PORT_HANDLE_NONE, speakerPortId);
+
+ const uid_t uid = 1234;
+ const audio_attributes_t mediaAttr = {
+ .content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
+ .usage = AUDIO_USAGE_ALARM,
+ };
+
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_OUT_STEREO, k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, &output,
+ &portId, mediaAttr, AUDIO_SESSION_NONE, uid));
+ EXPECT_FALSE(selectedDeviceIds.empty());
+ EXPECT_NE(std::find(selectedDeviceIds.begin(), selectedDeviceIds.end(), usbPortId),
+ selectedDeviceIds.end());
+ EXPECT_NE(std::find(selectedDeviceIds.begin(), selectedDeviceIds.end(), speakerPortId),
+ selectedDeviceIds.end());
+ EXPECT_FALSE(hasDuplicates(selectedDeviceIds));
+
+ ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(AUDIO_DEVICE_OUT_USB_DEVICE,
+ AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ "", "", AUDIO_FORMAT_DEFAULT));
+}
+
TEST_F(AudioPolicyManagerTestWithConfigurationFile, PreferExactConfigForInput) {
const audio_channel_mask_t deviceChannelMask = AUDIO_CHANNEL_IN_3POINT1;
mClient->addSupportedFormat(AUDIO_FORMAT_PCM_16_BIT);
@@ -1953,14 +2004,15 @@
const DPTestParam param = GetParam();
const audio_attributes_t& attr = param.attributes;
- audio_port_handle_t playbackRoutedPortId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&playbackRoutedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ DeviceIdVector playbackRoutedPortIds;
+ getOutputForAttr(&playbackRoutedPortIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, nullptr /*portId*/,
attr, param.session);
if (param.expected_match) {
- EXPECT_EQ(mInjectionPort.id, playbackRoutedPortId);
+ ASSERT_EQ(mInjectionPort.id, playbackRoutedPortIds[0]);
} else {
- EXPECT_NE(mInjectionPort.id, playbackRoutedPortId);
+ ASSERT_GT(playbackRoutedPortIds.size(), 0);
+ ASSERT_NE(mInjectionPort.id, playbackRoutedPortIds[0]);
}
}
@@ -2129,7 +2181,7 @@
audio_config_t audioConfig;
audio_io_handle_t mOutput;
audio_stream_type_t mStream = AUDIO_STREAM_DEFAULT;
- audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector mSelectedDeviceIds;
audio_port_handle_t mPortId = AUDIO_PORT_HANDLE_NONE;
AudioPolicyInterface::output_type_t mOutputType;
audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
@@ -2154,7 +2206,7 @@
ASSERT_EQ(INVALID_OPERATION,
mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
createAttributionSourceState(testUid), &audioConfig,
- &outputFlags, &mSelectedDeviceId, &mPortId, {},
+ &outputFlags, &mSelectedDeviceIds, &mPortId, {},
&mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
&mMuted));
}
@@ -2174,7 +2226,7 @@
ASSERT_EQ(NO_ERROR,
mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
createAttributionSourceState(testUid), &audioConfig,
- &outputFlags, &mSelectedDeviceId, &mPortId, {},
+ &outputFlags, &mSelectedDeviceIds, &mPortId, {},
&mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
&mMuted));
}
@@ -2206,10 +2258,9 @@
ASSERT_EQ(NO_ERROR,
mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
createAttributionSourceState(testUid), &audioConfig,
- &outputFlags, &mSelectedDeviceId, &mPortId, {},
+ &outputFlags, &mSelectedDeviceIds, &mPortId, {},
&mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
&mMuted));
- ASSERT_EQ(usbDevicePort.id, mSelectedDeviceId);
auto outputDesc = mManager->getOutputs().valueFor(mOutput);
ASSERT_NE(nullptr, outputDesc);
ASSERT_EQ(mmapDirectFlags, outputDesc->getFlags().output);
@@ -2223,10 +2274,10 @@
ASSERT_EQ(NO_ERROR,
mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
createAttributionSourceState(testUid), &audioConfig,
- &outputFlags, &mSelectedDeviceId, &mPortId, {},
+ &outputFlags, &mSelectedDeviceIds, &mPortId, {},
&mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
&mMuted));
- ASSERT_EQ(usbDevicePort.id, mSelectedDeviceId);
+ ASSERT_EQ(usbDevicePort.id, mSelectedDeviceIds[0]);
outputDesc = mManager->getOutputs().valueFor(mOutput);
ASSERT_NE(nullptr, outputDesc);
ASSERT_NE(mmapDirectFlags, outputDesc->getFlags().output);
@@ -2253,7 +2304,7 @@
ASSERT_EQ(INVALID_OPERATION,
mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
createAttributionSourceState(testUid), &audioConfig,
- &outputFlags, &mSelectedDeviceId, &mPortId, {},
+ &outputFlags, &mSelectedDeviceIds, &mPortId, {},
&mOutputType, &mIsSpatialized, &mIsBitPerfect, &mVolume,
&mMuted));
}
@@ -2298,13 +2349,13 @@
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
mMixAddress, &injectionPort));
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_usage_t usage = AUDIO_USAGE_VIRTUAL_SOURCE;
audio_attributes_t attr =
{AUDIO_CONTENT_TYPE_UNKNOWN, usage, AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
std::string tags = std::string("addr=") + mMixAddress;
strncpy(attr.tags, tags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1);
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE, nullptr /*output*/, &mPortId, attr);
ASSERT_EQ(NO_ERROR, mManager->startOutput(mPortId));
ASSERT_EQ(injectionPort.id, getDeviceIdFromPatch(mClient->getLastAddedPatch()));
@@ -2502,19 +2553,21 @@
? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
ASSERT_TRUE(findDevicePort(role, type, address, &devicePort));
- audio_port_handle_t routedPortId = devicePort.id;
// Try start input or output according to the device type
if (audio_is_output_devices(type)) {
- getOutputForAttr(&routedPortId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ DeviceIdVector routedPortIds = { devicePort.id };
+ getOutputForAttr(&routedPortIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_NONE);
+ ASSERT_EQ(devicePort.id, routedPortIds[0]);
} else if (audio_is_input_device(type)) {
+ audio_port_handle_t routedPortId = devicePort.id;
RecordingActivityTracker tracker;
audio_io_handle_t input = AUDIO_PORT_HANDLE_NONE;
getInputForAttr({}, &input, AUDIO_SESSION_NONE, tracker.getRiid(), &routedPortId,
AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO, k48000SamplingRate,
AUDIO_INPUT_FLAG_NONE);
+ ASSERT_EQ(devicePort.id, routedPortId);
}
- ASSERT_EQ(devicePort.id, routedPortId);
ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
type, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
@@ -2775,24 +2828,24 @@
AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig);
ASSERT_EQ(NO_ERROR, ret);
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_io_handle_t output;
audio_port_handle_t portId;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_E_AC3_JOC, AUDIO_CHANNEL_OUT_5POINT1,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_E_AC3_JOC, AUDIO_CHANNEL_OUT_5POINT1,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId);
- ASSERT_NE(AUDIO_PORT_HANDLE_NONE, selectedDeviceId);
+ ASSERT_GT(selectedDeviceIds.size(), 0);
sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
ASSERT_NE(nullptr, outDesc.get());
ASSERT_EQ(AUDIO_FORMAT_E_AC3_JOC, outDesc->getFormat());
ASSERT_EQ(AUDIO_CHANNEL_OUT_5POINT1, outDesc->getChannelMask());
ASSERT_EQ(k48000SamplingRate, outDesc->getSamplingRate());
- selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ selectedDeviceIds.clear();
output = AUDIO_IO_HANDLE_NONE;
portId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_7POINT1POINT4,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_7POINT1POINT4,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId);
- ASSERT_NE(AUDIO_PORT_HANDLE_NONE, selectedDeviceId);
+ ASSERT_GT(selectedDeviceIds.size(), 0);
outDesc = mManager->getOutputs().valueFor(output);
ASSERT_NE(nullptr, outDesc.get());
ASSERT_EQ(AUDIO_FORMAT_PCM_16_BIT, outDesc->getFormat());
@@ -2812,25 +2865,25 @@
AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
std::vector<AudioMixMatchCriterion> navMatchCriteria = {
- createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
/*exclude=*/ false)};
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
+ AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
audio_port_v7 mediaDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusMediaOutput, &mediaDevicePort));
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t mediaAttribute = {
AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
- ASSERT_EQ(mediaDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(mediaDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputAfterRegisteringPolicyMix) {
@@ -2845,25 +2898,25 @@
AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
std::vector<AudioMixMatchCriterion> navMatchCriteria = {
- createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
/*exclude=*/ false)};
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
+ AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusNavigationOutput, &navDevicePort));
- audio_port_handle_t selectedDeviceId = navDevicePort.id;
+ DeviceIdVector selectedDeviceIds = { navDevicePort.id };
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t mediaAttribute = {
AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
- ASSERT_EQ(navDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(navDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputAfterUserAffinities) {
@@ -2878,10 +2931,10 @@
AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
std::vector<AudioMixMatchCriterion> navMatchCriteria = {
- createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
/*exclude=*/ false)};
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
+ AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
const AudioDeviceTypeAddrVector outputDevices = {mediaOutputDevice};
@@ -2889,17 +2942,18 @@
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusNavigationOutput, &navDevicePort));
- audio_port_handle_t selectedDeviceId = navDevicePort.id;
+ DeviceIdVector selectedDeviceIds = { navDevicePort.id };
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t mediaAttribute = {
AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
- ASSERT_NE(navDevicePort.id, selectedDeviceId);
+ ASSERT_GT(selectedDeviceIds.size(), 0);
+ ASSERT_NE(navDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithExcludeUserIdCriteria) {
@@ -2914,11 +2968,11 @@
AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
std::vector<AudioMixMatchCriterion> navMatchCriteria = {
- createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
/*exclude=*/ false),
- createUserIdCriterion(/* userId */ 0, /* exclude */ true)};
+ createUserIdCriterion(/* userId */ 0, /* exclude */ true)};
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
+ AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
@@ -2926,14 +2980,15 @@
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t navigationAttribute = {
- AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ DeviceIdVector selectedDeviceIds;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, navigationAttribute);
- ASSERT_NE(navDevicePort.id, selectedDeviceId);
+ ASSERT_GT(selectedDeviceIds.size(), 0);
+ ASSERT_NE(navDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithSelectedOutputExcludeUserIdCriteria) {
@@ -2948,30 +3003,30 @@
AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
std::vector<AudioMixMatchCriterion> navMatchCriteria = {
- createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
/*exclude=*/ false),
- createUserIdCriterion(0 /* userId */, /* exclude */ true)};
+ createUserIdCriterion(0 /* userId */, /* exclude */ true)};
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
+ AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
- sCarBusNavigationOutput, &navDevicePort));
- audio_port_handle_t selectedDeviceId = navDevicePort.id;
+ sCarBusNavigationOutput, &navDevicePort));
+ DeviceIdVector selectedDeviceIds = { navDevicePort.id };
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t mediaAttribute = {
- AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
- ASSERT_EQ(navDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(navDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest,
- GetOutputForAttrWithMatchingMixAndSelectedOutputAfterUserAffinities) {
+ GetOutputForAttrWithMatchingMixAndSelectedOutputAfterUserAffinities) {
status_t ret;
audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
@@ -2983,10 +3038,10 @@
AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
std::vector<AudioMixMatchCriterion> navMatchCriteria = {
- createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
/*exclude=*/ false)};
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
+ AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
@@ -2995,21 +3050,21 @@
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusNavigationOutput, &navDevicePort));
- audio_port_handle_t selectedDeviceId = navDevicePort.id;
+ DeviceIdVector selectedDeviceIds = { navDevicePort.id };
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t mediaAttribute = {
- AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute);
- ASSERT_EQ(navDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(navDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest,
- GetOutputForAttrWithNoMatchingMaxAndSelectedOutputAfterUserAffinities) {
+ GetOutputForAttrWithNoMatchingMaxAndSelectedOutputAfterUserAffinities) {
status_t ret;
audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
@@ -3021,10 +3076,10 @@
AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
std::vector<AudioMixMatchCriterion> navMatchCriteria = {
- createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
/*exclude=*/ false)};
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
+ AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
@@ -3033,21 +3088,21 @@
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusNavigationOutput, &navDevicePort));
- audio_port_handle_t selectedDeviceId = navDevicePort.id;
+ DeviceIdVector selectedDeviceIds = { navDevicePort.id };
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t alarmAttribute = {
- AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, alarmAttribute);
- ASSERT_EQ(navDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(navDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest,
- GetOutputForAttrWithMatMixAfterUserAffinitiesForOneUser) {
+ GetOutputForAttrWithMatMixAfterUserAffinitiesForOneUser) {
status_t ret;
audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
@@ -3070,23 +3125,23 @@
audio_port_v7 primaryZoneDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusMediaOutput, &primaryZoneDevicePort));
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t mediaAttribute = {
- AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
AUDIO_SESSION_NONE, user11AppUid);
- ASSERT_EQ(primaryZoneDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(primaryZoneDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest,
- GetOutputForAttrWithMatMixAfterUserAffinitiesForTwoUsers) {
+ GetOutputForAttrWithMatMixAfterUserAffinitiesForTwoUsers) {
status_t ret;
audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
@@ -3112,23 +3167,23 @@
audio_port_v7 secondaryZoneDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarRearZoneOneOutput, &secondaryZoneDevicePort));
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t mediaAttribute = {
- AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
uid_t user11AppUid = multiuser_get_uid(/* user_id */ 11, /* app_id */ 12345);
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
AUDIO_SESSION_NONE, user11AppUid);
- ASSERT_EQ(secondaryZoneDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(secondaryZoneDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest,
- GetOutputForAttrWithMatMixAfterUserAffinitiesForThreeUsers) {
+ GetOutputForAttrWithMatMixAfterUserAffinitiesForThreeUsers) {
status_t ret;
audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
@@ -3157,19 +3212,19 @@
audio_port_v7 tertiaryZoneDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarRearZoneTwoOutput, &tertiaryZoneDevicePort));
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t mediaAttribute = {
- AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_MEDIA,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
uid_t user15AppUid = multiuser_get_uid(/* user_id */ 15, /* app_id */ 12345);
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, mediaAttribute,
AUDIO_SESSION_NONE, user15AppUid);
- ASSERT_EQ(tertiaryZoneDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(tertiaryZoneDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrWithNoMatchingMix) {
@@ -3184,10 +3239,10 @@
AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput, audioConfig, mediaMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
std::vector<AudioMixMatchCriterion> navMatchCriteria = {
- createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ createUsageCriterion(AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
/*exclude=*/ false)};
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
+ AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput, audioConfig, navMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
const AudioDeviceTypeAddr mediaOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusMediaOutput);
const AudioDeviceTypeAddr navOutputDevice(AUDIO_DEVICE_OUT_BUS, sCarBusNavigationOutput);
@@ -3196,17 +3251,17 @@
audio_port_v7 navDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
sCarBusNavigationOutput, &navDevicePort));
- audio_port_handle_t selectedDeviceId = navDevicePort.id;
+ DeviceIdVector selectedDeviceIds = { navDevicePort.id };
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t alarmAttribute = {
- AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
- AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
+ AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_ALARM,
+ AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId, alarmAttribute);
- ASSERT_EQ(navDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(navDevicePort.id, selectedDeviceIds[0]);
}
TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrForMMapWithPolicyMatched) {
@@ -3218,13 +3273,13 @@
std::vector<AudioMixMatchCriterion> mediaMatchCriteria = {
createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/ false)};
ret = addPolicyMix(MIX_TYPE_PLAYERS, MIX_ROUTE_FLAG_RENDER,
- AUDIO_DEVICE_OUT_BUS, sCarBusMmapOutput, audioConfig, mediaMatchCriteria);
+ AUDIO_DEVICE_OUT_BUS, sCarBusMmapOutput, audioConfig, mediaMatchCriteria);
ASSERT_EQ(NO_ERROR, ret);
ASSERT_EQ(NO_ERROR, ret);
audio_port_v7 mmapDevicePort;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_BUS,
- sCarBusMmapOutput, &mmapDevicePort));
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ sCarBusMmapOutput, &mmapDevicePort));
+ DeviceIdVector selectedDeviceIds;
audio_io_handle_t output;
audio_port_handle_t portId;
const audio_attributes_t mediaAttribute = {
@@ -3232,12 +3287,13 @@
AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};
getOutputForAttr(
- &selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ &selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate,
(audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT),
&output, &portId, mediaAttribute);
- ASSERT_EQ(mmapDevicePort.id, selectedDeviceId);
+ ASSERT_EQ(mmapDevicePort.id, selectedDeviceIds[0]);
+
}
class AudioPolicyManagerTVTest : public AudioPolicyManagerTestWithConfigurationFile {
@@ -3257,10 +3313,10 @@
ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
"" /*address*/, "" /*name*/, AUDIO_FORMAT_DEFAULT));
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_io_handle_t output;
audio_port_handle_t portId;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
k48000SamplingRate, flags, &output, &portId);
sp<SwAudioOutputDescriptor> outDesc = mManager->getOutputs().valueFor(output);
ASSERT_NE(nullptr, outDesc.get());
@@ -3339,7 +3395,7 @@
void AudioPolicyManagerPhoneTest::testOutputMixPortSelectionForAttr(
audio_output_flags_t flags, audio_format_t format, int samplingRate, bool isMusic,
const char* expectedMixPortName) {
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_io_handle_t output;
audio_port_handle_t portId;
audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
@@ -3347,7 +3403,7 @@
attr.content_type = AUDIO_CONTENT_TYPE_MUSIC;
attr.usage = AUDIO_USAGE_MEDIA;
}
- getOutputForAttr(&selectedDeviceId, format, AUDIO_CHANNEL_OUT_STEREO, samplingRate, flags,
+ getOutputForAttr(&selectedDeviceIds, format, AUDIO_CHANNEL_OUT_STEREO, samplingRate, flags,
&output, &portId, attr);
EXPECT_NO_FATAL_FAILURE(verifyMixPortNameAndFlags(output, expectedMixPortName));
mManager->releaseOutput(portId);
@@ -3916,7 +3972,7 @@
audio_port_handle_t mUsbPortId = AUDIO_PORT_HANDLE_NONE;
audio_io_handle_t mBitPerfectOutput = AUDIO_IO_HANDLE_NONE;
- audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector mSelectedDeviceIds;
audio_port_handle_t mBitPerfectPortId = AUDIO_PORT_HANDLE_NONE;
static constexpr audio_attributes_t sMediaAttr = {
@@ -3975,12 +4031,12 @@
reset();
bool isBitPerfect;
- getOutputForAttr(&mSelectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
+ getOutputForAttr(&mSelectedDeviceIds, mBitPerfectFormat, mBitPerfectChannelMask,
mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &mBitPerfectOutput,
&mBitPerfectPortId, sMediaAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
status_t status = mManager->startOutput(mBitPerfectPortId);
if (status == DEAD_OBJECT) {
- getOutputForAttr(&mSelectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
+ getOutputForAttr(&mSelectedDeviceIds, mBitPerfectFormat, mBitPerfectChannelMask,
mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &mBitPerfectOutput,
&mBitPerfectPortId, sMediaAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
status = mManager->startOutput(mBitPerfectPortId);
@@ -3996,8 +4052,8 @@
void AudioPolicyManagerTestBitPerfectBase::reset() {
mBitPerfectOutput = AUDIO_IO_HANDLE_NONE;
- mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
mBitPerfectPortId = AUDIO_PORT_HANDLE_NONE;
+ mSelectedDeviceIds.clear();
}
void AudioPolicyManagerTestBitPerfectBase::getBitPerfectOutput(status_t expected) {
@@ -4017,7 +4073,7 @@
EXPECT_EQ(expected,
mManager->getOutputForAttr(&sMediaAttr, &mBitPerfectOutput, AUDIO_SESSION_NONE,
&stream, attributionSource, &config, &flags,
- &mSelectedDeviceId, &mBitPerfectPortId, {}, &outputType,
+ &mSelectedDeviceIds, &mBitPerfectPortId, {}, &outputType,
&isSpatialized, &isBitPerfect, &volume, &muted));
}
@@ -4027,13 +4083,13 @@
TEST_F(AudioPolicyManagerTestBitPerfect, UseBitPerfectOutput) {
const uid_t anotherUid = 5678;
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
bool isBitPerfect;
// When there is no active bit-perfect playback, the output selection will follow default
// routing strategy.
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_QUAD,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_QUAD,
48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
AUDIO_SESSION_NONE, mUid, &isBitPerfect);
EXPECT_FALSE(isBitPerfect);
@@ -4047,14 +4103,14 @@
// If the playback is from preferred mixer attributes owner but the request doesn't match
// preferred mixer attributes, it will not be bit-perfect.
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_QUAD,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_QUAD,
48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
AUDIO_SESSION_NONE, mUid, &isBitPerfect);
EXPECT_FALSE(isBitPerfect);
EXPECT_EQ(mBitPerfectOutput, output);
// When bit-perfect playback is active, all other playback will be routed to bit-perfect output.
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
EXPECT_FALSE(isBitPerfect);
@@ -4066,9 +4122,9 @@
.usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
};
audio_io_handle_t dtmfOutput = AUDIO_IO_HANDLE_NONE;
- selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ selectedDeviceIds.clear();
portId = AUDIO_PORT_HANDLE_NONE;
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
48000, AUDIO_OUTPUT_FLAG_NONE, &dtmfOutput, &portId, dtmfAttr,
AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
EXPECT_FALSE(isBitPerfect);
@@ -4076,7 +4132,7 @@
// When configuration matches preferred mixer attributes, which is bit-perfect, but the client
// is not the owner of preferred mixer attributes, the playback will not be bit-perfect.
- getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
+ getOutputForAttr(&selectedDeviceIds, mBitPerfectFormat, mBitPerfectChannelMask,
mBitPerfectSampleRate, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, sMediaAttr,
AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
EXPECT_FALSE(isBitPerfect);
@@ -4102,9 +4158,9 @@
.content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
.usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION,
};
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
bool isBitPerfect;
- getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
+ getOutputForAttr(&selectedDeviceIds, mBitPerfectFormat, mBitPerfectChannelMask,
anotherSampleRate, AUDIO_OUTPUT_FLAG_NONE, &systemSoundOutput,
&systemSoundPortId, systemSoundAttr, AUDIO_SESSION_NONE, mUid, &isBitPerfect);
EXPECT_FALSE(isBitPerfect);
@@ -4124,7 +4180,7 @@
.content_type = AUDIO_CONTENT_TYPE_SONIFICATION,
.usage = AUDIO_USAGE_NOTIFICATION,
};
- getOutputForAttr(&selectedDeviceId, mBitPerfectFormat, mBitPerfectChannelMask,
+ getOutputForAttr(&selectedDeviceIds, mBitPerfectFormat, mBitPerfectChannelMask,
anotherSampleRate, AUDIO_OUTPUT_FLAG_NONE, ¬ificationOutput,
¬ificationPortId, notificationAttr, AUDIO_SESSION_NONE, mUid,
&isBitPerfect);
@@ -4191,11 +4247,11 @@
.content_type = AUDIO_CONTENT_TYPE_UNKNOWN,
.usage = GetParam(),
};
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector selectedDeviceIds;
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
ASSERT_NO_FATAL_FAILURE(
- getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
+ getOutputForAttr(&selectedDeviceIds, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
48000, AUDIO_OUTPUT_FLAG_NONE, &output, &portId, attr));
EXPECT_NE(mBitPerfectOutput, output);
EXPECT_EQ(NO_ERROR, mManager->startOutput(portId));