Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2eae537e authored by Mikhail Naganov's avatar Mikhail Naganov Committed by android-build-merger
Browse files

Merge "AudioPolicyService: Properly handle service restarts in UidPolicy" into...

Merge "AudioPolicyService: Properly handle service restarts in UidPolicy" into pi-dev am: 63977aac
am: fcefd95f

Change-Id: Ib66210326afd764ed891c085e8b620ea86fd5fce
parents f8a50ccf fcefd95f
Loading
Loading
Loading
Loading
+104 −72
Original line number Original line Diff line number Diff line
@@ -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)
@@ -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 ----------
+19 −11
Original line number Original line Diff line number Diff line
@@ -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 {


@@ -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