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

Commit 5348e683 authored by Kevin Han's avatar Kevin Han
Browse files

Lock before checking if user state is null

If a user is removed between the user state null check and the lock, it
is possible to run into a NPE. We fix this by putting the entire user
state check inside the lock.

Bug: 211906910
Test: builds
Change-Id: I1f5f4d05f7d21db1af08e4d8cbaa48f41470dee0
parent 65094b9d
Loading
Loading
Loading
Loading
+17 −9
Original line number Diff line number Diff line
@@ -223,10 +223,10 @@ public final class AppHibernationService extends SystemService {
                android.Manifest.permission.MANAGE_APP_HIBERNATION,
                "Caller does not have MANAGE_APP_HIBERNATION permission.");
        userId = handleIncomingUser(userId, methodName);
        synchronized (mLock) {
            if (!checkUserStatesExist(userId, methodName)) {
                return false;
            }
        synchronized (mLock) {
            final Map<String, UserLevelState> packageStates = mUserStates.get(userId);
            final UserLevelState pkgState = packageStates.get(packageName);
            if (pkgState == null) {
@@ -278,10 +278,10 @@ public final class AppHibernationService extends SystemService {
                android.Manifest.permission.MANAGE_APP_HIBERNATION,
                "Caller does not have MANAGE_APP_HIBERNATION permission.");
        final int realUserId = handleIncomingUser(userId, methodName);
        synchronized (mLock) {
            if (!checkUserStatesExist(realUserId, methodName)) {
                return;
            }
        synchronized (mLock) {
            final Map<String, UserLevelState> packageStates = mUserStates.get(realUserId);
            final UserLevelState pkgState = packageStates.get(packageName);
            if (pkgState == null) {
@@ -365,10 +365,10 @@ public final class AppHibernationService extends SystemService {
                android.Manifest.permission.MANAGE_APP_HIBERNATION,
                "Caller does not have MANAGE_APP_HIBERNATION permission.");
        userId = handleIncomingUser(userId, methodName);
        synchronized (mLock) {
            if (!checkUserStatesExist(userId, methodName)) {
                return hibernatingPackages;
            }
        synchronized (mLock) {
            Map<String, UserLevelState> userStates = mUserStates.get(userId);
            for (UserLevelState state : userStates.values()) {
                if (state.hibernated) {
@@ -658,6 +658,14 @@ public final class AppHibernationService extends SystemService {
        }
    }

    /**
     * Check that user states exist.
     *
     * @param userId user to check
     * @param methodName method name that is calling. Used for logging purposes.
     * @return true if user states exist
     */
    @GuardedBy("mLock")
    private boolean checkUserStatesExist(int userId, String methodName) {
        if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
            Slog.e(TAG, String.format(