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