diff options
-rw-r--r-- | include/media/AudioSystem.h | 25 | ||||
-rw-r--r-- | include/media/IAudioPolicyService.h | 2 | ||||
-rw-r--r-- | include/media/IAudioPolicyServiceClient.h | 56 | ||||
-rw-r--r-- | media/libmedia/Android.mk | 1 | ||||
-rw-r--r-- | media/libmedia/AudioSystem.cpp | 30 | ||||
-rw-r--r-- | media/libmedia/IAudioPolicyService.cpp | 17 | ||||
-rw-r--r-- | media/libmedia/IAudioPolicyServiceClient.cpp | 83 | ||||
-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 |
12 files changed, 407 insertions, 4 deletions
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index a79a9ff..6fe0c7f 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -19,6 +19,7 @@ #include <hardware/audio_effect.h> #include <media/IAudioFlingerClient.h> +#include <media/IAudioPolicyServiceClient.h> #include <system/audio.h> #include <system/audio_policy.h> #include <utils/Errors.h> @@ -301,6 +302,21 @@ public: // ---------------------------------------------------------------------------- + class AudioPortCallback : public RefBase + { + public: + + AudioPortCallback() {} + virtual ~AudioPortCallback() {} + + virtual void onAudioPortListUpdate() = 0; + virtual void onAudioPatchListUpdate() = 0; + virtual void onServiceDied() = 0; + + }; + + static void setAudioPortCallback(sp<AudioPortCallback> callBack); + private: class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient @@ -319,7 +335,8 @@ private: virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2); }; - class AudioPolicyServiceClient: public IBinder::DeathRecipient + class AudioPolicyServiceClient: public IBinder::DeathRecipient, + public BnAudioPolicyServiceClient { public: AudioPolicyServiceClient() { @@ -327,6 +344,10 @@ private: // DeathRecipient virtual void binderDied(const wp<IBinder>& who); + + // IAudioPolicyServiceClient + virtual void onAudioPortListUpdate(); + virtual void onAudioPatchListUpdate(); }; static sp<AudioFlingerClient> gAudioFlingerClient; @@ -349,6 +370,8 @@ private: // list of output descriptors containing cached parameters // (sampling rate, framecount, channel count...) static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs; + + static sp<AudioPortCallback> gAudioPortCallback; }; }; // namespace android diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index 6b6df6e..d422aa3 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -25,6 +25,7 @@ #include <utils/Errors.h> #include <binder/IInterface.h> #include <media/AudioSystem.h> +#include <media/IAudioPolicyServiceClient.h> #include <system/audio_policy.h> @@ -124,6 +125,7 @@ public: /* Set audio port configuration */ virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0; + virtual void registerClient(const sp<IAudioPolicyServiceClient>& client) = 0; }; diff --git a/include/media/IAudioPolicyServiceClient.h b/include/media/IAudioPolicyServiceClient.h new file mode 100644 index 0000000..59df046 --- /dev/null +++ b/include/media/IAudioPolicyServiceClient.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IAUDIOPOLICYSERVICECLIENT_H +#define ANDROID_IAUDIOPOLICYSERVICECLIENT_H + + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <system/audio.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +class IAudioPolicyServiceClient : public IInterface +{ +public: + DECLARE_META_INTERFACE(AudioPolicyServiceClient); + + // Notifies a change of audio port configuration. + virtual void onAudioPortListUpdate() = 0; + // Notifies a change of audio patch configuration. + virtual void onAudioPatchListUpdate() = 0; +}; + + +// ---------------------------------------------------------------------------- + +class BnAudioPolicyServiceClient : public BnInterface<IAudioPolicyServiceClient> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAUDIOPOLICYSERVICECLIENT_H diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index f3770e4..69eead3 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -44,6 +44,7 @@ LOCAL_SRC_FILES:= \ JetPlayer.cpp \ IOMX.cpp \ IAudioPolicyService.cpp \ + IAudioPolicyServiceClient.cpp \ MediaScanner.cpp \ MediaScannerClient.cpp \ CharacterEncodingDetector.cpp \ diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 845ee20..eafb3ad 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -45,6 +45,7 @@ audio_format_t AudioSystem::gPrevInFormat; audio_channel_mask_t AudioSystem::gPrevInChannelMask; size_t AudioSystem::gInBuffSize = 0; // zero indicates cache is invalid +sp<AudioSystem::AudioPortCallback> AudioSystem::gAudioPortCallback; // establish binder interface to AudioFlinger service const sp<IAudioFlinger>& AudioSystem::get_audio_flinger() @@ -528,6 +529,7 @@ void AudioSystem::setErrorCallback(audio_error_callback cb) gAudioErrorCallback = cb; } + bool AudioSystem::routedToA2dpOutput(audio_stream_type_t streamType) { switch (streamType) { @@ -566,6 +568,7 @@ const sp<IAudioPolicyService>& AudioSystem::get_audio_policy_service() } binder->linkToDeath(gAudioPolicyServiceClient); gAudioPolicyService = interface_cast<IAudioPolicyService>(binder); + gAudioPolicyService->registerClient(gAudioPolicyServiceClient); gLock.unlock(); } else { gLock.unlock(); @@ -880,14 +883,39 @@ status_t AudioSystem::setAudioPortConfig(const struct audio_port_config *config) return aps->setAudioPortConfig(config); } +void AudioSystem::setAudioPortCallback(sp<AudioPortCallback> callBack) +{ + Mutex::Autolock _l(gLock); + gAudioPortCallback = callBack; +} + // --------------------------------------------------------------------------- void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused) { - Mutex::Autolock _l(AudioSystem::gLock); + Mutex::Autolock _l(gLock); + if (gAudioPortCallback != 0) { + gAudioPortCallback->onServiceDied(); + } AudioSystem::gAudioPolicyService.clear(); ALOGW("AudioPolicyService server died!"); } +void AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate() +{ + Mutex::Autolock _l(gLock); + if (gAudioPortCallback != 0) { + gAudioPortCallback->onAudioPortListUpdate(); + } +} + +void AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate() +{ + Mutex::Autolock _l(gLock); + if (gAudioPortCallback != 0) { + gAudioPortCallback->onAudioPatchListUpdate(); + } +} + }; // namespace android diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index ad2d4eb..eee72c5 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -63,7 +63,8 @@ enum { CREATE_AUDIO_PATCH, RELEASE_AUDIO_PATCH, LIST_AUDIO_PATCHES, - SET_AUDIO_PORT_CONFIG + SET_AUDIO_PORT_CONFIG, + REGISTER_CLIENT }; class BpAudioPolicyService : public BpInterface<IAudioPolicyService> @@ -524,6 +525,13 @@ public: } return status; } + virtual void registerClient(const sp<IAudioPolicyServiceClient>& client) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.writeStrongBinder(client->asBinder()); + remote()->transact(REGISTER_CLIENT, data, &reply); + } }; IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); @@ -910,6 +918,13 @@ status_t BnAudioPolicyService::onTransact( reply->writeInt32(status); return NO_ERROR; } + case REGISTER_CLIENT: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>( + data.readStrongBinder()); + registerClient(client); + return NO_ERROR; + } break; default: return BBinder::onTransact(code, data, reply, flags); diff --git a/media/libmedia/IAudioPolicyServiceClient.cpp b/media/libmedia/IAudioPolicyServiceClient.cpp new file mode 100644 index 0000000..e802277 --- /dev/null +++ b/media/libmedia/IAudioPolicyServiceClient.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "IAudioPolicyServiceClient" +#include <utils/Log.h> + +#include <stdint.h> +#include <sys/types.h> + +#include <binder/Parcel.h> + +#include <media/IAudioPolicyServiceClient.h> +#include <media/AudioSystem.h> + +namespace android { + +enum { + PORT_LIST_UPDATE = IBinder::FIRST_CALL_TRANSACTION, + PATCH_LIST_UPDATE +}; + +class BpAudioPolicyServiceClient : public BpInterface<IAudioPolicyServiceClient> +{ +public: + BpAudioPolicyServiceClient(const sp<IBinder>& impl) + : BpInterface<IAudioPolicyServiceClient>(impl) + { + } + + void onAudioPortListUpdate() + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor()); + remote()->transact(PORT_LIST_UPDATE, data, &reply, IBinder::FLAG_ONEWAY); + } + + void onAudioPatchListUpdate() + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor()); + remote()->transact(PATCH_LIST_UPDATE, data, &reply, IBinder::FLAG_ONEWAY); + } +}; + +IMPLEMENT_META_INTERFACE(AudioPolicyServiceClient, "android.media.IAudioPolicyServiceClient"); + +// ---------------------------------------------------------------------- + +status_t BnAudioPolicyServiceClient::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch (code) { + case PORT_LIST_UPDATE: { + CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply); + onAudioPortListUpdate(); + return NO_ERROR; + } break; + case PATCH_LIST_UPDATE: { + CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply); + onAudioPatchListUpdate(); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// ---------------------------------------------------------------------------- + +}; // namespace android 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 905418b..b5b26d3 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -286,6 +286,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; } else { + mpClientInterface->onAudioPortListUpdate(); return NO_ERROR; } } // end if is output device @@ -343,6 +344,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, closeAllInputs(); + mpClientInterface->onAudioPortListUpdate(); return NO_ERROR; } // end if is input device @@ -754,6 +756,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; } @@ -986,6 +989,7 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output) if (dstOutput != mPrimaryOutput) { mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput); } + mpClientInterface->onAudioPortListUpdate(); } } } @@ -1067,6 +1071,7 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, return 0; } addInput(input, inputDesc); + mpClientInterface->onAudioPortListUpdate(); return input; } @@ -1152,6 +1157,7 @@ void AudioPolicyManager::releaseInput(audio_io_handle_t input) delete mInputs.valueAt(index); mInputs.removeItem(input); nextAudioPortGeneration(); + mpClientInterface->onAudioPortListUpdate(); ALOGV("releaseInput() exit"); } @@ -1904,6 +1910,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); @@ -1967,6 +1974,7 @@ status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle, status, patchDesc->mAfPatchHandle); removeAudioPatch(patchDesc->mHandle); nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); } else { return BAD_VALUE; } @@ -3584,6 +3592,7 @@ uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, } outputDesc->mPatchHandle = patchDesc->mHandle; nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); } } } @@ -3614,6 +3623,7 @@ status_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output, outputDesc->mPatchHandle = 0; removeAudioPatch(patchDesc->mHandle); nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); return status; } @@ -3669,6 +3679,7 @@ status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input, } inputDesc->mPatchHandle = patchDesc->mHandle; nextAudioPortGeneration(); + mpClientInterface->onAudioPatchListUpdate(); } } } @@ -3694,6 +3705,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 |