Merge "Use routed devices throughout the audio framework" into main
diff --git a/media/libaaudio/fuzzer/Android.bp b/media/libaaudio/fuzzer/Android.bp
index 3b50744..5b48401 100644
--- a/media/libaaudio/fuzzer/Android.bp
+++ b/media/libaaudio/fuzzer/Android.bp
@@ -60,6 +60,7 @@
"libaaudio",
"libaaudio_internal",
"libaudioclient",
+ "libaudiofoundation",
"libaudioutils",
"libbase_ndk",
"libcutils",
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index e19d526..136edcc 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -1909,11 +1909,33 @@
* Available since API level 26.
*
* @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return actual device ID
+ * @return actual device id. If there are multiple device ids used, the first device picked by
+ * the audio policy engine will be returned.
*/
AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* _Nonnull stream) __INTRODUCED_IN(26);
/**
+ * Available since API level 36.
+ *
+ * Call this function after AAudioStreamBuilder_openStream().
+ * This function will crash if stream is null.
+ * An array of size 16 should generally be large enough to fit all device identifiers.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream().
+ * @param ids reference to an array of ids.
+ * @params numIds size allocated to the array of ids.
+ * The input should be the size of the ids array.
+ * The output will be the actual number of device ids.
+ * @return {@link #AAUDIO_OK} or an error code.
+ * If numIds is null, return {@link #AAUDIO_ERROR_ILLEGAL_ARGUMENT}.
+ * If numIds is smaller than the number of device ids, return
+ * {@link #AAUDIO_ERROR_OUT_OF_RANGE}. The value of numIds will still be updated.
+ * Otherwise, if ids is null, return {@link #AAUDIO_ERROR_ILLEGAL_ARGUMENT}.
+ */
+AAUDIO_API aaudio_result_t AAudioStream_getDeviceIds(AAudioStream* _Nonnull stream,
+ int32_t* _Nonnull ids, int32_t* _Nonnull numIds) __INTRODUCED_IN(36);
+
+/**
* Available since API level 26.
*
* @param stream reference provided by AAudioStreamBuilder_openStream()
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index ebb7637..cccb096 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -103,6 +103,7 @@
"framework-permission-aidl-cpp",
"libaaudio_internal",
"libaudioclient",
+ "libaudiofoundation",
"libaudioutils",
"libbinder",
"libcutils",
@@ -166,6 +167,7 @@
"framework-permission-aidl-cpp",
"libaudioclient",
"libaudioclient_aidl_conversion",
+ "libaudiofoundation",
"libaudioutils",
"libbinder",
"libcutils",
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
index c53a897..37c1a98 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
@@ -34,7 +34,16 @@
AAudioStreamConfiguration::AAudioStreamConfiguration(const StreamParameters& parcelable) {
setChannelMask(parcelable.channelMask);
setSampleRate(parcelable.sampleRate);
- setDeviceId(parcelable.deviceId);
+ auto deviceIds = android::convertContainer<android::DeviceIdVector>(
+ parcelable.deviceIds, android::aidl2legacy_int32_t_audio_port_handle_t);
+ if (deviceIds.ok()) {
+ setDeviceIds(deviceIds.value());
+ } else {
+ ALOGE("deviceIds (%s) aidl2legacy conversion failed",
+ android::toString(parcelable.deviceIds).c_str());
+ android::DeviceIdVector emptyDeviceIds;
+ setDeviceIds(emptyDeviceIds);
+ }
static_assert(sizeof(aaudio_sharing_mode_t) == sizeof(parcelable.sharingMode));
setSharingMode(parcelable.sharingMode);
auto convFormat = android::aidl2legacy_AudioFormatDescription_audio_format_t(
@@ -87,7 +96,15 @@
StreamParameters result;
result.channelMask = getChannelMask();
result.sampleRate = getSampleRate();
- result.deviceId = getDeviceId();
+ auto deviceIds = android::convertContainer<std::vector<int32_t>>(
+ getDeviceIds(), android::legacy2aidl_audio_port_handle_t_int32_t);
+ if (deviceIds.ok()) {
+ result.deviceIds = deviceIds.value();
+ } else {
+ ALOGE("deviceIds (%s) legacy2aidl conversion failed",
+ android::toString(getDeviceIds()).c_str());
+ result.deviceIds = {};
+ }
static_assert(sizeof(aaudio_sharing_mode_t) == sizeof(result.sharingMode));
result.sharingMode = getSharingMode();
auto convAudioFormat = android::legacy2aidl_audio_format_t_AudioFormatDescription(getFormat());
diff --git a/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl b/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl
index a301da8..7d7abce 100644
--- a/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl
+++ b/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl
@@ -21,7 +21,7 @@
parcelable StreamParameters {
int channelMask; // = AAUDIO_UNSPECIFIED;
int sampleRate; // = AAUDIO_UNSPECIFIED;
- int deviceId; // = AAUDIO_UNSPECIFIED;
+ int[] deviceIds; // = null;
int /* aaudio_sharing_mode_t */ sharingMode; // = AAUDIO_SHARING_MODE_SHARED;
AudioFormatDescription audioFormat; // = AUDIO_FORMAT_DEFAULT;
int /* aaudio_direction_t */ direction; // = AAUDIO_DIRECTION_OUTPUT;
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 99b90e2..6bc7dc2 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -121,7 +121,7 @@
request.setSharingModeMatchRequired(isSharingModeMatchRequired());
request.setInService(isInService());
- request.getConfiguration().setDeviceId(getDeviceId());
+ request.getConfiguration().setDeviceIds(getDeviceIds());
request.getConfiguration().setSampleRate(getSampleRate());
request.getConfiguration().setDirection(getDirection());
request.getConfiguration().setSharingMode(getSharingMode());
@@ -180,7 +180,7 @@
setChannelMask(configurationOutput.getChannelMask());
}
- setDeviceId(configurationOutput.getDeviceId());
+ setDeviceIds(configurationOutput.getDeviceIds());
setSessionId(configurationOutput.getSessionId());
setSharingMode(configurationOutput.getSharingMode());
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index fb87dd9..64152f0 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -95,7 +95,11 @@
int32_t deviceId)
{
AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
- streamBuilder->setDeviceId(deviceId);
+ android::DeviceIdVector deviceIds;
+ if (deviceId != AAUDIO_UNSPECIFIED) {
+ deviceIds.push_back(deviceId);
+ }
+ streamBuilder->setDeviceIds(deviceIds);
}
AAUDIO_API void AAudioStreamBuilder_setPackageName(AAudioStreamBuilder* builder,
@@ -537,7 +541,33 @@
AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream)
{
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
- return audioStream->getDeviceId();
+ auto deviceIds = audioStream->getDeviceIds();
+ if (deviceIds.empty()) {
+ return AAUDIO_UNSPECIFIED;
+ }
+ return deviceIds[0];
+}
+
+AAUDIO_API aaudio_result_t AAudioStream_getDeviceIds(AAudioStream* stream, int32_t* ids,
+ int32_t* numIds)
+{
+ if (numIds == nullptr) {
+ return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ }
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ auto deviceIds = audioStream->getDeviceIds();
+ if (*numIds < deviceIds.size()) {
+ *numIds = deviceIds.size();
+ return AAUDIO_ERROR_OUT_OF_RANGE;
+ }
+ if (ids == nullptr) {
+ return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+ }
+ for (int i = 0; i < deviceIds.size(); i++) {
+ ids[i] = deviceIds[i];
+ }
+ *numIds = deviceIds.size();
+ return AAUDIO_OK;
}
AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream)
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index 056918a..f504fa9 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -27,7 +27,7 @@
void AAudioStreamParameters::copyFrom(const AAudioStreamParameters &other) {
mSamplesPerFrame = other.mSamplesPerFrame;
mSampleRate = other.mSampleRate;
- mDeviceId = other.mDeviceId;
+ mDeviceIds = other.mDeviceIds;
mSessionId = other.mSessionId;
mSharingMode = other.mSharingMode;
mAudioFormat = other.mAudioFormat;
@@ -74,9 +74,13 @@
return AAUDIO_ERROR_OUT_OF_RANGE;
}
- if (mDeviceId < 0) {
- ALOGD("deviceId out of range = %d", mDeviceId);
- return AAUDIO_ERROR_OUT_OF_RANGE;
+ // TODO(b/379139078): Query AudioSystem::listAudioPorts
+ for (auto deviceId : mDeviceIds) {
+ if (deviceId < 0) {
+ ALOGE("deviceId out of range = %d, deviceIds = %s", deviceId,
+ android::toString(mDeviceIds).c_str());
+ return AAUDIO_ERROR_OUT_OF_RANGE;
+ }
}
// All Session ID values are legal.
@@ -296,7 +300,7 @@
}
void AAudioStreamParameters::dump() const {
- ALOGD("mDeviceId = %6d", mDeviceId);
+ ALOGD("mDeviceIds = %s", android::toString(mDeviceIds).c_str());
ALOGD("mSessionId = %6d", mSessionId);
ALOGD("mSampleRate = %6d", mSampleRate);
ALOGD("mSamplesPerFrame = %6d", mSamplesPerFrame);
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.h b/media/libaaudio/src/core/AAudioStreamParameters.h
index cad27a7..c4c0a4f 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.h
+++ b/media/libaaudio/src/core/AAudioStreamParameters.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <aaudio/AAudio.h>
+#include <media/AudioContainers.h>
#include <utility/AAudioUtilities.h>
namespace aaudio {
@@ -29,12 +30,12 @@
AAudioStreamParameters() = default;
virtual ~AAudioStreamParameters() = default;
- int32_t getDeviceId() const {
- return mDeviceId;
+ android::DeviceIdVector getDeviceIds() const {
+ return mDeviceIds;
}
- void setDeviceId(int32_t deviceId) {
- mDeviceId = deviceId;
+ void setDeviceIds(const android::DeviceIdVector& deviceIds) {
+ mDeviceIds = deviceIds;
}
int32_t getSampleRate() const {
@@ -225,7 +226,7 @@
int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
int32_t mSampleRate = AAUDIO_UNSPECIFIED;
- int32_t mDeviceId = AAUDIO_UNSPECIFIED;
+ android::DeviceIdVector mDeviceIds;
aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
audio_format_t mAudioFormat = AUDIO_FORMAT_DEFAULT;
aaudio_direction_t mDirection = AAUDIO_DIRECTION_OUTPUT;
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index a75a2a1..8e3bcf7 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -79,7 +79,7 @@
mSamplesPerFrame = builder.getSamplesPerFrame();
mChannelMask = builder.getChannelMask();
mSampleRate = builder.getSampleRate();
- mDeviceId = builder.getDeviceId();
+ mDeviceIds = builder.getDeviceIds();
mFormat = builder.getFormat();
mSharingMode = builder.getSharingMode();
mSharingModeMatchRequired = builder.isSharingModeMatchRequired();
@@ -204,7 +204,7 @@
aaudio_result_t result = requestStart_l();
if (result == AAUDIO_OK) {
// We only call this for logging in "dumpsys audio". So ignore return code.
- (void) mPlayerBase->startWithStatus(getDeviceId());
+ (void) mPlayerBase->startWithStatus(getDeviceIds());
}
return result;
}
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 3271882..3354adf 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -27,6 +27,7 @@
#include <utils/StrongPointer.h>
#include <aaudio/AAudio.h>
+#include <media/AudioContainers.h>
#include <media/AudioSystem.h>
#include <media/PlayerBase.h>
#include <media/VolumeShaper.h>
@@ -268,8 +269,8 @@
mPerformanceMode = performanceMode;
}
- int32_t getDeviceId() const {
- return mDeviceId;
+ android::DeviceIdVector getDeviceIds() const {
+ return mDeviceIds;
}
aaudio_sharing_mode_t getSharingMode() const {
@@ -411,7 +412,7 @@
// Implement AudioDeviceCallback
void onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId) override {};
+ const android::DeviceIdVector& deviceIds) override {};
// ============== I/O ===========================
// A Stream will only implement read() or write() depending on its direction.
@@ -632,8 +633,8 @@
}
void setDisconnected();
- void setDeviceId(int32_t deviceId) {
- mDeviceId = deviceId;
+ void setDeviceIds(const android::DeviceIdVector& deviceIds) {
+ mDeviceIds = deviceIds;
}
// This should not be called after the open() call.
@@ -774,7 +775,7 @@
int32_t mSampleRate = AAUDIO_UNSPECIFIED;
int32_t mDeviceSampleRate = AAUDIO_UNSPECIFIED;
int32_t mHardwareSampleRate = AAUDIO_UNSPECIFIED;
- int32_t mDeviceId = AAUDIO_UNSPECIFIED;
+ android::DeviceIdVector mDeviceIds;
aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
bool mSharingModeMatchRequired = false; // must match sharing mode requested
audio_format_t mFormat = AUDIO_FORMAT_DEFAULT;
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index b0dc669..73bd69f 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -307,8 +307,8 @@
getSampleRate(), getSamplesPerFrame(), getChannelMask(), getFormat(),
AAudio_convertSharingModeToShortText(getSharingMode()),
AAudio_convertDirectionToText(getDirection()));
- ALOGI("device = %6d, sessionId = %d, perfMode = %d, callback: %s with frames = %d",
- getDeviceId(),
+ ALOGI("devices = %s, sessionId = %d, perfMode = %d, callback: %s with frames = %d",
+ android::toString(getDeviceIds()).c_str(),
getSessionId(),
getPerformanceMode(),
((getDataCallbackProc() != nullptr) ? "ON" : "OFF"),
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index 255bd0f..dfb9a01 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -260,36 +260,41 @@
}
void AudioStreamLegacy::onAudioDeviceUpdate(audio_io_handle_t /* audioIo */,
- audio_port_handle_t deviceId) {
- // Check for an invalid deviceId. Why change to UNSPECIFIED?
- if (deviceId == AAUDIO_UNSPECIFIED) {
- ALOGE("%s(, deviceId = AAUDIO_UNSPECIFIED)! Why?", __func__);
+ const android::DeviceIdVector& deviceIds) {
+ // Check for empty deviceIds. Callbacks for duplicating threads returns empty devices.
+ if (deviceIds.empty()) {
+ ALOGW("%s(empty deviceIds", __func__);
return;
}
+ android::DeviceIdVector oldDeviceIds = getDeviceIds();
// Device routing is a common source of errors and DISCONNECTS.
// Please leave this log in place. If there is a bug then this might
// get called after the stream has been deleted so log before we
// touch the stream object.
- ALOGD("%s(deviceId = %d)", __func__, (int)deviceId);
- if (getDeviceId() != AAUDIO_UNSPECIFIED
- && getDeviceId() != deviceId
+ ALOGD("%s() devices %s => %s",
+ __func__, android::toString(oldDeviceIds).c_str(),
+ android::toString(deviceIds).c_str());
+ if (!oldDeviceIds.empty()
+ && !android::areDeviceIdsEqual(oldDeviceIds, deviceIds)
&& !isDisconnected()
) {
// Note that isDataCallbackActive() is affected by state so call it before DISCONNECTING.
// If we have a data callback and the stream is active, then ask the data callback
// to DISCONNECT and call the error callback.
if (isDataCallbackActive()) {
- ALOGD("%s() request DISCONNECT in data callback, device %d => %d",
- __func__, (int) getDeviceId(), (int) deviceId);
+ ALOGD("%s() request DISCONNECT in data callback, devices %s => %s",
+ __func__, android::toString(oldDeviceIds).c_str(),
+ android::toString(deviceIds).c_str());
// If the stream is stopped before the data callback has a chance to handle the
// request then the requestStop_l() and requestPause() methods will handle it after
// the callback has stopped.
mRequestDisconnect.request();
} else {
- ALOGD("%s() DISCONNECT the stream now, device %d => %d",
- __func__, (int) getDeviceId(), (int) deviceId);
+ ALOGD("%s() DISCONNECT the stream now, devices %s => %s",
+ __func__, android::toString(oldDeviceIds).c_str(),
+ android::toString(deviceIds).c_str());
forceDisconnect();
}
}
- setDeviceId(deviceId);
+ setDeviceIds(deviceIds);
}
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.h b/media/libaaudio/src/legacy/AudioStreamLegacy.h
index 53f6e06..a729161 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.h
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.h
@@ -95,7 +95,7 @@
android::ExtendedTimestamp *extendedTimestamp);
void onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId) override;
+ const android::DeviceIdVector& deviceIds) override;
/*
* Check to see whether a callback thread has requested a disconnected.
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index fe4bf2c..1591f7d 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -112,9 +112,7 @@
mCallbackBufferSize = builder.getFramesPerDataCallback();
// Don't call mAudioRecord->setInputDevice() because it will be overwritten by set()!
- audio_port_handle_t selectedDeviceId = (getDeviceId() == AAUDIO_UNSPECIFIED)
- ? AUDIO_PORT_HANDLE_NONE
- : getDeviceId();
+ audio_port_handle_t selectedDeviceId = getFirstDeviceId(getDeviceIds());
const audio_content_type_t contentType =
AAudioConvert_contentTypeToInternal(builder.getContentType());
@@ -198,7 +196,8 @@
AudioGlobal_convertPerformanceModeToText(builder.getPerformanceMode()))
.set(AMEDIAMETRICS_PROP_SHARINGMODE,
AudioGlobal_convertSharingModeToText(builder.getSharingMode()))
- .set(AMEDIAMETRICS_PROP_ENCODINGCLIENT, toString(requestedFormat).c_str()).record();
+ .set(AMEDIAMETRICS_PROP_ENCODINGCLIENT,
+ android::toString(requestedFormat).c_str()).record();
// Get the actual values from the AudioRecord.
setChannelMask(AAudioConvert_androidToAAudioChannelMask(
@@ -275,7 +274,7 @@
perfMode, actualPerformanceMode);
setState(AAUDIO_STREAM_STATE_OPEN);
- setDeviceId(mAudioRecord->getRoutedDeviceId());
+ setDeviceIds(mAudioRecord->getRoutedDeviceIds());
aaudio_session_id_t actualSessionId =
(requestedSessionId == AAUDIO_SESSION_ID_NONE)
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 16c0bcd..2e57f0d 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -132,9 +132,7 @@
notificationFrames, (uint)frameCount);
// Don't call mAudioTrack->setDeviceId() because it will be overwritten by set()!
- audio_port_handle_t selectedDeviceId = (getDeviceId() == AAUDIO_UNSPECIFIED)
- ? AUDIO_PORT_HANDLE_NONE
- : getDeviceId();
+ audio_port_handle_t selectedDeviceId = getFirstDeviceId(getDeviceIds());
const audio_content_type_t contentType =
AAudioConvert_contentTypeToInternal(builder.getContentType());
@@ -197,7 +195,8 @@
AudioGlobal_convertPerformanceModeToText(builder.getPerformanceMode()))
.set(AMEDIAMETRICS_PROP_SHARINGMODE,
AudioGlobal_convertSharingModeToText(builder.getSharingMode()))
- .set(AMEDIAMETRICS_PROP_ENCODINGCLIENT, toString(getFormat()).c_str()).record();
+ .set(AMEDIAMETRICS_PROP_ENCODINGCLIENT,
+ android::toString(getFormat()).c_str()).record();
doSetVolume();
@@ -233,7 +232,7 @@
mBlockAdapter = nullptr;
}
- setDeviceId(mAudioTrack->getRoutedDeviceId());
+ setDeviceIds(mAudioTrack->getRoutedDeviceIds());
aaudio_session_id_t actualSessionId =
(requestedSessionId == AAUDIO_SESSION_ID_NONE)
@@ -317,7 +316,7 @@
if (mAudioTrack->channelCount() != getSamplesPerFrame()
|| mAudioTrack->format() != getFormat()
|| mAudioTrack->getSampleRate() != getSampleRate()
- || mAudioTrack->getRoutedDeviceId() != getDeviceId()
+ || !areDeviceIdsEqual(mAudioTrack->getRoutedDeviceIds(), getDeviceIds())
|| getBufferCapacityFromDevice() != getBufferCapacity()
|| getFramesPerBurstFromDevice() != getFramesPerBurst()) {
AudioStreamLegacy::onNewIAudioTrack();
diff --git a/media/libaaudio/src/libaaudio.map.txt b/media/libaaudio/src/libaaudio.map.txt
index 13c19a1..36d76aa 100644
--- a/media/libaaudio/src/libaaudio.map.txt
+++ b/media/libaaudio/src/libaaudio.map.txt
@@ -72,6 +72,7 @@
AAudioStream_getHardwareSampleRate; # introduced=UpsideDownCake
AAudio_getPlatformMMapPolicy; # introduced=36
AAudio_getPlatformMMapExclusivePolicy; #introduced=36
+ AAudioStream_getDeviceIds; # introduced=36
AAudioStreamBuilder_setTags; # systemapi
AAudioStream_getTags; # systemapi
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 1e6be68..9a4b45d 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -731,7 +731,7 @@
mSelectedDeviceId = deviceId;
if (mStatus == NO_ERROR) {
if (mActive) {
- if (mSelectedDeviceId != mRoutedDeviceId) {
+ if (getFirstDeviceId(mRoutedDeviceIds) != mSelectedDeviceId) {
// stop capture so that audio policy manager does not reject the new instance
// start request as only one capture can be active at a time.
if (mAudioRecord != 0) {
@@ -758,7 +758,7 @@
}
// must be called with mLock held
-void AudioRecord::updateRoutedDeviceId_l()
+void AudioRecord::updateRoutedDeviceIds_l()
{
// if the record is inactive, do not update actual device as the input stream maybe routed
// from a device not relevant to this client because of other active use cases.
@@ -766,17 +766,21 @@
return;
}
if (mInput != AUDIO_IO_HANDLE_NONE) {
- audio_port_handle_t deviceId = AudioSystem::getDeviceIdForIo(mInput);
- if (deviceId != AUDIO_PORT_HANDLE_NONE) {
- mRoutedDeviceId = deviceId;
+ DeviceIdVector deviceIds;
+ status_t result = AudioSystem::getDeviceIdsForIo(mInput, deviceIds);
+ if (result != OK) {
+ ALOGW("%s: getDeviceIdsForIo returned: %d", __func__, result);
+ }
+ if (!deviceIds.empty()) {
+ mRoutedDeviceIds = deviceIds;
}
}
}
-audio_port_handle_t AudioRecord::getRoutedDeviceId() {
+DeviceIdVector AudioRecord::getRoutedDeviceIds() {
AutoMutex lock(mLock);
- updateRoutedDeviceId_l();
- return mRoutedDeviceId;
+ updateRoutedDeviceIds_l();
+ return mRoutedDeviceIds;
}
status_t AudioRecord::dump(int fd, const Vector<String16>& args __unused) const
@@ -794,10 +798,11 @@
mFrameCount, mReqFrameCount);
result.appendFormat(" notif. frame count(%u), req. notif. frame count(%u)\n",
mNotificationFramesAct, mNotificationFramesReq);
- result.appendFormat(" input(%d), latency(%u), selected device Id(%d), routed device Id(%d)\n",
- mInput, mLatency, mSelectedDeviceId, mRoutedDeviceId);
- result.appendFormat(" mic direction(%d) mic field dimension(%f)",
- mSelectedMicDirection, mSelectedMicFieldDimension);
+ result.appendFormat(" input(%d), latency(%u), selected device Id(%d)\n",
+ mInput, mLatency, mSelectedDeviceId);
+ result.appendFormat(" routed device Ids(%s), mic direction(%d) mic field dimension(%f)",
+ toString(mRoutedDeviceIds).c_str(), mSelectedMicDirection,
+ mSelectedMicFieldDimension);
::write(fd, result.c_str(), result.size());
return NO_ERROR;
}
@@ -940,7 +945,7 @@
mAwaitBoost = true;
}
mFlags = output.flags;
- mRoutedDeviceId = output.selectedDeviceId;
+ mRoutedDeviceIds = { output.selectedDeviceId };
mSessionId = output.sessionId;
mSampleRate = output.sampleRate;
mServerConfig = output.serverConfig;
@@ -1063,7 +1068,8 @@
.set(AMEDIAMETRICS_PROP_SOURCE, toString(mAttributes.source).c_str())
.set(AMEDIAMETRICS_PROP_THREADID, (int32_t)output.inputId)
.set(AMEDIAMETRICS_PROP_SELECTEDDEVICEID, (int32_t)mSelectedDeviceId)
- .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEID, (int32_t)mRoutedDeviceId)
+ .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEID, (int32_t)(getFirstDeviceId(mRoutedDeviceIds)))
+ .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEIDS, toString(mRoutedDeviceIds).c_str())
.set(AMEDIAMETRICS_PROP_ENCODING, toString(mFormat).c_str())
.set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
.set(AMEDIAMETRICS_PROP_FRAMECOUNT, (int32_t)mFrameCount)
@@ -1656,7 +1662,7 @@
}
void AudioRecord::onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId)
+ const DeviceIdVector& deviceIds)
{
sp<AudioSystem::AudioDeviceCallback> callback;
{
@@ -1668,11 +1674,11 @@
// only update device if the record is active as route changes due to other use cases are
// irrelevant for this client
if (mActive) {
- mRoutedDeviceId = deviceId;
+ mRoutedDeviceIds = deviceIds;
}
}
if (callback.get() != nullptr) {
- callback->onAudioDeviceUpdate(mInput, mRoutedDeviceId);
+ callback->onAudioDeviceUpdate(mInput, mRoutedDeviceIds);
}
}
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 47d5dd5..b8dadb4 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -683,7 +683,7 @@
if (ioDesc->getIoHandle() == AUDIO_IO_HANDLE_NONE) return Status::ok();
- audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector deviceIds;
std::vector<sp<AudioDeviceCallback>> callbacksToCall;
{
std::lock_guard _l(mMutex);
@@ -695,12 +695,12 @@
case AUDIO_INPUT_OPENED:
case AUDIO_INPUT_REGISTERED: {
if (sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->getIoHandle())) {
- deviceId = oldDesc->getDeviceId();
+ deviceIds = oldDesc->getDeviceIds();
}
mIoDescriptors[ioDesc->getIoHandle()] = ioDesc;
- if (ioDesc->getDeviceId() != AUDIO_PORT_HANDLE_NONE) {
- deviceId = ioDesc->getDeviceId();
+ if (!ioDesc->getDeviceIds().empty()) {
+ deviceIds = ioDesc->getDeviceIds();
if (event == AUDIO_OUTPUT_OPENED || event == AUDIO_INPUT_OPENED) {
auto it = mAudioDeviceCallbacks.find(ioDesc->getIoHandle());
if (it != mAudioDeviceCallbacks.end()) {
@@ -741,11 +741,12 @@
break;
}
- deviceId = oldDesc->getDeviceId();
+ deviceIds = oldDesc->getDeviceIds();
mIoDescriptors[ioDesc->getIoHandle()] = ioDesc;
- if (deviceId != ioDesc->getDeviceId()) {
- deviceId = ioDesc->getDeviceId();
+ DeviceIdVector ioDescDeviceIds = ioDesc->getDeviceIds();
+ if (!areDeviceIdsEqual(deviceIds, ioDescDeviceIds)) {
+ deviceIds = ioDescDeviceIds;
auto it = mAudioDeviceCallbacks.find(ioDesc->getIoHandle());
if (it != mAudioDeviceCallbacks.end()) {
callbacks = it->second;
@@ -773,7 +774,7 @@
auto it2 = cbks.find(ioDesc->getPortId());
if (it2 != cbks.end()) {
callbacks.emplace(ioDesc->getPortId(), it2->second);
- deviceId = oldDesc->getDeviceId();
+ deviceIds = oldDesc->getDeviceIds();
}
}
}
@@ -792,7 +793,7 @@
// example getRoutedDevice that updates the device and tries to acquire mMutex.
for (auto cb : callbacksToCall) {
// If callbacksToCall is not empty, it implies ioDesc->getIoHandle() and deviceId are valid
- cb->onAudioDeviceUpdate(ioDesc->getIoHandle(), deviceId);
+ cb->onAudioDeviceUpdate(ioDesc->getIoHandle(), deviceIds);
}
return Status::ok();
@@ -1964,14 +1965,16 @@
return afc->removeSupportedLatencyModesCallback(callback);
}
-audio_port_handle_t AudioSystem::getDeviceIdForIo(audio_io_handle_t audioIo) {
+status_t AudioSystem::getDeviceIdsForIo(audio_io_handle_t audioIo, DeviceIdVector& deviceIds) {
const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) return AudioFlingerServiceTraits::getError();
const sp<AudioIoDescriptor> desc = getIoDescriptor(audioIo);
if (desc == 0) {
- return AUDIO_PORT_HANDLE_NONE;
+ deviceIds.clear();
+ } else {
+ deviceIds = desc->getDeviceIds();
}
- return desc->getDeviceId();
+ return OK;
}
status_t AudioSystem::acquireSoundTriggerSession(audio_session_t* session,
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index a9409eb..3591fbf 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1736,7 +1736,7 @@
// allow track invalidation when track is not playing to propagate
// the updated mSelectedDeviceId
if (isPlaying_l()) {
- if (mSelectedDeviceId != mRoutedDeviceId) {
+ if (getFirstDeviceId(mRoutedDeviceIds) != mSelectedDeviceId) {
android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
mProxy->interrupt();
}
@@ -1759,7 +1759,7 @@
}
// must be called with mLock held
-void AudioTrack::updateRoutedDeviceId_l()
+void AudioTrack::updateRoutedDeviceIds_l()
{
// if the track is inactive, do not update actual device as the output stream maybe routed
// to a device not relevant to this client because of other active use cases.
@@ -1767,17 +1767,21 @@
return;
}
if (mOutput != AUDIO_IO_HANDLE_NONE) {
- audio_port_handle_t deviceId = AudioSystem::getDeviceIdForIo(mOutput);
- if (deviceId != AUDIO_PORT_HANDLE_NONE) {
- mRoutedDeviceId = deviceId;
+ DeviceIdVector deviceIds;
+ status_t result = AudioSystem::getDeviceIdsForIo(mOutput, deviceIds);
+ if (result != OK) {
+ ALOGW("%s: getDeviceIdsForIo returned: %d", __func__, result);
+ }
+ if (!deviceIds.empty()) {
+ mRoutedDeviceIds = deviceIds;
}
}
}
-audio_port_handle_t AudioTrack::getRoutedDeviceId() {
+DeviceIdVector AudioTrack::getRoutedDeviceIds() {
AutoMutex lock(mLock);
- updateRoutedDeviceId_l();
- return mRoutedDeviceId;
+ updateRoutedDeviceIds_l();
+ return mRoutedDeviceIds;
}
status_t AudioTrack::attachAuxEffect(int effectId)
@@ -1937,7 +1941,7 @@
mFrameCount = output.frameCount;
mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
- mRoutedDeviceId = output.selectedDeviceId;
+ mRoutedDeviceIds = output.selectedDeviceIds;
mSessionId = output.sessionId;
mStreamType = output.streamType;
@@ -2106,7 +2110,8 @@
.set(AMEDIAMETRICS_PROP_USAGE, toString(mAttributes.usage).c_str())
.set(AMEDIAMETRICS_PROP_THREADID, (int32_t)output.outputId)
.set(AMEDIAMETRICS_PROP_SELECTEDDEVICEID, (int32_t)mSelectedDeviceId)
- .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEID, (int32_t)mRoutedDeviceId)
+ .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEID, (int32_t)(getFirstDeviceId(mRoutedDeviceIds)))
+ .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEIDS, toString(mRoutedDeviceIds).c_str())
.set(AMEDIAMETRICS_PROP_ENCODING, toString(mFormat).c_str())
.set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
.set(AMEDIAMETRICS_PROP_FRAMECOUNT, (int32_t)mFrameCount)
@@ -3555,8 +3560,8 @@
result.appendFormat(" notif. frame count(%u), req. notif. frame count(%u),"
" req. notif. per buff(%u)\n",
mNotificationFramesAct, mNotificationFramesReq, mNotificationsPerBufferReq);
- result.appendFormat(" latency (%d), selected device Id(%d), routed device Id(%d)\n",
- mLatency, mSelectedDeviceId, mRoutedDeviceId);
+ result.appendFormat(" latency (%d), selected device Id(%d), routed device Ids(%s)\n",
+ mLatency, mSelectedDeviceId, toString(mRoutedDeviceIds).c_str());
result.appendFormat(" output(%d) AF latency (%u) AF frame count(%zu) AF SampleRate(%u)\n",
mOutput, mAfLatency, mAfFrameCount, mAfSampleRate);
::write(fd, result.c_str(), result.size());
@@ -3623,7 +3628,7 @@
// first time when the track is created we do not have a valid piid
if (mPlayerIId != PLAYER_PIID_INVALID) {
- mAudioManager->playerEvent(mPlayerIId, PLAYER_UPDATE_PORT_ID, mPortId);
+ mAudioManager->playerEvent(mPlayerIId, PLAYER_UPDATE_PORT_ID, {mPortId});
}
}
@@ -3672,7 +3677,7 @@
void AudioTrack::onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId)
+ const DeviceIdVector& deviceIds)
{
sp<AudioSystem::AudioDeviceCallback> callback;
{
@@ -3684,12 +3689,12 @@
// only update device if the track is active as route changes due to other use cases are
// irrelevant for this client
if (mState == STATE_ACTIVE) {
- mRoutedDeviceId = deviceId;
+ mRoutedDeviceIds = deviceIds;
}
}
if (callback.get() != nullptr) {
- callback->onAudioDeviceUpdate(mOutput, mRoutedDeviceId);
+ callback->onAudioDeviceUpdate(mOutput, mRoutedDeviceIds);
}
}
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 168b47e..1523607 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -103,8 +103,8 @@
aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
aidl.frameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(frameCount));
aidl.notificationFrameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(notificationFrameCount));
- aidl.selectedDeviceId = VALUE_OR_RETURN(
- legacy2aidl_audio_port_handle_t_int32_t(selectedDeviceId));
+ aidl.selectedDeviceIds = VALUE_OR_RETURN(convertContainer<std::vector<int32_t>>(
+ selectedDeviceIds, legacy2aidl_audio_port_handle_t_int32_t));
aidl.sessionId = VALUE_OR_RETURN(legacy2aidl_audio_session_t_int32_t(sessionId));
aidl.sampleRate = VALUE_OR_RETURN(convertIntegral<int32_t>(sampleRate));
aidl.streamType = VALUE_OR_RETURN(
@@ -132,8 +132,8 @@
legacy.frameCount = VALUE_OR_RETURN(convertIntegral<size_t>(aidl.frameCount));
legacy.notificationFrameCount = VALUE_OR_RETURN(
convertIntegral<size_t>(aidl.notificationFrameCount));
- legacy.selectedDeviceId = VALUE_OR_RETURN(
- aidl2legacy_int32_t_audio_port_handle_t(aidl.selectedDeviceId));
+ legacy.selectedDeviceIds = VALUE_OR_RETURN(convertContainer<DeviceIdVector>(
+ aidl.selectedDeviceIds, aidl2legacy_int32_t_audio_port_handle_t));
legacy.sessionId = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_session_t(aidl.sessionId));
legacy.sampleRate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.sampleRate));
legacy.streamType = VALUE_OR_RETURN(
diff --git a/media/libaudioclient/PlayerBase.cpp b/media/libaudioclient/PlayerBase.cpp
index 651255a..5999040 100644
--- a/media/libaudioclient/PlayerBase.cpp
+++ b/media/libaudioclient/PlayerBase.cpp
@@ -30,8 +30,7 @@
PlayerBase::PlayerBase() : BnPlayer(),
mPanMultiplierL(1.0f), mPanMultiplierR(1.0f),
mVolumeMultiplierL(1.0f), mVolumeMultiplierR(1.0f),
- mPIId(PLAYER_PIID_INVALID), mLastReportedEvent(PLAYER_STATE_UNKNOWN),
- mLastReportedDeviceId(AUDIO_PORT_HANDLE_NONE)
+ mPIId(PLAYER_PIID_INVALID), mLastReportedEvent(PLAYER_STATE_UNKNOWN)
{
ALOGD("PlayerBase::PlayerBase()");
// use checkService() to avoid blocking if audio service is not up yet
@@ -68,7 +67,7 @@
}
if (mPIId != PLAYER_PIID_INVALID && portId != AUDIO_PORT_HANDLE_NONE) {
- mAudioManager->playerEvent(mPIId, android::PLAYER_UPDATE_PORT_ID, portId);
+ mAudioManager->playerEvent(mPIId, android::PLAYER_UPDATE_PORT_ID, { portId });
}
}
@@ -80,13 +79,13 @@
}
//------------------------------------------------------------------------------
-void PlayerBase::servicePlayerEvent(player_state_t event, audio_port_handle_t deviceId) {
+void PlayerBase::servicePlayerEvent(player_state_t event, const DeviceIdVector& deviceIds) {
if (mAudioManager != 0) {
bool changed = false;
{
Mutex::Autolock _l(mDeviceIdLock);
- changed = mLastReportedDeviceId != deviceId;
- mLastReportedDeviceId = deviceId;
+ changed = !areDeviceIdsEqual(deviceIds, mLastReportedDeviceIds);
+ mLastReportedDeviceIds = deviceIds;
}
{
@@ -99,7 +98,7 @@
}
}
if (changed && (mPIId != PLAYER_PIID_INVALID)) {
- mAudioManager->playerEvent(mPIId, event, deviceId);
+ mAudioManager->playerEvent(mPIId, event, deviceIds);
}
}
}
@@ -112,18 +111,18 @@
}
//FIXME temporary method while some player state is outside of this class
-void PlayerBase::reportEvent(player_state_t event, audio_port_handle_t deviceId) {
- servicePlayerEvent(event, deviceId);
+void PlayerBase::reportEvent(player_state_t event, const DeviceIdVector& deviceIds) {
+ servicePlayerEvent(event, deviceIds);
}
-void PlayerBase::baseUpdateDeviceId(audio_port_handle_t deviceId) {
- servicePlayerEvent(PLAYER_UPDATE_DEVICE_ID, deviceId);
+void PlayerBase::baseUpdateDeviceIds(const DeviceIdVector& deviceIds) {
+ servicePlayerEvent(PLAYER_UPDATE_DEVICE_ID, deviceIds);
}
-status_t PlayerBase::startWithStatus(audio_port_handle_t deviceId) {
+status_t PlayerBase::startWithStatus(const DeviceIdVector& deviceIds) {
status_t status = playerStart();
if (status == NO_ERROR) {
- servicePlayerEvent(PLAYER_STATE_STARTED, deviceId);
+ servicePlayerEvent(PLAYER_STATE_STARTED, deviceIds);
} else {
ALOGW("PlayerBase::start() error %d", status);
}
@@ -133,7 +132,7 @@
status_t PlayerBase::pauseWithStatus() {
status_t status = playerPause();
if (status == NO_ERROR) {
- servicePlayerEvent(PLAYER_STATE_PAUSED, AUDIO_PORT_HANDLE_NONE);
+ servicePlayerEvent(PLAYER_STATE_PAUSED, {});
} else {
ALOGW("PlayerBase::pause() error %d", status);
}
@@ -144,7 +143,7 @@
status_t status = playerStop();
if (status == NO_ERROR) {
- servicePlayerEvent(PLAYER_STATE_STOPPED, AUDIO_PORT_HANDLE_NONE);
+ servicePlayerEvent(PLAYER_STATE_STOPPED, {});
} else {
ALOGW("PlayerBase::stop() error %d", status);
}
@@ -155,12 +154,12 @@
// Implementation of IPlayer
binder::Status PlayerBase::start() {
ALOGD("PlayerBase::start() from IPlayer");
- audio_port_handle_t deviceId;
+ DeviceIdVector deviceIds;
{
Mutex::Autolock _l(mDeviceIdLock);
- deviceId = mLastReportedDeviceId;
+ deviceIds = mLastReportedDeviceIds;
}
- (void)startWithStatus(deviceId);
+ (void)startWithStatus(deviceIds);
return binder::Status::ok();
}
diff --git a/media/libaudioclient/TrackPlayerBase.cpp b/media/libaudioclient/TrackPlayerBase.cpp
index bc38251..7928c65 100644
--- a/media/libaudioclient/TrackPlayerBase.cpp
+++ b/media/libaudioclient/TrackPlayerBase.cpp
@@ -60,8 +60,8 @@
}
void TrackPlayerBase::SelfAudioDeviceCallback::onAudioDeviceUpdate(audio_io_handle_t __unused,
- audio_port_handle_t deviceId) {
- mSelf.baseUpdateDeviceId(deviceId);
+ const DeviceIdVector& deviceIds) {
+ mSelf.baseUpdateDeviceIds(deviceIds);
}
void TrackPlayerBase::doDestroy() {
diff --git a/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl b/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl
index ab60461..0c9a947 100644
--- a/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl
@@ -33,8 +33,8 @@
int flags;
long frameCount;
long notificationFrameCount;
- /** Interpreted as audio_port_handle_t. */
- int selectedDeviceId;
+ /** Interpreted as audio_port_handle_t[]. */
+ int[] selectedDeviceIds;
int sessionId;
int sampleRate;
AudioStreamType streamType;
diff --git a/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp b/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
index b0b7e03..ba5b3b1 100644
--- a/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
+++ b/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
@@ -396,7 +396,7 @@
static_cast<audio_port_handle_t>(mFdp.ConsumeIntegral<int32_t>());
record->setInputDevice(deviceId);
record->getInputDevice();
- record->getRoutedDeviceId();
+ record->getRoutedDeviceIds();
record->getPortId();
}
diff --git a/media/libaudioclient/include/media/AudioIoDescriptor.h b/media/libaudioclient/include/media/AudioIoDescriptor.h
index 405ec7d..961cc1c 100644
--- a/media/libaudioclient/include/media/AudioIoDescriptor.h
+++ b/media/libaudioclient/include/media/AudioIoDescriptor.h
@@ -69,12 +69,21 @@
size_t getFrameCountHAL() const { return mFrameCountHAL; }
uint32_t getLatency() const { return mLatency; }
audio_port_handle_t getPortId() const { return mPortId; }
- audio_port_handle_t getDeviceId() const {
- if (mPatch.num_sources != 0 && mPatch.num_sinks != 0) {
- // FIXME: the API only returns the first device in case of multiple device selection
- return mIsInput ? mPatch.sources[0].id : mPatch.sinks[0].id;
+ std::vector<audio_port_handle_t> getDeviceIds() const {
+ std::vector<audio_port_handle_t> deviceIds;
+ if (mPatch.num_sources == 0 || mPatch.num_sinks == 0) {
+ return deviceIds;
}
- return AUDIO_PORT_HANDLE_NONE;
+ if (mIsInput) {
+ for (unsigned int i = 0; i < mPatch.num_sources; i++) {
+ deviceIds.push_back(mPatch.sources[i].id);
+ }
+ } else {
+ for (unsigned int i = 0; i < mPatch.num_sinks; i++) {
+ deviceIds.push_back(mPatch.sinks[i].id);
+ }
+ }
+ return deviceIds;
}
void setPatch(const audio_patch& patch) { mPatch = patch; }
@@ -88,7 +97,13 @@
(mIsInput ? audio_channel_in_mask_to_string(mChannelMask) :
audio_channel_out_mask_to_string(mChannelMask)))
<< ", frameCount " << mFrameCount << ", frameCountHAL " << mFrameCountHAL
- << ", deviceId " << getDeviceId();
+ << ", deviceIds ";
+
+ std::vector<audio_port_handle_t> deviceIds = getDeviceIds();
+ for (auto deviceId : deviceIds) {
+ ss << deviceId << " ";
+ }
+
return ss.str();
}
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 25d91d3..80a756e 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -495,19 +495,19 @@
*/
audio_port_handle_t getInputDevice();
- /* Returns the ID of the audio device actually used by the input to which this AudioRecord
+ /* Returns the IDs of the audio devices actually used by the input to which this AudioRecord
* is attached.
- * The device ID is relevant only if the AudioRecord is active.
- * When the AudioRecord is inactive, the device ID returned can be either:
- * - AUDIO_PORT_HANDLE_NONE if the AudioRecord is not attached to any output.
- * - The device ID used before paused or stopped.
+ * The device IDs is relevant only if the AudioRecord is active.
+ * When the AudioRecord is inactive, the device IDs returned can be either:
+ * - An empty vector if the AudioRecord is not attached to any output.
+ * - The device IDs used before paused or stopped.
* - The device ID selected by audio policy manager of setOutputDevice() if the AudioRecord
* has not been started yet.
*
* Parameters:
* none.
*/
- audio_port_handle_t getRoutedDeviceId();
+ DeviceIdVector getRoutedDeviceIds();
/* Add an AudioDeviceCallback. The caller will be notified when the audio device
* to which this AudioRecord is routed is updated.
@@ -534,7 +534,7 @@
// AudioSystem::AudioDeviceCallback> virtuals
virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId);
+ const DeviceIdVector& deviceIds);
private:
/* If nonContig is non-NULL, it is an output parameter that will be set to the number of
@@ -678,7 +678,7 @@
// FIXME enum is faster than strcmp() for parameter 'from'
status_t restoreRecord_l(const char *from);
- void updateRoutedDeviceId_l();
+ void updateRoutedDeviceIds_l();
sp<AudioRecordThread> mAudioRecordThread;
mutable Mutex mLock;
@@ -810,7 +810,7 @@
audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
// Device actually selected by AudioPolicyManager: This may not match the app
// selection depending on other activity and connected devices
- audio_port_handle_t mRoutedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector mRoutedDeviceIds;
wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index fbc7629..45ede3c 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -767,7 +767,7 @@
virtual ~AudioDeviceCallback() {}
virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId) = 0;
+ const DeviceIdVector& deviceIds) = 0;
};
static status_t addAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
@@ -793,7 +793,7 @@
static status_t removeSupportedLatencyModesCallback(
const sp<SupportedLatencyModesCallback>& callback);
- static audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);
+ static status_t getDeviceIdsForIo(audio_io_handle_t audioIo, DeviceIdVector& deviceIds);
static status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos);
@@ -842,7 +842,8 @@
status_t removeSupportedLatencyModesCallback(
const sp<SupportedLatencyModesCallback>& callback) EXCLUDES(mMutex);
- audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo) EXCLUDES(mMutex);
+ status_t getDeviceIdsForIo(audio_io_handle_t audioIo, DeviceIdVector& deviceIds)
+ EXCLUDES(mMutex);
private:
mutable std::mutex mMutex;
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index de97863..330b5ee 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -835,18 +835,18 @@
*/
audio_port_handle_t getOutputDevice();
- /* Returns the ID of the audio device actually used by the output to which this AudioTrack is
+ /* Returns the IDs of the audio devices actually used by the output to which this AudioTrack is
* attached.
* When the AudioTrack is inactive, the device ID returned can be either:
- * - AUDIO_PORT_HANDLE_NONE if the AudioTrack is not attached to any output.
- * - The device ID used before paused or stopped.
+ * - An empty vector if the AudioTrack is not attached to any output.
+ * - The device IDs used before paused or stopped.
* - The device ID selected by audio policy manager of setOutputDevice() if the AudioTrack
* has not been started yet.
*
* Parameters:
* none.
*/
- audio_port_handle_t getRoutedDeviceId();
+ DeviceIdVector getRoutedDeviceIds();
/* Returns the unique session ID associated with this track.
*
@@ -1089,7 +1089,7 @@
// AudioSystem::AudioDeviceCallback> virtuals
virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId);
+ const DeviceIdVector& deviceIds);
/* Obtain the pending duration in milliseconds for playback of pure PCM
* (mixable without embedded timing) data remaining in AudioTrack.
@@ -1258,7 +1258,7 @@
void restartIfDisabled();
- void updateRoutedDeviceId_l();
+ void updateRoutedDeviceIds_l();
/* Sets the Dual Mono mode presentation on the output device. */
status_t setDualMonoMode_l(audio_dual_mono_mode_t mode);
@@ -1482,9 +1482,9 @@
// Device requested by the application.
audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- // Device actually selected by AudioPolicyManager: This may not match the app
+ // Devices actually selected by AudioPolicyManager: This may not match the app
// selection depending on other activity and connected devices.
- audio_port_handle_t mRoutedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector mRoutedDeviceIds;
sp<media::VolumeHandler> mVolumeHandler;
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 21ecb09..8292eef 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -109,7 +109,7 @@
audio_output_flags_t flags;
size_t frameCount;
size_t notificationFrameCount;
- audio_port_handle_t selectedDeviceId;
+ DeviceIdVector selectedDeviceIds;
audio_session_t sessionId;
/* output */
diff --git a/media/libaudioclient/include/media/PlayerBase.h b/media/libaudioclient/include/media/PlayerBase.h
index 5475f76..5df1a6e 100644
--- a/media/libaudioclient/include/media/PlayerBase.h
+++ b/media/libaudioclient/include/media/PlayerBase.h
@@ -22,6 +22,7 @@
#include <utils/Mutex.h>
#include "android/media/BnPlayer.h"
+#include "media/AudioContainers.h"
namespace android {
@@ -44,14 +45,14 @@
const media::VolumeShaperConfiguration& configuration,
const media::VolumeShaperOperation& operation) override;
- status_t startWithStatus(audio_port_handle_t deviceId);
+ status_t startWithStatus(const DeviceIdVector& deviceIds);
status_t pauseWithStatus();
status_t stopWithStatus();
//FIXME temporary method while some player state is outside of this class
- void reportEvent(player_state_t event, audio_port_handle_t deviceId);
+ void reportEvent(player_state_t event, const DeviceIdVector& deviceIds);
- void baseUpdateDeviceId(audio_port_handle_t deviceId);
+ void baseUpdateDeviceIds(const DeviceIdVector& deviceIds);
/**
* Updates the mapping in the AudioService between portId and piid
@@ -80,7 +81,7 @@
audio_unique_id_t mPIId;
private:
// report events to AudioService
- void servicePlayerEvent(player_state_t event, audio_port_handle_t deviceId);
+ void servicePlayerEvent(player_state_t event, const DeviceIdVector& deviceIds);
void serviceReleasePlayer();
// native interface to AudioService
@@ -91,7 +92,7 @@
player_state_t mLastReportedEvent;
Mutex mDeviceIdLock;
- audio_port_handle_t mLastReportedDeviceId;
+ DeviceIdVector mLastReportedDeviceIds GUARDED_BY(mDeviceIdLock);
};
} // namespace android
diff --git a/media/libaudioclient/include/media/TrackPlayerBase.h b/media/libaudioclient/include/media/TrackPlayerBase.h
index 8df9ff8..575b14c 100644
--- a/media/libaudioclient/include/media/TrackPlayerBase.h
+++ b/media/libaudioclient/include/media/TrackPlayerBase.h
@@ -60,7 +60,7 @@
public:
SelfAudioDeviceCallback(PlayerBase& self);
virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId);
+ const DeviceIdVector& deviceIds);
private:
virtual ~SelfAudioDeviceCallback();
PlayerBase& mSelf;
diff --git a/media/libaudioclient/tests/audio_test_utils.cpp b/media/libaudioclient/tests/audio_test_utils.cpp
index 1599839..7d13939 100644
--- a/media/libaudioclient/tests/audio_test_utils.cpp
+++ b/media/libaudioclient/tests/audio_test_utils.cpp
@@ -27,12 +27,12 @@
#define MAX_WAIT_TIME_MS 5000
void OnAudioDeviceUpdateNotifier::onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId) {
- ALOGI("%s: audioIo=%d deviceId=%d", __func__, audioIo, deviceId);
+ const DeviceIdVector& deviceIds) {
+ ALOGI("%s: audioIo=%d deviceIds=%s", __func__, audioIo, toString(deviceIds).c_str());
{
std::lock_guard lock(mMutex);
mAudioIo = audioIo;
- mDeviceId = deviceId;
+ mDeviceIds = deviceIds;
}
mCondition.notify_all();
}
@@ -41,20 +41,23 @@
std::unique_lock lock(mMutex);
android::base::ScopedLockAssertion lock_assertion(mMutex);
if (mAudioIo == AUDIO_IO_HANDLE_NONE ||
- (expDeviceId != AUDIO_PORT_HANDLE_NONE && expDeviceId != mDeviceId)) {
+ (expDeviceId != AUDIO_PORT_HANDLE_NONE &&
+ std::find(mDeviceIds.begin(), mDeviceIds.end(), expDeviceId) == mDeviceIds.end())) {
mCondition.wait_for(lock, std::chrono::milliseconds(500));
if (mAudioIo == AUDIO_IO_HANDLE_NONE ||
- (expDeviceId != AUDIO_PORT_HANDLE_NONE && expDeviceId != mDeviceId)) {
+ (expDeviceId != AUDIO_PORT_HANDLE_NONE &&
+ std::find(mDeviceIds.begin(), mDeviceIds.end(), expDeviceId) == mDeviceIds.end())) {
return TIMED_OUT;
}
}
return OK;
}
-std::pair<audio_io_handle_t, audio_port_handle_t>
-OnAudioDeviceUpdateNotifier::getLastPortAndDevice() const {
+std::pair<audio_io_handle_t, DeviceIdVector> OnAudioDeviceUpdateNotifier::getLastPortAndDevices()
+ const {
std::lock_guard lock(mMutex);
- return {mAudioIo, mDeviceId};
+ ALOGI("%s: audioIo=%d deviceIds=%s", __func__, mAudioIo, toString(mDeviceIds).c_str());
+ return {mAudioIo, mDeviceIds};
}
AudioPlayback::AudioPlayback(uint32_t sampleRate, audio_format_t format,
@@ -761,13 +764,15 @@
return BAD_VALUE;
}
-bool patchContainsOutputDevice(audio_port_handle_t deviceId, audio_patch patch) {
+// Check if the patch matches all the output devices in the deviceIds vector.
+bool patchMatchesOutputDevices(const DeviceIdVector& deviceIds, audio_patch patch) {
+ DeviceIdVector patchDeviceIds;
for (auto j = 0; j < patch.num_sinks; j++) {
- if (patch.sinks[j].type == AUDIO_PORT_TYPE_DEVICE && patch.sinks[j].id == deviceId) {
- return true;
+ if (patch.sinks[j].type == AUDIO_PORT_TYPE_DEVICE) {
+ patchDeviceIds.push_back(patch.sinks[j].id);
}
}
- return false;
+ return areDeviceIdsEqual(deviceIds, patchDeviceIds);
}
bool patchContainsInputDevice(audio_port_handle_t deviceId, audio_patch patch) {
@@ -779,10 +784,10 @@
return false;
}
-bool checkPatchPlayback(audio_io_handle_t audioIo, audio_port_handle_t deviceId) {
+bool checkPatchPlayback(audio_io_handle_t audioIo, const DeviceIdVector& deviceIds) {
struct audio_patch patch;
if (getPatchForOutputMix(audioIo, patch) == OK) {
- return patchContainsOutputDevice(deviceId, patch);
+ return patchMatchesOutputDevices(deviceIds, patch);
}
return false;
}
diff --git a/media/libaudioclient/tests/audio_test_utils.h b/media/libaudioclient/tests/audio_test_utils.h
index 022ecf3..9ccc7da 100644
--- a/media/libaudioclient/tests/audio_test_utils.h
+++ b/media/libaudioclient/tests/audio_test_utils.h
@@ -52,9 +52,9 @@
audio_port_v7& port);
status_t getPatchForOutputMix(audio_io_handle_t audioIo, audio_patch& patch);
status_t getPatchForInputMix(audio_io_handle_t audioIo, audio_patch& patch);
-bool patchContainsOutputDevice(audio_port_handle_t deviceId, audio_patch patch);
+bool patchContainsOutputDevices(DeviceIdVector deviceIds, audio_patch patch);
bool patchContainsInputDevice(audio_port_handle_t deviceId, audio_patch patch);
-bool checkPatchPlayback(audio_io_handle_t audioIo, audio_port_handle_t deviceId);
+bool checkPatchPlayback(audio_io_handle_t audioIo, const DeviceIdVector& deviceIds);
bool checkPatchCapture(audio_io_handle_t audioIo, audio_port_handle_t deviceId);
std::string dumpPort(const audio_port_v7& port);
std::string dumpPortConfig(const audio_port_config& port);
@@ -62,13 +62,13 @@
class OnAudioDeviceUpdateNotifier : public AudioSystem::AudioDeviceCallback {
public:
- void onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId) override;
+ void onAudioDeviceUpdate(audio_io_handle_t audioIo, const DeviceIdVector& deviceIds) override;
status_t waitForAudioDeviceCb(audio_port_handle_t expDeviceId = AUDIO_PORT_HANDLE_NONE);
- std::pair<audio_io_handle_t, audio_port_handle_t> getLastPortAndDevice() const;
+ std::pair<audio_io_handle_t, DeviceIdVector> getLastPortAndDevices() const;
private:
audio_io_handle_t mAudioIo GUARDED_BY(mMutex) = AUDIO_IO_HANDLE_NONE;
- audio_port_handle_t mDeviceId GUARDED_BY(mMutex) = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector mDeviceIds GUARDED_BY(mMutex);
mutable std::mutex mMutex;
std::condition_variable mCondition;
};
diff --git a/media/libaudioclient/tests/audioeffect_analyser.cpp b/media/libaudioclient/tests/audioeffect_analyser.cpp
index 199fb8b..3df5fd8 100644
--- a/media/libaudioclient/tests/audioeffect_analyser.cpp
+++ b/media/libaudioclient/tests/audioeffect_analyser.cpp
@@ -119,7 +119,8 @@
CHECK_OK(capture->start(), "start recording failed")
CHECK_OK(capture->audioProcess(), "recording process failed")
CHECK_OK(cbCapture->waitForAudioDeviceCb(), "audio device callback notification timed out");
- if (port.id != capture->getAudioRecordHandle()->getRoutedDeviceId()) {
+ DeviceIdVector routedDeviceIds = capture->getAudioRecordHandle()->getRoutedDeviceIds();
+ if (port.id != routedDeviceIds[0]) {
CHECK_OK(BAD_VALUE, "Capture NOT routed on expected port")
}
CHECK_OK(getPortByAttributes(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE,
diff --git a/media/libaudioclient/tests/audiorecord_tests.cpp b/media/libaudioclient/tests/audiorecord_tests.cpp
index f2fee8b..550ce6c 100644
--- a/media/libaudioclient/tests/audiorecord_tests.cpp
+++ b/media/libaudioclient/tests/audiorecord_tests.cpp
@@ -123,12 +123,12 @@
EXPECT_EQ(OK, mAC->getAudioRecordHandle()->addAudioDeviceCallback(cb));
EXPECT_EQ(OK, mAC->start()) << "record creation failed";
EXPECT_EQ(OK, cb->waitForAudioDeviceCb());
- const auto [oldAudioIo, oldDeviceId] = cbOld->getLastPortAndDevice();
+ const auto [oldAudioIo, oldDeviceIds] = cbOld->getLastPortAndDevices();
EXPECT_EQ(AUDIO_IO_HANDLE_NONE, oldAudioIo);
- EXPECT_EQ(AUDIO_PORT_HANDLE_NONE, oldDeviceId);
- const auto [audioIo, deviceId] = cb->getLastPortAndDevice();
+ EXPECT_TRUE(oldDeviceIds.empty());
+ const auto [audioIo, deviceIds] = cb->getLastPortAndDevices();
EXPECT_NE(AUDIO_IO_HANDLE_NONE, audioIo);
- EXPECT_NE(AUDIO_PORT_HANDLE_NONE, deviceId);
+ EXPECT_FALSE(deviceIds.empty());
EXPECT_EQ(BAD_VALUE, mAC->getAudioRecordHandle()->removeAudioDeviceCallback(nullptr));
EXPECT_EQ(INVALID_OPERATION, mAC->getAudioRecordHandle()->removeAudioDeviceCallback(cbOld));
EXPECT_EQ(OK, mAC->getAudioRecordHandle()->removeAudioDeviceCallback(cb));
diff --git a/media/libaudioclient/tests/audiorouting_tests.cpp b/media/libaudioclient/tests/audiorouting_tests.cpp
index a3ab9d2..7957c10 100644
--- a/media/libaudioclient/tests/audiorouting_tests.cpp
+++ b/media/libaudioclient/tests/audiorouting_tests.cpp
@@ -64,8 +64,8 @@
EXPECT_EQ(OK, ap->start()) << "audio track start failed";
EXPECT_EQ(OK, ap->onProcess());
EXPECT_EQ(OK, cb->waitForAudioDeviceCb());
- const auto [audioIo, deviceId] = cb->getLastPortAndDevice();
- EXPECT_TRUE(checkPatchPlayback(audioIo, deviceId));
+ const auto [audioIo, deviceIds] = cb->getLastPortAndDevices();
+ EXPECT_TRUE(checkPatchPlayback(audioIo, deviceIds));
EXPECT_NE(0, ap->getAudioTrackHandle()->getFlags() & output_flags[i]);
audio_patch patch;
EXPECT_EQ(OK, getPatchForOutputMix(audioIo, patch));
@@ -127,8 +127,8 @@
// capture should be routed to submix in port
EXPECT_EQ(OK, capture->start()) << "start recording failed";
EXPECT_EQ(OK, cbCapture->waitForAudioDeviceCb());
- EXPECT_EQ(port.id, capture->getAudioRecordHandle()->getRoutedDeviceId())
- << "Capture NOT routed on expected port";
+ DeviceIdVector routedDeviceIds = capture->getAudioRecordHandle()->getRoutedDeviceIds();
+ EXPECT_EQ(port.id, routedDeviceIds[0]) << "Capture NOT routed on expected port";
// capture start should create submix out port
status_t status = getPortByAttributes(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE,
@@ -138,8 +138,8 @@
// playback should be routed to submix out as long as capture is active
EXPECT_EQ(OK, playback->start()) << "audio track start failed";
EXPECT_EQ(OK, cbPlayback->waitForAudioDeviceCb());
- EXPECT_EQ(port.id, playback->getAudioTrackHandle()->getRoutedDeviceId())
- << "Playback NOT routed on expected port";
+ routedDeviceIds = playback->getAudioTrackHandle()->getRoutedDeviceIds();
+ EXPECT_EQ(port.id, routedDeviceIds[0]) << "Playback NOT routed on expected port";
capture->stop();
playback->stop();
@@ -235,13 +235,13 @@
// launch
EXPECT_EQ(OK, captureA->start()) << "start recording failed";
EXPECT_EQ(OK, cbCaptureA->waitForAudioDeviceCb());
- EXPECT_EQ(port.id, captureA->getAudioRecordHandle()->getRoutedDeviceId())
- << "Capture NOT routed on expected port";
+ DeviceIdVector routedDeviceIds = captureA->getAudioRecordHandle()->getRoutedDeviceIds();
+ EXPECT_EQ(port.id, routedDeviceIds[0]) << "Capture NOT routed on expected port";
EXPECT_EQ(OK, captureB->start()) << "start recording failed";
EXPECT_EQ(OK, cbCaptureB->waitForAudioDeviceCb());
- EXPECT_EQ(port_mix.id, captureB->getAudioRecordHandle()->getRoutedDeviceId())
- << "Capture NOT routed on expected port";
+ routedDeviceIds = captureB->getAudioRecordHandle()->getRoutedDeviceIds();
+ EXPECT_EQ(port_mix.id, routedDeviceIds[0]) << "Capture NOT routed on expected port";
// as record started, expect submix out ports to be connected
status = getPortByAttributes(AUDIO_PORT_ROLE_SINK, AUDIO_PORT_TYPE_DEVICE,
@@ -255,8 +255,8 @@
// check if playback routed to desired port
EXPECT_EQ(OK, playback->start());
EXPECT_EQ(OK, cbPlayback->waitForAudioDeviceCb());
- EXPECT_EQ(port_mix.id, playback->getAudioTrackHandle()->getRoutedDeviceId())
- << "Playback NOT routed on expected port";
+ routedDeviceIds = playback->getAudioTrackHandle()->getRoutedDeviceIds();
+ EXPECT_EQ(port_mix.id, routedDeviceIds[0]) << "Playback NOT routed on expected port";
captureB->stop();
@@ -282,8 +282,8 @@
playback->onProcess();
// as captureA is active, it should re route to legacy submix
EXPECT_EQ(OK, cbPlayback->waitForAudioDeviceCb(port.id));
- EXPECT_EQ(port.id, playback->getAudioTrackHandle()->getRoutedDeviceId())
- << "Playback NOT routed on expected port";
+ routedDeviceIds = playback->getAudioTrackHandle()->getRoutedDeviceIds();
+ EXPECT_EQ(port.id, routedDeviceIds[0]) << "Playback NOT routed on expected port";
captureA->stop();
playback->stop();
diff --git a/media/libaudioclient/tests/audiosystem_tests.cpp b/media/libaudioclient/tests/audiosystem_tests.cpp
index 742ca48..31cab78 100644
--- a/media/libaudioclient/tests/audiosystem_tests.cpp
+++ b/media/libaudioclient/tests/audiosystem_tests.cpp
@@ -108,7 +108,7 @@
// UNIT TESTS
TEST_F(AudioSystemTest, CheckServerSideValues) {
ASSERT_NO_FATAL_FAILURE(createPlaybackSession());
- const auto [pbAudioIo, _] = mCbPlayback->getLastPortAndDevice();
+ const auto [pbAudioIo, _] = mCbPlayback->getLastPortAndDevices();
EXPECT_GT(mAF->sampleRate(pbAudioIo), 0);
EXPECT_NE(mAF->format(pbAudioIo), AUDIO_FORMAT_INVALID);
EXPECT_GT(mAF->frameCount(pbAudioIo), 0);
@@ -122,7 +122,7 @@
EXPECT_LE(mAF->latency(pbAudioIo), mPlayback->getAudioTrackHandle()->latency());
ASSERT_NO_FATAL_FAILURE(createRecordSession());
- const auto [recAudioIo, __] = mCbRecord->getLastPortAndDevice();
+ const auto [recAudioIo, __] = mCbRecord->getLastPortAndDevices();
EXPECT_GT(mAF->sampleRate(recAudioIo), 0);
// EXPECT_NE(mAF->format(recAudioIo), AUDIO_FORMAT_INVALID);
EXPECT_GT(mAF->frameCount(recAudioIo), 0);
diff --git a/media/libaudioclient/tests/audiotrack_tests.cpp b/media/libaudioclient/tests/audiotrack_tests.cpp
index cf7d926..d283c6c 100644
--- a/media/libaudioclient/tests/audiotrack_tests.cpp
+++ b/media/libaudioclient/tests/audiotrack_tests.cpp
@@ -157,20 +157,21 @@
EXPECT_EQ(OK, ap->start()) << "audio track start failed";
EXPECT_EQ(OK, ap->onProcess());
EXPECT_EQ(OK, cb->waitForAudioDeviceCb());
- const auto [oldAudioIo, oldDeviceId] = cbOld->getLastPortAndDevice();
+ const auto [oldAudioIo, oldDeviceIds] = cbOld->getLastPortAndDevices();
EXPECT_EQ(AUDIO_IO_HANDLE_NONE, oldAudioIo);
- EXPECT_EQ(AUDIO_PORT_HANDLE_NONE, oldDeviceId);
- const auto [audioIo, deviceId] = cb->getLastPortAndDevice();
+ EXPECT_TRUE(oldDeviceIds.empty());
+ const auto [audioIo, deviceIds] = cb->getLastPortAndDevices();
EXPECT_NE(AUDIO_IO_HANDLE_NONE, audioIo);
- EXPECT_NE(AUDIO_PORT_HANDLE_NONE, deviceId);
+ EXPECT_FALSE(deviceIds.empty());
EXPECT_EQ(audioIo, ap->getAudioTrackHandle()->getOutput());
- EXPECT_EQ(deviceId, ap->getAudioTrackHandle()->getRoutedDeviceId());
+ DeviceIdVector routedDeviceIds = ap->getAudioTrackHandle()->getRoutedDeviceIds();
+ EXPECT_TRUE(areDeviceIdsEqual(routedDeviceIds, deviceIds));
String8 keys;
keys = ap->getAudioTrackHandle()->getParameters(keys);
if (!keys.empty()) {
std::cerr << "track parameters :: " << keys << std::endl;
}
- EXPECT_TRUE(checkPatchPlayback(audioIo, deviceId));
+ EXPECT_TRUE(checkPatchPlayback(audioIo, deviceIds));
EXPECT_EQ(BAD_VALUE, ap->getAudioTrackHandle()->removeAudioDeviceCallback(nullptr));
EXPECT_EQ(INVALID_OPERATION, ap->getAudioTrackHandle()->removeAudioDeviceCallback(cbOld));
EXPECT_EQ(OK, ap->getAudioTrackHandle()->removeAudioDeviceCallback(cb));
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
index 3e2066b..f3d295b 100644
--- a/media/libaudiofoundation/AudioContainers.cpp
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -151,6 +151,12 @@
return deviceIds[0];
}
+bool areDeviceIdsEqual(const DeviceIdVector& first, const DeviceIdVector& second) {
+ const std::set<audio_port_handle_t> firstSet(first.begin(), first.end());
+ const std::set<audio_port_handle_t> secondSet(second.begin(), second.end());
+ return firstSet == secondSet;
+}
+
AudioProfileAttributesMultimap createAudioProfilesAttrMap(audio_profile profiles[],
uint32_t first,
uint32_t last) {
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 8d4665e..b6c0444 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -140,16 +140,21 @@
}
/**
- * Returns human readable string for a set of device ids.
+ * Returns human readable string for a vector of device ids.
*/
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.
+ * Returns the first device id of a vector of device ids or AUDIO_PORT_HANDLE_NONE when its empty.
*/
audio_port_handle_t getFirstDeviceId(const DeviceIdVector& deviceIds);
/**
+ * Returns whether two vectors of device ids have the same elements.
+ */
+bool areDeviceIdsEqual(const DeviceIdVector& first, const DeviceIdVector& second);
+
+/**
* Create audio profile attributes map by given audio profile array from the range of [first, last).
*
* @param profiles the array of audio profiles.
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;
}
diff --git a/media/libmediametrics/include/MediaMetricsConstants.h b/media/libmediametrics/include/MediaMetricsConstants.h
index 98c3382..a7b2077 100644
--- a/media/libmediametrics/include/MediaMetricsConstants.h
+++ b/media/libmediametrics/include/MediaMetricsConstants.h
@@ -183,6 +183,7 @@
#define AMEDIAMETRICS_PROP_PLAYBACK_SPEED "playback.speed" // double value (AudioTrack)
#define AMEDIAMETRICS_PROP_PLAYERIID "playerIId" // int32 (-1 invalid/unset IID)
#define AMEDIAMETRICS_PROP_ROUTEDDEVICEID "routedDeviceId" // int32
+#define AMEDIAMETRICS_PROP_ROUTEDDEVICEIDS "routedDeviceIds" // string value
#define AMEDIAMETRICS_PROP_SAMPLERATE "sampleRate" // int32
#define AMEDIAMETRICS_PROP_SAMPLERATECLIENT "sampleRateClient" // int32
#define AMEDIAMETRICS_PROP_SAMPLERATEHARDWARE "sampleRateHardware" // int32
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index a10c509..1d493e2 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -46,13 +46,14 @@
"av-types-aidl-cpp",
"framework-permission-aidl-cpp",
"libaconfig_storage_read_api_cc",
- "libaudioclient_aidl_conversion",
- "libbase",
- "libbinder_ndk",
"libactivitymanager_aidl",
"libandroid_net",
"libaudioclient",
+ "libaudioclient_aidl_conversion",
+ "libaudiofoundation",
+ "libbase",
"libbinder",
+ "libbinder_ndk",
"libcamera_client",
"libcodec2_client",
"libcrypto",
@@ -81,25 +82,25 @@
],
header_libs: [
- "media_plugin_headers",
"libmediautils_headers",
"libstagefright_rtsp_headers",
"libstagefright_webm_headers",
+ "media_plugin_headers",
],
static_libs: [
"com.android.media.flags.editing-aconfig-cc",
+ "framework-permission-aidl-cpp",
"libplayerservice_datasource",
"libstagefright_nuplayer",
"libstagefright_rtsp",
"libstagefright_timedtext",
- "framework-permission-aidl-cpp",
],
cflags: [
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
],
sanitize: {
@@ -115,8 +116,8 @@
],
export_shared_lib_headers: [
- "libmedia",
"framework-permission-aidl-cpp",
+ "libmedia",
],
export_header_lib_headers: [
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index b267c08..0067344 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -856,10 +856,13 @@
void MediaPlayerService::Client::AudioDeviceUpdatedNotifier::onAudioDeviceUpdate(
audio_io_handle_t audioIo,
- audio_port_handle_t deviceId) {
+ const DeviceIdVector& deviceIds) {
+ ALOGD("onAudioDeviceUpdate deviceIds: %s", toString(deviceIds).c_str());
sp<MediaPlayerBase> listener = mListener.promote();
if (listener != NULL) {
- listener->sendEvent(MEDIA_AUDIO_ROUTING_CHANGED, audioIo, deviceId);
+ // Java should query the new device ids once it gets the event.
+ // TODO(b/378505346): Pass the deviceIds to Java to avoid race conditions.
+ listener->sendEvent(MEDIA_AUDIO_ROUTING_CHANGED, audioIo);
} else {
ALOGW("listener for process %d death is gone", MEDIA_AUDIO_ROUTING_CHANGED);
}
@@ -1750,13 +1753,13 @@
return NO_INIT;
}
-status_t MediaPlayerService::Client::getRoutedDeviceId(audio_port_handle_t* deviceId)
+status_t MediaPlayerService::Client::getRoutedDeviceIds(DeviceIdVector& deviceIds)
{
- ALOGV("[%d] getRoutedDeviceId", mConnId);
+ ALOGV("[%d] getRoutedDeviceIds", mConnId);
{
Mutex::Autolock l(mLock);
if (mAudioOutput.get() != nullptr) {
- return mAudioOutput->getRoutedDeviceId(deviceId);
+ return mAudioOutput->getRoutedDeviceIds(deviceIds);
}
}
return NO_INIT;
@@ -1830,7 +1833,6 @@
mFlags(AUDIO_OUTPUT_FLAG_NONE),
mVolumeHandler(new media::VolumeHandler()),
mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
- mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
mDeviceCallbackEnabled(false),
mDeviceCallback(deviceCallback)
{
@@ -2604,14 +2606,14 @@
return NO_ERROR;
}
-status_t MediaPlayerService::AudioOutput::getRoutedDeviceId(audio_port_handle_t* deviceId)
+status_t MediaPlayerService::AudioOutput::getRoutedDeviceIds(DeviceIdVector& deviceIds)
{
- ALOGV("getRoutedDeviceId");
+ ALOGV("getRoutedDeviceIds");
Mutex::Autolock lock(mLock);
if (mTrack != 0) {
- mRoutedDeviceId = mTrack->getRoutedDeviceId();
+ mRoutedDeviceIds = mTrack->getRoutedDeviceIds();
}
- *deviceId = mRoutedDeviceId;
+ deviceIds = mRoutedDeviceIds;
return NO_ERROR;
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 76b7bcf..497ef79 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -28,6 +28,7 @@
#include <utils/Vector.h>
#include <media/AidlConversion.h>
+#include <media/AudioContainers.h>
#include <media/AudioResamplerPublic.h>
#include <media/AudioSystem.h>
#include <media/AudioTrack.h>
@@ -148,7 +149,7 @@
// AudioRouting
virtual status_t setOutputDevice(audio_port_handle_t deviceId);
- virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
+ virtual status_t getRoutedDeviceIds(DeviceIdVector& deviceIds);
virtual status_t enableAudioDeviceCallback(bool enabled);
private:
@@ -181,7 +182,7 @@
audio_output_flags_t mFlags;
sp<media::VolumeHandler> mVolumeHandler;
audio_port_handle_t mSelectedDeviceId;
- audio_port_handle_t mRoutedDeviceId;
+ DeviceIdVector mRoutedDeviceIds;
bool mDeviceCallbackEnabled;
wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
mutable Mutex mLock;
@@ -401,7 +402,7 @@
virtual status_t releaseDrm();
// AudioRouting
virtual status_t setOutputDevice(audio_port_handle_t deviceId);
- virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
+ virtual status_t getRoutedDeviceIds(DeviceIdVector& deviceIds);
virtual status_t enableAudioDeviceCallback(bool enabled);
private:
@@ -414,7 +415,7 @@
~AudioDeviceUpdatedNotifier() {}
virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
- audio_port_handle_t deviceId);
+ const DeviceIdVector& deviceIds);
private:
wp<MediaPlayerBase> mListener;
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index ed3ec89..53f4e61 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -409,10 +409,13 @@
void MediaRecorderClient::AudioDeviceUpdatedNotifier::onAudioDeviceUpdate(
audio_io_handle_t audioIo,
- audio_port_handle_t deviceId) {
+ const DeviceIdVector& deviceIds) {
+ ALOGD("onAudioDeviceUpdate deviceIds: %s", toString(deviceIds).c_str());
sp<IMediaRecorderClient> listener = mListener.promote();
if (listener != NULL) {
- listener->notify(MEDIA_RECORDER_AUDIO_ROUTING_CHANGED, audioIo, deviceId);
+ // Java should query the new device ids once it gets the event.
+ // TODO(b/378505346): Pass the deviceIds to Java to avoid race conditions.
+ listener->notify(MEDIA_RECORDER_AUDIO_ROUTING_CHANGED, audioIo, 0 /*ext2*/);
} else {
ALOGW("listener for process %d death is gone", MEDIA_RECORDER_AUDIO_ROUTING_CHANGED);
}
@@ -550,11 +553,11 @@
return NO_INIT;
}
-status_t MediaRecorderClient::getRoutedDeviceId(audio_port_handle_t* deviceId) {
- ALOGV("getRoutedDeviceId");
+status_t MediaRecorderClient::getRoutedDeviceIds(DeviceIdVector& deviceIds) {
+ ALOGV("getRoutedDeviceIds");
Mutex::Autolock lock(mLock);
if (mRecorder != NULL) {
- return mRecorder->getRoutedDeviceId(deviceId);
+ return mRecorder->getRoutedDeviceIds(deviceIds);
}
return NO_INIT;
}
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index dec0c99..3b9ab07 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -41,7 +41,7 @@
virtual ~AudioDeviceUpdatedNotifier();
virtual void onAudioDeviceUpdate(
audio_io_handle_t audioIo,
- audio_port_handle_t deviceId);
+ const DeviceIdVector& deviceIds);
private:
wp<IMediaRecorderClient> mListener;
};
@@ -80,7 +80,7 @@
virtual status_t setInputSurface(const sp<PersistentSurface>& surface);
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource();
virtual status_t setInputDevice(audio_port_handle_t deviceId);
- virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
+ virtual status_t getRoutedDeviceIds(DeviceIdVector& deviceIds);
virtual status_t enableAudioDeviceCallback(bool enabled);
virtual status_t getActiveMicrophones(
std::vector<media::MicrophoneInfoFw>* activeMicrophones);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 23e7a47..fa42da2 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -2595,11 +2595,11 @@
return NO_ERROR;
}
-status_t StagefrightRecorder::getRoutedDeviceId(audio_port_handle_t* deviceId) {
- ALOGV("getRoutedDeviceId");
+status_t StagefrightRecorder::getRoutedDeviceIds(DeviceIdVector& deviceIds) {
+ ALOGV("getRoutedDeviceIds");
if (mAudioSourceNode != 0) {
- status_t status = mAudioSourceNode->getRoutedDeviceId(deviceId);
+ status_t status = mAudioSourceNode->getRoutedDeviceIds(deviceIds);
return status;
}
return NO_INIT;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 0b6a5bb..4c5e62f 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -80,7 +80,7 @@
// Querying a SurfaceMediaSourcer
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const;
virtual status_t setInputDevice(audio_port_handle_t deviceId);
- virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
+ virtual status_t getRoutedDeviceIds(DeviceIdVector& deviceIds);
virtual void setAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
virtual status_t enableAudioDeviceCallback(bool enabled);
virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw>* activeMicrophones);
diff --git a/media/libmediaplayerservice/fuzzer/Android.bp b/media/libmediaplayerservice/fuzzer/Android.bp
index e413241..a3285ee 100644
--- a/media/libmediaplayerservice/fuzzer/Android.bp
+++ b/media/libmediaplayerservice/fuzzer/Android.bp
@@ -82,6 +82,7 @@
"libactivitymanager_aidl",
"libandroid_net",
"libaudioflinger",
+ "libaudiofoundation",
"libcamera_client",
"libcodec2_client",
"libcrypto",
@@ -160,6 +161,7 @@
"libactivitymanager_aidl",
"libandroid_net",
"libaudioclient",
+ "libaudiofoundation",
"libcamera_client",
"libcodec2_client",
"libcrypto",
diff --git a/media/libmediaplayerservice/fuzzer/mediaplayer_fuzzer.cpp b/media/libmediaplayerservice/fuzzer/mediaplayer_fuzzer.cpp
index 15265bf..a52d751 100644
--- a/media/libmediaplayerservice/fuzzer/mediaplayer_fuzzer.cpp
+++ b/media/libmediaplayerservice/fuzzer/mediaplayer_fuzzer.cpp
@@ -482,8 +482,8 @@
mMediaPlayer->setOutputDevice(deviceId);
},
[&]() {
- audio_port_handle_t deviceId;
- mMediaPlayer->getRoutedDeviceId(&deviceId);
+ DeviceIdVector deviceIds;
+ mMediaPlayer->getRoutedDeviceIds(deviceIds);
},
[&]() { mMediaPlayer->enableAudioDeviceCallback(mFdp.ConsumeBool()); },
[&]() {
diff --git a/media/libmediaplayerservice/fuzzer/mediarecorder_fuzzer.cpp b/media/libmediaplayerservice/fuzzer/mediarecorder_fuzzer.cpp
index 3339ae8..b95cae7 100644
--- a/media/libmediaplayerservice/fuzzer/mediarecorder_fuzzer.cpp
+++ b/media/libmediaplayerservice/fuzzer/mediarecorder_fuzzer.cpp
@@ -116,7 +116,7 @@
virtual ~TestAudioDeviceCallback() = default;
void onAudioDeviceUpdate(audio_io_handle_t /*audioIo*/,
- audio_port_handle_t /*deviceId*/) override{};
+ const DeviceIdVector& /*deviceIds*/) override{};
};
class TestCamera : public ICamera {
@@ -185,8 +185,8 @@
int32_t max;
mStfRecorder->getMaxAmplitude(&max);
- int32_t deviceId;
- mStfRecorder->getRoutedDeviceId(&deviceId);
+ DeviceIdVector deviceIds;
+ mStfRecorder->getRoutedDeviceIds(deviceIds);
vector<android::media::MicrophoneInfoFw> activeMicrophones{};
mStfRecorder->getActiveMicrophones(&activeMicrophones);
diff --git a/media/libmediaplayerservice/include/MediaPlayerInterface.h b/media/libmediaplayerservice/include/MediaPlayerInterface.h
index 495cf00..9fe0e95 100644
--- a/media/libmediaplayerservice/include/MediaPlayerInterface.h
+++ b/media/libmediaplayerservice/include/MediaPlayerInterface.h
@@ -26,6 +26,7 @@
#include <utils/RefBase.h>
#include <media/mediaplayer.h>
+#include <media/AudioContainers.h>
#include <media/AudioResamplerPublic.h>
#include <media/AudioTimestamp.h>
#include <media/AVSyncSettings.h>
@@ -185,7 +186,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;
};
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 92bf35d..b466f18 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -47,8 +47,8 @@
],
cflags: [
- "-Werror",
"-Wall",
+ "-Werror",
],
header_libs: [
@@ -57,6 +57,8 @@
],
shared_libs: [
+ "android.hardware.cas.native@1.0",
+ "android.hardware.drm@1.0",
"libaudioutils",
"libgui",
"libhidlallocatorutils",
@@ -66,15 +68,13 @@
"libstagefright_foundation",
"libui",
"libutils",
- "android.hardware.cas.native@1.0",
- "android.hardware.drm@1.0",
],
sanitize: {
cfi: true,
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
},
}
@@ -88,9 +88,9 @@
min_sdk_version: "29",
srcs: [
- "Utils.cpp",
- "MediaSource.cpp",
"HevcUtils.cpp",
+ "MediaSource.cpp",
+ "Utils.cpp",
],
shared_libs: [
@@ -114,17 +114,17 @@
],
cflags: [
- "-Wno-multichar",
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
+ "-Wno-multichar",
],
sanitize: {
cfi: true,
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
},
@@ -150,12 +150,11 @@
],
shared_libs: [
- "libbase",
- "libcutils",
"libEGL",
"libGLESv1_CM",
"libGLESv2",
- "libvulkan",
+ "libbase",
+ "libcutils",
"libgui",
"liblog",
"libprocessgroup",
@@ -163,6 +162,7 @@
"libsync",
"libui",
"libutils",
+ "libvulkan",
],
static_libs: [
@@ -174,18 +174,18 @@
],
cflags: [
- "-Wno-multichar",
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
+ "-Wno-multichar",
],
sanitize: {
// TODO: re-enabled cfi for this lib after b/139945549 fixed
cfi: false,
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
},
}
@@ -209,16 +209,16 @@
],
cflags: [
- "-Wno-multichar",
- "-Werror",
"-Wall",
+ "-Werror",
+ "-Wno-multichar",
],
sanitize: {
cfi: true,
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
},
}
@@ -255,13 +255,13 @@
"MediaCodecSource.cpp",
"MediaExtractor.cpp",
"MediaExtractorFactory.cpp",
+ "MediaMuxer.cpp",
"MediaSource.cpp",
"MediaSync.cpp",
"MediaTrack.cpp",
- "MediaMuxer.cpp",
"NuMediaExtractor.cpp",
- "OggWriter.cpp",
"OMXClient.cpp",
+ "OggWriter.cpp",
"OmxInfoBuilder.cpp",
"RemoteMediaExtractor.cpp",
"RemoteMediaSource.cpp",
@@ -270,13 +270,22 @@
"SurfaceUtils.cpp",
"ThrottledSource.cpp",
"Utils.cpp",
- "VideoFrameSchedulerBase.cpp",
"VideoFrameScheduler.cpp",
+ "VideoFrameSchedulerBase.cpp",
"VideoRenderQualityTracker.cpp",
],
shared_libs: [
- "libstagefright_framecapture_utils",
+ "aconfig_mediacodec_flags_c_lib",
+ "android.hardware.cas.native@1.0",
+ "android.hardware.drm@1.0",
+ "android.hardware.media.omx@1.0",
+ "android.hidl.allocator@1.0",
+ "framework-permission-aidl-cpp",
+ "libaconfig_storage_read_api_cc",
+ "libaudioclient",
+ "libaudioclient_aidl_conversion",
+ "libaudiofoundation",
"libaudioutils",
"libbase",
"libbinder",
@@ -289,30 +298,24 @@
"libdl",
"libdl_android",
"libgui",
+ "libhidlallocatorutils",
+ "libhidlbase",
+ "libhidlmemory",
"liblog",
"libmedia",
"libmedia_codeclist",
+ "libmedia_helper",
"libmedia_omx",
"libmedia_omx_client",
- "libaudioclient",
"libmediametrics",
- "libui",
- "libutils",
- "libmedia_helper",
"libsfplugin_ccodec",
"libsfplugin_ccodec_utils",
"libstagefright_codecbase",
"libstagefright_foundation",
+ "libstagefright_framecapture_utils",
"libstagefright_omx_utils",
- "libhidlallocatorutils",
- "libhidlbase",
- "libhidlmemory",
- "android.hidl.allocator@1.0",
- "android.hardware.cas.native@1.0",
- "android.hardware.drm@1.0",
- "android.hardware.media.omx@1.0",
- "framework-permission-aidl-cpp",
- "libaudioclient_aidl_conversion",
+ "libui",
+ "libutils",
"packagemanager_aidl-cpp",
"server_configurable_flags",
"libaconfig_storage_read_api_cc",
@@ -323,32 +326,32 @@
static_libs: [
"android.media.codec-aconfig-cc",
"com.android.media.flags.editing-aconfig-cc",
- "libstagefright_esds",
- "libstagefright_color_conversion",
- "libyuv",
- "libstagefright_webm",
- "libstagefright_timedtext",
- "libogg",
- "libstagefright_id3",
"framework-permission-aidl-cpp",
- "libmediandk_format",
"libmedia_ndkformatpriv",
+ "libmediandk_format",
+ "libogg",
+ "libstagefright_color_conversion",
+ "libstagefright_esds",
+ "libstagefright_id3",
+ "libstagefright_timedtext",
+ "libstagefright_webm",
+ "libyuv",
],
header_libs: [
"libmediadrm_headers",
+ "libmediaformatshaper_headers",
"libnativeloader-headers",
"libstagefright_xmlparser_headers",
"media_ndk_headers",
- "libmediaformatshaper_headers",
],
export_shared_lib_headers: [
+ "android.hidl.allocator@1.0",
+ "framework-permission-aidl-cpp",
"libgui",
"libhidlmemory",
"libmedia",
- "android.hidl.allocator@1.0",
- "framework-permission-aidl-cpp",
],
export_include_dirs: [
@@ -356,10 +359,10 @@
],
cflags: [
- "-Wno-multichar",
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
+ "-Wno-multichar",
],
version_script: "exports.lds",
@@ -374,8 +377,8 @@
sanitize: {
cfi: true,
misc_undefined: [
- "unsigned-integer-overflow",
"signed-integer-overflow",
+ "unsigned-integer-overflow",
],
},
}
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 584dad6..f658d84 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -497,9 +497,9 @@
return NO_INIT;
}
-status_t AudioSource::getRoutedDeviceId(audio_port_handle_t* deviceId) {
+status_t AudioSource::getRoutedDeviceIds(DeviceIdVector& deviceIds) {
if (mRecord != 0) {
- *deviceId = mRecord->getRoutedDeviceId();
+ deviceIds = mRecord->getRoutedDeviceIds();
return NO_ERROR;
}
return NO_INIT;
diff --git a/media/libstagefright/include/media/stagefright/AudioSource.h b/media/libstagefright/include/media/stagefright/AudioSource.h
index 65d5246..51f6ac4 100644
--- a/media/libstagefright/include/media/stagefright/AudioSource.h
+++ b/media/libstagefright/include/media/stagefright/AudioSource.h
@@ -78,7 +78,7 @@
virtual void signalBufferReturned(MediaBufferBase *buffer);
status_t setInputDevice(audio_port_handle_t deviceId);
- status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
+ status_t getRoutedDeviceIds(DeviceIdVector& deviceIds);
status_t addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
status_t removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
diff --git a/media/libstagefright/webm/Android.bp b/media/libstagefright/webm/Android.bp
index 723131d..c3bd36e 100644
--- a/media/libstagefright/webm/Android.bp
+++ b/media/libstagefright/webm/Android.bp
@@ -11,8 +11,8 @@
name: "libstagefright_webm",
cflags: [
- "-Werror",
"-Wall",
+ "-Werror",
],
sanitize: {
@@ -38,11 +38,12 @@
export_include_dirs: ["include"],
shared_libs: [
+ "framework-permission-aidl-cpp",
+ "libaudiofoundation",
"libdatasource",
+ "liblog",
"libstagefright_foundation",
"libutils",
- "liblog",
- "framework-permission-aidl-cpp",
],
header_libs: [
@@ -51,7 +52,6 @@
],
}
-
cc_library_headers {
name: "libstagefright_webm_headers",
export_include_dirs: ["include"],
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 2322780..b2edaf7 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1190,7 +1190,7 @@
adjAttributionSource, &input.config, input.flags,
&selectedDeviceIds, &portId, &secondaryOutputs,
&isSpatialized, &isBitPerfect, &volume, &muted);
- output.selectedDeviceId = getFirstDeviceId(selectedDeviceIds);
+ output.selectedDeviceIds = 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 e42b39e..200175b 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -10921,7 +10921,7 @@
// For mmap streams, once the routing has changed, they will be disconnected. It should be
// okay to notify the client earlier before the new patch creation.
- if (mDeviceIds != deviceIds) {
+ if (!areDeviceIdsEqual(deviceIds, mDeviceIds)) {
if (const sp<MmapStreamCallback> callback = mCallback.promote()) {
// The aaudioservice handle the routing changed event asynchronously. In that case,
// it is safe to hold the lock here.
@@ -10945,7 +10945,7 @@
*handle = AUDIO_PATCH_HANDLE_NONE;
}
- if (numDevices == 0 || mDeviceIds != deviceIds) {
+ if (numDevices == 0 || (!areDeviceIdsEqual(deviceIds, mDeviceIds))) {
if (isOutput()) {
sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
mOutDeviceTypeAddrs = sinkDeviceTypeAddrs;
@@ -11110,8 +11110,7 @@
if (const sp<MmapStreamCallback> callback = mCallback.promote()) {
// The aaudioservice handle the routing changed event asynchronously. In that case,
// it is safe to hold the lock here.
- DeviceIdVector emptyDeviceIdVector;
- callback->onRoutingChanged(emptyDeviceIdVector);
+ callback->onRoutingChanged({});
} else if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
ALOGW("Could not notify MMAP stream tear down: no onRoutingChanged callback!");
mNoCallbackWarningCount++;
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index b5ee2f2..243f1f1 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -119,8 +119,9 @@
}
}
- ALOGV("findExclusiveEndpoint_l(), found %p for device = %d, sessionId = %d",
- endpoint.get(), configuration.getDeviceId(), configuration.getSessionId());
+ ALOGV("findExclusiveEndpoint_l(), found %p for devices = %s, sessionId = %d",
+ endpoint.get(), toString(configuration.getDeviceIds()).c_str(),
+ configuration.getSessionId());
return endpoint;
}
@@ -137,8 +138,9 @@
}
}
- ALOGV("findSharedEndpoint_l(), found %p for device = %d, sessionId = %d",
- endpoint.get(), configuration.getDeviceId(), configuration.getSessionId());
+ ALOGV("findSharedEndpoint_l(), found %p for devices = %s, sessionId = %d",
+ endpoint.get(), toString(configuration.getDeviceIds()).c_str(),
+ configuration.getSessionId());
return endpoint;
}
@@ -192,8 +194,8 @@
} else {
const sp<AAudioServiceEndpointMMAP> endpointMMap =
new AAudioServiceEndpointMMAP(aaudioService);
- ALOGV("%s(), no match so try to open MMAP %p for dev %d",
- __func__, endpointMMap.get(), configuration.getDeviceId());
+ ALOGV("%s(), no match so try to open MMAP %p for devices %s",
+ __func__, endpointMMap.get(), toString(configuration.getDeviceIds()).c_str());
endpoint = endpointMMap;
const aaudio_result_t result = endpoint->open(request);
@@ -250,8 +252,9 @@
mSharedOpenCount++;
}
}
- ALOGV("%s(), created endpoint %p, requested device = %d, dir = %d",
- __func__, endpoint.get(), configuration.getDeviceId(), (int)direction);
+ ALOGV("%s(), created endpoint %p, requested device = %s, dir = %d",
+ __func__, endpoint.get(), android::toString(configuration.getDeviceIds()).c_str(),
+ (int)direction);
IPCThreadState::self()->restoreCallingIdentity(token);
}
@@ -289,8 +292,9 @@
serviceEndpoint->close();
mExclusiveCloseCount++;
- ALOGV("%s() %p for device %d",
- __func__, serviceEndpoint.get(), serviceEndpoint->getDeviceId());
+ ALOGV("%s() %p for devices %s",
+ __func__, serviceEndpoint.get(),
+ android::toString(serviceEndpoint->getDeviceIds()).c_str());
}
}
@@ -313,7 +317,8 @@
serviceEndpoint->close();
mSharedCloseCount++;
- ALOGV("%s(%p) closed for device %d",
- __func__, serviceEndpoint.get(), serviceEndpoint->getDeviceId());
+ ALOGV("%s(%p) closed for device %s",
+ __func__, serviceEndpoint.get(),
+ android::toString(serviceEndpoint->getDeviceIds()).c_str());
}
}
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index e49e9e7..c677619 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -57,7 +57,7 @@
result << " Direction: " << ((getDirection() == AAUDIO_DIRECTION_OUTPUT)
? "OUTPUT" : "INPUT") << "\n";
result << " Requested Device Id: " << mRequestedDeviceId << "\n";
- result << " Device Id: " << getDeviceId() << "\n";
+ result << " Device Ids: " << android::toString(getDeviceIds()).c_str() << "\n";
result << " Sample Rate: " << getSampleRate() << "\n";
result << " Channel Count: " << getSamplesPerFrame() << "\n";
result << " Channel Mask: 0x" << std::hex << getChannelMask() << std::dec << "\n";
@@ -155,8 +155,8 @@
if (configuration.getDirection() != getDirection()) {
return false;
}
- if (configuration.getDeviceId() != AAUDIO_UNSPECIFIED &&
- configuration.getDeviceId() != getDeviceId()) {
+ if (!configuration.getDeviceIds().empty() &&
+ !android::areDeviceIdsEqual(configuration.getDeviceIds(), getDeviceIds())) {
return false;
}
if (configuration.getSessionId() != AAUDIO_SESSION_ID_ALLOCATE &&
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 59bb98e..66918c1 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -105,7 +105,7 @@
aaudio_result_t result = AAUDIO_OK;
mAudioDataWrapper = std::make_unique<SharedMemoryWrapper>();
copyFrom(request.getConstantConfiguration());
- mRequestedDeviceId = getDeviceId();
+ mRequestedDeviceId = android::getFirstDeviceId(getDeviceIds());
mMmapClient.attributionSource = request.getAttributionSource();
// TODO b/182392769: use attribution source util
@@ -173,11 +173,13 @@
audio_config_base_t* config) {
aaudio_result_t result = AAUDIO_OK;
audio_config_base_t currentConfig = *config;
- audio_port_handle_t deviceId;
+ android::DeviceIdVector deviceIds;
const audio_attributes_t attributes = getAudioAttributesFrom(this);
- deviceId = mRequestedDeviceId;
+ if (mRequestedDeviceId != AAUDIO_UNSPECIFIED) {
+ deviceIds.push_back(mRequestedDeviceId);
+ }
const aaudio_direction_t direction = getDirection();
@@ -202,14 +204,9 @@
// Open HAL stream. Set mMmapStream
ALOGD("%s trying to open MMAP stream with format=%#x, "
- "sample_rate=%u, channel_mask=%#x, device=%d",
+ "sample_rate=%u, channel_mask=%#x, device=%s",
__func__, config->format, config->sample_rate,
- config->channel_mask, deviceId);
-
- android::DeviceIdVector deviceIds;
- if (deviceId != AAUDIO_UNSPECIFIED) {
- deviceIds.push_back(deviceId);
- }
+ config->channel_mask, android::toString(deviceIds).c_str());
const std::lock_guard<std::mutex> lock(mMmapStreamLock);
const status_t status = MmapStreamInterface::openMmapStream(streamDirection,
@@ -233,12 +230,11 @@
config->channel_mask = currentConfig.channel_mask;
return AAUDIO_ERROR_UNAVAILABLE;
}
- deviceId = android::getFirstDeviceId(deviceIds);
- if (deviceId == AAUDIO_UNSPECIFIED) {
- ALOGW("%s() - openMmapStream() failed to set deviceId", __func__);
+ if (deviceIds.empty()) {
+ ALOGW("%s() - openMmapStream() failed to set deviceIds", __func__);
}
- setDeviceId(deviceId);
+ setDeviceIds(deviceIds);
if (sessionId == AUDIO_SESSION_ALLOCATE) {
ALOGW("%s() - openMmapStream() failed to set sessionId", __func__);
@@ -250,8 +246,8 @@
: (aaudio_session_id_t) sessionId;
setSessionId(actualSessionId);
- ALOGD("%s(format = 0x%X) deviceId = %d, sessionId = %d",
- __func__, config->format, getDeviceId(), getSessionId());
+ ALOGD("%s(format = 0x%X) deviceIds = %s, sessionId = %d",
+ __func__, config->format, toString(getDeviceIds()).c_str(), getSessionId());
// Create MMAP/NOIRQ buffer.
result = createMmapBuffer_l();
@@ -280,9 +276,9 @@
mDataReportOffsetNanos = ((int64_t)mTimestampGracePeriodMs) * AAUDIO_NANOS_PER_MILLISECOND;
- ALOGD("%s() got rate = %d, channels = %d channelMask = %#x, deviceId = %d, capacity = %d\n",
+ ALOGD("%s() got rate = %d, channels = %d channelMask = %#x, deviceIds = %s, capacity = %d\n",
__func__, getSampleRate(), getSamplesPerFrame(), getChannelMask(),
- deviceId, getBufferCapacity());
+ android::toString(deviceIds).c_str(), getBufferCapacity());
ALOGD("%s() got format = 0x%X = %s, frame size = %d, burst size = %d",
__func__, getFormat(), audio_format_to_string(getFormat()),
@@ -293,7 +289,11 @@
error:
close_l();
// restore original requests
- setDeviceId(mRequestedDeviceId);
+ android::DeviceIdVector requestedDeviceIds;
+ if (mRequestedDeviceId != AAUDIO_UNSPECIFIED) {
+ requestedDeviceIds.push_back(mRequestedDeviceId);
+ }
+ setDeviceIds(requestedDeviceIds);
setSessionId(requestedSessionId);
return result;
}
@@ -491,27 +491,26 @@
};
void AAudioServiceEndpointMMAP::onRoutingChanged(const android::DeviceIdVector& deviceIds) {
- const auto deviceId = android::getFirstDeviceId(deviceIds);
- // TODO(b/367816690): Compare the new and saved device sets.
- ALOGD("%s() called with dev %d, old = %d", __func__, deviceId, getDeviceId());
- if (getDeviceId() != deviceId) {
- if (getDeviceId() != AUDIO_PORT_HANDLE_NONE) {
+ ALOGD("%s() called with dev %s, old = %s", __func__, android::toString(deviceIds).c_str(),
+ android::toString(getDeviceIds()).c_str());
+ if (!android::areDeviceIdsEqual(getDeviceIds(), deviceIds)) {
+ if (!getDeviceIds().empty()) {
// When there is a routing changed, mmap stream should be disconnected. Set `mConnected`
- // as false here so that there won't be a new stream connect to this endpoint.
+ // as false here so that there won't be a new stream connected to this endpoint.
mConnected.store(false);
const android::sp<AAudioServiceEndpointMMAP> holdEndpoint(this);
- std::thread asyncTask([holdEndpoint, deviceId]() {
+ std::thread asyncTask([holdEndpoint, deviceIds]() {
ALOGD("onRoutingChanged() asyncTask launched");
// When routing changed, the stream is disconnected and cannot be used except for
// closing. In that case, it should be safe to release all registered streams.
// This can help release service side resource in case the client doesn't close
// the stream after receiving disconnect event.
holdEndpoint->releaseRegisteredStreams();
- holdEndpoint->setDeviceId(deviceId);
+ holdEndpoint->setDeviceIds(deviceIds);
});
asyncTask.detach();
} else {
- setDeviceId(deviceId);
+ setDeviceIds(deviceIds);
}
}
};
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index 5e1e594..f54de5e 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -64,7 +64,7 @@
const AAudioStreamConfiguration &configuration = request.getConstantConfiguration();
copyFrom(configuration);
- mRequestedDeviceId = configuration.getDeviceId();
+ mRequestedDeviceId = android::getFirstDeviceId(configuration.getDeviceIds());
AudioStreamBuilder builder;
builder.copyFrom(configuration);
@@ -79,7 +79,7 @@
setSampleRate(mStreamInternal->getSampleRate());
setChannelMask(mStreamInternal->getChannelMask());
- setDeviceId(mStreamInternal->getDeviceId());
+ setDeviceIds(mStreamInternal->getDeviceIds());
setSessionId(mStreamInternal->getSessionId());
setFormat(AUDIO_FORMAT_PCM_FLOAT); // force for mixer
setHardwareSampleRate(mStreamInternal->getHardwareSampleRate());
@@ -220,7 +220,7 @@
void AAudioServiceEndpointShared::handleDisconnectRegisteredStreamsAsync() {
android::sp<AAudioServiceEndpointShared> holdEndpoint(this);
// When there is a routing changed, mmap stream should be disconnected. Set `mConnected`
- // as false here so that there won't be a new stream connect to this endpoint.
+ // as false here so that there won't be a new stream connected to this endpoint.
mConnected.store(false);
std::thread asyncTask([holdEndpoint]() {
// When handling disconnection, the service side has disconnected. In that case,
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 78cf706..1c24f18 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -127,7 +127,8 @@
.set(AMEDIAMETRICS_PROP_DIRECTION,
AudioGlobal_convertDirectionToText(getDirection()))
.set(AMEDIAMETRICS_PROP_ENCODING, toString(getFormat()).c_str())
- .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEID, (int32_t)getDeviceId())
+ .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEID, android::getFirstDeviceId(getDeviceIds()))
+ .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEIDS, android::toString(getDeviceIds()).c_str())
.set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)getSampleRate())
.set(AMEDIAMETRICS_PROP_SESSIONID, (int32_t)getSessionId())
.set(AMEDIAMETRICS_PROP_SOURCE, toString(attributes.source).c_str())
diff --git a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
index f5c2e6c..e80f51d 100644
--- a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
+++ b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
@@ -372,7 +372,8 @@
request.setAttributionSource(attributionSource);
request.setInService(fdp.ConsumeBool());
- request.getConfiguration().setDeviceId(fdp.ConsumeIntegral<int32_t>());
+ android::DeviceIdVector DeviceIdVector = { fdp.ConsumeIntegral<int32_t>() };
+ request.getConfiguration().setDeviceIds(DeviceIdVector);
request.getConfiguration().setSampleRate(fdp.ConsumeIntegral<int32_t>());
request.getConfiguration().setChannelMask((aaudio_channel_mask_t)(
fdp.ConsumeBool()