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

Commit 7b4ab788 authored by Svet Ganov's avatar Svet Ganov Committed by Svetoslav Ganov
Browse files

Improve camera availability for active UIDs

Test: cts-tradefed run cts-dev -m CtsCameraTestCases

Bug: 72863398

Change-Id: I9abfe39ca6bedbb08aea6f1b6678f8d752b2d298
parent e1d2f7dd
Loading
Loading
Loading
Loading
+32 −15
Original line number Diff line number Diff line
@@ -904,7 +904,7 @@ Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
    }

    // Make sure the UID is in an active state to use the camera
    if (!mUidPolicy->isUidActive(callingUid)) {
    if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
        ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
            clientPid, clientUid);
        return STATUS_ERROR_FMT(ERROR_DISABLED,
@@ -2423,12 +2423,12 @@ void CameraService::UidPolicy::onUidIdle(uid_t uid, bool /* disabled */) {
    }
}

bool CameraService::UidPolicy::isUidActive(uid_t uid) {
bool CameraService::UidPolicy::isUidActive(uid_t uid, String16 callingPackage) {
    Mutex::Autolock _l(mUidLock);
    return isUidActiveLocked(uid);
    return isUidActiveLocked(uid, callingPackage);
}

bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) {
bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, String16 callingPackage) {
    // Non-app UIDs are considered always active
    // If activity manager is unreachable, assume everything is active
    if (uid < FIRST_APPLICATION_UID || !mRegistered) {
@@ -2438,15 +2438,31 @@ bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) {
    if (it != mOverrideUids.end()) {
        return it->second;
    }
    return mActiveUids.find(uid) != mActiveUids.end();
    bool active = mActiveUids.find(uid) != mActiveUids.end();
    if (!active) {
        // We want active UIDs to always access camera with their first attempt since
        // there is no guarantee the app is robustly written and would retry getting
        // the camera on failure. The inverse case is not a problem as we would take
        // camera away soon once we get the callback that the uid is no longer active.
        ActivityManager am;
        // Okay to access with a lock held as UID changes are dispatched without
        // a lock and we are a higher level component.
        active = am.isUidActive(uid, callingPackage);
        if (active) {
            // Now that we found out the UID is actually active, cache that
            mActiveUids.insert(uid);
        }
    }
    return active;
}

void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid, bool active) {
    updateOverrideUid(uid, active, true);
void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid,
        String16 callingPackage, bool active) {
    updateOverrideUid(uid, callingPackage, active, true);
}

void CameraService::UidPolicy::removeOverrideUid(uid_t uid) {
    updateOverrideUid(uid, false, false);
void CameraService::UidPolicy::removeOverrideUid(uid_t uid, String16 callingPackage) {
    updateOverrideUid(uid, callingPackage, false, false);
}

void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
@@ -2456,17 +2472,18 @@ void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
    mActiveUids.clear();
}

void CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPackage,
        bool active, bool insert) {
    bool wasActive = false;
    bool isActive = false;
    {
        Mutex::Autolock _l(mUidLock);
        wasActive = isUidActiveLocked(uid);
        wasActive = isUidActiveLocked(uid, callingPackage);
        mOverrideUids.erase(uid);
        if (insert) {
            mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
        }
        isActive = isUidActiveLocked(uid);
        isActive = isUidActiveLocked(uid, callingPackage);
    }
    if (wasActive != isActive && !isActive) {
        sp<CameraService> service = mService.promote();
@@ -2999,7 +3016,7 @@ status_t CameraService::handleSetUidState(const Vector<String16>& args, int err)
        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
        return BAD_VALUE;
    }
    mUidPolicy->addOverrideUid(uid, active);
    mUidPolicy->addOverrideUid(uid, args[1], active);
    return NO_ERROR;
}

@@ -3011,7 +3028,7 @@ status_t CameraService::handleResetUidState(const Vector<String16>& args, int er
        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
        return BAD_VALUE;
    }
    mUidPolicy->removeOverrideUid(uid);
    mUidPolicy->removeOverrideUid(uid, args[1]);
    return NO_ERROR;
}

@@ -3023,7 +3040,7 @@ status_t CameraService::handleGetUidState(const Vector<String16>& args, int out,
        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
        return BAD_VALUE;
    }
    if (mUidPolicy->isUidActive(uid)) {
    if (mUidPolicy->isUidActive(uid, args[1])) {
        return dprintf(out, "active\n");
    } else {
        return dprintf(out, "idle\n");
+5 −5
Original line number Diff line number Diff line
@@ -526,20 +526,20 @@ private:
        void registerSelf();
        void unregisterSelf();

        bool isUidActive(uid_t uid);
        bool isUidActive(uid_t uid, String16 callingPackage);

        void onUidGone(uid_t uid, bool disabled);
        void onUidActive(uid_t uid);
        void onUidIdle(uid_t uid, bool disabled);

        void addOverrideUid(uid_t uid, bool active);
        void removeOverrideUid(uid_t uid);
        void addOverrideUid(uid_t uid, String16 callingPackage, bool active);
        void removeOverrideUid(uid_t uid, String16 callingPackage);

        // IBinder::DeathRecipient implementation
        virtual void binderDied(const wp<IBinder> &who);
    private:
        bool isUidActiveLocked(uid_t uid);
        void updateOverrideUid(uid_t uid, bool active, bool insert);
        bool isUidActiveLocked(uid_t uid, String16 callingPackage);
        void updateOverrideUid(uid_t uid, String16 callingPackage, bool active, bool insert);

        Mutex mUidLock;
        bool mRegistered;