Merge "Synchronize mPermissions to void NullPointerException."

am: 9e7c6b3865

Change-Id: I8cb95984bf85c6a687d20fa9cd7305b712754439
This commit is contained in:
Philip P. Moltmann
2018-10-29 19:31:03 -07:00
committed by android-build-merger

View File

@@ -30,6 +30,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import com.android.internal.annotations.GuardedBy;
/** /**
* This class encapsulates the permissions for a package or a shared user. * This class encapsulates the permissions for a package or a shared user.
@@ -62,6 +63,9 @@ public final class PermissionsState {
private static final int[] NO_GIDS = {}; private static final int[] NO_GIDS = {};
private final Object mLock = new Object();
@GuardedBy("mLock")
private ArrayMap<String, PermissionData> mPermissions; private ArrayMap<String, PermissionData> mPermissions;
private int[] mGlobalGids = NO_GIDS; private int[] mGlobalGids = NO_GIDS;
@@ -96,22 +100,25 @@ public final class PermissionsState {
if (other == this) { if (other == this) {
return; return;
} }
if (mPermissions != null) {
if (other.mPermissions == null) { synchronized (mLock) {
mPermissions = null; if (mPermissions != null) {
} else { if (other.mPermissions == null) {
mPermissions.clear(); mPermissions = null;
} else {
mPermissions.clear();
}
} }
} if (other.mPermissions != null) {
if (other.mPermissions != null) { if (mPermissions == null) {
if (mPermissions == null) { mPermissions = new ArrayMap<>();
mPermissions = new ArrayMap<>(); }
} final int permissionCount = other.mPermissions.size();
final int permissionCount = other.mPermissions.size(); for (int i = 0; i < permissionCount; i++) {
for (int i = 0; i < permissionCount; i++) { String name = other.mPermissions.keyAt(i);
String name = other.mPermissions.keyAt(i); PermissionData permissionData = other.mPermissions.valueAt(i);
PermissionData permissionData = other.mPermissions.valueAt(i); mPermissions.put(name, new PermissionData(permissionData));
mPermissions.put(name, new PermissionData(permissionData)); }
} }
} }
@@ -153,13 +160,16 @@ public final class PermissionsState {
} }
final PermissionsState other = (PermissionsState) obj; final PermissionsState other = (PermissionsState) obj;
if (mPermissions == null) { synchronized (mLock) {
if (other.mPermissions != null) { if (mPermissions == null) {
if (other.mPermissions != null) {
return false;
}
} else if (!mPermissions.equals(other.mPermissions)) {
return false; return false;
} }
} else if (!mPermissions.equals(other.mPermissions)) {
return false;
} }
if (mPermissionReviewRequired == null) { if (mPermissionReviewRequired == null) {
if (other.mPermissionReviewRequired != null) { if (other.mPermissionReviewRequired != null) {
return false; return false;
@@ -266,12 +276,15 @@ public final class PermissionsState {
public boolean hasPermission(String name, int userId) { public boolean hasPermission(String name, int userId) {
enforceValidUserId(userId); enforceValidUserId(userId);
if (mPermissions == null) { synchronized (mLock) {
return false; if (mPermissions == null) {
return false;
}
PermissionData permissionData = mPermissions.get(name);
return permissionData != null && permissionData.isGranted(userId);
} }
PermissionData permissionData = mPermissions.get(name);
return permissionData != null && permissionData.isGranted(userId);
} }
/** /**
@@ -279,14 +292,17 @@ public final class PermissionsState {
* whether or not it has been granted. * whether or not it has been granted.
*/ */
public boolean hasRequestedPermission(ArraySet<String> names) { public boolean hasRequestedPermission(ArraySet<String> names) {
if (mPermissions == null) { synchronized (mLock) {
return false; if (mPermissions == null) {
} return false;
for (int i=names.size()-1; i>=0; i--) { }
if (mPermissions.get(names.valueAt(i)) != null) { for (int i=names.size()-1; i>=0; i--) {
return true; if (mPermissions.get(names.valueAt(i)) != null) {
return true;
}
} }
} }
return false; return false;
} }
@@ -300,29 +316,31 @@ public final class PermissionsState {
public Set<String> getPermissions(int userId) { public Set<String> getPermissions(int userId) {
enforceValidUserId(userId); enforceValidUserId(userId);
if (mPermissions == null) { synchronized (mLock) {
return Collections.emptySet(); if (mPermissions == null) {
} return Collections.emptySet();
Set<String> permissions = new ArraySet<>(mPermissions.size());
final int permissionCount = mPermissions.size();
for (int i = 0; i < permissionCount; i++) {
String permission = mPermissions.keyAt(i);
if (hasInstallPermission(permission)) {
permissions.add(permission);
continue;
} }
if (userId != UserHandle.USER_ALL) { Set<String> permissions = new ArraySet<>(mPermissions.size());
if (hasRuntimePermission(permission, userId)) {
final int permissionCount = mPermissions.size();
for (int i = 0; i < permissionCount; i++) {
String permission = mPermissions.keyAt(i);
if (hasInstallPermission(permission)) {
permissions.add(permission); permissions.add(permission);
continue;
}
if (userId != UserHandle.USER_ALL) {
if (hasRuntimePermission(permission, userId)) {
permissions.add(permission);
}
} }
} }
}
return permissions; return permissions;
}
} }
/** /**
@@ -399,14 +417,20 @@ public final class PermissionsState {
final boolean mayChangeFlags = flagValues != 0 || flagMask != 0; final boolean mayChangeFlags = flagValues != 0 || flagMask != 0;
if (mPermissions == null) { synchronized (mLock) {
if (!mayChangeFlags) { if (mPermissions == null) {
return false; if (!mayChangeFlags) {
return false;
}
ensurePermissionData(permission);
} }
ensurePermissionData(permission);
} }
PermissionData permissionData = mPermissions.get(permission.getName()); PermissionData permissionData = null;
synchronized (mLock) {
permissionData = mPermissions.get(permission.getName());
}
if (permissionData == null) { if (permissionData == null) {
if (!mayChangeFlags) { if (!mayChangeFlags) {
return false; return false;
@@ -439,14 +463,17 @@ public final class PermissionsState {
} }
private boolean hasPermissionRequiringReview(int userId) { private boolean hasPermissionRequiringReview(int userId) {
final int permissionCount = mPermissions.size(); synchronized (mLock) {
for (int i = 0; i < permissionCount; i++) { final int permissionCount = mPermissions.size();
final PermissionData permission = mPermissions.valueAt(i); for (int i = 0; i < permissionCount; i++) {
if ((permission.getFlags(userId) final PermissionData permission = mPermissions.valueAt(i);
& PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { if ((permission.getFlags(userId)
return true; & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
return true;
}
} }
} }
return false; return false;
} }
@@ -454,16 +481,19 @@ public final class PermissionsState {
int userId, int flagMask, int flagValues) { int userId, int flagMask, int flagValues) {
enforceValidUserId(userId); enforceValidUserId(userId);
if (mPermissions == null) { synchronized (mLock) {
return false; if (mPermissions == null) {
return false;
}
boolean changed = false;
final int permissionCount = mPermissions.size();
for (int i = 0; i < permissionCount; i++) {
PermissionData permissionData = mPermissions.valueAt(i);
changed |= permissionData.updateFlags(userId, flagMask, flagValues);
}
return changed;
} }
boolean changed = false;
final int permissionCount = mPermissions.size();
for (int i = 0; i < permissionCount; i++) {
PermissionData permissionData = mPermissions.valueAt(i);
changed |= permissionData.updateFlags(userId, flagMask, flagValues);
}
return changed;
} }
/** /**
@@ -479,17 +509,19 @@ public final class PermissionsState {
int[] gids = mGlobalGids; int[] gids = mGlobalGids;
if (mPermissions != null) { synchronized (mLock) {
final int permissionCount = mPermissions.size(); if (mPermissions != null) {
for (int i = 0; i < permissionCount; i++) { final int permissionCount = mPermissions.size();
String permission = mPermissions.keyAt(i); for (int i = 0; i < permissionCount; i++) {
if (!hasPermission(permission, userId)) { String permission = mPermissions.keyAt(i);
continue; if (!hasPermission(permission, userId)) {
} continue;
PermissionData permissionData = mPermissions.valueAt(i); }
final int[] permGids = permissionData.computeGids(userId); PermissionData permissionData = mPermissions.valueAt(i);
if (permGids != NO_GIDS) { final int[] permGids = permissionData.computeGids(userId);
gids = appendInts(gids, permGids); if (permGids != NO_GIDS) {
gids = appendInts(gids, permGids);
}
} }
} }
} }
@@ -519,41 +551,50 @@ public final class PermissionsState {
*/ */
public void reset() { public void reset() {
mGlobalGids = NO_GIDS; mGlobalGids = NO_GIDS;
mPermissions = null;
synchronized (mLock) {
mPermissions = null;
}
mPermissionReviewRequired = null; mPermissionReviewRequired = null;
} }
private PermissionState getPermissionState(String name, int userId) { private PermissionState getPermissionState(String name, int userId) {
if (mPermissions == null) { synchronized (mLock) {
return null; if (mPermissions == null) {
return null;
}
PermissionData permissionData = mPermissions.get(name);
if (permissionData == null) {
return null;
}
return permissionData.getPermissionState(userId);
} }
PermissionData permissionData = mPermissions.get(name);
if (permissionData == null) {
return null;
}
return permissionData.getPermissionState(userId);
} }
private List<PermissionState> getPermissionStatesInternal(int userId) { private List<PermissionState> getPermissionStatesInternal(int userId) {
enforceValidUserId(userId); enforceValidUserId(userId);
if (mPermissions == null) { synchronized (mLock) {
return Collections.emptyList(); if (mPermissions == null) {
} return Collections.emptyList();
List<PermissionState> permissionStates = new ArrayList<>();
final int permissionCount = mPermissions.size();
for (int i = 0; i < permissionCount; i++) {
PermissionData permissionData = mPermissions.valueAt(i);
PermissionState permissionState = permissionData.getPermissionState(userId);
if (permissionState != null) {
permissionStates.add(permissionState);
} }
}
return permissionStates; List<PermissionState> permissionStates = new ArrayList<>();
final int permissionCount = mPermissions.size();
for (int i = 0; i < permissionCount; i++) {
PermissionData permissionData = mPermissions.valueAt(i);
PermissionState permissionState = permissionData.getPermissionState(userId);
if (permissionState != null) {
permissionStates.add(permissionState);
}
}
return permissionStates;
}
} }
private int grantPermission(BasePermission permission, int userId) { private int grantPermission(BasePermission permission, int userId) {
@@ -589,7 +630,10 @@ public final class PermissionsState {
final boolean hasGids = !ArrayUtils.isEmpty(permission.computeGids(userId)); final boolean hasGids = !ArrayUtils.isEmpty(permission.computeGids(userId));
final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS; final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS;
PermissionData permissionData = mPermissions.get(permName); PermissionData permissionData = null;
synchronized (mLock) {
permissionData = mPermissions.get(permName);
}
if (!permissionData.revoke(userId)) { if (!permissionData.revoke(userId)) {
return PERMISSION_OPERATION_FAILURE; return PERMISSION_OPERATION_FAILURE;
@@ -627,25 +671,32 @@ public final class PermissionsState {
private PermissionData ensurePermissionData(BasePermission permission) { private PermissionData ensurePermissionData(BasePermission permission) {
final String permName = permission.getName(); final String permName = permission.getName();
if (mPermissions == null) {
mPermissions = new ArrayMap<>(); synchronized (mLock) {
if (mPermissions == null) {
mPermissions = new ArrayMap<>();
}
PermissionData permissionData = mPermissions.get(permName);
if (permissionData == null) {
permissionData = new PermissionData(permission);
mPermissions.put(permName, permissionData);
}
return permissionData;
} }
PermissionData permissionData = mPermissions.get(permName);
if (permissionData == null) {
permissionData = new PermissionData(permission);
mPermissions.put(permName, permissionData);
}
return permissionData;
} }
private void ensureNoPermissionData(String name) { private void ensureNoPermissionData(String name) {
if (mPermissions == null) { synchronized (mLock) {
return; if (mPermissions == null) {
} return;
mPermissions.remove(name); }
if (mPermissions.isEmpty()) { mPermissions.remove(name);
mPermissions = null; if (mPermissions.isEmpty()) {
mPermissions = null;
}
} }
} }
private static final class PermissionData { private static final class PermissionData {