From e8726fea8a53bf3474aa3c6deaf2f6c1f565e694 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 26 Jun 2015 09:39:24 -0700 Subject: reduce number of binder calls from mediaserver Reduce the number of audio port, audio patch and IO config changed binder calls from mediaserver to client processes: - Do not call IO config changed callback if selected device is the same as previously selected one on a given audio flinger playback or capture thread. - Do not call the audio port or audo patch list update callback on a client if this client as no listener registered. Bug: 22045560. Change-Id: If780e105404de79b7cb5c80c27b793ceb6b1c423 --- include/media/AudioSystem.h | 4 ++-- include/media/IAudioPolicyService.h | 2 ++ media/libmedia/AudioSystem.cpp | 24 ++++++++++++++-------- media/libmedia/IAudioPolicyService.cpp | 17 ++++++++++++++- services/audioflinger/Threads.cpp | 15 +++++++++++--- services/audioflinger/Threads.h | 1 + .../audiopolicy/service/AudioPolicyService.cpp | 24 +++++++++++++++++++--- services/audiopolicy/service/AudioPolicyService.h | 4 ++++ 8 files changed, 74 insertions(+), 17 deletions(-) diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 26cffa6..06116a5 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -408,8 +408,8 @@ private: AudioPolicyServiceClient() { } - status_t addAudioPortCallback(const sp& callback); - status_t removeAudioPortCallback(const sp& callback); + int addAudioPortCallback(const sp& callback); + int removeAudioPortCallback(const sp& callback); // DeathRecipient virtual void binderDied(const wp& who); diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index ee462a0..6b93f6f 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -149,6 +149,8 @@ public: virtual void registerClient(const sp& client) = 0; + virtual void setAudioPortCallbacksEnabled(bool enabled) = 0; + virtual status_t acquireSoundTriggerSession(audio_session_t *session, audio_io_handle_t *ioHandle, audio_devices_t *device) = 0; diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 6c2c226..f13bcf3 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -1043,7 +1043,11 @@ status_t AudioSystem::addAudioPortCallback(const sp& callback if (gAudioPolicyServiceClient == 0) { return NO_INIT; } - return gAudioPolicyServiceClient->addAudioPortCallback(callback); + int ret = gAudioPolicyServiceClient->addAudioPortCallback(callback); + if (ret == 1) { + aps->setAudioPortCallbacksEnabled(true); + } + return (ret < 0) ? INVALID_OPERATION : NO_ERROR; } /*static*/ @@ -1056,7 +1060,11 @@ status_t AudioSystem::removeAudioPortCallback(const sp& callb if (gAudioPolicyServiceClient == 0) { return NO_INIT; } - return gAudioPolicyServiceClient->removeAudioPortCallback(callback); + int ret = gAudioPolicyServiceClient->removeAudioPortCallback(callback); + if (ret == 0) { + aps->setAudioPortCallbacksEnabled(false); + } + return (ret < 0) ? INVALID_OPERATION : NO_ERROR; } status_t AudioSystem::addAudioDeviceCallback( @@ -1138,20 +1146,20 @@ status_t AudioSystem::stopAudioSource(audio_io_handle_t handle) // --------------------------------------------------------------------------- -status_t AudioSystem::AudioPolicyServiceClient::addAudioPortCallback( +int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback( const sp& callback) { Mutex::Autolock _l(mLock); for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { if (mAudioPortCallbacks[i] == callback) { - return INVALID_OPERATION; + return -1; } } mAudioPortCallbacks.add(callback); - return NO_ERROR; + return mAudioPortCallbacks.size(); } -status_t AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback( +int AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback( const sp& callback) { Mutex::Autolock _l(mLock); @@ -1162,10 +1170,10 @@ status_t AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback( } } if (i == mAudioPortCallbacks.size()) { - return INVALID_OPERATION; + return -1; } mAudioPortCallbacks.removeAt(i); - return NO_ERROR; + return mAudioPortCallbacks.size(); } diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index fd18f17..3348441 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -72,7 +72,8 @@ enum { GET_PHONE_STATE, REGISTER_POLICY_MIXES, START_AUDIO_SOURCE, - STOP_AUDIO_SOURCE + STOP_AUDIO_SOURCE, + SET_AUDIO_PORT_CALLBACK_ENABLED, }; #define MAX_ITEMS_PER_LIST 1024 @@ -646,6 +647,14 @@ public: remote()->transact(REGISTER_CLIENT, data, &reply); } + virtual void setAudioPortCallbacksEnabled(bool enabled) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.writeInt32(enabled ? 1 : 0); + remote()->transact(SET_AUDIO_PORT_CALLBACK_ENABLED, data, &reply); + } + virtual status_t acquireSoundTriggerSession(audio_session_t *session, audio_io_handle_t *ioHandle, audio_devices_t *device) @@ -1219,6 +1228,12 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } break; + case SET_AUDIO_PORT_CALLBACK_ENABLED: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + setAudioPortCallbacksEnabled(data.readInt32() == 1); + return NO_ERROR; + } break; + case ACQUIRE_SOUNDTRIGGER_SESSION: { CHECK_INTERFACE(IAudioPolicyService, data, reply); sp client = interface_cast( diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 410fff5..c8f9be0 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -530,7 +530,7 @@ AudioFlinger::ThreadBase::ThreadBase(const sp& audioFlinger, audio // RecordThread::readInputParameters_l() //FIXME: mStandby should be true here. Is this some kind of hack? mStandby(false), mOutDevice(outDevice), mInDevice(inDevice), - mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), + mPrevInDevice(AUDIO_DEVICE_NONE), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), // mName will be set by concrete (non-virtual) subclass mDeathRecipient(new PMDeathRecipient(this)), mSystemReady(systemReady) @@ -3131,6 +3131,7 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat for (size_t i = 0; i < mEffectChains.size(); i++) { mEffectChains[i]->setDevice_l(type); } + bool configChanged = mOutDevice != type; mOutDevice = type; mPatch = *patch; @@ -3159,7 +3160,9 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat param.toString().string()); *handle = AUDIO_PATCH_HANDLE_NONE; } - sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); + if (configChanged) { + sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); + } return status; } @@ -6796,6 +6799,9 @@ bool AudioFlinger::RecordThread::checkForNewParameter_l(const String8& keyValueP status = BAD_VALUE; } else { mInDevice = value; + if (value != AUDIO_DEVICE_NONE) { + mPrevInDevice = value; + } // disable AEC and NS if the device is a BT SCO headset supporting those // pre processings if (mTracks.size() > 0) { @@ -7079,7 +7085,10 @@ status_t AudioFlinger::RecordThread::createAudioPatch_l(const struct audio_patch *handle = AUDIO_PATCH_HANDLE_NONE; } - sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); + if (mInDevice != mPrevInDevice) { + sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); + mPrevInDevice = mInDevice; + } return status; } diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index b12b091..0783371 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -436,6 +436,7 @@ protected: bool mStandby; // Whether thread is currently in standby. audio_devices_t mOutDevice; // output device audio_devices_t mInDevice; // input device + audio_devices_t mPrevInDevice; // previous input device struct audio_patch mPatch; audio_source_t mAudioSource; diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index c5f4fb7..fbe4f18 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -166,6 +166,17 @@ void AudioPolicyService::registerClient(const sp& cli } } +void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled) +{ + Mutex::Autolock _l(mNotificationClientsLock); + + uid_t uid = IPCThreadState::self()->getCallingUid(); + if (mNotificationClients.indexOfKey(uid) < 0) { + return; + } + mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled); +} + // removeNotificationClient() is called when the client process dies. void AudioPolicyService::removeNotificationClient(uid_t uid) { @@ -246,7 +257,8 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co AudioPolicyService::NotificationClient::NotificationClient(const sp& service, const sp& client, uid_t uid) - : mService(service), mUid(uid), mAudioPolicyServiceClient(client) + : mService(service), mUid(uid), mAudioPolicyServiceClient(client), + mAudioPortCallbacksEnabled(false) { } @@ -265,14 +277,14 @@ void AudioPolicyService::NotificationClient::binderDied(const wp& who _ void AudioPolicyService::NotificationClient::onAudioPortListUpdate() { - if (mAudioPolicyServiceClient != 0) { + if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { mAudioPolicyServiceClient->onAudioPortListUpdate(); } } void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() { - if (mAudioPolicyServiceClient != 0) { + if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) { mAudioPolicyServiceClient->onAudioPatchListUpdate(); } } @@ -285,6 +297,12 @@ void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate( } } +void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled) +{ + mAudioPortCallbacksEnabled = enabled; +} + + void AudioPolicyService::binderDied(const wp& who) { ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), IPCThreadState::self()->getCallingPid()); diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h index eb50cdd..a0d5aa2 100644 --- a/services/audiopolicy/service/AudioPolicyService.h +++ b/services/audiopolicy/service/AudioPolicyService.h @@ -185,6 +185,8 @@ public: virtual void registerClient(const sp& client); + virtual void setAudioPortCallbacksEnabled(bool enabled); + virtual status_t acquireSoundTriggerSession(audio_session_t *session, audio_io_handle_t *ioHandle, audio_devices_t *device); @@ -507,6 +509,7 @@ private: void onAudioPortListUpdate(); void onAudioPatchListUpdate(); void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); + void setAudioPortCallbacksEnabled(bool enabled); // IBinder::DeathRecipient virtual void binderDied(const wp& who); @@ -518,6 +521,7 @@ private: const wp mService; const uid_t mUid; const sp mAudioPolicyServiceClient; + bool mAudioPortCallbacksEnabled; }; // Internal dump utilities. -- cgit v1.1