summaryrefslogtreecommitdiffstats
path: root/services/audiopolicy/service/AudioPolicyEffects.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/audiopolicy/service/AudioPolicyEffects.cpp')
-rw-r--r--services/audiopolicy/service/AudioPolicyEffects.cpp132
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;