audiopolicy:Enable custom audio policy.
Change-Id: I493c9155b230373f5041df814508b1c6996fe559
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 13a2a4b..345f9e4 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -104,25 +104,27 @@
delete interface;
}
-status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t device,
+status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t deviceType,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name)
+ const char *device_name,
+ audio_format_t encodedFormat)
{
- ALOGD("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
- device, state, device_address, device_name);
+ ALOGD("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s encodedFormat = 0x%X",
+ deviceType, state, device_address, device_name, encodedFormat);
// connect/disconnect only 1 device at a time
- if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
+ if (!audio_is_output_device(deviceType) && !audio_is_input_device(deviceType)) return BAD_VALUE;
- sp<DeviceDescriptor> devDesc =
- mHwModules.getDeviceDescriptor(device, device_address, device_name);
+ sp<DeviceDescriptor> device =
+ mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
+ state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
// handle output devices
- if (audio_is_output_device(device)) {
+ if (audio_is_output_device(deviceType)) {
SortedVector <audio_io_handle_t> outputs;
- ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
+ ssize_t index = mAvailableOutputDevices.indexOf(device);
// save a copy of the opened output descriptors before any output is opened or closed
// by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
@@ -133,41 +135,42 @@
case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
if (index >= 0) {
if (mApmConfigs->isHDMISpkEnabled() &&
- (popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ (popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
if (!strncmp(device_address, "hdmi_spkr", 9)) {
mHdmiAudioDisabled = false;
} else {
mHdmiAudioEvent = true;
}
}
- ALOGW("setDeviceConnectionState() device already connected: %x", device);
+ ALOGW("setDeviceConnectionState() device already connected: %x", deviceType);
return INVALID_OPERATION;
}
- ALOGV("setDeviceConnectionState() connecting device %x", device);
+ ALOGV("setDeviceConnectionState() connecting device %x", deviceType);
// register new device as available
- index = mAvailableOutputDevices.add(devDesc);
+ index = mAvailableOutputDevices.add(device);
if (mApmConfigs->isHDMISpkEnabled() &&
- (popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ (popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
if (!strncmp(device_address, "hdmi_spkr", 9)) {
mHdmiAudioDisabled = false;
} else {
mHdmiAudioEvent = true;
}
if (mHdmiAudioDisabled || !mHdmiAudioEvent) {
- mAvailableOutputDevices.remove(devDesc);
+ mAvailableOutputDevices.remove(device);
ALOGW("HDMI sink not connected, do not route audio to HDMI out");
return INVALID_OPERATION;
}
}
if (index >= 0) {
- sp<HwModule> module = mHwModules.getModuleForDevice(device);
+ sp<HwModule> module = mHwModules.getModuleForDevice(device, encodedFormat);
if (module == 0) {
ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
- device);
- mAvailableOutputDevices.remove(devDesc);
+ deviceType);
+ mAvailableOutputDevices.remove(device);
return INVALID_OPERATION;
}
+ ALOGV("setDeviceConnectionState() module name=%s", module->getName());
mAvailableOutputDevices[index]->attach(module);
} else {
return NO_MEMORY;
@@ -175,20 +178,23 @@
// Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the outputs...)
- broadcastDeviceConnectionState(device, state, devDesc->address());
+ broadcastDeviceConnectionState(device, state);
- if (checkOutputsForDevice(devDesc, state, outputs, devDesc->address()) != NO_ERROR) {
- mAvailableOutputDevices.remove(devDesc);
+ if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) {
+ mAvailableOutputDevices.remove(device);
- broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- devDesc->address());
+ broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
return INVALID_OPERATION;
}
// Propagate device availability to Engine
- mEngine->setDeviceConnectionState(devDesc, state);
- if (device == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ mEngine->setDeviceConnectionState(device, state);
+//TODO CP Begin
+#if 0
+ if (deviceType == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
chkDpConnAndAllowedForVoice();
}
+#endif
+//TODO CP End
// outputs should never be empty here
ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
@@ -201,39 +207,46 @@
case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
if (index < 0) {
if (mApmConfigs->isHDMISpkEnabled() &&
- (popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ (popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
if (!strncmp(device_address, "hdmi_spkr", 9)) {
mHdmiAudioDisabled = true;
} else {
mHdmiAudioEvent = false;
}
}
- ALOGW("setDeviceConnectionState() device not connected: %x", device);
+ ALOGW("setDeviceConnectionState() device not connected: %x", deviceType);
return INVALID_OPERATION;
}
- ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
+ ALOGV("setDeviceConnectionState() disconnecting output device %x", deviceType);
// Send Disconnect to HALs
- broadcastDeviceConnectionState(device, state, devDesc->address());
+ broadcastDeviceConnectionState(device, state);
// remove device from available output devices
- mAvailableOutputDevices.remove(devDesc);
+ mAvailableOutputDevices.remove(device);
if (mApmConfigs->isHDMISpkEnabled() &&
- (popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ (popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
if (!strncmp(device_address, "hdmi_spkr", 9)) {
mHdmiAudioDisabled = true;
} else {
mHdmiAudioEvent = false;
}
}
- checkOutputsForDevice(devDesc, state, outputs, devDesc->address());
+ checkOutputsForDevice(device, state, outputs);
+
+ // Reset active device codec
+ device->setEncodedFormat(AUDIO_FORMAT_DEFAULT);
// Propagate device availability to Engine
- mEngine->setDeviceConnectionState(devDesc, state);
- if (device == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ mEngine->setDeviceConnectionState(device, state);
+//TODO CP Begin
+#if 0
+ if (deviceType == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
mEngine->setDpConnAndAllowedForVoice(false);
}
+#endif
+//TODO CP End
} break;
default:
@@ -275,8 +288,10 @@
}
// handle FM device connection state to trigger FM AFE loopback
+//TODO CP Begin
+#if 0
if (mApmConfigs->isFMPowerOptEnabled() &&
- device == AUDIO_DEVICE_OUT_FM && hasPrimaryOutput()) {
+ deviceType == AUDIO_DEVICE_OUT_FM && hasPrimaryOutput()) {
audio_devices_t newDevice = AUDIO_DEVICE_NONE;
if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
/*
@@ -323,30 +338,32 @@
param.addInt(String8("handle_fm"), (int)newDevice);
mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString());
}
+#endif
+//TODO CP End
updateDevicesAndOutputs();
if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
- audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
- updateCallRouting(newDevice);
+ DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
+ updateCallRouting(newDevices);
}
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
- audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
+ DeviceVector newDevices = getNewOutputDevices(desc, true /*fromCache*/);
// do not force device change on duplicated output because if device is 0, it will
// also force a device 0 for the two outputs it is duplicated to which may override
// a valid device selection on those outputs.
bool force = !desc->isDuplicated()
- && (!device_distinguishes_on_address(device)
+ && (!device_distinguishes_on_address(deviceType)
// always force when disconnecting (a non-duplicated device)
|| (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
- setOutputDevice(desc, newDevice, force, 0);
+ setOutputDevices(desc, newDevices, force, 0);
}
}
if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
- cleanUpForDevice(devDesc);
+ cleanUpForDevice(device);
}
mpClientInterface->onAudioPortListUpdate();
@@ -354,36 +371,35 @@
} // end if is output device
// handle input devices
- if (audio_is_input_device(device)) {
+ if (audio_is_input_device(deviceType)) {
SortedVector <audio_io_handle_t> inputs;
- ssize_t index = mAvailableInputDevices.indexOf(devDesc);
+ ssize_t index = mAvailableInputDevices.indexOf(device);
switch (state)
{
// handle input device connection
case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
if (index >= 0) {
- ALOGW("setDeviceConnectionState() device already connected: %d", device);
+ ALOGW("setDeviceConnectionState() device already connected: %d", deviceType);
return INVALID_OPERATION;
}
- sp<HwModule> module = mHwModules.getModuleForDevice(device);
+ sp<HwModule> module = mHwModules.getModuleForDevice(device, AUDIO_FORMAT_DEFAULT);
if (module == NULL) {
ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
- device);
+ deviceType);
return INVALID_OPERATION;
}
// Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the inputs...)
- broadcastDeviceConnectionState(device, state, devDesc->address());
+ broadcastDeviceConnectionState(device, state);
- if (checkInputsForDevice(devDesc, state, inputs, devDesc->address()) != NO_ERROR) {
- broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- devDesc->address());
+ if (checkInputsForDevice(device, state, inputs) != NO_ERROR) {
+ broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
return INVALID_OPERATION;
}
- index = mAvailableInputDevices.add(devDesc);
+ index = mAvailableInputDevices.add(device);
if (index >= 0) {
mAvailableInputDevices[index]->attach(module);
} else {
@@ -391,26 +407,26 @@
}
// Propagate device availability to Engine
- mEngine->setDeviceConnectionState(devDesc, state);
+ mEngine->setDeviceConnectionState(device, state);
} break;
// handle input device disconnection
case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
if (index < 0) {
- ALOGW("setDeviceConnectionState() device not connected: %d", device);
+ ALOGW("setDeviceConnectionState() device not connected: %d", deviceType);
return INVALID_OPERATION;
}
- ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
+ ALOGV("setDeviceConnectionState() disconnecting input device %x", deviceType);
// Set Disconnect to HALs
- broadcastDeviceConnectionState(device, state, devDesc->address());
+ broadcastDeviceConnectionState(device, state);
- checkInputsForDevice(devDesc, state, inputs, devDesc->address());
- mAvailableInputDevices.remove(devDesc);
+ checkInputsForDevice(device, state, inputs);
+ mAvailableInputDevices.remove(device);
// Propagate device availability to Engine
- mEngine->setDeviceConnectionState(devDesc, state);
+ mEngine->setDeviceConnectionState(device, state);
} break;
default:
@@ -425,22 +441,26 @@
updateDevicesAndOutputs();
if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
- audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
- updateCallRouting(newDevice);
+ DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
+ updateCallRouting(newDevices);
}
if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
- cleanUpForDevice(devDesc);
+ cleanUpForDevice(device);
}
mpClientInterface->onAudioPortListUpdate();
return NO_ERROR;
} // end if is input device
- ALOGW("setDeviceConnectionState() invalid device: %x", device);
+ ALOGW("setDeviceConnectionState() invalid device: %x", deviceType);
return BAD_VALUE;
}
+
+//TODO CP Begin
+#if 0
+
void AudioPolicyManagerCustom::chkDpConnAndAllowedForVoice()
{
String8 value;
@@ -454,10 +474,12 @@
}
mEngine->setDpConnAndAllowedForVoice(connAndAllowed);
}
+#endif
+//TODO CP End
-bool AudioPolicyManagerCustom::isInvalidationOfMusicStreamNeeded(routing_strategy strategy)
+bool AudioPolicyManagerCustom::isInvalidationOfMusicStreamNeeded(const audio_attributes_t &attr)
{
- if (strategy == STRATEGY_MEDIA) {
+ if (followsSameRouting(attr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> newOutputDesc = mOutputs.valueAt(i);
if (newOutputDesc->mFormat == AUDIO_FORMAT_DSD)
@@ -467,33 +489,35 @@
return true;
}
-void AudioPolicyManagerCustom::checkOutputForStrategy(routing_strategy strategy)
+
+void AudioPolicyManagerCustom::checkOutputForAttributes(const audio_attributes_t &attr)
{
- audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
- audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
- SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mOutputs);
- SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
+
+ DeviceVector oldDevices = mEngine->getOutputDevicesForAttributes(attr, 0, true /*fromCache*/);
+ DeviceVector newDevices = mEngine->getOutputDevicesForAttributes(attr, 0, false /*fromCache*/);
+ SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevices(oldDevices, mPreviousOutputs);
+ SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevices(newDevices, mOutputs);
// also take into account external policy-related changes: add all outputs which are
// associated with policies in the "before" and "after" output vectors
- ALOGV("checkOutputForStrategy(): policy related outputs");
+ ALOGVV("%s(): policy related outputs", __func__);
for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
if (desc != 0 && desc->mPolicyMix != NULL) {
srcOutputs.add(desc->mIoHandle);
- ALOGV(" previous outputs: adding %d", desc->mIoHandle);
+ ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
}
}
for (size_t i = 0 ; i < mOutputs.size() ; i++) {
const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if (desc != 0 && desc->mPolicyMix != NULL) {
dstOutputs.add(desc->mIoHandle);
- ALOGV(" new outputs: adding %d", desc->mIoHandle);
+ ALOGVV(" new outputs: adding %d", desc->mIoHandle);
}
}
- if ((srcOutputs != dstOutputs) && isInvalidationOfMusicStreamNeeded(strategy)) {
- AudioPolicyManager::checkOutputForStrategy(strategy);
+ if ((srcOutputs != dstOutputs) && isInvalidationOfMusicStreamNeeded(attr)) {
+ AudioPolicyManager::checkOutputForAttributes(attr);
}
}
@@ -502,6 +526,7 @@
// of the system.
bool AudioPolicyManagerCustom::isOffloadSupported(const audio_offload_info_t& offloadInfo)
{
+ DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
" BitRate=%u, duration=%" PRId64 " us, has_video=%d",
offloadInfo.sample_rate, offloadInfo.channel_mask,
@@ -526,7 +551,8 @@
}
if (mApmConfigs->isRecPlayConcEnabled()) {
if (mApmConfigs->isRecPlayConcDisabled() &&
- ((true == mIsInputRequestOnProgress) || (mInputs.activeInputsCountOnDevices() > 0))) {
+ ((true == mIsInputRequestOnProgress) ||
+ (mInputs.activeInputsCountOnDevices(primaryInputDevices) > 0))) {
ALOGD("copl: blocking compress offload for record concurrency");
return false;
}
@@ -650,7 +676,7 @@
// See if there is a profile to support this.
// AUDIO_DEVICE_NONE
- sp<IOProfile> profile = getProfileForOutput(AUDIO_DEVICE_NONE /*ignore device */,
+ sp<IOProfile> profile = getProfileForOutput(DeviceVector() /*ignore device */,
offloadInfo.sample_rate,
offloadInfo.format,
offloadInfo.channel_mask,
@@ -664,7 +690,6 @@
{
ALOGD("setPhoneState() state %d", state);
// store previous phone state for management of sonification strategy below
- audio_devices_t newDevice = AUDIO_DEVICE_NONE;
int oldState = mEngine->getPhoneState();
if (mEngine->setPhoneState(state) != NO_ERROR) {
@@ -707,18 +732,18 @@
if (activeInputs.size() != 0) {
for (size_t i = 0; i < activeInputs.size(); i++) {
sp<AudioInputDescriptor> activeInput = activeInputs[i];
- switch(activeInput->inputSource()) {
+ switch(activeInput->source()) {
case AUDIO_SOURCE_VOICE_UPLINK:
case AUDIO_SOURCE_VOICE_DOWNLINK:
case AUDIO_SOURCE_VOICE_CALL:
ALOGD("voice_conc:FOUND active input during call active: %d",
- activeInput->inputSource());
+ activeInput->source());
break;
case AUDIO_SOURCE_VOICE_COMMUNICATION:
if (prop_voip_enabled) {
ALOGD("voice_conc:CLOSING VoIP input source on call setup :%d ",
- activeInput->inputSource());
+ activeInput->source());
RecordClientVector activeClients = activeInput->clientsList(true /*activeOnly*/);
for (const auto& activeClient : activeClients) {
closeClient(activeClient->portId());
@@ -728,7 +753,7 @@
default:
ALOGD("voice_conc:CLOSING input on call setup for inputSource: %d",
- activeInput->inputSource());
+ activeInput->source());
RecordClientVector activeClients = activeInput->clientsList(true /*activeOnly*/);
for (const auto& activeClient : activeClients) {
closeClient(activeClient->portId());
@@ -742,8 +767,8 @@
if (activeInputs.size() != 0) {
for (size_t i = 0; i < activeInputs.size(); i++) {
sp<AudioInputDescriptor> activeInput = activeInputs[i];
- if (AUDIO_SOURCE_VOICE_COMMUNICATION == activeInput->inputSource()) {
- ALOGD("voice_conc:CLOSING VoIP on call setup : %d",activeInput->inputSource());
+ if (AUDIO_SOURCE_VOICE_COMMUNICATION == activeInput->source()) {
+ ALOGD("voice_conc:CLOSING VoIP on call setup : %d",activeInput->source());
RecordClientVector activeClients = activeInput->clientsList(true /*activeOnly*/);
for (const auto& activeClient : activeClients) {
closeClient(activeClient->portId());
@@ -897,41 +922,46 @@
int delayMs = 0;
if (isStateInCall(state)) {
nsecs_t sysTime = systemTime();
+ auto musicStrategy = streamToStrategy(AUDIO_STREAM_MUSIC);
+ auto sonificationStrategy = streamToStrategy(AUDIO_STREAM_ALARM);
+
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
// mute media and sonification strategies and delay device switch by the largest
// latency of any output where either strategy is active.
// This avoid sending the ring tone or music tail into the earpiece or headset.
- if ((isStrategyActive(desc, STRATEGY_MEDIA,
+ if ((desc->isStrategyActive(musicStrategy,
SONIFICATION_HEADSET_MUSIC_DELAY,
sysTime) ||
- isStrategyActive(desc, STRATEGY_SONIFICATION,
+ desc->isStrategyActive(sonificationStrategy,
SONIFICATION_HEADSET_MUSIC_DELAY,
sysTime)) &&
(delayMs < (int)desc->latency()*2)) {
delayMs = desc->latency()*2;
}
- setStrategyMute(STRATEGY_MEDIA, true, desc);
- setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
- getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
- setStrategyMute(STRATEGY_SONIFICATION, true, desc);
- setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
- getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
+ setStrategyMute(musicStrategy, true, desc);
+ setStrategyMute(musicStrategy, false, desc, MUTE_TIME_MS,
+ mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
+ nullptr, true /*fromCache*/).types());
+ setStrategyMute(sonificationStrategy, true, desc);
+ setStrategyMute(sonificationStrategy, false, desc, MUTE_TIME_MS,
+ mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_ALARM),
+ nullptr, true /*fromCache*/).types());
}
}
if (hasPrimaryOutput()) {
// Note that despite the fact that getNewOutputDevice() is called on the primary output,
// the device returned is not necessarily reachable via this output
- audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
+ DeviceVector rxDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
// force routing command to audio hardware when ending call
// even if no device change is needed
- if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
- rxDevice = mPrimaryOutput->device();
+ if (isStateInCall(oldState) && rxDevices.isEmpty()) {
+ rxDevices = mPrimaryOutput->devices();
}
if (state == AUDIO_MODE_IN_CALL) {
- updateCallRouting(rxDevice, delayMs);
+ updateCallRouting(rxDevices, delayMs);
} else if (oldState == AUDIO_MODE_IN_CALL) {
if (mCallRxPatch != 0) {
mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
@@ -941,17 +971,17 @@
mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
mCallTxPatch.clear();
}
- setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
+ setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
} else {
- setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
+ setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
}
}
//update device for all non-primary outputs
for (size_t i = 0; i < mOutputs.size(); i++) {
audio_io_handle_t output = mOutputs.keyAt(i);
if (output != mPrimaryOutput->mIoHandle) {
- newDevice = getNewOutputDevice(mOutputs.valueFor(output), false /*fromCache*/);
- setOutputDevice(mOutputs.valueFor(output), newDevice, (newDevice != AUDIO_DEVICE_NONE));
+ DeviceVector newDevices = getNewOutputDevices(mOutputs.valueFor(output), false /*fromCache*/);
+ setOutputDevices(mOutputs.valueFor(output), newDevices, !newDevices.isEmpty());
}
}
if (isStateInCall(state)) {
@@ -1000,11 +1030,11 @@
delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
}
if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
- audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
- if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
- applyStreamVolumes(mPrimaryOutput, newDevice, delayMs, true);
+ DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, true /*fromCache*/);
+ if (forceVolumeReeval && !newDevices.isEmpty()) {
+ applyStreamVolumes(mPrimaryOutput, newDevices.types(), delayMs, true);
}
- waitMs = updateCallRouting(newDevice, delayMs);
+ waitMs = updateCallRouting(newDevices, delayMs);
}
// Use reverse loop to make sure any low latency usecases (generally tones)
// are not routed before non LL usecases (generally music).
@@ -1015,13 +1045,13 @@
// gets routing update while processing first output itself.
for (size_t i = mOutputs.size(); i > 0; i--) {
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i-1);
- audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
+ DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/);
if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
- waitMs = setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE),
+ waitMs = setOutputDevices(outputDesc, newDevices, !newDevices.isEmpty(),
delayMs);
- if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
- applyStreamVolumes(outputDesc, newDevice, waitMs, true);
+ if (forceVolumeReeval && !newDevices.isEmpty()) {
+ applyStreamVolumes(outputDesc, newDevices.types(), waitMs, true);
}
}
}
@@ -1035,10 +1065,9 @@
activeDesc->source() == AUDIO_SOURCE_HOTWORD) {
continue;
}
- audio_devices_t newDevice = getNewInputDevice(activeDesc);
+ auto newDevice = getNewInputDevice(activeDesc);
// Force new input selection if the new device can not be reached via current input
- if (activeDesc->mProfile->getSupportedDevices().types() &
- (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
+ if (activeDesc->mProfile->getSupportedDevices().contains(newDevice)) {
setInputDevice(activeDesc->mIoHandle, newDevice);
} else {
closeInput(activeDesc->mIoHandle);
@@ -1062,18 +1091,18 @@
if (outputDesc->streamActiveCount(stream) == 1) {
// Automatically disable the remote submix input when output is stopped on a
// re routing mix of type MIX_TYPE_RECORDERS
- if (audio_is_remote_submix_device(outputDesc->mDevice) &&
+ if (audio_is_remote_submix_device(outputDesc->devices().types()) &&
outputDesc->mPolicyMix != NULL &&
outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
outputDesc->mPolicyMix->mDeviceAddress,
- "remote-submix");
+ "remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
bool forceDeviceUpdate = false;
if (client->hasPreferredDevice(true)) {
- checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
+ checkStrategyRoute(client->strategy(), AUDIO_IO_HANDLE_NONE);
forceDeviceUpdate = true;
}
// decrement usage count of this stream on the output
@@ -1083,40 +1112,40 @@
// store time at which the stream was stopped - see isStreamActive()
if (outputDesc->streamActiveCount(stream) == 0 || forceDeviceUpdate) {
outputDesc->mStopTime[stream] = systemTime();
- audio_devices_t prevDevice = outputDesc->device();
- audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
+ DeviceVector prevDevices = outputDesc->devices();
+ DeviceVector newDevices = getNewOutputDevices(outputDesc, false /*fromCache*/);
// delay the device switch by twice the latency because stopOutput() is executed when
// the track stop() command is received and at that time the audio track buffer can
// still contain data that needs to be drained. The latency only covers the audio HAL
// and kernel buffers. Also the latency does not always include additional delay in the
// audio path (audio DSP, CODEC ...)
- setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
+ setOutputDevices(outputDesc, newDevices, false, outputDesc->latency()*2);
// force restoring the device selection on other active outputs if it differs from the
// one being selected for this output
for (size_t i = 0; i < mOutputs.size(); i++) {
audio_io_handle_t curOutput = mOutputs.keyAt(i);
- sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if (desc != outputDesc &&
desc->isActive() &&
outputDesc->sharesHwModuleWith(desc) &&
- (newDevice != desc->device())) {
- audio_devices_t dev = getNewOutputDevice(mOutputs.valueFor(curOutput), false /*fromCache*/);
- bool force = prevDevice != dev;
+ (newDevices != desc->devices())) {
+ DeviceVector dev = getNewOutputDevices(mOutputs.valueFor(curOutput), false /*fromCache*/);
+ bool force = prevDevices != dev;
uint32_t delayMs;
- if (dev == prevDevice) {
+ if (dev == prevDevices) {
delayMs = 0;
} else {
delayMs = outputDesc->latency()*2;
}
- setOutputDevice(desc,
+ setOutputDevices(desc,
dev,
force,
delayMs);
/*audio policy: fix media volume after ringtone*/
// re-apply device specific volume if not done by setOutputDevice()
if (!force) {
- applyStreamVolumes(desc, dev, delayMs);
+ applyStreamVolumes(desc, dev.types(), delayMs);
}
}
}
@@ -1140,6 +1169,7 @@
// cannot start playback of STREAM_TTS if any other output is being used
uint32_t beaconMuteLatency = 0;
audio_stream_type_t stream = client->stream();
+ auto clientAttr = client->attributes();
if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
ALOGW("startSource() invalid stream %d", stream);
@@ -1164,17 +1194,20 @@
bool force = !outputDesc->isActive() &&
(outputDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE);
- audio_devices_t device = AUDIO_DEVICE_NONE;
+ DeviceVector devices;
AudioMix *policyMix = NULL;
const char *address = NULL;
if (outputDesc->mPolicyMix != NULL) {
policyMix = outputDesc->mPolicyMix;
+ audio_devices_t newDeviceType;
address = policyMix->mDeviceAddress.string();
if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
- device = policyMix->mDeviceType;
+ newDeviceType = policyMix->mDeviceType;
} else {
- device = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+ newDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
}
+ devices.add(mAvailableOutputDevices.getDevice(newDeviceType,
+ String8(address), AUDIO_FORMAT_DEFAULT));
}
// increment usage count for this stream on the requested output:
@@ -1186,18 +1219,18 @@
selectOutputForMusicEffects();
}
- if (outputDesc->streamActiveCount(stream) == 1 || device != AUDIO_DEVICE_NONE) {
+ if (outputDesc->streamActiveCount(stream) == 1 || !devices.isEmpty()) {
// starting an output being rerouted?
- if (device == AUDIO_DEVICE_NONE) {
- device = getNewOutputDevice(outputDesc, false /*fromCache*/);
+ if (devices.isEmpty()) {
+ devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
}
- routing_strategy strategy = getStrategy(stream);
- bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
- (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
- (beaconMuteLatency > 0);
+ bool shouldWait = (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM)) ||
+ followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_NOTIFICATION)) ||
+ (beaconMuteLatency > 0));
+
uint32_t waitMs = beaconMuteLatency;
for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if (desc != outputDesc) {
// force a device change if any other output is:
// - managed by the same hw module
@@ -1207,8 +1240,8 @@
// In this case, the audio HAL must receive the new device selection so that it can
// change the device currently selected by the other active output.
if (outputDesc->sharesHwModuleWith(desc) &&
- desc->device() != device &&
- desc->supportedDevices() & device &&
+ desc->devices() != devices &&
+ !(desc->filterSupportedDevices(devices).isEmpty()) &&
desc->getPatchHandle() != AUDIO_PATCH_HANDLE_NONE) {
force = true;
}
@@ -1221,20 +1254,20 @@
}
}
}
- uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force, 0, NULL, address);
+ uint32_t muteWaitMs = setOutputDevices(outputDesc, devices, force, 0, NULL, address);
// apply volume rules for current stream and device if necessary
checkAndSetVolume(stream,
- mVolumeCurves->getVolumeIndex(stream, device),
+ mVolumeCurves->getVolumeIndex(stream, outputDesc->devices().types()),
outputDesc,
- device);
+ outputDesc->devices().types());
// update the outputs if starting an output with a stream that can affect notification
// routing
handleNotificationRoutingForStream(stream);
// force reevaluating accessibility routing when ringtone or alarm starts
- if (strategy == STRATEGY_SONIFICATION) {
+ if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM))) {
mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
}
if (waitMs > muteWaitMs) {
@@ -1248,7 +1281,7 @@
void AudioPolicyManagerCustom::handleNotificationRoutingForStream(audio_stream_type_t stream) {
switch(stream) {
case AUDIO_STREAM_MUSIC:
- checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
+ checkOutputForAttributes(attributes_initializer(AUDIO_USAGE_NOTIFICATION));
updateDevicesAndOutputs();
break;
default:
@@ -1284,7 +1317,7 @@
}
if (device == AUDIO_DEVICE_NONE) {
- device = outputDesc->device();
+ device = outputDesc->devices().types();
}
float volumeDb = computeVolume(stream, index, device);
@@ -1355,7 +1388,8 @@
const audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
- audio_port_handle_t *portId)
+ audio_port_handle_t *portId,
+ std::vector<audio_io_handle_t> *secondaryOutputs)
{
audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
audio_config_t tConfig;
@@ -1382,11 +1416,12 @@
(uid_t)uid, &tConfig,
flags,
(audio_port_handle_t*)selectedDeviceId,
- portId);
+ portId,
+ secondaryOutputs);
}
-audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevice(
- audio_devices_t device,
+audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices(
+ const DeviceVector &devices,
audio_session_t session,
audio_stream_type_t stream,
const audio_config_t *config,
@@ -1464,7 +1499,7 @@
if (desc->mFlags == (AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_DIRECT)) {
//close voip output if currently open by the same client with different device
if (desc->mDirectClientSession == session &&
- desc->device() != device) {
+ desc->devices() != devices) {
closeOutput(desc->mIoHandle);
} else {
voip_pcm_already_in_use = true;
@@ -1564,8 +1599,10 @@
}
if (mApmConfigs->isRecPlayConcEnabled()) {
bool prop_rec_play_enabled = mApmConfigs->isRecPlayConcDisabled();
+ DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
if ((prop_rec_play_enabled) &&
- ((true == mIsInputRequestOnProgress) || (mInputs.activeInputsCountOnDevices() > 0))) {
+ ((true == mIsInputRequestOnProgress) ||
+ (mInputs.activeInputsCountOnDevices(primaryInputDevices) > 0))) {
if (AUDIO_MODE_IN_COMMUNICATION == mEngine->getPhoneState()) {
if (AUDIO_OUTPUT_FLAG_VOIP_RX & *flags) {
// allow VoIP using voice path
@@ -1674,7 +1711,7 @@
*flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
AUDIO_OUTPUT_FLAG_DIRECT);
ALOGV("Set VoIP and Direct output flags for PCM format");
- } else if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
+ } else if (devices.types() == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
stream == AUDIO_STREAM_MUSIC &&
audio_is_linear_pcm(config->format) &&
isInCall()) {
@@ -1707,7 +1744,7 @@
goto non_direct_output;
}
- profile = getProfileForOutput(device,
+ profile = getProfileForOutput(devices,
config->sample_rate,
config->format,
config->channel_mask,
@@ -1764,10 +1801,10 @@
outputDesc =
new SwAudioOutputDescriptor(profile, mpClientInterface);
- DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(device);
+ DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(devices.types());
String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->address()
: String8("");
- status = outputDesc->open(config, device, address, stream, *flags, &output);
+ status = outputDesc->open(config, devices, stream, *flags, &output);
// only accept an output with the requested parameters
if (status != NO_ERROR ||
@@ -1823,7 +1860,7 @@
if (audio_is_linear_pcm(config->format)) {
// get which output is suitable for the specified stream. The actual
// routing change will happen when startOutput() will be called
- SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
+ SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
// at this stage we should ignore the DIRECT flag as no direct output could be found earlier
*flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
@@ -1932,7 +1969,7 @@
const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i);
if (inputDescriptor->isActive() && !inputDescriptor->isSoundTrigger() &&
((devices == AUDIO_DEVICE_IN_DEFAULT) ||
- ((inputDescriptor->mDevice & devices & ~AUDIO_DEVICE_BIT_IN) != 0))) {
+ ((inputDescriptor->getDeviceType() & devices & ~AUDIO_DEVICE_BIT_IN) != 0))) {
count++;
}
}
@@ -1980,8 +2017,8 @@
if (mApmConfigs->isRecPlayConcEnabled()) {
mIsInputRequestOnProgress = true;
-
- if (mApmConfigs->isRecPlayConcDisabled() && (mInputs.activeInputsCountOnDevices() == 0)) {
+ DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
+ if (mApmConfigs->isRecPlayConcDisabled() && (mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0)) {
// send update to HAL on record playback concurrency
AudioParameter param = AudioParameter();
param.add(String8("rec_play_conc_on"), String8("true"));
@@ -2026,7 +2063,7 @@
// indicate active capture to sound trigger service if starting capture from a mic on
// primary HW module
- audio_devices_t device = getNewInputDevice(inputDesc);
+ sp<DeviceDescriptor> device = getNewInputDevice(inputDesc);
setInputDevice(input, device, true /* force */);
if (inputDesc->activeCount() == 1) {
@@ -2037,10 +2074,10 @@
MIX_STATE_MIXING);
}
- audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
- if ((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) {
+ DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
+ if ((primaryInputDevices.contains(device) && (device->type() & ~AUDIO_DEVICE_BIT_IN)) != 0) {
if (mApmConfigs->isVAConcEnabled()) {
- if (activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices) == 1)
+ if (activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices.types()) == 1)
SoundTrigger::setCaptureState(true);
} else if (mInputs.activeInputsCountOnDevices(primaryInputDevices) == 1)
SoundTrigger::setCaptureState(true);
@@ -2049,7 +2086,7 @@
// automatically enable the remote submix output when input is started if not
// used by a policy mix of type MIX_TYPE_RECORDERS
// For remote submix (a virtual device), we open only one input per capture request.
- if (audio_is_remote_submix_device(inputDesc->mDevice)) {
+ if (audio_is_remote_submix_device(inputDesc->getDeviceType())) {
String8 address = String8("");
if (inputDesc->mPolicyMix == NULL) {
address = String8("0");
@@ -2059,7 +2096,7 @@
if (address != "") {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- address, "remote-submix");
+ address, "remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
}
@@ -2084,18 +2121,17 @@
audio_io_handle_t input = inputDesc->mIoHandle;
ALOGV("stopInput() input %d", input);
+ DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
if (mApmConfigs->isVAConcEnabled()) {
sp<AudioInputDescriptor> inputDesc = mInputs.getInputForClient(portId);
- audio_devices_t device = inputDesc->mDevice;
- audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
- if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
- activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices) == 0) {
+ if ((primaryInputDevices.contains(inputDesc->getDevice()) &&
+ activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices.types())) == 0) {
SoundTrigger::setCaptureState(false);
}
}
if (mApmConfigs->isRecPlayConcEnabled()) {
if (mApmConfigs->isRecPlayConcDisabled() &&
- (mInputs.activeInputsCountOnDevices() == 0)) {
+ (mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0)) {
//send update to HAL on record playback concurrency
AudioParameter param = AudioParameter();
param.add(String8("rec_play_conc_on"), String8("false"));
@@ -2115,7 +2151,6 @@
}
return status;
}
-
AudioPolicyManagerCustom::AudioPolicyManagerCustom(AudioPolicyClientInterface *clientInterface)
: AudioPolicyManager(clientInterface),
mFallBackflag(AUDIO_OUTPUT_FLAG_NONE),
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 3dfddeb..37fb806 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -86,7 +86,8 @@
status_t setDeviceConnectionStateInt(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
- const char *device_name);
+ const char *device_name,
+ audio_format_t encodedFormat);
virtual void setPhoneState(audio_mode_t state);
virtual void setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config);
@@ -114,7 +115,6 @@
static sp<APMConfigHelper> mApmConfigs;
protected:
-
status_t checkAndSetVolume(audio_stream_type_t stream,
int index,
const sp<AudioOutputDescriptor>& outputDesc,
@@ -123,11 +123,11 @@
// avoid invalidation for active music stream on previous outputs
// which is supported on the new device.
- bool isInvalidationOfMusicStreamNeeded(routing_strategy strategy);
+
+ bool isInvalidationOfMusicStreamNeeded(const audio_attributes_t &attr);
// Must be called before updateDevicesAndOutputs()
- void checkOutputForStrategy(routing_strategy strategy);
-
+ void checkOutputForAttributes(const audio_attributes_t &attr);
// returns true if given output is direct output
bool isDirectOutput(audio_io_handle_t output);
@@ -141,28 +141,30 @@
// event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON
// returns 0 if no mute/unmute event happened, the largest latency of the device where
// the mute/unmute happened
+
uint32_t handleEventForBeacon(int){return 0;}
uint32_t setBeaconMute(bool){return 0;}
static audio_output_flags_t getFallBackPath();
int mFallBackflag;
void moveGlobalEffect();
-
//parameter indicates of HDMI speakers disabled
bool mHdmiAudioDisabled;
//parameter indicates if HDMI plug in/out detected
bool mHdmiAudioEvent;
+
private:
// updates device caching and output for streams that can influence the
// routing of notifications
void handleNotificationRoutingForStream(audio_stream_type_t stream);
// internal method to return the output handle for the given device and format
- audio_io_handle_t getOutputForDevice(
- audio_devices_t device,
+ audio_io_handle_t getOutputForDevices(
+ const DeviceVector &devices,
audio_session_t session,
audio_stream_type_t stream,
const audio_config_t *config,
audio_output_flags_t *flags);
+
// internal method to fill offload info in case of Direct PCM
status_t getOutputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *output,
@@ -172,7 +174,12 @@
const audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
- audio_port_handle_t *portId);
+ audio_port_handle_t *portId,
+ std::vector<audio_io_handle_t> *secondaryOutputs);
+
+
+
+
// internal method to query hal for whether display-port is connected
// and can be used for voip/voice call
void chkDpConnAndAllowedForVoice();