diff options
author | Steve Kondik <steve@cyngn.com> | 2016-01-14 02:46:40 -0800 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2016-03-08 17:34:16 -0800 |
commit | 0479d7c79a7fd6f112e8dc7e45c009cf6602dbaa (patch) | |
tree | 6ad8d2cd4abd2f7f2fe6beb8348fd696426f76b2 /services/audiopolicy/service/AudioPolicyService.cpp | |
parent | 51aee1e55bee9cf8e4fd30ecf19fccd7ab7bfc15 (diff) | |
download | frameworks_av-0479d7c79a7fd6f112e8dc7e45c009cf6602dbaa.zip frameworks_av-0479d7c79a7fd6f112e8dc7e45c009cf6602dbaa.tar.gz frameworks_av-0479d7c79a7fd6f112e8dc7e45c009cf6602dbaa.tar.bz2 |
audiopolicy: Add notification when default effects are updated
* In M, we now have the ability to define a default set of audio effect
on a per-stream basis. This allows us to get around the problem of
apps not sending the control intents so we can implement smart
global effects for specific media types.
* We still need a session id in order to get a handle and configure them
from an app like AudioFX, so we'll need to add some plumbing in
order to send an event to interested applications.
* This patch implements the native side of this. The Java layer will
call down thru AudioSystem and register a callback which will be
invoked by the audio policy when default effects are updated on
a stream. This callback will receive both the stream type as well
as the session id.
* Attaching this listener requires that the caller hold the
MODIFY_AUDIO_ROUTING permission.
Change-Id: I142b15f2585ffca6a953c3e828e2a7c07b24f56c
Diffstat (limited to 'services/audiopolicy/service/AudioPolicyService.cpp')
-rw-r--r-- | services/audiopolicy/service/AudioPolicyService.cpp | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index 12cca65..dbeed80 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -116,7 +116,7 @@ void AudioPolicyService::onFirstRef() #endif } // load audio processing modules - sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(); + sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects(this); { Mutex::Autolock _l(mLock); mAudioPolicyEffects = audioPolicyEffects; @@ -177,6 +177,23 @@ void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled) mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled); } +status_t AudioPolicyService::setEffectSessionCallbacksEnabled(bool enabled) +{ + Mutex::Autolock _l(mNotificationClientsLock); + + uid_t uid = IPCThreadState::self()->getCallingUid(); + if (mNotificationClients.indexOfKey(uid) < 0) { + return NO_INIT; + } + if (!modifyAudioRoutingAllowed()) { + ALOGE("setEffectSessionCallbacksEnabled requires MODIFY_AUDIO_ROUTING"); + return PERMISSION_DENIED; + } + mNotificationClients.valueFor(uid)->setEffectSessionCallbacksEnabled(enabled); + return OK; +} + + // removeNotificationClient() is called when the client process dies. void AudioPolicyService::removeNotificationClient(uid_t uid) { @@ -254,11 +271,31 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs); } +void AudioPolicyService::onOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, + bool added) +{ + ALOGV("AudioPolicyService::onOutputSessionEffectsUpdate(%d, %d, %d)", + stream, sessionId, added); + mOutputCommandThread->effectSessionUpdateCommand(stream, sessionId, added); +} + +void AudioPolicyService::doOnOutputSessionEffectsUpdate(audio_stream_type_t stream, + audio_unique_id_t sessionId, + bool added) +{ + Mutex::Autolock _l(mNotificationClientsLock); + for (size_t i = 0; i < mNotificationClients.size(); i++) { + mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(stream, sessionId, added); + } +} + AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, const sp<IAudioPolicyServiceClient>& client, uid_t uid) : mService(service), mUid(uid), mAudioPolicyServiceClient(client), - mAudioPortCallbacksEnabled(false) + mAudioPortCallbacksEnabled(false), + mEffectSessionCallbacksEnabled(false) { } @@ -289,6 +326,14 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() } } +void AudioPolicyService::NotificationClient::onOutputSessionEffectsUpdate( + audio_stream_type_t stream, audio_unique_id_t sessionId, bool added) +{ + if (mAudioPolicyServiceClient != 0 && mEffectSessionCallbacksEnabled) { + mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(stream, sessionId, added); + } +} + void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( String8 regId, int32_t state) { @@ -302,6 +347,10 @@ void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool e mAudioPortCallbacksEnabled = enabled; } +void AudioPolicyService::NotificationClient::setEffectSessionCallbacksEnabled(bool enabled) +{ + mEffectSessionCallbacksEnabled = enabled; +} void AudioPolicyService::binderDied(const wp<IBinder>& who) { ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), @@ -579,6 +628,20 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState); mLock.lock(); } break; + case EFFECT_SESSION_UPDATE: { + EffectSessionUpdateData *data = + (EffectSessionUpdateData *)command->mParam.get(); + ALOGV("AudioCommandThread() processing effect session update %d %d %d", + data->mStream, data->mSessionId, data->mAdded); + svc = mService.promote(); + if (svc == 0) { + break; + } + mLock.unlock(); + svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId, data->mAdded); + mLock.lock(); + } break; + default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); } @@ -851,6 +914,21 @@ void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand( sendCommand(command); } +void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand( + audio_stream_type_t stream, audio_unique_id_t sessionId, bool added) +{ + sp<AudioCommand> command = new AudioCommand(); + command->mCommand = EFFECT_SESSION_UPDATE; + EffectSessionUpdateData *data = new EffectSessionUpdateData(); + data->mStream = stream; + data->mSessionId = sessionId; + data->mAdded = added; + command->mParam = data; + ALOGV("AudioCommandThread() sending effect session update (id=%d) for stream %d (added=%d)", + stream, sessionId, added); + sendCommand(command); +} + status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) { { |