Add audio attributes info when starting aaudio tracks on MMAP mix.
In aaudio, when adding tracks to mixed stream, it is needed to update
audio attributes to HAL whenever the tracks are added or removed.
Currently, only the audio attributes used to open the stream will be
sent to the HAL. In that case, adding audio attributes of the clients
when starting the stream can help solve the problem. In audio flinger,
the client's audio attributes will be used to create MmapTrack.
Test: play multiple aaudio tracks, add log
Bug: 77279923
Change-Id: Ic1c536049e194a2bb7513425ee4828d52769d27f
diff --git a/include/media/MmapStreamInterface.h b/include/media/MmapStreamInterface.h
index 0196a0c..b3bf16d 100644
--- a/include/media/MmapStreamInterface.h
+++ b/include/media/MmapStreamInterface.h
@@ -107,12 +107,15 @@
* createMmapBuffer() must be called before calling start()
*
* \param[in] client a AudioClient struct describing the client starting on this stream.
+ * \param[in] attr audio attributes provided by the client.
* \param[out] handle unique handle for this instance. Used with stop().
* \return OK in case of success.
* NO_INIT in case of initialization error
* INVALID_OPERATION if called out of sequence
*/
- virtual status_t start(const AudioClient& client, audio_port_handle_t *handle) = 0;
+ virtual status_t start(const AudioClient& client,
+ const audio_attributes_t *attr,
+ audio_port_handle_t *handle) = 0;
/**
* Stop a stream operating in mmap mode.
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.h b/media/libaaudio/src/binding/AAudioBinderClient.h
index f9da8b4..e8c91fc 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.h
+++ b/media/libaaudio/src/binding/AAudioBinderClient.h
@@ -98,8 +98,9 @@
pid_t clientThreadId) override;
aaudio_result_t startClient(aaudio_handle_t streamHandle __unused,
- const android::AudioClient& client __unused,
- audio_port_handle_t *clientHandle) override {
+ const android::AudioClient& client __unused,
+ const audio_attributes_t *attr __unused,
+ audio_port_handle_t *clientHandle __unused) override {
return AAUDIO_ERROR_UNAVAILABLE;
}
diff --git a/media/libaaudio/src/binding/AAudioServiceInterface.h b/media/libaaudio/src/binding/AAudioServiceInterface.h
index a64405b..9c28cc7 100644
--- a/media/libaaudio/src/binding/AAudioServiceInterface.h
+++ b/media/libaaudio/src/binding/AAudioServiceInterface.h
@@ -89,8 +89,9 @@
pid_t clientThreadId) = 0;
virtual aaudio_result_t startClient(aaudio_handle_t streamHandle,
- const android::AudioClient& client,
- audio_port_handle_t *clientHandle) = 0;
+ const android::AudioClient& client,
+ const audio_attributes_t *attr,
+ audio_port_handle_t *clientHandle) = 0;
virtual aaudio_result_t stopClient(aaudio_handle_t streamHandle,
audio_port_handle_t clientHandle) = 0;
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index b6548e6..fcccf03 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -429,13 +429,14 @@
}
aaudio_result_t AudioStreamInternal::startClient(const android::AudioClient& client,
+ const audio_attributes_t *attr,
audio_port_handle_t *portHandle) {
ALOGV("%s() called", __func__);
if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
return AAUDIO_ERROR_INVALID_STATE;
}
aaudio_result_t result = mServiceInterface.startClient(mServiceStreamHandle,
- client, portHandle);
+ client, attr, portHandle);
ALOGV("%s(%d) returning %d", __func__, *portHandle, result);
return result;
}
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 8843a8a..095f30c 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -90,6 +90,7 @@
int64_t calculateReasonableTimeout();
aaudio_result_t startClient(const android::AudioClient& client,
+ const audio_attributes_t *attr,
audio_port_handle_t *clientHandle);
aaudio_result_t stopClient(audio_port_handle_t clientHandle);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 40519b0..5c20a2d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -681,7 +681,8 @@
struct audio_mmap_buffer_info *info);
virtual status_t getMmapPosition(struct audio_mmap_position *position);
virtual status_t start(const AudioClient& client,
- audio_port_handle_t *handle);
+ const audio_attributes_t *attr,
+ audio_port_handle_t *handle);
virtual status_t stop(audio_port_handle_t handle);
virtual status_t standby();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d8d4d35..105fa14 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -8633,10 +8633,10 @@
}
status_t AudioFlinger::MmapThreadHandle::start(const AudioClient& client,
- audio_port_handle_t *handle)
+ const audio_attributes_t *attr, audio_port_handle_t *handle)
{
- return mThread->start(client, handle);
+ return mThread->start(client, attr, handle);
}
status_t AudioFlinger::MmapThreadHandle::stop(audio_port_handle_t handle)
@@ -8741,6 +8741,7 @@
}
status_t AudioFlinger::MmapThread::start(const AudioClient& client,
+ const audio_attributes_t *attr,
audio_port_handle_t *handle)
{
ALOGV("%s clientUid %d mStandby %d mPortId %d *handle %d", __FUNCTION__,
@@ -8831,9 +8832,10 @@
}
// Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
- sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
- isOutput(), client.clientUid, client.clientPid,
- IPCThreadState::self()->getCallingPid(), portId);
+ sp<MmapTrack> track = new MmapTrack(this, attr == nullptr ? mAttr : *attr, mSampleRate, mFormat,
+ mChannelMask, mSessionId, isOutput(), client.clientUid,
+ client.clientPid, IPCThreadState::self()->getCallingPid(),
+ portId);
if (isOutput()) {
// force volume update when a new track is added
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 8149e95..e5a6196 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1776,7 +1776,9 @@
status_t createMmapBuffer(int32_t minSizeFrames,
struct audio_mmap_buffer_info *info);
status_t getMmapPosition(struct audio_mmap_position *position);
- status_t start(const AudioClient& client, audio_port_handle_t *handle);
+ status_t start(const AudioClient& client,
+ const audio_attributes_t *attr,
+ audio_port_handle_t *handle);
status_t stop(audio_port_handle_t handle);
status_t standby();
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index af8c67b..aba8e08 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -310,14 +310,15 @@
}
aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle,
- const android::AudioClient& client,
- audio_port_handle_t *clientHandle) {
+ const android::AudioClient& client,
+ const audio_attributes_t *attr,
+ audio_port_handle_t *clientHandle) {
sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
if (serviceStream.get() == nullptr) {
ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle);
return AAUDIO_ERROR_INVALID_HANDLE;
}
- aaudio_result_t result = serviceStream->startClient(client, clientHandle);
+ aaudio_result_t result = serviceStream->startClient(client, attr, clientHandle);
return checkForPendingClose(serviceStream, result);
}
diff --git a/services/oboeservice/AAudioService.h b/services/oboeservice/AAudioService.h
index 43a59c3..eddb5a0 100644
--- a/services/oboeservice/AAudioService.h
+++ b/services/oboeservice/AAudioService.h
@@ -77,8 +77,9 @@
pid_t tid) override;
aaudio_result_t startClient(aaudio::aaudio_handle_t streamHandle,
- const android::AudioClient& client,
- audio_port_handle_t *clientHandle) override;
+ const android::AudioClient& client,
+ const audio_attributes_t *attr,
+ audio_port_handle_t *clientHandle) override;
aaudio_result_t stopClient(aaudio::aaudio_handle_t streamHandle,
audio_port_handle_t clientHandle) override;
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 2753f1f..647dcf7 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -138,3 +138,36 @@
}
return true;
}
+
+// static
+audio_attributes_t AAudioServiceEndpoint::getAudioAttributesFrom(
+ const AAudioStreamParameters *params) {
+ if (params == nullptr) {
+ return {};
+ }
+ const aaudio_direction_t direction = params->getDirection();
+
+ const audio_content_type_t contentType =
+ AAudioConvert_contentTypeToInternal(params->getContentType());
+ // Usage only used for OUTPUT
+ const audio_usage_t usage = (direction == AAUDIO_DIRECTION_OUTPUT)
+ ? AAudioConvert_usageToInternal(params->getUsage())
+ : AUDIO_USAGE_UNKNOWN;
+ const audio_source_t source = (direction == AAUDIO_DIRECTION_INPUT)
+ ? AAudioConvert_inputPresetToAudioSource(params->getInputPreset())
+ : AUDIO_SOURCE_DEFAULT;
+ audio_flags_mask_t flags;
+ if (direction == AAUDIO_DIRECTION_OUTPUT) {
+ flags = AUDIO_FLAG_LOW_LATENCY
+ | AAudioConvert_allowCapturePolicyToAudioFlagsMask(params->getAllowedCapturePolicy());
+ } else {
+ flags = AUDIO_FLAG_LOW_LATENCY
+ | AAudioConvert_privacySensitiveToAudioFlagsMask(params->isPrivacySensitive());
+ }
+ return {
+ .content_type = contentType,
+ .usage = usage,
+ .source = source,
+ .flags = flags,
+ .tags = "" };
+}
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index a2f66a5..a6bb019 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -60,6 +60,7 @@
audio_port_handle_t clientHandle) = 0;
virtual aaudio_result_t startClient(const android::AudioClient& client,
+ const audio_attributes_t *attr,
audio_port_handle_t *clientHandle) {
ALOGD("AAudioServiceEndpoint::startClient(...) AAUDIO_ERROR_UNAVAILABLE");
return AAUDIO_ERROR_UNAVAILABLE;
@@ -118,6 +119,8 @@
void disconnectRegisteredStreams();
+ static audio_attributes_t getAudioAttributesFrom(const AAudioStreamParameters *params);
+
mutable std::mutex mLockStreams;
std::vector<android::sp<AAudioServiceStreamBase>> mRegisteredStreams;
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 5bdb8eb..af2710d 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -79,32 +79,7 @@
copyFrom(request.getConstantConfiguration());
- aaudio_direction_t direction = getDirection();
-
- const audio_content_type_t contentType =
- AAudioConvert_contentTypeToInternal(getContentType());
- // Usage only used for OUTPUT
- const audio_usage_t usage = (direction == AAUDIO_DIRECTION_OUTPUT)
- ? AAudioConvert_usageToInternal(getUsage())
- : AUDIO_USAGE_UNKNOWN;
- const audio_source_t source = (direction == AAUDIO_DIRECTION_INPUT)
- ? AAudioConvert_inputPresetToAudioSource(getInputPreset())
- : AUDIO_SOURCE_DEFAULT;
- audio_flags_mask_t flags;
- if (direction == AAUDIO_DIRECTION_OUTPUT) {
- flags = AUDIO_FLAG_LOW_LATENCY
- | AAudioConvert_allowCapturePolicyToAudioFlagsMask(getAllowedCapturePolicy());
- } else {
- flags = AUDIO_FLAG_LOW_LATENCY
- | AAudioConvert_privacySensitiveToAudioFlagsMask(isPrivacySensitive());
- }
- const audio_attributes_t attributes = {
- .content_type = contentType,
- .usage = usage,
- .source = source,
- .flags = flags,
- .tags = ""
- };
+ const audio_attributes_t attributes = getAudioAttributesFrom(this);
mMmapClient.clientUid = request.getUserId();
mMmapClient.clientPid = request.getProcessId();
@@ -127,6 +102,8 @@
int32_t aaudioSamplesPerFrame = getSamplesPerFrame();
+ const aaudio_direction_t direction = getDirection();
+
if (direction == AAUDIO_DIRECTION_OUTPUT) {
config.channel_mask = (aaudioSamplesPerFrame == AAUDIO_UNSPECIFIED)
? AUDIO_CHANNEL_OUT_STEREO
@@ -269,7 +246,12 @@
// Start the client on behalf of the AAudio service.
// Use the port handle that was provided by openMmapStream().
audio_port_handle_t tempHandle = mPortHandle;
- aaudio_result_t result = startClient(mMmapClient, &tempHandle);
+ audio_attributes_t attr = {};
+ if (stream != nullptr) {
+ attr = getAudioAttributesFrom(stream.get());
+ }
+ aaudio_result_t result = startClient(
+ mMmapClient, stream == nullptr ? nullptr : &attr, &tempHandle);
// When AudioFlinger is passed a valid port handle then it should not change it.
LOG_ALWAYS_FATAL_IF(tempHandle != mPortHandle,
"%s() port handle not expected to change from %d to %d",
@@ -294,9 +276,10 @@
}
aaudio_result_t AAudioServiceEndpointMMAP::startClient(const android::AudioClient& client,
+ const audio_attributes_t *attr,
audio_port_handle_t *clientHandle) {
if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
- status_t status = mMmapStream->start(client, clientHandle);
+ status_t status = mMmapStream->start(client, attr, clientHandle);
return AAudioConvert_androidToAAudioResult(status);
}
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h
index 5e815e0..f599066 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.h
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.h
@@ -59,7 +59,8 @@
audio_port_handle_t clientHandle) override;
aaudio_result_t startClient(const android::AudioClient& client,
- audio_port_handle_t *clientHandle) override;
+ const audio_attributes_t *attr,
+ audio_port_handle_t *clientHandle) override;
aaudio_result_t stopClient(audio_port_handle_t clientHandle) override;
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index 9b3b3b8..21253c8 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -152,7 +152,9 @@
}
if (result == AAUDIO_OK) {
- result = getStreamInternal()->startClient(sharedStream->getAudioClient(), clientHandle);
+ const audio_attributes_t attr = getAudioAttributesFrom(sharedStream.get());
+ result = getStreamInternal()->startClient(
+ sharedStream->getAudioClient(), &attr, clientHandle);
if (result != AAUDIO_OK) {
if (--mRunningStreamCount == 0) { // atomic
stopSharingThread();
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index 097bc64..aaab567 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -111,7 +111,8 @@
virtual aaudio_result_t flush();
- virtual aaudio_result_t startClient(const android::AudioClient& client __unused,
+ virtual aaudio_result_t startClient(const android::AudioClient& client,
+ const audio_attributes_t *attr __unused,
audio_port_handle_t *clientHandle __unused) {
ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client);
return AAUDIO_ERROR_UNAVAILABLE;
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index f4e72b7..639a0a8 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -86,7 +86,7 @@
aaudio_result_t result = AAudioServiceStreamBase::startDevice();
if (!mInService && result == AAUDIO_OK) {
// Note that this can sometimes take 200 to 300 msec for a cold start!
- result = startClient(mMmapClient, &mClientHandle);
+ result = startClient(mMmapClient, nullptr /*const audio_attributes_t* */, &mClientHandle);
}
return result;
}
@@ -117,14 +117,15 @@
}
aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client,
- audio_port_handle_t *clientHandle) {
+ const audio_attributes_t *attr,
+ audio_port_handle_t *clientHandle) {
sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
if (endpoint == nullptr) {
ALOGE("%s() has no endpoint", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
// Start the client on behalf of the application. Generate a new porthandle.
- aaudio_result_t result = endpoint->startClient(client, clientHandle);
+ aaudio_result_t result = endpoint->startClient(client, attr, clientHandle);
return result;
}
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h
index 3d56623..9105469 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.h
+++ b/services/oboeservice/AAudioServiceStreamMMAP.h
@@ -63,6 +63,7 @@
aaudio_result_t stop() override;
aaudio_result_t startClient(const android::AudioClient& client,
+ const audio_attributes_t *attr,
audio_port_handle_t *clientHandle) override;
aaudio_result_t stopClient(audio_port_handle_t clientHandle) override;