diff --git a/include/media/MmapStreamInterface.h b/include/media/MmapStreamInterface.h index 0196a0c9d4..b3bf16d04b 100644 --- a/include/media/MmapStreamInterface.h +++ b/include/media/MmapStreamInterface.h @@ -107,12 +107,15 @@ class MmapStreamInterface : public virtual RefBase * 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 f9da8b4519..e8c91fc935 100644 --- a/media/libaaudio/src/binding/AAudioBinderClient.h +++ b/media/libaaudio/src/binding/AAudioBinderClient.h @@ -98,8 +98,9 @@ public: 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 a64405b1da..9c28cc7305 100644 --- a/media/libaaudio/src/binding/AAudioServiceInterface.h +++ b/media/libaaudio/src/binding/AAudioServiceInterface.h @@ -89,8 +89,9 @@ public: 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 b6548e6325..fcccf03112 100644 --- a/media/libaaudio/src/client/AudioStreamInternal.cpp +++ b/media/libaaudio/src/client/AudioStreamInternal.cpp @@ -429,13 +429,14 @@ aaudio_result_t AudioStreamInternal::unregisterThread() { } 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 8843a8a3b6..095f30c280 100644 --- a/media/libaaudio/src/client/AudioStreamInternal.h +++ b/media/libaaudio/src/client/AudioStreamInternal.h @@ -90,6 +90,7 @@ public: 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 40519b0be7..5c20a2d514 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -681,7 +681,8 @@ using effect_buffer_t = int16_t; 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 d8d4d35cb9..105fa14fec 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -8633,10 +8633,10 @@ status_t AudioFlinger::MmapThreadHandle::getMmapPosition(struct audio_mmap_posit } 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::exitStandby() } 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 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client, } // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ? - sp track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId, - isOutput(), client.clientUid, client.clientPid, - IPCThreadState::self()->getCallingPid(), portId); + sp 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 8149e95b8e..e5a6196031 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -1776,7 +1776,9 @@ class MmapThread : public ThreadBase 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 af8c67b3a3..aba8e0887b 100644 --- a/services/oboeservice/AAudioService.cpp +++ b/services/oboeservice/AAudioService.cpp @@ -310,14 +310,15 @@ aaudio_result_t AAudioService::unregisterAudioThread(aaudio_handle_t streamHandl } 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 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 43a59c3eef..eddb5a0593 100644 --- a/services/oboeservice/AAudioService.h +++ b/services/oboeservice/AAudioService.h @@ -77,8 +77,9 @@ public: 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 2753f1f536..647dcf770b 100644 --- a/services/oboeservice/AAudioServiceEndpoint.cpp +++ b/services/oboeservice/AAudioServiceEndpoint.cpp @@ -138,3 +138,36 @@ bool AAudioServiceEndpoint::matches(const AAudioStreamConfiguration& configurati } 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 a2f66a50f5..a6bb019ebf 100644 --- a/services/oboeservice/AAudioServiceEndpoint.h +++ b/services/oboeservice/AAudioServiceEndpoint.h @@ -60,6 +60,7 @@ public: 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 @@ protected: void disconnectRegisteredStreams(); + static audio_attributes_t getAudioAttributesFrom(const AAudioStreamParameters *params); + mutable std::mutex mLockStreams; std::vector> mRegisteredStreams; diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp index 5bdb8eb860..af2710dc42 100644 --- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp +++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp @@ -79,32 +79,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamReques 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 @@ aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamReques 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 @@ aaudio_result_t AAudioServiceEndpointMMAP::startStream(spstart(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 5e815e00c4..f599066e30 100644 --- a/services/oboeservice/AAudioServiceEndpointMMAP.h +++ b/services/oboeservice/AAudioServiceEndpointMMAP.h @@ -59,7 +59,8 @@ public: 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 9b3b3b86b5..21253c85b0 100644 --- a/services/oboeservice/AAudioServiceEndpointShared.cpp +++ b/services/oboeservice/AAudioServiceEndpointShared.cpp @@ -152,7 +152,9 @@ aaudio_result_t AAudioServiceEndpointShared::startStream(spstartClient(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 097bc64004..aaab567f31 100644 --- a/services/oboeservice/AAudioServiceStreamBase.h +++ b/services/oboeservice/AAudioServiceStreamBase.h @@ -111,7 +111,8 @@ public: 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 f4e72b7bd3..639a0a89f4 100644 --- a/services/oboeservice/AAudioServiceStreamMMAP.cpp +++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp @@ -86,7 +86,7 @@ aaudio_result_t AAudioServiceStreamMMAP::startDevice() { 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::stop() { } 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 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 3d56623129..91054691ad 100644 --- a/services/oboeservice/AAudioServiceStreamMMAP.h +++ b/services/oboeservice/AAudioServiceStreamMMAP.h @@ -63,6 +63,7 @@ public: 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;