Add AudioDeviceVector to MMAP path
This CL adds AudioDeviceVector in the MMAP interface between
AudioFlinger and AAudioService.
Bug: 367816690
Test: OboeTester Test Output
Flag: android.media.audio.routed_device_ids
Change-Id: Ib658a36e91ee9f0336a59855d33cb326497a1bdc
diff --git a/include/media/MmapStreamCallback.h b/include/media/MmapStreamCallback.h
index 76ee6d7..a3876d9 100644
--- a/include/media/MmapStreamCallback.h
+++ b/include/media/MmapStreamCallback.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_AUDIO_MMAP_STREAM_CALLBACK_H
#define ANDROID_AUDIO_MMAP_STREAM_CALLBACK_H
+#include <media/AudioContainers.h>
#include <system/audio.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -42,10 +43,10 @@
virtual void onVolumeChanged(float volume) = 0;
/**
- * The device the stream is routed to/from has changed
- * \param[in] onRoutingChanged the unique device ID of the new device.
+ * The devices the stream is routed to/from has changed
+ * \param[in] deviceIds a set of the device IDs of the new devices.
*/
- virtual void onRoutingChanged(audio_port_handle_t deviceId) = 0;
+ virtual void onRoutingChanged(const DeviceIdVector& deviceIds) = 0;
protected:
MmapStreamCallback() {}
diff --git a/include/media/MmapStreamInterface.h b/include/media/MmapStreamInterface.h
index 7725175..3d29335 100644
--- a/include/media/MmapStreamInterface.h
+++ b/include/media/MmapStreamInterface.h
@@ -19,6 +19,7 @@
#include <system/audio.h>
#include <media/AudioClient.h>
+#include <media/AudioContainers.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -51,9 +52,10 @@
* Requested parameters as input,
* Actual parameters as output
* \param[in] client a AudioClient struct describing the first client using this stream.
- * \param[in,out] deviceId audio device the stream should preferably be routed to/from
- * Requested as input,
- * Actual as output
+ * \param[in,out] deviceIds audio devices the stream should preferably be routed to/from.
+ * Leave empty if there are no preferred devices.
+ * Requested as input,
+ * Actual as output
* \param[in,out] sessionId audio sessionId for the stream
* Requested as input, may be AUDIO_SESSION_ALLOCATE
* Actual as output
@@ -70,7 +72,7 @@
const audio_attributes_t *attr,
audio_config_base_t *config,
const AudioClient& client,
- audio_port_handle_t *deviceId,
+ DeviceIdVector *deviceIds,
audio_session_t *sessionId,
const sp<MmapStreamCallback>& callback,
sp<MmapStreamInterface>& interface,
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 5fb326f..2322780 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -541,7 +541,7 @@
const audio_attributes_t *attr,
audio_config_base_t *config,
const AudioClient& client,
- audio_port_handle_t *deviceId,
+ DeviceIdVector *deviceIds,
audio_session_t *sessionId,
const sp<MmapStreamCallback>& callback,
sp<MmapStreamInterface>& interface,
@@ -553,7 +553,7 @@
status_t ret = NO_INIT;
if (af != 0) {
ret = af->openMmapStream(
- direction, attr, config, client, deviceId,
+ direction, attr, config, client, deviceIds,
sessionId, callback, interface, handle);
}
return ret;
@@ -563,7 +563,7 @@
const audio_attributes_t *attr,
audio_config_base_t *config,
const AudioClient& client,
- audio_port_handle_t *deviceId,
+ DeviceIdVector *deviceIds,
audio_session_t *sessionId,
const sp<MmapStreamCallback>& callback,
sp<MmapStreamInterface>& interface,
@@ -630,22 +630,17 @@
bool isBitPerfect;
float volume;
bool muted;
- DeviceIdVector selectedDeviceIds;
- if (*deviceId != AUDIO_PORT_HANDLE_NONE) {
- selectedDeviceIds.push_back(*deviceId);
- }
ret = AudioSystem::getOutputForAttr(&localAttr, &io,
actualSessionId,
&streamType, adjAttributionSource,
&fullConfig,
(audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
AUDIO_OUTPUT_FLAG_DIRECT),
- &selectedDeviceIds, &portId, &secondaryOutputs,
+ deviceIds, &portId, &secondaryOutputs,
&isSpatialized,
&isBitPerfect,
&volume,
&muted);
- *deviceId = getFirstDeviceId(selectedDeviceIds);
if (ret != NO_ERROR) {
config->sample_rate = fullConfig.sample_rate;
config->channel_mask = fullConfig.channel_mask;
@@ -654,12 +649,17 @@
ALOGW_IF(!secondaryOutputs.empty(),
"%s does not support secondary outputs, ignoring them", __func__);
} else {
+ audio_port_handle_t deviceId = getFirstDeviceId(*deviceIds);
ret = AudioSystem::getInputForAttr(&localAttr, &io,
RECORD_RIID_INVALID,
actualSessionId,
adjAttributionSource,
config,
- AUDIO_INPUT_FLAG_MMAP_NOIRQ, deviceId, &portId);
+ AUDIO_INPUT_FLAG_MMAP_NOIRQ, &deviceId, &portId);
+ deviceIds->clear();
+ if (deviceId != AUDIO_PORT_HANDLE_NONE) {
+ deviceIds->push_back(deviceId);
+ }
}
if (ret != NO_ERROR) {
return ret;
@@ -673,7 +673,7 @@
const sp<IAfMmapThread> thread = mMmapThreads.valueFor(io);
if (thread != 0) {
interface = IAfMmapThread::createMmapStreamInterfaceAdapter(thread);
- thread->configure(&localAttr, streamType, actualSessionId, callback, *deviceId, portId);
+ thread->configure(&localAttr, streamType, actualSessionId, callback, *deviceIds, portId);
*handle = portId;
*sessionId = actualSessionId;
config->sample_rate = thread->sampleRate();
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 042194f..133410e 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -439,7 +439,7 @@
const audio_attributes_t *attr,
audio_config_base_t *config,
const AudioClient& client,
- audio_port_handle_t *deviceId,
+ DeviceIdVector *deviceIds,
audio_session_t *sessionId,
const sp<MmapStreamCallback>& callback,
sp<MmapStreamInterface>& interface,
diff --git a/services/audioflinger/IAfThread.h b/services/audioflinger/IAfThread.h
index a13819c..3163d4c 100644
--- a/services/audioflinger/IAfThread.h
+++ b/services/audioflinger/IAfThread.h
@@ -661,7 +661,7 @@
audio_stream_type_t streamType,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
- audio_port_handle_t deviceId,
+ const DeviceIdVector& deviceIds,
audio_port_handle_t portId) EXCLUDES_ThreadBase_Mutex = 0;
virtual void disconnect() EXCLUDES_ThreadBase_Mutex = 0;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index db01cff..7ed53f2 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -10393,13 +10393,13 @@
audio_stream_type_t streamType __unused,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
- audio_port_handle_t deviceId,
+ const DeviceIdVector& deviceIds,
audio_port_handle_t portId)
{
mAttr = *attr;
mSessionId = sessionId;
mCallback = callback;
- mDeviceId = deviceId;
+ mDeviceIds = deviceIds;
mPortId = portId;
}
@@ -10492,12 +10492,7 @@
audio_stream_type_t stream = streamType_l();
audio_output_flags_t flags =
(audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
- DeviceIdVector deviceIds;
- if (mDeviceId != AUDIO_PORT_HANDLE_NONE) {
- deviceIds.push_back(mDeviceId);
- } else {
- ALOGW("%s no device id set", __func__);
- }
+ DeviceIdVector deviceIds = mDeviceIds;
std::vector<audio_io_handle_t> secondaryOutputs;
bool isSpatialized;
bool isBitPerfect;
@@ -10524,7 +10519,7 @@
config.sample_rate = mSampleRate;
config.channel_mask = mChannelMask;
config.format = mFormat;
- audio_port_handle_t deviceId = mDeviceId;
+ audio_port_handle_t deviceId = getFirstDeviceId(mDeviceIds);
mutex().unlock();
ret = AudioSystem::getInputForAttr(&localAttr, &io,
RECORD_RIID_INVALID,
@@ -10877,7 +10872,7 @@
// store new device and send to effects
audio_devices_t type = AUDIO_DEVICE_NONE;
- audio_port_handle_t deviceId;
+ DeviceIdVector deviceIds;
AudioDeviceTypeAddrVector sinkDeviceTypeAddrs;
AudioDeviceTypeAddr sourceDeviceTypeAddr;
uint32_t numDevices = 0;
@@ -10891,12 +10886,12 @@
type = static_cast<audio_devices_t>(type | patch->sinks[i].ext.device.type);
sinkDeviceTypeAddrs.emplace_back(patch->sinks[i].ext.device.type,
patch->sinks[i].ext.device.address);
+ deviceIds.push_back(patch->sinks[i].id);
}
- deviceId = patch->sinks[0].id;
numDevices = mPatch.num_sinks;
} else {
type = patch->sources[0].ext.device.type;
- deviceId = patch->sources[0].id;
+ deviceIds.push_back(patch->sources[0].id);
numDevices = mPatch.num_sources;
sourceDeviceTypeAddr.mType = patch->sources[0].ext.device.type;
sourceDeviceTypeAddr.setAddress(patch->sources[0].ext.device.address);
@@ -10922,11 +10917,11 @@
// 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 (mDeviceId != deviceId) {
+ if (mDeviceIds != deviceIds) {
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.
- callback->onRoutingChanged(deviceId);
+ callback->onRoutingChanged(deviceIds);
}
}
@@ -10946,7 +10941,7 @@
*handle = AUDIO_PATCH_HANDLE_NONE;
}
- if (numDevices == 0 || mDeviceId != deviceId) {
+ if (numDevices == 0 || mDeviceIds != deviceIds) {
if (isOutput()) {
sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
mOutDeviceTypeAddrs = sinkDeviceTypeAddrs;
@@ -10956,7 +10951,7 @@
mInDeviceTypeAddr = sourceDeviceTypeAddr;
}
mPatch = *patch;
- mDeviceId = deviceId;
+ mDeviceIds = deviceIds;
}
// Force meteadata update after a route change
mActiveTracks.setHasChanged();
@@ -11111,7 +11106,8 @@
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.
- callback->onRoutingChanged(AUDIO_PORT_HANDLE_NONE);
+ DeviceIdVector emptyDeviceIdVector;
+ callback->onRoutingChanged(emptyDeviceIdVector);
} else if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
ALOGW("Could not notify MMAP stream tear down: no onRoutingChanged callback!");
mNoCallbackWarningCount++;
@@ -11203,11 +11199,11 @@
audio_stream_type_t streamType,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
- audio_port_handle_t deviceId,
+ const DeviceIdVector& deviceIds,
audio_port_handle_t portId)
{
audio_utils::lock_guard l(mutex());
- MmapThread::configure_l(attr, streamType, sessionId, callback, deviceId, portId);
+ MmapThread::configure_l(attr, streamType, sessionId, callback, deviceIds, portId);
mStreamType = streamType;
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 0c5a2c3..1d6e244 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -2243,17 +2243,17 @@
audio_stream_type_t streamType,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
- audio_port_handle_t deviceId,
+ const DeviceIdVector& deviceIds,
audio_port_handle_t portId) override EXCLUDES_ThreadBase_Mutex {
audio_utils::lock_guard l(mutex());
- configure_l(attr, streamType, sessionId, callback, deviceId, portId);
+ configure_l(attr, streamType, sessionId, callback, deviceIds, portId);
}
void configure_l(const audio_attributes_t* attr,
audio_stream_type_t streamType,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
- audio_port_handle_t deviceId,
+ const DeviceIdVector& deviceIds,
audio_port_handle_t portId) REQUIRES(mutex());
void disconnect() final EXCLUDES_ThreadBase_Mutex;
@@ -2363,9 +2363,9 @@
void dumpTracks_l(int fd, const Vector<String16>& args) final REQUIRES(mutex());
/**
- * @brief mDeviceId current device port unique identifier
+ * @brief mDeviceIds current device port unique identifiers
*/
- audio_port_handle_t mDeviceId GUARDED_BY(mutex()) = AUDIO_PORT_HANDLE_NONE;
+ DeviceIdVector mDeviceIds GUARDED_BY(mutex());
audio_attributes_t mAttr GUARDED_BY(mutex());
audio_session_t mSessionId GUARDED_BY(mutex());
@@ -2397,7 +2397,7 @@
audio_stream_type_t streamType,
audio_session_t sessionId,
const sp<MmapStreamCallback>& callback,
- audio_port_handle_t deviceId,
+ const DeviceIdVector& deviceIds,
audio_port_handle_t portId) final EXCLUDES_ThreadBase_Mutex;
AudioStreamOut* clearOutput() final EXCLUDES_ThreadBase_Mutex;
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index d663f37..398068d 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -206,12 +206,17 @@
__func__, config->format, config->sample_rate,
config->channel_mask, deviceId);
+ android::DeviceIdVector deviceIds;
+ if (deviceId != AAUDIO_UNSPECIFIED) {
+ deviceIds.push_back(deviceId);
+ }
+
const std::lock_guard<std::mutex> lock(mMmapStreamLock);
const status_t status = MmapStreamInterface::openMmapStream(streamDirection,
&attributes,
config,
mMmapClient,
- &deviceId,
+ &deviceIds,
&sessionId,
this, // callback
mMmapStream,
@@ -228,6 +233,7 @@
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__);
@@ -476,8 +482,9 @@
}
};
-void AAudioServiceEndpointMMAP::onRoutingChanged(audio_port_handle_t portHandle) {
- const auto deviceId = static_cast<int32_t>(portHandle);
+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) {
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index 962d390..a4eeba1 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -83,7 +83,7 @@
void onVolumeChanged(float volume) override;
- void onRoutingChanged(audio_port_handle_t portHandle) override;
+ void onRoutingChanged(const android::DeviceIdVector& deviceIds) override;
// ------------------------------------------------------------------------------
aaudio_result_t getDownDataDescription(AudioEndpointParcelable* parcelable);
diff --git a/services/oboeservice/Android.bp b/services/oboeservice/Android.bp
index 67b319f..8200ab5 100644
--- a/services/oboeservice/Android.bp
+++ b/services/oboeservice/Android.bp
@@ -89,6 +89,7 @@
"libaaudio_internal",
"libaudioclient",
"libaudioclient_aidl_conversion",
+ "libaudiofoundation",
"libaudioutils",
"libbase",
"libbinder",
diff --git a/services/oboeservice/fuzzer/Android.bp b/services/oboeservice/fuzzer/Android.bp
index 97825b3..8f672e1 100644
--- a/services/oboeservice/fuzzer/Android.bp
+++ b/services/oboeservice/fuzzer/Android.bp
@@ -44,6 +44,7 @@
"libaudioclient",
"libaudioclient_aidl_conversion",
"libaudioflinger",
+ "libaudiofoundation",
"libaudioutils",
"libbase",
"libbinder",