AudioSystem::device_connection_state state,
const char *device_address)
{
+ // device_address can be NULL and should be handled as an empty string in this case,
+ // and it is not checked by AudioPolicyInterfaceImpl.cpp
+ if (device_address == NULL) {
+ device_address = "";
+ }
ALOGV("setDeviceConnectionState() device: 0x%X, state %d, address %s", device, state, device_address);
// connect/disconnect only 1 device at a time
if (audio_is_output_device(device)) {
SortedVector <audio_io_handle_t> outputs;
- if (!mHasA2dp && audio_is_a2dp_device(device)) {
+ if (!mHasA2dp && audio_is_a2dp_out_device(device)) {
ALOGE("setDeviceConnectionState() invalid A2DP device: %x", device);
return BAD_VALUE;
}
}
ALOGV("setDeviceConnectionState() connecting device %x", device);
- if (mHasA2dp && audio_is_a2dp_device(device)) {
+ if (mHasA2dp && audio_is_a2dp_out_device(device)) {
// handle A2DP device connection
AudioParameter param;
param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address));
// register new device as available
mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device);
- if (mHasA2dp && audio_is_a2dp_device(device)) {
+ if (mHasA2dp && audio_is_a2dp_out_device(device)) {
// handle A2DP device connection
mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
mA2dpSuspended = false;
mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device);
checkOutputsForDevice(device, state, outputs, paramStr);
- if (mHasA2dp && audio_is_a2dp_device(device)) {
+ if (mHasA2dp && audio_is_a2dp_out_device(device)) {
// handle A2DP device disconnection
mA2dpDeviceAddress = "";
mA2dpSuspended = false;
0);
}
- if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) {
- device = AUDIO_DEVICE_IN_WIRED_HEADSET;
- } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO ||
- device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
- device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
- device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
- } else {
- return NO_ERROR;
- }
+ return NO_ERROR;
} // end if is output device
// handle input devices
if (mHasUsb && audio_is_usb_in_device(device)) {
// handle USB device connection
paramStr = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
+ } else if (mHasA2dp && audio_is_a2dp_in_device(device)) {
+ // handle A2DP device connection
+ AudioParameter param;
+ param.add(String8(AUDIO_PARAMETER_A2DP_SOURCE_ADDRESS), String8(device_address));
+ paramStr = param.toString();
}
if (checkInputsForDevice(device, state, inputs, paramStr) != NO_ERROR) {
AudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(audio_devices_t device,
const char *device_address)
{
+ // similar to setDeviceConnectionState
+ if (device_address == NULL) {
+ device_address = "";
+ }
AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE;
String8 address = String8(device_address);
if (audio_is_output_device(device)) {
if (device & mAvailableOutputDevices) {
- if (audio_is_a2dp_device(device) &&
+ if (audio_is_a2dp_out_device(device) &&
(!mHasA2dp || (address != "" && mA2dpDeviceAddress != address))) {
return state;
}
if (device != AUDIO_DEVICE_NONE) {
outputDesc->mDevice = device;
+
+ // Force routing if previously asked for this output
+ if (outputDesc->mForceRouting) {
+ ALOGV("Force routing to current device as previous device was null for this output");
+ force = true;
+
+ // Request consumed. Reset mForceRouting to false
+ outputDesc->mForceRouting = false;
+ }
}
+ else {
+ // Device is null and does not reflect the routing. Save the necessity to force
+ // re-routing upon next attempt to select a non-null device for this output
+ outputDesc->mForceRouting = true;
+ }
+
muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
// Do not change the routing if:
case AUDIO_SOURCE_DEFAULT:
case AUDIO_SOURCE_MIC:
+ if (mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
+ device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
+ break;
+ }
+ // FALL THROUGH
+
case AUDIO_SOURCE_VOICE_RECOGNITION:
case AUDIO_SOURCE_HOTWORD:
case AUDIO_SOURCE_VOICE_COMMUNICATION:
};
const AudioPolicyManagerBase::VolumeCurvePoint
- *AudioPolicyManagerBase::sVolumeProfiles[AUDIO_STREAM_CNT]
+ *AudioPolicyManagerBase::sVolumeProfiles[AudioSystem::NUM_STREAM_TYPES]
[AudioPolicyManagerBase::DEVICE_CATEGORY_CNT] = {
{ // AUDIO_STREAM_VOICE_CALL
sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
void AudioPolicyManagerBase::initializeVolumeCurves()
{
- for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
+ for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
mStreams[i].mVolumeCurve[j] =
sVolumeProfiles[i][j];
if (stream == AudioSystem::MUSIC &&
index != mStreams[stream].mIndexMin &&
(device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
- device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET ||
- device == AUDIO_DEVICE_OUT_USB_ACCESSORY ||
- device == AUDIO_DEVICE_OUT_USB_DEVICE)) {
+ device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) {
return 1.0;
}
: mId(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT),
mChannelMask(0), mLatency(0),
mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE),
- mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)
+ mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0),
+ mForceRouting(false)
{
// clear usage count for all stream types
for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
+ STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
};
const struct StringToEnum sFlagNameToEnumTable[] = {
STRING_TO_ENUM(AUDIO_FORMAT_MP3),
STRING_TO_ENUM(AUDIO_FORMAT_AAC),
STRING_TO_ENUM(AUDIO_FORMAT_VORBIS),
+ STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V1),
+ STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V2),
+ STRING_TO_ENUM(AUDIO_FORMAT_OPUS),
+ STRING_TO_ENUM(AUDIO_FORMAT_AC3),
+ STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
};
const struct StringToEnum sOutChannelsNameToEnumTable[] = {