From b28753e19550e5051cd02e6af72ab06e4eff04e0 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Wed, 1 Apr 2015 13:06:28 -0700 Subject: audio port: support multiple clients Add support for more than one audio port callback client per process. Change-Id: I657c4fc28d5d2d993307551e3e69567dc60196cb --- include/media/AudioSystem.h | 13 ++++-- media/libmedia/AudioSystem.cpp | 91 +++++++++++++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 27 deletions(-) diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index ad5d6ed..f5db1bb 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -346,7 +346,8 @@ public: }; - static void setAudioPortCallback(sp callBack); + static status_t addAudioPortCallback(const sp& callBack); + static status_t removeAudioPortCallback(const sp& callBack); private: @@ -373,12 +374,19 @@ private: AudioPolicyServiceClient() { } + status_t addAudioPortCallback(const sp& callBack); + status_t removeAudioPortCallback(const sp& callBack); + // DeathRecipient virtual void binderDied(const wp& who); // IAudioPolicyServiceClient virtual void onAudioPortListUpdate(); virtual void onAudioPatchListUpdate(); + + private: + Mutex mLock; + Vector > mAudioPortCallbacks; }; static sp gAudioFlingerClient; @@ -390,7 +398,6 @@ private: static Mutex gLockCache; // protects gOutputs, gPrevInSamplingRate, gPrevInFormat, // gPrevInChannelMask and gInBuffSize static Mutex gLockAPS; // protects gAudioPolicyService and gAudioPolicyServiceClient - static Mutex gLockAPC; // protects gAudioPortCallback static sp gAudioFlinger; static audio_error_callback gAudioErrorCallback; @@ -405,8 +412,6 @@ private: // list of output descriptors containing cached parameters // (sampling rate, framecount, channel count...) static DefaultKeyedVector gOutputs; - - static sp gAudioPortCallback; }; }; // namespace android diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index c6b34a7..9150a94 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -34,7 +34,6 @@ namespace android { Mutex AudioSystem::gLock; Mutex AudioSystem::gLockCache; Mutex AudioSystem::gLockAPS; -Mutex AudioSystem::gLockAPC; sp AudioSystem::gAudioFlinger; sp AudioSystem::gAudioFlingerClient; audio_error_callback AudioSystem::gAudioErrorCallback = NULL; @@ -48,8 +47,6 @@ audio_format_t AudioSystem::gPrevInFormat; audio_channel_mask_t AudioSystem::gPrevInChannelMask; size_t AudioSystem::gInBuffSize = 0; // zero indicates cache is invalid -sp AudioSystem::gAudioPortCallback; - // establish binder interface to AudioFlinger service const sp AudioSystem::get_audio_flinger() { @@ -873,7 +870,6 @@ void AudioSystem::clearAudioConfigCache() Mutex::Autolock _l(gLockAPS); gAudioPolicyService.clear(); } - // Do not clear gAudioPortCallback } bool AudioSystem::isOffloadSupported(const audio_offload_info_t& info) @@ -933,12 +929,31 @@ status_t AudioSystem::setAudioPortConfig(const struct audio_port_config *config) return aps->setAudioPortConfig(config); } -void AudioSystem::setAudioPortCallback(sp callBack) +status_t AudioSystem::addAudioPortCallback(const sp& callBack) { - Mutex::Autolock _l(gLockAPC); - gAudioPortCallback = callBack; + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + + Mutex::Autolock _l(gLockAPS); + if (gAudioPolicyServiceClient == 0) { + return NO_INIT; + } + return gAudioPolicyServiceClient->addAudioPortCallback(callBack); } +status_t AudioSystem::removeAudioPortCallback(const sp& callBack) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + + Mutex::Autolock _l(gLockAPS); + if (gAudioPolicyServiceClient == 0) { + return NO_INIT; + } + return gAudioPolicyServiceClient->removeAudioPortCallback(callBack); +} + + status_t AudioSystem::acquireSoundTriggerSession(audio_session_t *session, audio_io_handle_t *ioHandle, audio_devices_t *device) @@ -971,36 +986,66 @@ status_t AudioSystem::registerPolicyMixes(Vector mixes, bool registrat // --------------------------------------------------------------------------- -void AudioSystem::AudioPolicyServiceClient::binderDied(const wp& who __unused) +status_t AudioSystem::AudioPolicyServiceClient::addAudioPortCallback( + const sp& callBack) { - { - Mutex::Autolock _l(gLockAPC); - if (gAudioPortCallback != 0) { - gAudioPortCallback->onServiceDied(); + Mutex::Autolock _l(mLock); + for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { + if (mAudioPortCallbacks[i] == callBack) { + return INVALID_OPERATION; } } - { - Mutex::Autolock _l(gLockAPS); - AudioSystem::gAudioPolicyService.clear(); - } + mAudioPortCallbacks.add(callBack); + return NO_ERROR; +} - ALOGW("AudioPolicyService server died!"); +status_t AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback( + const sp& callBack) +{ + Mutex::Autolock _l(mLock); + size_t i; + for (i = 0; i < mAudioPortCallbacks.size(); i++) { + if (mAudioPortCallbacks[i] == callBack) { + break; + } + } + if (i == mAudioPortCallbacks.size()) { + return INVALID_OPERATION; + } + mAudioPortCallbacks.removeAt(i); + return NO_ERROR; } void AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate() { - Mutex::Autolock _l(gLockAPC); - if (gAudioPortCallback != 0) { - gAudioPortCallback->onAudioPortListUpdate(); + Mutex::Autolock _l(mLock); + for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { + mAudioPortCallbacks[i]->onAudioPortListUpdate(); } } void AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate() { - Mutex::Autolock _l(gLockAPC); - if (gAudioPortCallback != 0) { - gAudioPortCallback->onAudioPatchListUpdate(); + Mutex::Autolock _l(mLock); + for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { + mAudioPortCallbacks[i]->onAudioPatchListUpdate(); + } +} + +void AudioSystem::AudioPolicyServiceClient::binderDied(const wp& who __unused) +{ + { + Mutex::Autolock _l(mLock); + for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { + mAudioPortCallbacks[i]->onServiceDied(); + } + } + { + Mutex::Autolock _l(gLockAPS); + AudioSystem::gAudioPolicyService.clear(); } + + ALOGW("AudioPolicyService server died!"); } } // namespace android -- cgit v1.1