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

Commit 5abe3e10 authored by Hai Zhang's avatar Hai Zhang
Browse files

Add synchronization for PermissionData.

Concurrent modifications of mUserStates need to be synchronized.

Fixes: 142476570
Test: presubmit
Change-Id: If0f57bd8027a5631a81f377907205db67d6979a8
parent 5836ffd3
Loading
Loading
Loading
Loading
+87 −66
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.util.ArraySet;
import android.util.SparseArray;
import android.util.SparseBooleanArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;

import java.util.ArrayList;
@@ -30,7 +31,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.android.internal.annotations.GuardedBy;

/**
 * This class encapsulates the permissions for a package or a shared user.
@@ -708,7 +708,11 @@ public final class PermissionsState {
    }

    private static final class PermissionData {

        private final Object mLock = new Object();

        private final BasePermission mPerm;
        @GuardedBy("mLock")
        private SparseArray<PermissionState> mUserStates = new SparseArray<>();

        public PermissionData(BasePermission perm) {
@@ -717,6 +721,8 @@ public final class PermissionsState {

        public PermissionData(PermissionData other) {
            this(other.mPerm);

            synchronized (mLock) {
                final int otherStateCount = other.mUserStates.size();
                for (int i = 0; i < otherStateCount; i++) {
                    final int otherUserId = other.mUserStates.keyAt(i);
@@ -724,12 +730,14 @@ public final class PermissionsState {
                    mUserStates.put(otherUserId, new PermissionState(otherState));
                }
            }
        }

        public int[] computeGids(int userId) {
            return mPerm.computeGids(userId);
        }

        public boolean isGranted(int userId) {
            synchronized (mLock) {
                if (isInstallPermission()) {
                    userId = UserHandle.USER_ALL;
                }
@@ -741,8 +749,10 @@ public final class PermissionsState {

                return userState.mGranted;
            }
        }

        public boolean grant(int userId) {
            synchronized (mLock) {
                if (!isCompatibleUserId(userId)) {
                    return false;
                }
@@ -761,8 +771,10 @@ public final class PermissionsState {

                return true;
            }
        }

        public boolean revoke(int userId) {
            synchronized (mLock) {
                if (!isCompatibleUserId(userId)) {
                    return false;
                }
@@ -780,28 +792,36 @@ public final class PermissionsState {

                return true;
            }
        }

        public PermissionState getPermissionState(int userId) {
            synchronized (mLock) {
                return mUserStates.get(userId);
            }
        }

        public int getFlags(int userId) {
            synchronized (mLock) {
                PermissionState userState = mUserStates.get(userId);
                if (userState != null) {
                    return userState.mFlags;
                }
                return 0;
            }
        }

        public boolean isDefault() {
            synchronized (mLock) {
                return mUserStates.size() <= 0;
            }
        }

        public static boolean isInstallPermissionKey(int userId) {
            return userId == UserHandle.USER_ALL;
        }

        public boolean updateFlags(int userId, int flagMask, int flagValues) {
            synchronized (mLock) {
                if (isInstallPermission()) {
                    userId = UserHandle.USER_ALL;
                }
@@ -829,6 +849,7 @@ public final class PermissionsState {

                return false;
            }
        }

        private boolean isCompatibleUserId(int userId) {
            return isDefault() || !(isInstallPermission() ^ isInstallPermissionKey(userId));