Loading services/audiopolicy/service/AudioPolicyService.cpp +104 −72 Original line number Diff line number Diff line Loading @@ -332,19 +332,16 @@ status_t AudioPolicyService::dumpInternals(int fd) void AudioPolicyService::setRecordSilenced(uid_t uid, bool silenced) { // FIXME: temporarily disable while investigating issue b/77300296 // { // Mutex::Autolock _l(mLock); // if (mAudioPolicyManager) { // mAudioPolicyManager->setRecordSilenced(uid, silenced); // } // } // sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); // if (af) { // af->setRecordSilenced(uid, silenced); // } (void)uid; (void)silenced; { Mutex::Autolock _l(mLock); if (mAudioPolicyManager) { mAudioPolicyManager->setRecordSilenced(uid, silenced); } } sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); if (af) { af->setRecordSilenced(uid, silenced); } } status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) Loading Loading @@ -508,94 +505,129 @@ void AudioPolicyService::UidPolicy::registerSelf() { | ActivityManager::UID_OBSERVER_ACTIVE, ActivityManager::PROCESS_STATE_UNKNOWN, String16("audioserver")); status_t res = am.linkToDeath(this); if (!res) { Mutex::Autolock _l(mLock); mObserverRegistered = true; } else { ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res); am.unregisterUidObserver(this); } } void AudioPolicyService::UidPolicy::unregisterSelf() { ActivityManager am; am.unlinkToDeath(this); am.unregisterUidObserver(this); Mutex::Autolock _l(mLock); mObserverRegistered = false; } void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) { onUidIdle(uid, disabled); void AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) { Mutex::Autolock _l(mLock); mCachedUids.clear(); mObserverRegistered = false; } void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) { bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) { if (isServiceUid(uid)) return true; bool needToReregister = false; { Mutex::Autolock _l(mUidLock); mActiveUids.insert(uid); Mutex::Autolock _l(mLock); needToReregister = !mObserverRegistered; } sp<AudioPolicyService> service = mService.promote(); if (service != nullptr) { service->setRecordSilenced(uid, false); if (needToReregister) { // Looks like ActivityManager has died previously, attempt to re-register. registerSelf(); } { Mutex::Autolock _l(mLock); auto overrideIter = mOverrideUids.find(uid); if (overrideIter != mOverrideUids.end()) { return overrideIter->second; } void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) { bool deleted = false; // In an absense of the ActivityManager, assume everything to be active. if (!mObserverRegistered) return true; auto cacheIter = mCachedUids.find(uid); if (cacheIter != mOverrideUids.end()) { return cacheIter->second; } } ActivityManager am; bool active = am.isUidActive(uid, String16("audioserver")); { Mutex::Autolock _l(mUidLock); if (mActiveUids.erase(uid) > 0) { deleted = true; Mutex::Autolock _l(mLock); mCachedUids.insert(std::pair<uid_t, bool>(uid, active)); } return active; } if (deleted) { sp<AudioPolicyService> service = mService.promote(); if (service != nullptr) { service->setRecordSilenced(uid, true); void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) { updateUidCache(uid, true, true); } void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) { updateUidCache(uid, false, false); } void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) { updateUidCache(uid, false, true); } void AudioPolicyService::UidPolicy::addOverrideUid(uid_t uid, bool active) { updateOverrideUid(uid, active, true); bool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const { return uid % AID_USER_OFFSET < AID_APP_START; } void AudioPolicyService::UidPolicy::removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) { sp<AudioPolicyService> service = mService.promote(); if (service != nullptr) { service->setRecordSilenced(uid, !active); } } void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) { bool wasActive = false; bool isActive = false; if (isServiceUid(uid)) return; bool wasOverridden = false, wasActive = false; { Mutex::Autolock _l(mUidLock); wasActive = isUidActiveLocked(uid); mOverrideUids.erase(uid); if (insert) { mOverrideUids.insert(std::pair<uid_t, bool>(uid, active)); Mutex::Autolock _l(mLock); updateUidLocked(&mOverrideUids, uid, active, insert, &wasOverridden, &wasActive); } isActive = isUidActiveLocked(uid); if (!wasOverridden && insert) { notifyService(uid, active); // Started to override. } else if (wasOverridden && !insert) { notifyService(uid, isUidActive(uid)); // Override ceased, notify with ground truth. } else if (wasActive != active) { notifyService(uid, active); // Override updated. } if (wasActive != isActive) { sp<AudioPolicyService> service = mService.promote(); if (service != nullptr) { service->setRecordSilenced(uid, !isActive); } void AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) { if (isServiceUid(uid)) return; bool wasActive = false; { Mutex::Autolock _l(mLock); updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive); // Do not notify service if currently overridden. if (mOverrideUids.find(uid) != mOverrideUids.end()) return; } bool nowActive = active && insert; if (wasActive != nowActive) notifyService(uid, nowActive); } bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) { // Non-app UIDs are considered always active if (uid < FIRST_APPLICATION_UID) { return true; } Mutex::Autolock _l(mUidLock); return isUidActiveLocked(uid); } bool AudioPolicyService::UidPolicy::isUidActiveLocked(uid_t uid) { // Non-app UIDs are considered always active // FIXME: temporarily disable while investigating issue b/77300296 // if (uid < FIRST_APPLICATION_UID) { // return true; // } // auto it = mOverrideUids.find(uid); // if (it != mOverrideUids.end()) { // return it->second; // } // return mActiveUids.find(uid) != mActiveUids.end(); (void)uid; return true; void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t, bool> *uids, uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive) { auto it = uids->find(uid); if (it != uids->end()) { if (wasThere != nullptr) *wasThere = true; if (wasActive != nullptr) *wasActive = it->second; if (insert) { it->second = active; } else { uids->erase(it); } } else if (insert) { uids->insert(std::pair<uid_t, bool>(uid, active)); } } // ----------- AudioPolicyService::AudioCommandThread implementation ---------- Loading services/audiopolicy/service/AudioPolicyService.h +19 −11 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ #include "managerdefault/AudioPolicyManager.h" #include <unordered_map> #include <unordered_set> namespace android { Loading Loading @@ -264,31 +263,40 @@ private: // transparently handles recording while the UID transitions between idle/active state // avoiding to get stuck in a state receiving non-empty buffers while idle or in a state // receiving empty buffers while active. class UidPolicy : public BnUidObserver { class UidPolicy : public BnUidObserver, public virtual IBinder::DeathRecipient { public: explicit UidPolicy(wp<AudioPolicyService> service) : mService(service) {} : mService(service), mObserverRegistered(false) {} void registerSelf(); void unregisterSelf(); // IBinder::DeathRecipient implementation void binderDied(const wp<IBinder> &who) override; bool isUidActive(uid_t uid); void onUidGone(uid_t uid, bool disabled); void onUidActive(uid_t uid); void onUidIdle(uid_t uid, bool disabled); // BnUidObserver implementation void onUidActive(uid_t uid) override; void onUidGone(uid_t uid, bool disabled) override; void onUidIdle(uid_t uid, bool disabled) override; void addOverrideUid(uid_t uid, bool active); void removeOverrideUid(uid_t uid); void addOverrideUid(uid_t uid, bool active) { updateOverrideUid(uid, active, true); } void removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); } private: bool isUidActiveLocked(uid_t uid); bool isServiceUid(uid_t uid) const; void notifyService(uid_t uid, bool active); void updateOverrideUid(uid_t uid, bool active, bool insert); void updateUidCache(uid_t uid, bool active, bool insert); void updateUidLocked(std::unordered_map<uid_t, bool> *uids, uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive); Mutex mUidLock; wp<AudioPolicyService> mService; std::unordered_set<uid_t> mActiveUids; Mutex mLock; bool mObserverRegistered; std::unordered_map<uid_t, bool> mOverrideUids; std::unordered_map<uid_t, bool> mCachedUids; }; // Thread used for tone playback and to send audio config commands to audio flinger Loading Loading
services/audiopolicy/service/AudioPolicyService.cpp +104 −72 Original line number Diff line number Diff line Loading @@ -332,19 +332,16 @@ status_t AudioPolicyService::dumpInternals(int fd) void AudioPolicyService::setRecordSilenced(uid_t uid, bool silenced) { // FIXME: temporarily disable while investigating issue b/77300296 // { // Mutex::Autolock _l(mLock); // if (mAudioPolicyManager) { // mAudioPolicyManager->setRecordSilenced(uid, silenced); // } // } // sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); // if (af) { // af->setRecordSilenced(uid, silenced); // } (void)uid; (void)silenced; { Mutex::Autolock _l(mLock); if (mAudioPolicyManager) { mAudioPolicyManager->setRecordSilenced(uid, silenced); } } sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); if (af) { af->setRecordSilenced(uid, silenced); } } status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused) Loading Loading @@ -508,94 +505,129 @@ void AudioPolicyService::UidPolicy::registerSelf() { | ActivityManager::UID_OBSERVER_ACTIVE, ActivityManager::PROCESS_STATE_UNKNOWN, String16("audioserver")); status_t res = am.linkToDeath(this); if (!res) { Mutex::Autolock _l(mLock); mObserverRegistered = true; } else { ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res); am.unregisterUidObserver(this); } } void AudioPolicyService::UidPolicy::unregisterSelf() { ActivityManager am; am.unlinkToDeath(this); am.unregisterUidObserver(this); Mutex::Autolock _l(mLock); mObserverRegistered = false; } void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) { onUidIdle(uid, disabled); void AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) { Mutex::Autolock _l(mLock); mCachedUids.clear(); mObserverRegistered = false; } void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) { bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) { if (isServiceUid(uid)) return true; bool needToReregister = false; { Mutex::Autolock _l(mUidLock); mActiveUids.insert(uid); Mutex::Autolock _l(mLock); needToReregister = !mObserverRegistered; } sp<AudioPolicyService> service = mService.promote(); if (service != nullptr) { service->setRecordSilenced(uid, false); if (needToReregister) { // Looks like ActivityManager has died previously, attempt to re-register. registerSelf(); } { Mutex::Autolock _l(mLock); auto overrideIter = mOverrideUids.find(uid); if (overrideIter != mOverrideUids.end()) { return overrideIter->second; } void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) { bool deleted = false; // In an absense of the ActivityManager, assume everything to be active. if (!mObserverRegistered) return true; auto cacheIter = mCachedUids.find(uid); if (cacheIter != mOverrideUids.end()) { return cacheIter->second; } } ActivityManager am; bool active = am.isUidActive(uid, String16("audioserver")); { Mutex::Autolock _l(mUidLock); if (mActiveUids.erase(uid) > 0) { deleted = true; Mutex::Autolock _l(mLock); mCachedUids.insert(std::pair<uid_t, bool>(uid, active)); } return active; } if (deleted) { sp<AudioPolicyService> service = mService.promote(); if (service != nullptr) { service->setRecordSilenced(uid, true); void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) { updateUidCache(uid, true, true); } void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) { updateUidCache(uid, false, false); } void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) { updateUidCache(uid, false, true); } void AudioPolicyService::UidPolicy::addOverrideUid(uid_t uid, bool active) { updateOverrideUid(uid, active, true); bool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const { return uid % AID_USER_OFFSET < AID_APP_START; } void AudioPolicyService::UidPolicy::removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) { sp<AudioPolicyService> service = mService.promote(); if (service != nullptr) { service->setRecordSilenced(uid, !active); } } void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) { bool wasActive = false; bool isActive = false; if (isServiceUid(uid)) return; bool wasOverridden = false, wasActive = false; { Mutex::Autolock _l(mUidLock); wasActive = isUidActiveLocked(uid); mOverrideUids.erase(uid); if (insert) { mOverrideUids.insert(std::pair<uid_t, bool>(uid, active)); Mutex::Autolock _l(mLock); updateUidLocked(&mOverrideUids, uid, active, insert, &wasOverridden, &wasActive); } isActive = isUidActiveLocked(uid); if (!wasOverridden && insert) { notifyService(uid, active); // Started to override. } else if (wasOverridden && !insert) { notifyService(uid, isUidActive(uid)); // Override ceased, notify with ground truth. } else if (wasActive != active) { notifyService(uid, active); // Override updated. } if (wasActive != isActive) { sp<AudioPolicyService> service = mService.promote(); if (service != nullptr) { service->setRecordSilenced(uid, !isActive); } void AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) { if (isServiceUid(uid)) return; bool wasActive = false; { Mutex::Autolock _l(mLock); updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive); // Do not notify service if currently overridden. if (mOverrideUids.find(uid) != mOverrideUids.end()) return; } bool nowActive = active && insert; if (wasActive != nowActive) notifyService(uid, nowActive); } bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) { // Non-app UIDs are considered always active if (uid < FIRST_APPLICATION_UID) { return true; } Mutex::Autolock _l(mUidLock); return isUidActiveLocked(uid); } bool AudioPolicyService::UidPolicy::isUidActiveLocked(uid_t uid) { // Non-app UIDs are considered always active // FIXME: temporarily disable while investigating issue b/77300296 // if (uid < FIRST_APPLICATION_UID) { // return true; // } // auto it = mOverrideUids.find(uid); // if (it != mOverrideUids.end()) { // return it->second; // } // return mActiveUids.find(uid) != mActiveUids.end(); (void)uid; return true; void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t, bool> *uids, uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive) { auto it = uids->find(uid); if (it != uids->end()) { if (wasThere != nullptr) *wasThere = true; if (wasActive != nullptr) *wasActive = it->second; if (insert) { it->second = active; } else { uids->erase(it); } } else if (insert) { uids->insert(std::pair<uid_t, bool>(uid, active)); } } // ----------- AudioPolicyService::AudioCommandThread implementation ---------- Loading
services/audiopolicy/service/AudioPolicyService.h +19 −11 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ #include "managerdefault/AudioPolicyManager.h" #include <unordered_map> #include <unordered_set> namespace android { Loading Loading @@ -264,31 +263,40 @@ private: // transparently handles recording while the UID transitions between idle/active state // avoiding to get stuck in a state receiving non-empty buffers while idle or in a state // receiving empty buffers while active. class UidPolicy : public BnUidObserver { class UidPolicy : public BnUidObserver, public virtual IBinder::DeathRecipient { public: explicit UidPolicy(wp<AudioPolicyService> service) : mService(service) {} : mService(service), mObserverRegistered(false) {} void registerSelf(); void unregisterSelf(); // IBinder::DeathRecipient implementation void binderDied(const wp<IBinder> &who) override; bool isUidActive(uid_t uid); void onUidGone(uid_t uid, bool disabled); void onUidActive(uid_t uid); void onUidIdle(uid_t uid, bool disabled); // BnUidObserver implementation void onUidActive(uid_t uid) override; void onUidGone(uid_t uid, bool disabled) override; void onUidIdle(uid_t uid, bool disabled) override; void addOverrideUid(uid_t uid, bool active); void removeOverrideUid(uid_t uid); void addOverrideUid(uid_t uid, bool active) { updateOverrideUid(uid, active, true); } void removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); } private: bool isUidActiveLocked(uid_t uid); bool isServiceUid(uid_t uid) const; void notifyService(uid_t uid, bool active); void updateOverrideUid(uid_t uid, bool active, bool insert); void updateUidCache(uid_t uid, bool active, bool insert); void updateUidLocked(std::unordered_map<uid_t, bool> *uids, uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive); Mutex mUidLock; wp<AudioPolicyService> mService; std::unordered_set<uid_t> mActiveUids; Mutex mLock; bool mObserverRegistered; std::unordered_map<uid_t, bool> mOverrideUids; std::unordered_map<uid_t, bool> mCachedUids; }; // Thread used for tone playback and to send audio config commands to audio flinger Loading