Loading media/libaudioclient/AudioSystem.cpp +167 −142 Original line number Diff line number Diff line Loading @@ -63,10 +63,6 @@ using media::audio::common::AudioUsage; using media::audio::common::Int; std::mutex AudioSystem::gMutex; sp<IAudioFlinger> AudioSystem::gAudioFlinger; sp<IBinder> AudioSystem::gAudioFlingerBinder; sp<IAudioFlinger> AudioSystem::gLocalAudioFlinger; sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient; dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL; record_config_callback AudioSystem::gRecordConfigCallback = NULL; routing_callback AudioSystem::gRoutingCallback = NULL; Loading @@ -86,90 +82,167 @@ sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient // from the system server. // This allows specific isolated processes to access the audio system. Currently used only for the // HotwordDetectionService. void AudioSystem::setAudioFlingerBinder(const sp<IBinder>& audioFlinger) { if (audioFlinger->getInterfaceDescriptor() != media::IAudioFlingerService::descriptor) { ALOGE("setAudioFlingerBinder: received a binder of type %s", String8(audioFlinger->getInterfaceDescriptor()).c_str()); return; } std::lock_guard _l(gMutex); if (gAudioFlinger != nullptr) { ALOGW("setAudioFlingerBinder: ignoring; AudioFlinger connection already established."); return; } gAudioFlingerBinder = audioFlinger; } status_t AudioSystem::setLocalAudioFlinger(const sp<IAudioFlinger>& af) { std::lock_guard _l(gMutex); if (gAudioFlinger != nullptr) return INVALID_OPERATION; gLocalAudioFlinger = af; return OK; } template <typename ServiceInterface, typename Client, typename AidlInterface, typename ServiceTraits> class ServiceHandler { public: sp<ServiceInterface> getService(bool canStartThreadPool = true) EXCLUDES(mMutex) NO_THREAD_SAFETY_ANALYSIS { // std::unique_ptr sp<ServiceInterface> service; sp<Client> client; // establish binder interface to AudioFlinger service const sp<IAudioFlinger> AudioSystem::getAudioFlingerImpl(bool canStartThreadPool = true) { sp<IAudioFlinger> af; sp<AudioFlingerClient> afc; bool reportNoError = false; { std::lock_guard _l(gMutex); if (gAudioFlinger != nullptr) { return gAudioFlinger; std::lock_guard _l(mMutex); if (mService != nullptr) { return mService; } } if (gAudioFlingerClient == nullptr) { gAudioFlingerClient = sp<AudioFlingerClient>::make(); std::unique_lock ul_only1thread(mSingleGetter); std::unique_lock ul(mMutex); if (mService != nullptr) { return mService; } if (mClient == nullptr) { mClient = sp<Client>::make(); } else { reportNoError = true; } while (true) { mService = mLocalService; if (mService != nullptr) break; if (gLocalAudioFlinger != nullptr) { gAudioFlinger = gLocalAudioFlinger; } else { sp<IBinder> binder; if (gAudioFlingerBinder != nullptr) { binder = gAudioFlingerBinder; } else { sp<IBinder> binder = mBinder; if (binder == nullptr) { sp <IServiceManager> sm = defaultServiceManager(); binder = sm->waitForService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME)); binder = sm->checkService(String16(ServiceTraits::SERVICE_NAME)); if (binder == nullptr) { return nullptr; ALOGD("%s: waiting for %s", __func__, ServiceTraits::SERVICE_NAME); // if the condition variable is present, setLocalService() and // setBinder() is allowed to use it to notify us. if (mCvGetter == nullptr) { mCvGetter = std::make_shared<std::condition_variable>(); } mCvGetter->wait_for(ul, std::chrono::seconds(1)); continue; } binder->linkToDeath(gAudioFlingerClient); const auto afs = interface_cast<media::IAudioFlingerService>(binder); LOG_ALWAYS_FATAL_IF(afs == nullptr); gAudioFlinger = sp<AudioFlingerClientAdapter>::make(afs); } afc = gAudioFlingerClient; af = gAudioFlinger; // Make sure callbacks can be received by gAudioFlingerClient binder->linkToDeath(mClient); auto aidlInterface = interface_cast<AidlInterface>(binder); LOG_ALWAYS_FATAL_IF(aidlInterface == nullptr); if constexpr (std::is_same_v<ServiceInterface, AidlInterface>) { mService = std::move(aidlInterface); } else /* constexpr */ { mService = ServiceTraits::createServiceAdapter(aidlInterface); } break; } if (mCvGetter) mCvGetter.reset(); // remove condition variable. client = mClient; service = mService; // Make sure callbacks can be received by the client if (canStartThreadPool) { ProcessState::self()->startThreadPool(); } ul.unlock(); ul_only1thread.unlock(); ServiceTraits::onServiceCreate(service, client); if (reportNoError) AudioSystem::reportError(NO_ERROR); return service; } status_t setLocalService(const sp<ServiceInterface>& service) EXCLUDES(mMutex) { std::lock_guard _l(mMutex); // we allow clearing once set, but not a double non-null set. if (mService != nullptr && service != nullptr) return INVALID_OPERATION; mLocalService = service; if (mCvGetter) mCvGetter->notify_one(); return OK; } sp<Client> getClient() EXCLUDES(mMutex) { const auto service = getService(); if (service == nullptr) return nullptr; std::lock_guard _l(mMutex); return mClient; } void setBinder(const sp<IBinder>& binder) EXCLUDES(mMutex) { std::lock_guard _l(mMutex); if (mService != nullptr) { ALOGW("%s: ignoring; %s connection already established.", __func__, ServiceTraits::SERVICE_NAME); return; } mBinder = binder; if (mCvGetter) mCvGetter->notify_one(); } void clearService() EXCLUDES(mMutex) { std::lock_guard _l(mMutex); mService.clear(); if (mClient) ServiceTraits::onClearService(mClient); } private: std::mutex mSingleGetter; std::mutex mMutex; std::shared_ptr<std::condition_variable> mCvGetter GUARDED_BY(mMutex); sp<IBinder> mBinder GUARDED_BY(mMutex); sp<ServiceInterface> mLocalService GUARDED_BY(mMutex); sp<ServiceInterface> mService GUARDED_BY(mMutex); sp<Client> mClient GUARDED_BY(mMutex); }; struct AudioFlingerTraits { static void onServiceCreate( const sp<IAudioFlinger>& af, const sp<AudioSystem::AudioFlingerClient>& afc) { const int64_t token = IPCThreadState::self()->clearCallingIdentity(); af->registerClient(afc); IPCThreadState::self()->restoreCallingIdentity(token); if (reportNoError) reportError(NO_ERROR); return af; } static sp<IAudioFlinger> createServiceAdapter( const sp<media::IAudioFlingerService>& aidlInterface) { return sp<AudioFlingerClientAdapter>::make(aidlInterface); } static void onClearService(const sp<AudioSystem::AudioFlingerClient>& afc) { afc->clearIoCache(); } static constexpr const char* SERVICE_NAME = IAudioFlinger::DEFAULT_SERVICE_NAME; }; [[clang::no_destroy]] static constinit ServiceHandler<IAudioFlinger, AudioSystem::AudioFlingerClient, media::IAudioFlingerService, AudioFlingerTraits> gAudioFlingerServiceHandler; sp<IAudioFlinger> AudioSystem::get_audio_flinger() { return getAudioFlingerImpl(); return gAudioFlingerServiceHandler.getService(); } sp<IAudioFlinger> AudioSystem::get_audio_flinger_for_fuzzer() { return getAudioFlingerImpl(false); return gAudioFlingerServiceHandler.getService(false /* canStartThreadPool */); } const sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() { // calling get_audio_flinger() will initialize gAudioFlingerClient if needed const sp<IAudioFlinger> af = get_audio_flinger(); if (af == 0) return 0; std::lock_guard _l(gMutex); return gAudioFlingerClient; sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() { return gAudioFlingerServiceHandler.getClient(); } void AudioSystem::setAudioFlingerBinder(const sp<IBinder>& audioFlinger) { if (audioFlinger->getInterfaceDescriptor() != media::IAudioFlingerService::descriptor) { ALOGE("%s: received a binder of type %s", __func__, String8(audioFlinger->getInterfaceDescriptor()).c_str()); return; } gAudioFlingerServiceHandler.setBinder(audioFlinger); } status_t AudioSystem::setLocalAudioFlinger(const sp<IAudioFlinger>& af) { return gAudioFlingerServiceHandler.setLocalService(af); } sp<AudioIoDescriptor> AudioSystem::getIoDescriptor(audio_io_handle_t ioHandle) { Loading Loading @@ -554,14 +627,7 @@ void AudioSystem::AudioFlingerClient::clearIoCache() { } void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused) { { std::lock_guard _l(AudioSystem::gMutex); AudioSystem::gAudioFlinger.clear(); } // clear output handles and stream to output map caches clearIoCache(); gAudioFlingerServiceHandler.clearService(); reportError(DEAD_OBJECT); ALOGW("AudioFlinger server died!"); Loading Loading @@ -591,13 +657,10 @@ Status AudioSystem::AudioFlingerClient::ioConfigChanged( case AUDIO_OUTPUT_REGISTERED: case AUDIO_INPUT_OPENED: case AUDIO_INPUT_REGISTERED: { sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->getIoHandle()); if (oldDesc == 0) { mIoDescriptors.add(ioDesc->getIoHandle(), ioDesc); } else { if (sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->getIoHandle())) { deviceId = oldDesc->getDeviceId(); mIoDescriptors.replaceValueFor(ioDesc->getIoHandle(), ioDesc); } mIoDescriptors[ioDesc->getIoHandle()] = ioDesc; if (ioDesc->getDeviceId() != AUDIO_PORT_HANDLE_NONE) { deviceId = ioDesc->getDeviceId(); Loading Loading @@ -626,7 +689,7 @@ Status AudioSystem::AudioFlingerClient::ioConfigChanged( ALOGV("ioConfigChanged() %s %d closed", event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->getIoHandle()); mIoDescriptors.removeItem(ioDesc->getIoHandle()); mIoDescriptors.erase(ioDesc->getIoHandle()); mAudioDeviceCallbacks.erase(ioDesc->getIoHandle()); } break; Loading @@ -642,7 +705,7 @@ Status AudioSystem::AudioFlingerClient::ioConfigChanged( } deviceId = oldDesc->getDeviceId(); mIoDescriptors.replaceValueFor(ioDesc->getIoHandle(), ioDesc); mIoDescriptors[ioDesc->getIoHandle()] = ioDesc; if (deviceId != ioDesc->getDeviceId()) { deviceId = ioDesc->getDeviceId(); Loading Loading @@ -755,12 +818,11 @@ status_t AudioSystem::AudioFlingerClient::getInputBufferSize( sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor_l(audio_io_handle_t ioHandle) { sp<AudioIoDescriptor> desc; ssize_t index = mIoDescriptors.indexOfKey(ioHandle); if (index >= 0) { desc = mIoDescriptors.valueAt(index); if (const auto it = mIoDescriptors.find(ioHandle); it != mIoDescriptors.end()) { return it->second; } return desc; return {}; } sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_handle_t ioHandle) { Loading Loading @@ -1502,13 +1564,7 @@ status_t AudioSystem::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) void AudioSystem::clearAudioConfigCache() { // called by restoreTrack_l(), which needs new IAudioFlinger and IAudioPolicyService instances ALOGV("clearAudioConfigCache()"); { std::lock_guard _l(gMutex); if (gAudioFlingerClient != 0) { gAudioFlingerClient->clearIoCache(); } gAudioFlinger.clear(); } gAudioFlingerServiceHandler.clearService(); clearAudioPolicyService(); } Loading Loading @@ -2726,44 +2782,27 @@ status_t AudioSystem::clearPreferredMixerAttributes(const audio_attributes_t *at int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback( const sp<AudioPortCallback>& callback) { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { if (mAudioPortCallbacks[i] == callback) { return -1; } } mAudioPortCallbacks.add(callback); return mAudioPortCallbacks.size(); return mAudioPortCallbacks.insert(callback).second ? mAudioPortCallbacks.size() : -1; } int AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback( const sp<AudioPortCallback>& callback) { std::lock_guard _l(mMutex); size_t i; for (i = 0; i < mAudioPortCallbacks.size(); i++) { if (mAudioPortCallbacks[i] == callback) { break; } } if (i == mAudioPortCallbacks.size()) { return -1; return mAudioPortCallbacks.erase(callback) > 0 ? mAudioPortCallbacks.size() : -1; } mAudioPortCallbacks.removeAt(i); return mAudioPortCallbacks.size(); } Status AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate() { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { mAudioPortCallbacks[i]->onAudioPortListUpdate(); for (const auto& callback : mAudioPortCallbacks) { callback->onAudioPortListUpdate(); } return Status::ok(); } Status AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate() { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { mAudioPortCallbacks[i]->onAudioPatchListUpdate(); for (const auto& callback : mAudioPortCallbacks) { callback->onAudioPatchListUpdate(); } return Status::ok(); } Loading @@ -2772,29 +2811,15 @@ Status AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate() { int AudioSystem::AudioPolicyServiceClient::addAudioVolumeGroupCallback( const sp<AudioVolumeGroupCallback>& callback) { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) { if (mAudioVolumeGroupCallback[i] == callback) { return -1; } } mAudioVolumeGroupCallback.add(callback); return mAudioVolumeGroupCallback.size(); return mAudioVolumeGroupCallbacks.insert(callback).second ? mAudioVolumeGroupCallbacks.size() : -1; } int AudioSystem::AudioPolicyServiceClient::removeAudioVolumeGroupCallback( const sp<AudioVolumeGroupCallback>& callback) { std::lock_guard _l(mMutex); size_t i; for (i = 0; i < mAudioVolumeGroupCallback.size(); i++) { if (mAudioVolumeGroupCallback[i] == callback) { break; } } if (i == mAudioVolumeGroupCallback.size()) { return -1; } mAudioVolumeGroupCallback.removeAt(i); return mAudioVolumeGroupCallback.size(); return mAudioVolumeGroupCallbacks.erase(callback) > 0 ? mAudioVolumeGroupCallbacks.size() : -1; } Status AudioSystem::AudioPolicyServiceClient::onAudioVolumeGroupChanged(int32_t group, Loading @@ -2804,8 +2829,8 @@ Status AudioSystem::AudioPolicyServiceClient::onAudioVolumeGroupChanged(int32_t int flagsLegacy = VALUE_OR_RETURN_BINDER_STATUS(convertReinterpret<int>(flags)); std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) { mAudioVolumeGroupCallback[i]->onAudioVolumeGroupChanged(groupLegacy, flagsLegacy); for (const auto& callback : mAudioVolumeGroupCallbacks) { callback->onAudioVolumeGroupChanged(groupLegacy, flagsLegacy); } return Status::ok(); } Loading Loading @@ -2899,11 +2924,11 @@ Status AudioSystem::AudioPolicyServiceClient::onVolumeRangeInitRequest() { void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused) { { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { mAudioPortCallbacks[i]->onServiceDied(); for (const auto& callback : mAudioPortCallbacks) { callback->onServiceDied(); } for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) { mAudioVolumeGroupCallback[i]->onServiceDied(); for (const auto& callback : mAudioVolumeGroupCallbacks) { callback->onServiceDied(); } } AudioSystem::clearAudioPolicyService(); Loading media/libaudioclient/include/media/AudioSystem.h +12 −14 Original line number Diff line number Diff line Loading @@ -100,6 +100,10 @@ class AudioSystem friend class AudioFlingerClient; friend class AudioPolicyServiceClient; friend class CaptureStateListenerImpl; template <typename ServiceInterface, typename Client, typename AidlInterface, typename ServiceTraits> friend class ServiceHandler; public: // FIXME Declare in binder opcode order, similarly to IAudioFlinger.h and IAudioFlinger.cpp Loading Loading @@ -779,8 +783,6 @@ public: static int32_t getAAudioHardwareBurstMinUsec(); private: class AudioFlingerClient: public IBinder::DeathRecipient, public media::BnAudioFlingerClient { public: Loading Loading @@ -821,8 +823,7 @@ private: private: mutable std::mutex mMutex; DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor>> mIoDescriptors GUARDED_BY(mMutex); std::map<audio_io_handle_t, sp<AudioIoDescriptor>> mIoDescriptors GUARDED_BY(mMutex); std::map<audio_io_handle_t, std::map<audio_port_handle_t, wp<AudioDeviceCallback>>> mAudioDeviceCallbacks GUARDED_BY(mMutex); Loading Loading @@ -850,7 +851,7 @@ private: bool isAudioPortCbEnabled() const EXCLUDES(mMutex) { std::lock_guard _l(mMutex); return (mAudioPortCallbacks.size() != 0); return !mAudioPortCallbacks.empty(); } int addAudioVolumeGroupCallback( Loading @@ -861,7 +862,7 @@ private: bool isAudioVolumeGroupCbEnabled() const EXCLUDES(mMutex) { std::lock_guard _l(mMutex); return (mAudioVolumeGroupCallback.size() != 0); return !mAudioVolumeGroupCallbacks.empty(); } // DeathRecipient Loading @@ -887,23 +888,20 @@ private: private: mutable std::mutex mMutex; Vector<sp<AudioPortCallback>> mAudioPortCallbacks GUARDED_BY(mMutex); Vector<sp<AudioVolumeGroupCallback>> mAudioVolumeGroupCallback GUARDED_BY(mMutex); std::set<sp<AudioPortCallback>> mAudioPortCallbacks GUARDED_BY(mMutex); std::set<sp<AudioVolumeGroupCallback>> mAudioVolumeGroupCallbacks GUARDED_BY(mMutex); }; private: static audio_io_handle_t getOutput(audio_stream_type_t stream); static const sp<AudioFlingerClient> getAudioFlingerClient(); static sp<AudioFlingerClient> getAudioFlingerClient(); static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle); static const sp<IAudioFlinger> getAudioFlingerImpl(bool canStartThreadPool); // Invokes all registered error callbacks with the given error code. static void reportError(status_t err); [[clang::no_destroy]] static std::mutex gMutex; [[clang::no_destroy]] static sp<IAudioFlinger> gAudioFlinger GUARDED_BY(gMutex); [[clang::no_destroy]] static sp<IBinder> gAudioFlingerBinder GUARDED_BY(gMutex); [[clang::no_destroy]] static sp<IAudioFlinger> gLocalAudioFlinger GUARDED_BY(gMutex); [[clang::no_destroy]] static sp<AudioFlingerClient> gAudioFlingerClient GUARDED_BY(gMutex); static dynamic_policy_callback gDynPolicyCallback GUARDED_BY(gMutex); static record_config_callback gRecordConfigCallback GUARDED_BY(gMutex); static routing_callback gRoutingCallback GUARDED_BY(gMutex); Loading Loading
media/libaudioclient/AudioSystem.cpp +167 −142 Original line number Diff line number Diff line Loading @@ -63,10 +63,6 @@ using media::audio::common::AudioUsage; using media::audio::common::Int; std::mutex AudioSystem::gMutex; sp<IAudioFlinger> AudioSystem::gAudioFlinger; sp<IBinder> AudioSystem::gAudioFlingerBinder; sp<IAudioFlinger> AudioSystem::gLocalAudioFlinger; sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient; dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL; record_config_callback AudioSystem::gRecordConfigCallback = NULL; routing_callback AudioSystem::gRoutingCallback = NULL; Loading @@ -86,90 +82,167 @@ sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient // from the system server. // This allows specific isolated processes to access the audio system. Currently used only for the // HotwordDetectionService. void AudioSystem::setAudioFlingerBinder(const sp<IBinder>& audioFlinger) { if (audioFlinger->getInterfaceDescriptor() != media::IAudioFlingerService::descriptor) { ALOGE("setAudioFlingerBinder: received a binder of type %s", String8(audioFlinger->getInterfaceDescriptor()).c_str()); return; } std::lock_guard _l(gMutex); if (gAudioFlinger != nullptr) { ALOGW("setAudioFlingerBinder: ignoring; AudioFlinger connection already established."); return; } gAudioFlingerBinder = audioFlinger; } status_t AudioSystem::setLocalAudioFlinger(const sp<IAudioFlinger>& af) { std::lock_guard _l(gMutex); if (gAudioFlinger != nullptr) return INVALID_OPERATION; gLocalAudioFlinger = af; return OK; } template <typename ServiceInterface, typename Client, typename AidlInterface, typename ServiceTraits> class ServiceHandler { public: sp<ServiceInterface> getService(bool canStartThreadPool = true) EXCLUDES(mMutex) NO_THREAD_SAFETY_ANALYSIS { // std::unique_ptr sp<ServiceInterface> service; sp<Client> client; // establish binder interface to AudioFlinger service const sp<IAudioFlinger> AudioSystem::getAudioFlingerImpl(bool canStartThreadPool = true) { sp<IAudioFlinger> af; sp<AudioFlingerClient> afc; bool reportNoError = false; { std::lock_guard _l(gMutex); if (gAudioFlinger != nullptr) { return gAudioFlinger; std::lock_guard _l(mMutex); if (mService != nullptr) { return mService; } } if (gAudioFlingerClient == nullptr) { gAudioFlingerClient = sp<AudioFlingerClient>::make(); std::unique_lock ul_only1thread(mSingleGetter); std::unique_lock ul(mMutex); if (mService != nullptr) { return mService; } if (mClient == nullptr) { mClient = sp<Client>::make(); } else { reportNoError = true; } while (true) { mService = mLocalService; if (mService != nullptr) break; if (gLocalAudioFlinger != nullptr) { gAudioFlinger = gLocalAudioFlinger; } else { sp<IBinder> binder; if (gAudioFlingerBinder != nullptr) { binder = gAudioFlingerBinder; } else { sp<IBinder> binder = mBinder; if (binder == nullptr) { sp <IServiceManager> sm = defaultServiceManager(); binder = sm->waitForService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME)); binder = sm->checkService(String16(ServiceTraits::SERVICE_NAME)); if (binder == nullptr) { return nullptr; ALOGD("%s: waiting for %s", __func__, ServiceTraits::SERVICE_NAME); // if the condition variable is present, setLocalService() and // setBinder() is allowed to use it to notify us. if (mCvGetter == nullptr) { mCvGetter = std::make_shared<std::condition_variable>(); } mCvGetter->wait_for(ul, std::chrono::seconds(1)); continue; } binder->linkToDeath(gAudioFlingerClient); const auto afs = interface_cast<media::IAudioFlingerService>(binder); LOG_ALWAYS_FATAL_IF(afs == nullptr); gAudioFlinger = sp<AudioFlingerClientAdapter>::make(afs); } afc = gAudioFlingerClient; af = gAudioFlinger; // Make sure callbacks can be received by gAudioFlingerClient binder->linkToDeath(mClient); auto aidlInterface = interface_cast<AidlInterface>(binder); LOG_ALWAYS_FATAL_IF(aidlInterface == nullptr); if constexpr (std::is_same_v<ServiceInterface, AidlInterface>) { mService = std::move(aidlInterface); } else /* constexpr */ { mService = ServiceTraits::createServiceAdapter(aidlInterface); } break; } if (mCvGetter) mCvGetter.reset(); // remove condition variable. client = mClient; service = mService; // Make sure callbacks can be received by the client if (canStartThreadPool) { ProcessState::self()->startThreadPool(); } ul.unlock(); ul_only1thread.unlock(); ServiceTraits::onServiceCreate(service, client); if (reportNoError) AudioSystem::reportError(NO_ERROR); return service; } status_t setLocalService(const sp<ServiceInterface>& service) EXCLUDES(mMutex) { std::lock_guard _l(mMutex); // we allow clearing once set, but not a double non-null set. if (mService != nullptr && service != nullptr) return INVALID_OPERATION; mLocalService = service; if (mCvGetter) mCvGetter->notify_one(); return OK; } sp<Client> getClient() EXCLUDES(mMutex) { const auto service = getService(); if (service == nullptr) return nullptr; std::lock_guard _l(mMutex); return mClient; } void setBinder(const sp<IBinder>& binder) EXCLUDES(mMutex) { std::lock_guard _l(mMutex); if (mService != nullptr) { ALOGW("%s: ignoring; %s connection already established.", __func__, ServiceTraits::SERVICE_NAME); return; } mBinder = binder; if (mCvGetter) mCvGetter->notify_one(); } void clearService() EXCLUDES(mMutex) { std::lock_guard _l(mMutex); mService.clear(); if (mClient) ServiceTraits::onClearService(mClient); } private: std::mutex mSingleGetter; std::mutex mMutex; std::shared_ptr<std::condition_variable> mCvGetter GUARDED_BY(mMutex); sp<IBinder> mBinder GUARDED_BY(mMutex); sp<ServiceInterface> mLocalService GUARDED_BY(mMutex); sp<ServiceInterface> mService GUARDED_BY(mMutex); sp<Client> mClient GUARDED_BY(mMutex); }; struct AudioFlingerTraits { static void onServiceCreate( const sp<IAudioFlinger>& af, const sp<AudioSystem::AudioFlingerClient>& afc) { const int64_t token = IPCThreadState::self()->clearCallingIdentity(); af->registerClient(afc); IPCThreadState::self()->restoreCallingIdentity(token); if (reportNoError) reportError(NO_ERROR); return af; } static sp<IAudioFlinger> createServiceAdapter( const sp<media::IAudioFlingerService>& aidlInterface) { return sp<AudioFlingerClientAdapter>::make(aidlInterface); } static void onClearService(const sp<AudioSystem::AudioFlingerClient>& afc) { afc->clearIoCache(); } static constexpr const char* SERVICE_NAME = IAudioFlinger::DEFAULT_SERVICE_NAME; }; [[clang::no_destroy]] static constinit ServiceHandler<IAudioFlinger, AudioSystem::AudioFlingerClient, media::IAudioFlingerService, AudioFlingerTraits> gAudioFlingerServiceHandler; sp<IAudioFlinger> AudioSystem::get_audio_flinger() { return getAudioFlingerImpl(); return gAudioFlingerServiceHandler.getService(); } sp<IAudioFlinger> AudioSystem::get_audio_flinger_for_fuzzer() { return getAudioFlingerImpl(false); return gAudioFlingerServiceHandler.getService(false /* canStartThreadPool */); } const sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() { // calling get_audio_flinger() will initialize gAudioFlingerClient if needed const sp<IAudioFlinger> af = get_audio_flinger(); if (af == 0) return 0; std::lock_guard _l(gMutex); return gAudioFlingerClient; sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() { return gAudioFlingerServiceHandler.getClient(); } void AudioSystem::setAudioFlingerBinder(const sp<IBinder>& audioFlinger) { if (audioFlinger->getInterfaceDescriptor() != media::IAudioFlingerService::descriptor) { ALOGE("%s: received a binder of type %s", __func__, String8(audioFlinger->getInterfaceDescriptor()).c_str()); return; } gAudioFlingerServiceHandler.setBinder(audioFlinger); } status_t AudioSystem::setLocalAudioFlinger(const sp<IAudioFlinger>& af) { return gAudioFlingerServiceHandler.setLocalService(af); } sp<AudioIoDescriptor> AudioSystem::getIoDescriptor(audio_io_handle_t ioHandle) { Loading Loading @@ -554,14 +627,7 @@ void AudioSystem::AudioFlingerClient::clearIoCache() { } void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused) { { std::lock_guard _l(AudioSystem::gMutex); AudioSystem::gAudioFlinger.clear(); } // clear output handles and stream to output map caches clearIoCache(); gAudioFlingerServiceHandler.clearService(); reportError(DEAD_OBJECT); ALOGW("AudioFlinger server died!"); Loading Loading @@ -591,13 +657,10 @@ Status AudioSystem::AudioFlingerClient::ioConfigChanged( case AUDIO_OUTPUT_REGISTERED: case AUDIO_INPUT_OPENED: case AUDIO_INPUT_REGISTERED: { sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->getIoHandle()); if (oldDesc == 0) { mIoDescriptors.add(ioDesc->getIoHandle(), ioDesc); } else { if (sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->getIoHandle())) { deviceId = oldDesc->getDeviceId(); mIoDescriptors.replaceValueFor(ioDesc->getIoHandle(), ioDesc); } mIoDescriptors[ioDesc->getIoHandle()] = ioDesc; if (ioDesc->getDeviceId() != AUDIO_PORT_HANDLE_NONE) { deviceId = ioDesc->getDeviceId(); Loading Loading @@ -626,7 +689,7 @@ Status AudioSystem::AudioFlingerClient::ioConfigChanged( ALOGV("ioConfigChanged() %s %d closed", event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->getIoHandle()); mIoDescriptors.removeItem(ioDesc->getIoHandle()); mIoDescriptors.erase(ioDesc->getIoHandle()); mAudioDeviceCallbacks.erase(ioDesc->getIoHandle()); } break; Loading @@ -642,7 +705,7 @@ Status AudioSystem::AudioFlingerClient::ioConfigChanged( } deviceId = oldDesc->getDeviceId(); mIoDescriptors.replaceValueFor(ioDesc->getIoHandle(), ioDesc); mIoDescriptors[ioDesc->getIoHandle()] = ioDesc; if (deviceId != ioDesc->getDeviceId()) { deviceId = ioDesc->getDeviceId(); Loading Loading @@ -755,12 +818,11 @@ status_t AudioSystem::AudioFlingerClient::getInputBufferSize( sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor_l(audio_io_handle_t ioHandle) { sp<AudioIoDescriptor> desc; ssize_t index = mIoDescriptors.indexOfKey(ioHandle); if (index >= 0) { desc = mIoDescriptors.valueAt(index); if (const auto it = mIoDescriptors.find(ioHandle); it != mIoDescriptors.end()) { return it->second; } return desc; return {}; } sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_handle_t ioHandle) { Loading Loading @@ -1502,13 +1564,7 @@ status_t AudioSystem::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) void AudioSystem::clearAudioConfigCache() { // called by restoreTrack_l(), which needs new IAudioFlinger and IAudioPolicyService instances ALOGV("clearAudioConfigCache()"); { std::lock_guard _l(gMutex); if (gAudioFlingerClient != 0) { gAudioFlingerClient->clearIoCache(); } gAudioFlinger.clear(); } gAudioFlingerServiceHandler.clearService(); clearAudioPolicyService(); } Loading Loading @@ -2726,44 +2782,27 @@ status_t AudioSystem::clearPreferredMixerAttributes(const audio_attributes_t *at int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback( const sp<AudioPortCallback>& callback) { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { if (mAudioPortCallbacks[i] == callback) { return -1; } } mAudioPortCallbacks.add(callback); return mAudioPortCallbacks.size(); return mAudioPortCallbacks.insert(callback).second ? mAudioPortCallbacks.size() : -1; } int AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback( const sp<AudioPortCallback>& callback) { std::lock_guard _l(mMutex); size_t i; for (i = 0; i < mAudioPortCallbacks.size(); i++) { if (mAudioPortCallbacks[i] == callback) { break; } } if (i == mAudioPortCallbacks.size()) { return -1; return mAudioPortCallbacks.erase(callback) > 0 ? mAudioPortCallbacks.size() : -1; } mAudioPortCallbacks.removeAt(i); return mAudioPortCallbacks.size(); } Status AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate() { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { mAudioPortCallbacks[i]->onAudioPortListUpdate(); for (const auto& callback : mAudioPortCallbacks) { callback->onAudioPortListUpdate(); } return Status::ok(); } Status AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate() { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { mAudioPortCallbacks[i]->onAudioPatchListUpdate(); for (const auto& callback : mAudioPortCallbacks) { callback->onAudioPatchListUpdate(); } return Status::ok(); } Loading @@ -2772,29 +2811,15 @@ Status AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate() { int AudioSystem::AudioPolicyServiceClient::addAudioVolumeGroupCallback( const sp<AudioVolumeGroupCallback>& callback) { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) { if (mAudioVolumeGroupCallback[i] == callback) { return -1; } } mAudioVolumeGroupCallback.add(callback); return mAudioVolumeGroupCallback.size(); return mAudioVolumeGroupCallbacks.insert(callback).second ? mAudioVolumeGroupCallbacks.size() : -1; } int AudioSystem::AudioPolicyServiceClient::removeAudioVolumeGroupCallback( const sp<AudioVolumeGroupCallback>& callback) { std::lock_guard _l(mMutex); size_t i; for (i = 0; i < mAudioVolumeGroupCallback.size(); i++) { if (mAudioVolumeGroupCallback[i] == callback) { break; } } if (i == mAudioVolumeGroupCallback.size()) { return -1; } mAudioVolumeGroupCallback.removeAt(i); return mAudioVolumeGroupCallback.size(); return mAudioVolumeGroupCallbacks.erase(callback) > 0 ? mAudioVolumeGroupCallbacks.size() : -1; } Status AudioSystem::AudioPolicyServiceClient::onAudioVolumeGroupChanged(int32_t group, Loading @@ -2804,8 +2829,8 @@ Status AudioSystem::AudioPolicyServiceClient::onAudioVolumeGroupChanged(int32_t int flagsLegacy = VALUE_OR_RETURN_BINDER_STATUS(convertReinterpret<int>(flags)); std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) { mAudioVolumeGroupCallback[i]->onAudioVolumeGroupChanged(groupLegacy, flagsLegacy); for (const auto& callback : mAudioVolumeGroupCallbacks) { callback->onAudioVolumeGroupChanged(groupLegacy, flagsLegacy); } return Status::ok(); } Loading Loading @@ -2899,11 +2924,11 @@ Status AudioSystem::AudioPolicyServiceClient::onVolumeRangeInitRequest() { void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused) { { std::lock_guard _l(mMutex); for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) { mAudioPortCallbacks[i]->onServiceDied(); for (const auto& callback : mAudioPortCallbacks) { callback->onServiceDied(); } for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) { mAudioVolumeGroupCallback[i]->onServiceDied(); for (const auto& callback : mAudioVolumeGroupCallbacks) { callback->onServiceDied(); } } AudioSystem::clearAudioPolicyService(); Loading
media/libaudioclient/include/media/AudioSystem.h +12 −14 Original line number Diff line number Diff line Loading @@ -100,6 +100,10 @@ class AudioSystem friend class AudioFlingerClient; friend class AudioPolicyServiceClient; friend class CaptureStateListenerImpl; template <typename ServiceInterface, typename Client, typename AidlInterface, typename ServiceTraits> friend class ServiceHandler; public: // FIXME Declare in binder opcode order, similarly to IAudioFlinger.h and IAudioFlinger.cpp Loading Loading @@ -779,8 +783,6 @@ public: static int32_t getAAudioHardwareBurstMinUsec(); private: class AudioFlingerClient: public IBinder::DeathRecipient, public media::BnAudioFlingerClient { public: Loading Loading @@ -821,8 +823,7 @@ private: private: mutable std::mutex mMutex; DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor>> mIoDescriptors GUARDED_BY(mMutex); std::map<audio_io_handle_t, sp<AudioIoDescriptor>> mIoDescriptors GUARDED_BY(mMutex); std::map<audio_io_handle_t, std::map<audio_port_handle_t, wp<AudioDeviceCallback>>> mAudioDeviceCallbacks GUARDED_BY(mMutex); Loading Loading @@ -850,7 +851,7 @@ private: bool isAudioPortCbEnabled() const EXCLUDES(mMutex) { std::lock_guard _l(mMutex); return (mAudioPortCallbacks.size() != 0); return !mAudioPortCallbacks.empty(); } int addAudioVolumeGroupCallback( Loading @@ -861,7 +862,7 @@ private: bool isAudioVolumeGroupCbEnabled() const EXCLUDES(mMutex) { std::lock_guard _l(mMutex); return (mAudioVolumeGroupCallback.size() != 0); return !mAudioVolumeGroupCallbacks.empty(); } // DeathRecipient Loading @@ -887,23 +888,20 @@ private: private: mutable std::mutex mMutex; Vector<sp<AudioPortCallback>> mAudioPortCallbacks GUARDED_BY(mMutex); Vector<sp<AudioVolumeGroupCallback>> mAudioVolumeGroupCallback GUARDED_BY(mMutex); std::set<sp<AudioPortCallback>> mAudioPortCallbacks GUARDED_BY(mMutex); std::set<sp<AudioVolumeGroupCallback>> mAudioVolumeGroupCallbacks GUARDED_BY(mMutex); }; private: static audio_io_handle_t getOutput(audio_stream_type_t stream); static const sp<AudioFlingerClient> getAudioFlingerClient(); static sp<AudioFlingerClient> getAudioFlingerClient(); static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle); static const sp<IAudioFlinger> getAudioFlingerImpl(bool canStartThreadPool); // Invokes all registered error callbacks with the given error code. static void reportError(status_t err); [[clang::no_destroy]] static std::mutex gMutex; [[clang::no_destroy]] static sp<IAudioFlinger> gAudioFlinger GUARDED_BY(gMutex); [[clang::no_destroy]] static sp<IBinder> gAudioFlingerBinder GUARDED_BY(gMutex); [[clang::no_destroy]] static sp<IAudioFlinger> gLocalAudioFlinger GUARDED_BY(gMutex); [[clang::no_destroy]] static sp<AudioFlingerClient> gAudioFlingerClient GUARDED_BY(gMutex); static dynamic_policy_callback gDynPolicyCallback GUARDED_BY(gMutex); static record_config_callback gRecordConfigCallback GUARDED_BY(gMutex); static routing_callback gRoutingCallback GUARDED_BY(gMutex); Loading