diff options
author | Eric Laurent <elaurent@google.com> | 2014-05-30 18:51:48 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2014-05-30 18:53:14 -0700 |
commit | 72aa32f7dbbfb658097930b57659d8e50f24a953 (patch) | |
tree | 7033c38865bfdb413c5ca891fd4f6d0a98a84d99 /services/audiopolicy | |
parent | cf570853ee36eeb58be38ea3dac16a17c6a5d4ba (diff) | |
parent | b52c152d553556b2d227ffc943489de0c60b4b02 (diff) | |
download | frameworks_av-72aa32f7dbbfb658097930b57659d8e50f24a953.zip frameworks_av-72aa32f7dbbfb658097930b57659d8e50f24a953.tar.gz frameworks_av-72aa32f7dbbfb658097930b57659d8e50f24a953.tar.bz2 |
resolved conflicts for merge of b52c152d to master
Change-Id: I34869bda071d511c9595ea0a5ff6571eb34da059
Diffstat (limited to 'services/audiopolicy')
-rw-r--r-- | services/audiopolicy/AudioPolicyClientImpl.cpp | 10 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyInterface.h | 3 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyManager.cpp | 12 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyService.cpp | 133 | ||||
-rw-r--r-- | services/audiopolicy/AudioPolicyService.h | 39 |
5 files changed, 196 insertions, 1 deletions
diff --git a/services/audiopolicy/AudioPolicyClientImpl.cpp b/services/audiopolicy/AudioPolicyClientImpl.cpp index 8225e36..cbab841 100644 --- a/services/audiopolicy/AudioPolicyClientImpl.cpp +++ b/services/audiopolicy/AudioPolicyClientImpl.cpp @@ -195,4 +195,14 @@ status_t AudioPolicyService::AudioPolicyClient::releaseAudioPatch(audio_patch_ha return mAudioPolicyService->clientReleaseAudioPatch(handle, delayMs); } +void AudioPolicyService::AudioPolicyClient::onAudioPortListUpdate() +{ + mAudioPolicyService->onAudioPortListUpdate(); +} + +void AudioPolicyService::AudioPolicyClient::onAudioPatchListUpdate() +{ + mAudioPolicyService->onAudioPatchListUpdate(); +} + }; // namespace android diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index 98ad1d4..e0c7f61 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -273,6 +273,9 @@ public: virtual status_t releaseAudioPatch(audio_patch_handle_t handle, int delayMs) = 0; + virtual void onAudioPortListUpdate() = 0; + + virtual void onAudioPatchListUpdate() = 0; }; extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface); diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp index c472b11..ee0c987 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -280,6 +280,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, 0); } + mpClientInterface->onAudioPortListUpdate(); return NO_ERROR; } // end if is output device @@ -336,6 +337,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, closeAllInputs(); + mpClientInterface->onAudioPortListUpdate(); return NO_ERROR; } // end if is input device @@ -747,6 +749,7 @@ audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, } mPreviousOutputs = mOutputs; ALOGV("getOutput() returns new direct output %d", output); + mpClientInterface->onAudioPortListUpdate(); return output; } @@ -979,6 +982,7 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output) if (dstOutput != mPrimaryOutput) { mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput); } + mpClientInterface->onAudioPortListUpdate(); } } } @@ -1060,6 +1064,7 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, return 0; } addInput(input, inputDesc); + mpClientInterface->onAudioPortListUpdate(); return input; } @@ -1145,6 +1150,7 @@ void AudioPolicyManager::releaseInput(audio_io_handle_t input) delete mInputs.valueAt(index); mInputs.removeItem(input); nextAudioPortGeneration(); + mpClientInterface->onAudioPortListUpdate(); ALOGV("releaseInput() exit"); } @@ -1897,6 +1903,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, patchDesc->mAfPatchHandle = afPatchHandle; *handle = patchDesc->mHandle; nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); } else { ALOGW("createAudioPatch() patch panel could not connect device patch, error %d", status); @@ -1960,6 +1967,7 @@ status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle, status, patchDesc->mAfPatchHandle); removeAudioPatch(patchDesc->mHandle); nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); } else { return BAD_VALUE; } @@ -3577,6 +3585,7 @@ uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, } outputDesc->mPatchHandle = patchDesc->mHandle; nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); } } } @@ -3607,6 +3616,7 @@ status_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output, outputDesc->mPatchHandle = 0; removeAudioPatch(patchDesc->mHandle); nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); return status; } @@ -3662,6 +3672,7 @@ status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input, } inputDesc->mPatchHandle = patchDesc->mHandle; nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); } } } @@ -3687,6 +3698,7 @@ status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input, inputDesc->mPatchHandle = 0; removeAudioPatch(patchDesc->mHandle); nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); return status; } diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp index ea573a4..f3d92ed 100644 --- a/services/audiopolicy/AudioPolicyService.cpp +++ b/services/audiopolicy/AudioPolicyService.cpp @@ -148,6 +148,61 @@ AudioPolicyService::~AudioPolicyService() delete mAudioPolicyManager; delete mAudioPolicyClient; #endif + + mNotificationClients.clear(); +} + +// A notification client is always registered by AudioSystem when the client process +// connects to AudioPolicyService. +void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client) +{ + + Mutex::Autolock _l(mLock); + + uid_t uid = IPCThreadState::self()->getCallingUid(); + if (mNotificationClients.indexOfKey(uid) < 0) { + sp<NotificationClient> notificationClient = new NotificationClient(this, + client, + uid); + ALOGV("registerClient() client %p, uid %d", client.get(), uid); + + mNotificationClients.add(uid, notificationClient); + + sp<IBinder> binder = client->asBinder(); + binder->linkToDeath(notificationClient); + } +} + +// removeNotificationClient() is called when the client process dies. +void AudioPolicyService::removeNotificationClient(uid_t uid) +{ + Mutex::Autolock _l(mLock); + + mNotificationClients.removeItem(uid); + +#ifndef USE_LEGACY_AUDIO_POLICY + if (mAudioPolicyManager) { + mAudioPolicyManager->clearAudioPatches(uid); + } +#endif +} + +void AudioPolicyService::onAudioPortListUpdate() +{ + mOutputCommandThread->updateAudioPortListCommand(); +} + +void AudioPolicyService::doOnAudioPortListUpdate() +{ + Mutex::Autolock _l(mLock); + for (size_t i = 0; i < mNotificationClients.size(); i++) { + mNotificationClients.valueAt(i)->onAudioPortListUpdate(); + } +} + +void AudioPolicyService::onAudioPatchListUpdate() +{ + mOutputCommandThread->updateAudioPatchListCommand(); } status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch, @@ -163,6 +218,47 @@ status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs); } +void AudioPolicyService::doOnAudioPatchListUpdate() +{ + Mutex::Autolock _l(mLock); + for (size_t i = 0; i < mNotificationClients.size(); i++) { + mNotificationClients.valueAt(i)->onAudioPatchListUpdate(); + } +} + +AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service, + const sp<IAudioPolicyServiceClient>& client, + uid_t uid) + : mService(service), mUid(uid), mAudioPolicyServiceClient(client) +{ +} + +AudioPolicyService::NotificationClient::~NotificationClient() +{ +} + +void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused) +{ + sp<NotificationClient> keep(this); + sp<AudioPolicyService> service = mService.promote(); + if (service != 0) { + service->removeNotificationClient(mUid); + } +} + +void AudioPolicyService::NotificationClient::onAudioPortListUpdate() +{ + if (mAudioPolicyServiceClient != 0) { + mAudioPolicyServiceClient->onAudioPortListUpdate(); + } +} + +void AudioPolicyService::NotificationClient::onAudioPatchListUpdate() +{ + if (mAudioPolicyServiceClient != 0) { + mAudioPolicyServiceClient->onAudioPatchListUpdate(); + } +} void AudioPolicyService::binderDied(const wp<IBinder>& who) { ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(), @@ -390,6 +486,26 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() command->mStatus = af->releaseAudioPatch(data->mHandle); } } break; + case UPDATE_AUDIOPORT_LIST: { + ALOGV("AudioCommandThread() processing update audio port list"); + sp<AudioPolicyService> svc = mService.promote(); + if (svc == 0) { + break; + } + mLock.unlock(); + svc->doOnAudioPortListUpdate(); + mLock.lock(); + }break; + case UPDATE_AUDIOPATCH_LIST: { + ALOGV("AudioCommandThread() processing update audio patch list"); + sp<AudioPolicyService> svc = mService.promote(); + if (svc == 0) { + break; + } + mLock.unlock(); + svc->doOnAudioPatchListUpdate(); + mLock.lock(); + }break; default: ALOGW("AudioCommandThread() unknown command %d", command->mCommand); } @@ -584,6 +700,22 @@ status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_ return sendCommand(command, delayMs); } +void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand() +{ + sp<AudioCommand> command = new AudioCommand(); + command->mCommand = UPDATE_AUDIOPORT_LIST; + ALOGV("AudioCommandThread() adding update audio port list"); + sendCommand(command); +} + +void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand() +{ + sp<AudioCommand>command = new AudioCommand(); + command->mCommand = UPDATE_AUDIOPATCH_LIST; + ALOGV("AudioCommandThread() adding update audio patch list"); + sendCommand(command); +} + status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs) { { @@ -602,7 +734,6 @@ status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& c return command->mStatus; } - // insertCommand_l() must be called with mLock held void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs) { diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h index 9f88b1e..a579d1d 100644 --- a/services/audiopolicy/AudioPolicyService.h +++ b/services/audiopolicy/AudioPolicyService.h @@ -154,6 +154,8 @@ public: unsigned int *generation); virtual status_t setAudioPortConfig(const struct audio_port_config *config); + virtual void registerClient(const sp<IAudioPolicyServiceClient>& client); + status_t doStopOutput(audio_io_handle_t output, audio_stream_type_t stream, int session = 0); @@ -164,6 +166,11 @@ public: int delayMs); status_t clientReleaseAudioPatch(audio_patch_handle_t handle, int delayMs); + void removeNotificationClient(uid_t uid); + void onAudioPortListUpdate(); + void doOnAudioPortListUpdate(); + void onAudioPatchListUpdate(); + void doOnAudioPatchListUpdate(); private: AudioPolicyService() ANDROID_API; @@ -192,6 +199,8 @@ private: RELEASE_OUTPUT, CREATE_AUDIO_PATCH, RELEASE_AUDIO_PATCH, + UPDATE_AUDIOPORT_LIST, + UPDATE_AUDIOPATCH_LIST }; AudioCommandThread (String8 name, const wp<AudioPolicyService>& service); @@ -223,6 +232,8 @@ private: int delayMs); status_t releaseAudioPatchCommand(audio_patch_handle_t handle, int delayMs); + void updateAudioPortListCommand(); + void updateAudioPatchListCommand(); void insertCommand_l(AudioCommand *command, int delayMs = 0); @@ -454,10 +465,36 @@ private: virtual status_t releaseAudioPatch(audio_patch_handle_t handle, int delayMs); + virtual void onAudioPortListUpdate(); + virtual void onAudioPatchListUpdate(); + private: AudioPolicyService *mAudioPolicyService; }; + // --- Notification Client --- + class NotificationClient : public IBinder::DeathRecipient { + public: + NotificationClient(const sp<AudioPolicyService>& service, + const sp<IAudioPolicyServiceClient>& client, + uid_t uid); + virtual ~NotificationClient(); + + void onAudioPortListUpdate(); + void onAudioPatchListUpdate(); + + // IBinder::DeathRecipient + virtual void binderDied(const wp<IBinder>& who); + + private: + NotificationClient(const NotificationClient&); + NotificationClient& operator = (const NotificationClient&); + + const wp<AudioPolicyService> mService; + const uid_t mUid; + const sp<IAudioPolicyServiceClient> mAudioPolicyServiceClient; + }; + static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1]; void setPreProcessorEnabled(const InputDesc *inputDesc, bool enabled); @@ -494,6 +531,8 @@ private: KeyedVector< audio_source_t, InputSourceDesc* > mInputSources; KeyedVector< audio_io_handle_t, InputDesc* > mInputs; + + DefaultKeyedVector< uid_t, sp<NotificationClient> > mNotificationClients; }; }; // namespace android |