Set initial audio device for AudioTrack and AudioRecord
Bug: 62090113
Test: run AAudio test and verify a valid device is reported just
after opening playback or capture streams in legacy mode.
Merged-In: Ic8be42e1735690eb00c811ef0cb8b5abb36172d6
Change-Id: Ic8be42e1735690eb00c811ef0cb8b5abb36172d6
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index d29aa74..b96adc7 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -69,7 +69,8 @@
: mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName),
mSessionId(AUDIO_SESSION_ALLOCATE),
mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
- mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mPortId(AUDIO_PORT_HANDLE_NONE)
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
+ mPortId(AUDIO_PORT_HANDLE_NONE)
{
}
@@ -503,7 +504,14 @@
if (mInput == AUDIO_IO_HANDLE_NONE) {
return AUDIO_PORT_HANDLE_NONE;
}
- return AudioSystem::getDeviceIdForIo(mInput);
+ // if the input stream does not have an active audio patch, use either the device initially
+ // selected by audio policy manager or the last routed device
+ audio_port_handle_t deviceId = AudioSystem::getDeviceIdForIo(mInput);
+ if (deviceId == AUDIO_PORT_HANDLE_NONE) {
+ deviceId = mRoutedDeviceId;
+ }
+ mRoutedDeviceId = deviceId;
+ return deviceId;
}
// -------------------------------------------------------------------------
@@ -538,13 +546,14 @@
.channel_mask = mChannelMask,
.format = mFormat
};
+ mRoutedDeviceId = mSelectedDeviceId;
status = AudioSystem::getInputForAttr(&mAttributes, &input,
mSessionId,
// FIXME compare to AudioTrack
mClientPid,
mClientUid,
&config,
- mFlags, mSelectedDeviceId, &mPortId);
+ mFlags, &mRoutedDeviceId, &mPortId);
if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE) {
ALOGE("Could not get audio input for session %d, record source %d, sample rate %u, "
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index ed1e6d1..2f710bd 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -819,7 +819,7 @@
uid_t uid,
const audio_config_t *config,
audio_output_flags_t flags,
- audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@@ -863,7 +863,7 @@
uid_t uid,
const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 98ec7d7..c614b6c 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -184,6 +184,7 @@
mPreviousSchedulingGroup(SP_DEFAULT),
mPausedPosition(0),
mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+ mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
mPortId(AUDIO_PORT_HANDLE_NONE)
{
mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN;
@@ -1226,7 +1227,14 @@
if (mOutput == AUDIO_IO_HANDLE_NONE) {
return AUDIO_PORT_HANDLE_NONE;
}
- return AudioSystem::getDeviceIdForIo(mOutput);
+ // if the output stream does not have an active audio patch, use either the device initially
+ // selected by audio policy manager or the last routed device
+ audio_port_handle_t deviceId = AudioSystem::getDeviceIdForIo(mOutput);
+ if (deviceId == AUDIO_PORT_HANDLE_NONE) {
+ deviceId = mRoutedDeviceId;
+ }
+ mRoutedDeviceId = deviceId;
+ return deviceId;
}
status_t AudioTrack::attachAuxEffect(int effectId)
@@ -1292,10 +1300,11 @@
config.channel_mask = mChannelMask;
config.format = mFormat;
config.offload_info = mOffloadInfoCopy;
+ mRoutedDeviceId = mSelectedDeviceId;
status = AudioSystem::getOutputForAttr(attr, &output,
mSessionId, &streamType, mClientUid,
&config,
- mFlags, mSelectedDeviceId, &mPortId);
+ mFlags, &mRoutedDeviceId, &mPortId);
if (status != NO_ERROR || output == AUDIO_IO_HANDLE_NONE) {
ALOGE("Could not get audio output for session %d, stream type %d, usage %d, sample rate %u,"
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index b72047b..d320320 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -193,7 +193,7 @@
uid_t uid,
const audio_config_t *config,
audio_output_flags_t flags,
- audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId)
{
Parcel data, reply;
@@ -212,6 +212,10 @@
ALOGE("getOutputForAttr NULL output - shouldn't happen");
return BAD_VALUE;
}
+ if (selectedDeviceId == NULL) {
+ ALOGE("getOutputForAttr NULL selectedDeviceId - shouldn't happen");
+ return BAD_VALUE;
+ }
if (portId == NULL) {
ALOGE("getOutputForAttr NULL portId - shouldn't happen");
return BAD_VALUE;
@@ -232,7 +236,7 @@
data.writeInt32(uid);
data.write(config, sizeof(audio_config_t));
data.writeInt32(static_cast <uint32_t>(flags));
- data.writeInt32(selectedDeviceId);
+ data.writeInt32(*selectedDeviceId);
data.writeInt32(*portId);
status_t status = remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply);
if (status != NO_ERROR) {
@@ -247,6 +251,7 @@
if (stream != NULL) {
*stream = lStream;
}
+ *selectedDeviceId = (audio_port_handle_t)reply.readInt32();
*portId = (audio_port_handle_t)reply.readInt32();
return status;
}
@@ -296,7 +301,7 @@
uid_t uid,
const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId)
{
Parcel data, reply;
@@ -309,6 +314,10 @@
ALOGE("getInputForAttr NULL input - shouldn't happen");
return BAD_VALUE;
}
+ if (selectedDeviceId == NULL) {
+ ALOGE("getInputForAttr NULL selectedDeviceId - shouldn't happen");
+ return BAD_VALUE;
+ }
if (portId == NULL) {
ALOGE("getInputForAttr NULL portId - shouldn't happen");
return BAD_VALUE;
@@ -319,7 +328,7 @@
data.writeInt32(uid);
data.write(config, sizeof(audio_config_base_t));
data.writeInt32(flags);
- data.writeInt32(selectedDeviceId);
+ data.writeInt32(*selectedDeviceId);
data.writeInt32(*portId);
status_t status = remote()->transact(GET_INPUT_FOR_ATTR, data, &reply);
if (status != NO_ERROR) {
@@ -330,6 +339,7 @@
return status;
}
*input = (audio_io_handle_t)reply.readInt32();
+ *selectedDeviceId = (audio_port_handle_t)reply.readInt32();
*portId = (audio_port_handle_t)reply.readInt32();
return NO_ERROR;
}
@@ -968,10 +978,11 @@
status_t status = getOutputForAttr(hasAttributes ? &attr : NULL,
&output, session, &stream, uid,
&config,
- flags, selectedDeviceId, &portId);
+ flags, &selectedDeviceId, &portId);
reply->writeInt32(status);
reply->writeInt32(output);
reply->writeInt32(stream);
+ reply->writeInt32(selectedDeviceId);
reply->writeInt32(portId);
return NO_ERROR;
} break;
@@ -1025,10 +1036,11 @@
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = getInputForAttr(&attr, &input, session, pid, uid,
&config,
- flags, selectedDeviceId, &portId);
+ flags, &selectedDeviceId, &portId);
reply->writeInt32(status);
if (status == NO_ERROR) {
reply->writeInt32(input);
+ reply->writeInt32(selectedDeviceId);
reply->writeInt32(portId);
}
return NO_ERROR;
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 1b034b5..32757d3 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -655,7 +655,10 @@
// For Device Selection API
// a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
- audio_port_handle_t mSelectedDeviceId;
+ audio_port_handle_t mSelectedDeviceId; // Device requested by the application.
+ audio_port_handle_t mRoutedDeviceId; // Device actually selected by audio policy manager:
+ // May not match the app selection depending on other
+ // activity and connected devices
sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
audio_port_handle_t mPortId; // unique ID allocated by audio policy
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 2875794..2e39d23 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -224,7 +224,7 @@
uid_t uid,
const audio_config_t *config,
audio_output_flags_t flags,
- audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId);
static status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
@@ -245,7 +245,7 @@
uid_t uid,
const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId);
static status_t startInput(audio_io_handle_t input,
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 5d73df3..3f9037f 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -1135,7 +1135,10 @@
// For Device Selection API
// a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
- audio_port_handle_t mSelectedDeviceId;
+ audio_port_handle_t mSelectedDeviceId; // Device requested by the application.
+ audio_port_handle_t mRoutedDeviceId; // Device actually selected by audio policy manager:
+ // May not match the app selection depending on other
+ // activity and connected devices.
sp<VolumeHandler> mVolumeHandler;
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index ac71873..9b3e35e 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -68,7 +68,7 @@
uid_t uid,
const audio_config_t *config,
audio_output_flags_t flags,
- audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId) = 0;
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
@@ -86,7 +86,7 @@
uid_t uid,
const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId) = 0;
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session) = 0;