From e13b58b988ab642d4ae5ca6d0a89013510714956 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Sun, 3 Apr 2016 11:50:58 -0700 Subject: audio: Send effect session notifications after startOutput success * Because we get a hellish firestorm during offload fallback, and our effects library really dislikes this. Change-Id: I22adb55d04502eedf03ce22f35f8b9f61de1c7b0 --- services/audiopolicy/service/AudioPolicyEffects.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'services/audiopolicy/service/AudioPolicyEffects.cpp') diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index f2d7f6f..725bc64 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -246,8 +246,6 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, if (idx < 0) { procDesc = new EffectVector(audioSession); mOutputSessions.add(audioSession, procDesc); - - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, true); } else { // EffectVector is existing and we just need to increase ref count procDesc = mOutputSessions.valueAt(idx); @@ -275,6 +273,7 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, } procDesc->setProcessorEnabled(true); + return 1; } return status; } -- cgit v1.1 From a4123803d0a0e9e0c69faa4207d357cc74a65d58 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 6 Apr 2016 18:35:02 -0700 Subject: audiopolicy: Be a little smarter with auto-attach * The edge cases, ZOMG! * Instead of relying on effects to be automatically attached, let's just always notify userspace and send a bit more information. This lets the application decide if effects should be attached rather than relying on a hard-coded configuration file. * Perform the setup in getOutputForAttr, but do it on the command thread so we don't block the client. OPO-593 Change-Id: I3900b349f2e895d51fa3a3dcc2de0c4bdf6dbc08 --- .../audiopolicy/service/AudioPolicyEffects.cpp | 32 ++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'services/audiopolicy/service/AudioPolicyEffects.cpp') diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 725bc64..bd1cc33 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -246,6 +246,7 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, if (idx < 0) { procDesc = new EffectVector(audioSession); mOutputSessions.add(audioSession, procDesc); + } else { // EffectVector is existing and we just need to increase ref count procDesc = mOutputSessions.valueAt(idx); @@ -273,11 +274,35 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, } procDesc->setProcessorEnabled(true); - return 1; } return status; } +status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t output, + audio_stream_type_t stream, + int session, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, uid_t uid) +{ + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + return BAD_VALUE; + } + ALOGV("doAddOutputSessionEffects()"); + + // create audio processors according to stream + status_t status = addOutputSessionEffects(output, stream, session); + if (status <= 0 && (status != NO_ERROR && status != ALREADY_EXISTS)) { + ALOGW("Failed to add effects on session %d", session); + } + + // notify listeners + mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)session, + flags, channelMask, uid, true); + + // Never return an error if effects setup fails. + return NO_ERROR; +} + status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, int audioSession) @@ -335,10 +360,13 @@ status_t AudioPolicyEffects::doReleaseOutputSessionEffects(audio_io_handle_t out procDesc->mEffects.clear(); delete procDesc; mOutputSessions.removeItemsAt(index); - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, false); ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d", audioSession); } + + mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)audioSession, + AUDIO_OUTPUT_FLAG_NONE, 0, -1, false); + return status; } -- cgit v1.1 From 32ef0556ae58ff6b7c6fe6fb0a17d3ff7f01de31 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Tue, 19 Apr 2016 02:41:45 -0700 Subject: audiopolicy: Clean up the mess * Since we're not using the policy directly to auto-attach, let's clean it up and remove the unused stuff. * Also fixes notifications for session release. This reverts commit 47f8c7303c9e2054f1492b02b6c7472385c52dc9. Change-Id: Ibe65f427773c6ef012dde4f289d10e4089c094ea --- .../audiopolicy/service/AudioPolicyEffects.cpp | 42 ++-------------------- 1 file changed, 2 insertions(+), 40 deletions(-) (limited to 'services/audiopolicy/service/AudioPolicyEffects.cpp') diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index bd1cc33..6a43bea 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -275,10 +275,11 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, procDesc->setProcessorEnabled(true); } + return status; } -status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t output, +status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t /* output */, audio_stream_type_t stream, int session, audio_output_flags_t flags, @@ -289,12 +290,6 @@ status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t output, } ALOGV("doAddOutputSessionEffects()"); - // create audio processors according to stream - status_t status = addOutputSessionEffects(output, stream, session); - if (status <= 0 && (status != NO_ERROR && status != ALREADY_EXISTS)) { - ALOGW("Failed to add effects on session %d", session); - } - // notify listeners mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)session, flags, channelMask, uid, true); @@ -319,42 +314,9 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu } EffectVector *procDesc = mOutputSessions.valueAt(index); - - // just in case it already has a death wish - if (procDesc->mRefCount == 0) { - return NO_ERROR; - } - procDesc->mRefCount--; ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d", audioSession, procDesc->mRefCount); - - if (procDesc->mRefCount == 0) { - mAudioPolicyService->releaseOutputSessionEffectsDelayed( - output, stream, audioSession, 10000); - } - - return status; -} - -status_t AudioPolicyEffects::doReleaseOutputSessionEffects(audio_io_handle_t output, - audio_stream_type_t stream, - int audioSession) -{ - status_t status = NO_ERROR; - (void) output; // argument not used for now - - Mutex::Autolock _l(mLock); - ssize_t index = mOutputSessions.indexOfKey(audioSession); - if (index < 0) { - ALOGV("doReleaseOutputSessionEffects: no output processing was attached to this stream"); - return NO_ERROR; - } - - EffectVector *procDesc = mOutputSessions.valueAt(index); - ALOGV("doReleaseOutputSessionEffects(): session: %d, refCount: %d", - audioSession, procDesc->mRefCount); - if (procDesc->mRefCount == 0) { procDesc->setProcessorEnabled(false); procDesc->mEffects.clear(); -- cgit v1.1 From c27a16c33c78a36482336a16199b1b8be794cea4 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Thu, 21 Apr 2016 23:22:00 -0700 Subject: audiopolicy: Fix notification not sent for session release Change-Id: Ifba4025532debc50c7931d08a9bcd1593d9b1721 --- services/audiopolicy/service/AudioPolicyEffects.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'services/audiopolicy/service/AudioPolicyEffects.cpp') diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 6a43bea..fce471f 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -325,10 +325,6 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d", audioSession); } - - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)audioSession, - AUDIO_OUTPUT_FLAG_NONE, 0, -1, false); - return status; } -- cgit v1.1 From 244deea89aaf3c5dfa8bd369a845276ae501cb5a Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Fri, 22 Apr 2016 18:26:43 -0700 Subject: audiopolicy: Revert all session callback patches. * This has been rearchitected in a better way, as this feature turns out to be more difficult than it seems. * Reverting all of this stuff and rolling it into a single commit. This reverts commit c27a16c33c78a36482336a16199b1b8be794cea4. This reverts commit 32ef0556ae58ff6b7c6fe6fb0a17d3ff7f01de31. This reverts commit 489c9fb62f02e1d23d6d6c89b22f7d19c596e65e. This reverts commit a4123803d0a0e9e0c69faa4207d357cc74a65d58. This reverts commit e13b58b988ab642d4ae5ca6d0a89013510714956. This reverts commit 47f8c7303c9e2054f1492b02b6c7472385c52dc9. This reverts commit 0479d7c79a7fd6f112e8dc7e45c009cf6602dbaa. Change-Id: Iaed9f198d806aa414c95960713e8187c98db248b --- .../audiopolicy/service/AudioPolicyEffects.cpp | 27 ++-------------------- 1 file changed, 2 insertions(+), 25 deletions(-) (limited to 'services/audiopolicy/service/AudioPolicyEffects.cpp') diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index fce471f..26857b1 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -28,7 +28,6 @@ #include #include #include -#include "AudioPolicyService.h" #include "AudioPolicyEffects.h" #include "ServiceUtilities.h" @@ -38,8 +37,7 @@ namespace android { // AudioPolicyEffects Implementation // ---------------------------------------------------------------------------- -AudioPolicyEffects::AudioPolicyEffects(AudioPolicyService *audioPolicyService) : - mAudioPolicyService(audioPolicyService) +AudioPolicyEffects::AudioPolicyEffects() { // load automatic audio effect modules if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE2, R_OK) == 0) { @@ -246,7 +244,6 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, if (idx < 0) { procDesc = new EffectVector(audioSession); mOutputSessions.add(audioSession, procDesc); - } else { // EffectVector is existing and we just need to increase ref count procDesc = mOutputSessions.valueAt(idx); @@ -275,29 +272,9 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, procDesc->setProcessorEnabled(true); } - return status; } -status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t /* output */, - audio_stream_type_t stream, - int session, - audio_output_flags_t flags, - audio_channel_mask_t channelMask, uid_t uid) -{ - if (uint32_t(stream) >= AUDIO_STREAM_CNT) { - return BAD_VALUE; - } - ALOGV("doAddOutputSessionEffects()"); - - // notify listeners - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)session, - flags, channelMask, uid, true); - - // Never return an error if effects setup fails. - return NO_ERROR; -} - status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, int audioSession) @@ -322,7 +299,7 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu procDesc->mEffects.clear(); delete procDesc; mOutputSessions.removeItemsAt(index); - ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d", + ALOGV("releaseOutputSessionEffects(): output processing released from session: %d", audioSession); } return status; -- cgit v1.1 From 3f9eb321481de3e118632a594bf1b0c9001c281c Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Fri, 22 Apr 2016 18:32:39 -0700 Subject: audiopolicy: Add AudioSessionInfo API * This patch introduces a new API which allows applications to query the state of the audio effects system, and receive callbacks with the necessary information to attach effects to any stream. * In the future, this may come as part of the AudioPort system, but since that's an active area of development by Google, we will dodge it for now. * The policy now simply keeps a refcounted list of objects which hold various bits of stream metadata. Callbacks are sent on stream open/close to applications which might be listening for them. Change-Id: I2d554d36e1378f4eb7b276010a3bfe8345c22ecd --- .../audiopolicy/service/AudioPolicyEffects.cpp | 111 ++++++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) (limited to 'services/audiopolicy/service/AudioPolicyEffects.cpp') diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 26857b1..31b1637 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -28,6 +28,7 @@ #include #include #include +#include "AudioPolicyService.h" #include "AudioPolicyEffects.h" #include "ServiceUtilities.h" @@ -37,7 +38,8 @@ namespace android { // AudioPolicyEffects Implementation // ---------------------------------------------------------------------------- -AudioPolicyEffects::AudioPolicyEffects() +AudioPolicyEffects::AudioPolicyEffects(AudioPolicyService *audioPolicyService) : + mAudioPolicyService(audioPolicyService) { // load automatic audio effect modules if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE2, R_OK) == 0) { @@ -226,6 +228,8 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, { status_t status = NO_ERROR; + ALOGV("addOutputSessionEffects %d", audioSession); + Mutex::Autolock _l(mLock); // create audio processors according to stream // FIXME: should we have specific post processing settings for internal streams? @@ -233,6 +237,22 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, if (stream >= AUDIO_STREAM_PUBLIC_CNT) { stream = AUDIO_STREAM_MUSIC; } + + // send the streaminfo notification only once + ssize_t sidx = mOutputAudioSessionInfo.indexOfKey(audioSession); + if (sidx >= 0) { + // AudioSessionInfo is existing and we just need to increase ref count + sp info = mOutputAudioSessionInfo.valueAt(sidx); + info->mRefCount++; + + if (info->mRefCount == 1) { + mAudioPolicyService->onOutputSessionEffectsUpdate(info, true); + } + ALOGV("addOutputSessionEffects(): session info %d refCount=%d", audioSession, info->mRefCount); + } else { + ALOGV("addOutputSessionEffects(): no output stream info found for stream"); + } + ssize_t index = mOutputStreams.indexOfKey(stream); if (index < 0) { ALOGV("addOutputSessionEffects(): no output processing needed for this stream"); @@ -275,6 +295,81 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, return status; } +status_t AudioPolicyEffects::releaseOutputAudioSessionInfo(audio_io_handle_t /* output */, + audio_stream_type_t stream, + int session) +{ + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + return BAD_VALUE; + } + + Mutex::Autolock _l(mLock); + + ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session); + if (idx >= 0) { + sp info = mOutputAudioSessionInfo.valueAt(idx); + if (info->mRefCount == 0) { + mOutputAudioSessionInfo.removeItemsAt(idx); + } + ALOGV("releaseOutputAudioSessionInfo() sessionId=%d refcount=%d", + session, info->mRefCount); + } else { + ALOGV("releaseOutputAudioSessionInfo() no session info found"); + } + return NO_ERROR; +} + +status_t AudioPolicyEffects::updateOutputAudioSessionInfo(audio_io_handle_t /* output */, + audio_stream_type_t stream, + int session, + audio_output_flags_t flags, + audio_channel_mask_t channelMask, uid_t uid) +{ + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + return BAD_VALUE; + } + + Mutex::Autolock _l(mLock); + + // update AudioSessionInfo. This is used in the stream open/close path + // to notify userspace applications about session creation and + // teardown, allowing the app to make decisions about effects for + // a particular stream. This is independent of the current + // output_session_processing feature which forcibly attaches a + // static list of effects to a stream. + ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session); + sp info; + if (idx < 0) { + info = new AudioSessionInfo(session, stream, flags, channelMask, uid); + mOutputAudioSessionInfo.add(session, info); + } else { + // the streaminfo may actually change + info = mOutputAudioSessionInfo.valueAt(idx); + info->mFlags = flags; + info->mChannelMask = channelMask; + } + + ALOGV("updateOutputAudioSessionInfo() sessionId=%d, flags=0x%x, channelMask=0x%x uid=%d refCount=%d", + info->mSessionId, info->mFlags, info->mChannelMask, info->mUid, info->mRefCount); + + return NO_ERROR; +} + +status_t AudioPolicyEffects::listAudioSessions(audio_stream_type_t streams, + Vector< sp> &sessions) +{ + ALOGV("listAudioSessions() streams %d", streams); + + for (unsigned int i = 0; i < mOutputAudioSessionInfo.size(); i++) { + sp info = mOutputAudioSessionInfo.valueAt(i); + if (streams == -1 || info->mStream == streams) { + sessions.push_back(info); + } + } + + return NO_ERROR; +} + status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, int audioSession) @@ -284,7 +379,19 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu (void) stream; // argument not used for now Mutex::Autolock _l(mLock); - ssize_t index = mOutputSessions.indexOfKey(audioSession); + ssize_t index = mOutputAudioSessionInfo.indexOfKey(audioSession); + if (index >= 0) { + sp info = mOutputAudioSessionInfo.valueAt(index); + info->mRefCount--; + if (info->mRefCount == 0) { + mAudioPolicyService->onOutputSessionEffectsUpdate(info, false); + } + ALOGV("releaseOutputSessionEffects(): session=%d refCount=%d", info->mSessionId, info->mRefCount); + } else { + ALOGV("releaseOutputSessionEffects: no stream info was attached to this stream"); + } + + index = mOutputSessions.indexOfKey(audioSession); if (index < 0) { ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream"); return NO_ERROR; -- cgit v1.1 From a5ec3545f879e882ed5397707f65a4757f7232d5 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 18 Jul 2016 16:50:06 -0700 Subject: audiopolicy: Constrain session events to music streams * We're really only interested in music streams right now, but events are being generated for all streams (system sounds, etc). * Constrain for now, in the future we will filter based on client registrations. Change-Id: Ic445052028c454eed146addebcdb28c4b26c4f20 --- services/audiopolicy/service/AudioPolicyEffects.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'services/audiopolicy/service/AudioPolicyEffects.cpp') diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 31b1637..d6fabfe 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -331,6 +331,11 @@ status_t AudioPolicyEffects::updateOutputAudioSessionInfo(audio_io_handle_t /* o Mutex::Autolock _l(mLock); + // TODO: Handle other stream types based on client registration + if (stream != AUDIO_STREAM_MUSIC) { + return NO_ERROR; + } + // update AudioSessionInfo. This is used in the stream open/close path // to notify userspace applications about session creation and // teardown, allowing the app to make decisions about effects for -- cgit v1.1