diff options
Diffstat (limited to 'services/audiopolicy/service/AudioPolicyEffects.cpp')
-rw-r--r-- | services/audiopolicy/service/AudioPolicyEffects.cpp | 132 |
1 files changed, 103 insertions, 29 deletions
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index f2d7f6f..d6fabfe 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -228,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? @@ -235,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<AudioSessionInfo> 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"); @@ -246,8 +264,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); @@ -279,65 +295,123 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, return status; } -status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, - audio_stream_type_t stream, - int audioSession) +status_t AudioPolicyEffects::releaseOutputAudioSessionInfo(audio_io_handle_t /* output */, + audio_stream_type_t stream, + int session) { - status_t status = NO_ERROR; - (void) output; // argument not used for now - (void) stream; // argument not used for now + if (uint32_t(stream) >= AUDIO_STREAM_CNT) { + return BAD_VALUE; + } Mutex::Autolock _l(mLock); - ssize_t index = mOutputSessions.indexOfKey(audioSession); - if (index < 0) { - ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream"); - return NO_ERROR; + + ssize_t idx = mOutputAudioSessionInfo.indexOfKey(session); + if (idx >= 0) { + sp<AudioSessionInfo> 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; +} - EffectVector *procDesc = mOutputSessions.valueAt(index); +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; + } - // just in case it already has a death wish - if (procDesc->mRefCount == 0) { + Mutex::Autolock _l(mLock); + + // TODO: Handle other stream types based on client registration + if (stream != AUDIO_STREAM_MUSIC) { return NO_ERROR; } - procDesc->mRefCount--; - ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d", - audioSession, procDesc->mRefCount); + // 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<AudioSessionInfo> 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; + } - if (procDesc->mRefCount == 0) { - mAudioPolicyService->releaseOutputSessionEffectsDelayed( - output, stream, audioSession, 10000); + 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<AudioSessionInfo>> &sessions) +{ + ALOGV("listAudioSessions() streams %d", streams); + + for (unsigned int i = 0; i < mOutputAudioSessionInfo.size(); i++) { + sp<AudioSessionInfo> info = mOutputAudioSessionInfo.valueAt(i); + if (streams == -1 || info->mStream == streams) { + sessions.push_back(info); + } } - return status; + return NO_ERROR; } -status_t AudioPolicyEffects::doReleaseOutputSessionEffects(audio_io_handle_t output, +status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, int audioSession) { status_t status = NO_ERROR; (void) output; // argument not used for now + (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<AudioSessionInfo> 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("doReleaseOutputSessionEffects: no output processing was attached to this stream"); + ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream"); return NO_ERROR; } EffectVector *procDesc = mOutputSessions.valueAt(index); - ALOGV("doReleaseOutputSessionEffects(): session: %d, refCount: %d", + procDesc->mRefCount--; + ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d", audioSession, procDesc->mRefCount); - if (procDesc->mRefCount == 0) { procDesc->setProcessorEnabled(false); procDesc->mEffects.clear(); delete procDesc; mOutputSessions.removeItemsAt(index); - mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, false); - ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d", + ALOGV("releaseOutputSessionEffects(): output processing released from session: %d", audioSession); } return status; |