Use routed devices throughout the audio framework
After you open an audio stream, you can call getRoutedDevice() to
get which output device is actually used.
However, if you play an ALARM with a headset attached, audio comes
out of both the speaker and the headset. This is not properly reflected
with our current APIs.
Throughout the audio framework, we should use DeviceIdVector instead
of a single device when getRoutedDevice(s) are called.
This change touches many files because onAudioDeviceUpdate() has many
callers.
BYPASS_LARGE_CHANGE_WARNING
Bug: 367816690
Test: atest AAudioTests
Test: atest audiorecord_tests
Test: atest audiosystem_tests
Test: atest audiotrack_tests
Test: adb shell /data/fuzz/arm64/libaaudio_fuzzer/libaaudio_fuzzer
Test: adb shell /data/fuzz/arm64/mediaplayer_fuzzer/mediaplayer_fuzzer
Test: adb shell /data/fuzz/arm64/mediarecorder_fuzzer/mediarecorder_fuzzer
Test: OboeTester Test Output with Alarm and USB
Flag: EXEMPT refactor
Change-Id: I5e32ac5d1c24229e60112ef00d82af41d8eff6e7
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 8a962c6..06dd27b 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -104,8 +104,8 @@
],
shared_libs: [
- "android.hidl.token@1.0-utils",
"android.hardware.media.omx@1.0",
+ "android.hidl.token@1.0-utils",
"libbinder",
"libcutils",
"libhidlbase",
@@ -116,8 +116,8 @@
],
export_shared_lib_headers: [
- "android.hidl.token@1.0-utils",
"android.hardware.media.omx@1.0",
+ "android.hidl.token@1.0-utils",
"libstagefright_foundation",
"libui",
],
@@ -138,15 +138,15 @@
],
cflags: [
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
],
sanitize: {
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
cfi: true,
},
@@ -197,15 +197,15 @@
],
cflags: [
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
],
sanitize: {
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
cfi: true,
},
@@ -232,15 +232,15 @@
],
cflags: [
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
],
sanitize: {
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
cfi: true,
},
@@ -279,15 +279,15 @@
],
cflags: [
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
],
sanitize: {
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
cfi: true,
},
@@ -323,15 +323,15 @@
],
cflags: [
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
],
sanitize: {
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
cfi: true,
},
@@ -346,35 +346,35 @@
srcs: [
":mediaextractorservice_aidl",
- "IDataSource.cpp",
"BufferingSettings.cpp",
- "mediaplayer.cpp",
+ "CharacterEncodingDetector.cpp",
+ "IDataSource.cpp",
+ "IMediaDeathNotifier.cpp",
+ "IMediaExtractor.cpp",
"IMediaHTTPConnection.cpp",
"IMediaHTTPService.cpp",
- "IMediaExtractor.cpp",
- "IMediaPlayerService.cpp",
- "IMediaPlayerClient.cpp",
- "IMediaRecorderClient.cpp",
+ "IMediaMetadataRetriever.cpp",
"IMediaPlayer.cpp",
+ "IMediaPlayerClient.cpp",
+ "IMediaPlayerService.cpp",
"IMediaRecorder.cpp",
+ "IMediaRecorderClient.cpp",
"IMediaSource.cpp",
"IRemoteDisplay.cpp",
"IRemoteDisplayClient.cpp",
"IStreamSource.cpp",
- "Metadata.cpp",
- "mediarecorder.cpp",
- "IMediaMetadataRetriever.cpp",
- "mediametadataretriever.cpp",
- "MediaScanner.cpp",
- "MediaScannerClient.cpp",
- "CharacterEncodingDetector.cpp",
- "IMediaDeathNotifier.cpp",
"MediaProfiles.cpp",
"MediaResource.cpp",
"MediaResourcePolicy.cpp",
- "StringArray.cpp",
- "NdkMediaFormatPriv.cpp",
+ "MediaScanner.cpp",
+ "MediaScannerClient.cpp",
+ "Metadata.cpp",
"NdkMediaErrorPriv.cpp",
+ "NdkMediaFormatPriv.cpp",
+ "StringArray.cpp",
+ "mediametadataretriever.cpp",
+ "mediaplayer.cpp",
+ "mediarecorder.cpp",
],
aidl: {
@@ -383,55 +383,57 @@
},
header_libs: [
+ "jni_headers",
"libstagefright_headers",
"media_ndk_headers",
- "jni_headers",
],
export_header_lib_headers: [
+ "jni_headers",
"libstagefright_headers",
"media_ndk_headers",
- "jni_headers",
],
shared_libs: [
"android.hidl.token@1.0-utils",
"audioclient-types-aidl-cpp",
"av-types-aidl-cpp",
- "liblog",
- "libcutils",
- "libutils",
"libbinder",
"libbinder_ndk",
//"libsonivox",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "framework-permission-aidl-cpp",
"libandroidicu",
- "libexpat",
- "libcamera_client",
- "libstagefright_foundation",
- "libgui",
- "libdl",
"libaudioclient",
+ "libaudiofoundation",
+ "libcamera_client",
+ "libdl",
+ "libexpat",
+ "libgui",
"libmedia_codeclist",
"libmedia_omx",
- "framework-permission-aidl-cpp",
+ "libstagefright_foundation",
],
export_shared_lib_headers: [
"libaudioclient",
+ "libaudiofoundation",
"libbinder",
//"libsonivox",
- "libmedia_omx",
"framework-permission-aidl-cpp",
+ "libmedia_omx",
],
static_libs: [
- "resourcemanager_aidl_interface-ndk",
"framework-permission-aidl-cpp",
+ "resourcemanager_aidl_interface-ndk",
],
export_static_lib_headers: [
- "resourcemanager_aidl_interface-ndk",
"framework-permission-aidl-cpp",
+ "resourcemanager_aidl_interface-ndk",
],
export_include_dirs: [
@@ -439,17 +441,17 @@
],
cflags: [
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
],
version_script: "exports.lds",
sanitize: {
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
cfi: true,
},
@@ -461,8 +463,8 @@
host_supported: true,
srcs: [
- "NdkMediaFormatPriv.cpp",
"NdkMediaErrorPriv.cpp",
+ "NdkMediaFormatPriv.cpp",
],
header_libs: [
@@ -473,8 +475,8 @@
cflags: [
"-DEXPORT=__attribute__((visibility(\"default\")))",
- "-Werror",
"-Wall",
+ "-Werror",
],
export_include_dirs: ["include"],
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index c9f361e..4967dda 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -567,23 +567,24 @@
return reply.readInt32();
}
- status_t getRoutedDeviceId(audio_port_handle_t* deviceId)
+ status_t getRoutedDeviceIds(DeviceIdVector& deviceIds)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+ deviceIds.clear();
- status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply);
+ status_t status = remote()->transact(GET_ROUTED_DEVICE_IDS, data, &reply);
if (status != OK) {
- ALOGE("getRoutedDeviceid: binder call failed: %d", status);
- *deviceId = AUDIO_PORT_HANDLE_NONE;
+ ALOGE("getRoutedDeviceIds: binder call failed: %d", status);
return status;
}
status = reply.readInt32();
- if (status != NO_ERROR) {
- *deviceId = AUDIO_PORT_HANDLE_NONE;
- } else {
- *deviceId = reply.readInt32();
+ if (status == NO_ERROR) {
+ int size = reply.readInt32();
+ for (int i = 0; i < size; i++) {
+ deviceIds.push_back(reply.readInt32());
+ }
}
return status;
}
@@ -983,13 +984,16 @@
}
return NO_ERROR;
}
- case GET_ROUTED_DEVICE_ID: {
+ case GET_ROUTED_DEVICE_IDS: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
- audio_port_handle_t deviceId;
- status_t ret = getRoutedDeviceId(&deviceId);
+ DeviceIdVector deviceIds;
+ status_t ret = getRoutedDeviceIds(deviceIds);
reply->writeInt32(ret);
if (ret == NO_ERROR) {
- reply->writeInt32(deviceId);
+ reply->writeInt32(deviceIds.size());
+ for (auto deviceId : deviceIds) {
+ reply->writeInt32(deviceId);
+ }
}
return NO_ERROR;
} break;
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 755a147..1f04217 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -62,7 +62,7 @@
RESUME,
GET_METRICS,
SET_INPUT_DEVICE,
- GET_ROUTED_DEVICE_ID,
+ GET_ROUTED_DEVICE_IDS,
ENABLE_AUDIO_DEVICE_CALLBACK,
GET_ACTIVE_MICROPHONES,
GET_PORT_ID,
@@ -392,24 +392,24 @@
return reply.readInt32();;
}
- audio_port_handle_t getRoutedDeviceId(audio_port_handle_t *deviceId)
+ status_t getRoutedDeviceIds(DeviceIdVector& deviceIds)
{
- ALOGV("getRoutedDeviceId");
Parcel data, reply;
data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+ deviceIds.clear();
- status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply);
+ status_t status = remote()->transact(GET_ROUTED_DEVICE_IDS, data, &reply);
if (status != OK) {
- ALOGE("getRoutedDeviceid binder call failed: %d", status);
- *deviceId = AUDIO_PORT_HANDLE_NONE;
+ ALOGE("getRoutedDeviceIds: binder call failed: %d", status);
return status;
}
status = reply.readInt32();
- if (status != NO_ERROR) {
- *deviceId = AUDIO_PORT_HANDLE_NONE;
- } else {
- *deviceId = reply.readInt32();
+ if (status == NO_ERROR) {
+ int size = reply.readInt32();
+ for (int i = 0; i < size; i++) {
+ deviceIds.push_back(reply.readInt32());
+ }
}
return status;
}
@@ -730,14 +730,17 @@
}
return NO_ERROR;
} break;
- case GET_ROUTED_DEVICE_ID: {
- ALOGV("GET_ROUTED_DEVICE_ID");
+ case GET_ROUTED_DEVICE_IDS: {
+ ALOGV("GET_ROUTED_DEVICE_IDS");
CHECK_INTERFACE(IMediaRecorder, data, reply);
- audio_port_handle_t deviceId;
- status_t status = getRoutedDeviceId(&deviceId);
- reply->writeInt32(status);
- if (status == NO_ERROR) {
- reply->writeInt32(deviceId);
+ DeviceIdVector deviceIds;
+ status_t ret = getRoutedDeviceIds(deviceIds);
+ reply->writeInt32(ret);
+ if (ret == NO_ERROR) {
+ reply->writeInt32(deviceIds.size());
+ for (auto deviceId : deviceIds) {
+ reply->writeInt32(deviceId);
+ }
}
return NO_ERROR;
} break;
diff --git a/media/libmedia/include/media/IMediaPlayer.h b/media/libmedia/include/media/IMediaPlayer.h
index 28684d1..4c6f32c 100644
--- a/media/libmedia/include/media/IMediaPlayer.h
+++ b/media/libmedia/include/media/IMediaPlayer.h
@@ -23,6 +23,7 @@
#include <utils/KeyedVector.h>
#include <system/audio.h>
+#include <media/AudioContainers.h>
#include <media/AudioResamplerPublic.h>
#include <media/stagefright/MediaSource.h>
#include <media/VolumeShaper.h>
@@ -135,7 +136,7 @@
// AudioRouting
virtual status_t setOutputDevice(audio_port_handle_t deviceId) = 0;
- virtual status_t getRoutedDeviceId(audio_port_handle_t *deviceId) = 0;
+ virtual status_t getRoutedDeviceIds(DeviceIdVector& deviceIds) = 0;
virtual status_t enableAudioDeviceCallback(bool enabled) = 0;
protected:
@@ -184,7 +185,7 @@
RELEASE_DRM,
// AudioRouting
SET_OUTPUT_DEVICE,
- GET_ROUTED_DEVICE_ID,
+ GET_ROUTED_DEVICE_IDS,
ENABLE_AUDIO_DEVICE_CALLBACK,
};
};
diff --git a/media/libmedia/include/media/IMediaRecorder.h b/media/libmedia/include/media/IMediaRecorder.h
index 05da5c2..8411ca7 100644
--- a/media/libmedia/include/media/IMediaRecorder.h
+++ b/media/libmedia/include/media/IMediaRecorder.h
@@ -20,6 +20,7 @@
#include <android/media/MicrophoneInfoFw.h>
#include <binder/IInterface.h>
+#include <media/AudioContainers.h>
#include <system/audio.h>
#include <vector>
@@ -71,7 +72,7 @@
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() = 0;
virtual status_t setInputDevice(audio_port_handle_t deviceId) = 0;
- virtual status_t getRoutedDeviceId(audio_port_handle_t *deviceId) = 0;
+ virtual status_t getRoutedDeviceIds(DeviceIdVector& deviceIds) = 0;
virtual status_t enableAudioDeviceCallback(bool enabled) = 0;
virtual status_t getActiveMicrophones(
std::vector<media::MicrophoneInfoFw>* activeMicrophones) = 0;
diff --git a/media/libmedia/include/media/MediaRecorderBase.h b/media/libmedia/include/media/MediaRecorderBase.h
index 82ec9c5..e3698e3 100644
--- a/media/libmedia/include/media/MediaRecorderBase.h
+++ b/media/libmedia/include/media/MediaRecorderBase.h
@@ -69,7 +69,7 @@
virtual status_t setInputSurface(const sp<PersistentSurface>& surface) = 0;
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const = 0;
virtual status_t setInputDevice(audio_port_handle_t deviceId) = 0;
- virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId) = 0;
+ virtual status_t getRoutedDeviceIds(DeviceIdVector& deviceIds) = 0;
virtual void setAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback) = 0;
virtual status_t enableAudioDeviceCallback(bool enabled) = 0;
virtual status_t getActiveMicrophones(
diff --git a/media/libmedia/include/media/mediaplayer.h b/media/libmedia/include/media/mediaplayer.h
index 2f9b85e..7c612c3 100644
--- a/media/libmedia/include/media/mediaplayer.h
+++ b/media/libmedia/include/media/mediaplayer.h
@@ -281,7 +281,7 @@
status_t releaseDrm();
// AudioRouting
status_t setOutputDevice(audio_port_handle_t deviceId);
- audio_port_handle_t getRoutedDeviceId();
+ status_t getRoutedDeviceIds(DeviceIdVector& deviceIds);
status_t enableAudioDeviceCallback(bool enabled);
private:
diff --git a/media/libmedia/include/media/mediarecorder.h b/media/libmedia/include/media/mediarecorder.h
index 602f72e..1377d61 100644
--- a/media/libmedia/include/media/mediarecorder.h
+++ b/media/libmedia/include/media/mediarecorder.h
@@ -22,6 +22,7 @@
#include <utils/threads.h>
#include <utils/List.h>
#include <utils/Errors.h>
+#include <media/AudioContainers.h>
#include <media/IMediaRecorderClient.h>
#include <media/IMediaDeathNotifier.h>
#include <android/media/MicrophoneInfoFw.h>
@@ -266,7 +267,7 @@
sp<IGraphicBufferProducer> querySurfaceMediaSourceFromMediaServer();
status_t getMetrics(Parcel *reply);
status_t setInputDevice(audio_port_handle_t deviceId);
- status_t getRoutedDeviceId(audio_port_handle_t *deviceId);
+ status_t getRoutedDeviceIds(DeviceIdVector& deviceIds);
status_t enableAudioDeviceCallback(bool enabled);
status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw>* activeMicrophones);
status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index b5c75b3..9d3fce7 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -1105,19 +1105,14 @@
return mPlayer->setOutputDevice(deviceId);
}
-audio_port_handle_t MediaPlayer::getRoutedDeviceId()
+status_t MediaPlayer::getRoutedDeviceIds(DeviceIdVector& deviceIds)
{
Mutex::Autolock _l(mLock);
if (mPlayer == NULL) {
- ALOGV("getRoutedDeviceId: player not init");
- return AUDIO_PORT_HANDLE_NONE;
+ ALOGV("getRoutedDeviceIds: player not init");
+ return NO_INIT;
}
- audio_port_handle_t deviceId;
- status_t status = mPlayer->getRoutedDeviceId(&deviceId);
- if (status != NO_ERROR) {
- return AUDIO_PORT_HANDLE_NONE;
- }
- return deviceId;
+ return mPlayer->getRoutedDeviceIds(deviceIds);
}
status_t MediaPlayer::enableAudioDeviceCallback(bool enabled)
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 48f5e4b..e676d5a 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -858,17 +858,17 @@
return mMediaRecorder->setInputDevice(deviceId);
}
-status_t MediaRecorder::getRoutedDeviceId(audio_port_handle_t* deviceId)
+status_t MediaRecorder::getRoutedDeviceIds(DeviceIdVector& deviceIds)
{
- ALOGV("getRoutedDeviceId");
+ ALOGV("getRoutedDeviceIds");
if (mMediaRecorder == NULL) {
ALOGE("media recorder is not initialized yet");
return INVALID_OPERATION;
}
- status_t status = mMediaRecorder->getRoutedDeviceId(deviceId);
+ status_t status = mMediaRecorder->getRoutedDeviceIds(deviceIds);
if (status != NO_ERROR) {
- *deviceId = AUDIO_PORT_HANDLE_NONE;
+ deviceIds.clear();
}
return status;
}