diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index 396a84ffcfb8b..ed663cfeb6136 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -46,6 +46,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; import libcore.io.IoUtils; +import libcore.util.EmptyArray; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -55,7 +56,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; -import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -95,7 +95,7 @@ public class SystemConfig { private static final String VENDOR_SKU_PROPERTY = "ro.boot.product.vendor.sku"; // Group-ids that are given to all packages as read from etc/permissions/*.xml. - int[] mGlobalGids; + int[] mGlobalGids = EmptyArray.INT; // These are the built-in uid -> permission mappings that were read from the // system configuration files. diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 82c897ce1a9c2..eb06bf953059e 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -36,13 +36,14 @@ import android.os.UserHandle; import android.util.Log; import android.util.Slog; -import com.android.internal.util.ArrayUtils; import com.android.server.pm.DumpState; import com.android.server.pm.PackageManagerService; import com.android.server.pm.PackageSettingBase; import com.android.server.pm.parsing.PackageInfoUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; +import libcore.util.EmptyArray; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; @@ -95,7 +96,8 @@ public final class BasePermission { int uid; /** Additional GIDs given to apps granted this permission */ - private int[] gids; + @NonNull + private int[] gids = EmptyArray.INT; /** * Flag indicating that {@link #gids} should be adjusted based on the @@ -132,7 +134,7 @@ public final class BasePermission { public int getUid() { return uid; } - public void setGids(int[] gids, boolean perUser) { + public void setGids(@NonNull int[] gids, boolean perUser) { this.gids = gids; this.perUser = perUser; } @@ -141,18 +143,20 @@ public final class BasePermission { } public boolean hasGids() { - return !ArrayUtils.isEmpty(gids); + return gids.length != 0; } + @NonNull public int[] computeGids(int userId) { if (perUser) { final int[] userGids = new int[gids.length]; for (int i = 0; i < gids.length; i++) { - userGids[i] = UserHandle.getUid(userId, gids[i]); + final int gid = gids[i]; + userGids[i] = UserHandle.getUid(userId, gid); } return userGids; } else { - return gids; + return gids.length != 0 ? gids.clone() : gids; } } @@ -291,7 +295,8 @@ public final class BasePermission { pendingPermissionInfo.packageName = newPackageName; } uid = 0; - setGids(null, false); + gids = EmptyArray.INT; + perUser = false; } public boolean addToTree(@ProtectionLevel int protectionLevel, diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 4910041b2884b..b293ba6ccc2de 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -55,7 +55,6 @@ import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS; import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; -import static com.android.server.pm.permission.UidPermissionState.PERMISSION_OPERATION_FAILURE; import static java.util.concurrent.TimeUnit.SECONDS; @@ -154,6 +153,8 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal.Permiss import com.android.server.policy.PermissionPolicyInternal; import com.android.server.policy.SoftRestrictedPermissionPolicy; +import libcore.util.EmptyArray; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; @@ -247,6 +248,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { private final SparseArray> mSystemPermissions; /** Built-in group IDs given to all packages. Read from system configuration files. */ + @NonNull private final int[] mGlobalGids; private final HandlerThread mHandlerThread; @@ -1513,7 +1515,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // normal runtime permissions. For now they apply to all users. // TODO(zhanghai): We are breaking the behavior above by making all permission state // per-user. It isn't documented behavior and relatively rarely used anyway. - if (uidState.grantPermission(bp) != PERMISSION_OPERATION_FAILURE) { + if (uidState.grantPermission(bp)) { if (callback != null) { callback.onInstallPermissionGranted(); } @@ -1531,18 +1533,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { return; } - final int result = uidState.grantPermission(bp); - switch (result) { - case PERMISSION_OPERATION_FAILURE: { - return; - } + if (!uidState.grantPermission(bp)) { + return; + } - case UidPermissionState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { - if (callback != null) { - callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId); - } + if (bp.hasGids()) { + if (callback != null) { + callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId); } - break; } if (bp.isRuntime()) { @@ -1662,7 +1660,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { // normal runtime permissions. For now they apply to all users. // TODO(zhanghai): We are breaking the behavior above by making all permission state // per-user. It isn't documented behavior and relatively rarely used anyway. - if (uidState.revokePermission(bp) != PERMISSION_OPERATION_FAILURE) { + if (uidState.revokePermission(bp)) { if (callback != null) { mDefaultPermissionCallback.onInstallPermissionRevoked(); } @@ -1670,12 +1668,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { return; } - // Permission is already revoked, no need to do anything. - if (!uidState.isPermissionGranted(permName)) { - return; - } - - if (uidState.revokePermission(bp) == PERMISSION_OPERATION_FAILURE) { + if (!uidState.revokePermission(bp)) { return; } @@ -2525,11 +2518,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - @Nullable + @NonNull private int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId) { BasePermission permission = mSettings.getPermission(permissionName); if (permission == null) { - return null; + return EmptyArray.INT; } return permission.computeGids(userId); } @@ -2650,8 +2643,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - uidState.setGlobalGids(mGlobalGids); - ArraySet newImplicitPermissions = new ArraySet<>(); final String friendlyName = pkg.getPackageName() + "(" + pkg.getUid() + ")"; @@ -2786,7 +2777,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { switch (grant) { case GRANT_INSTALL: { // Grant an install permission. - if (uidState.grantPermission(bp) != PERMISSION_OPERATION_FAILURE) { + if (uidState.grantPermission(bp)) { changedInstallPermission = true; } } break; @@ -2818,8 +2809,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (permissionPolicyInitialized && hardRestricted) { if (!restrictionExempt) { if (origPermState != null && origPermState.isGranted() - && uidState.revokePermission( - bp) != PERMISSION_OPERATION_FAILURE) { + && uidState.revokePermission(bp)) { wasChanged = true; } if (!restrictionApplied) { @@ -2851,8 +2841,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { || (!hardRestricted || restrictionExempt)) { if ((origPermState != null && origPermState.isGranted()) || upgradedActivityRecognitionPermission != null) { - if (uidState.grantPermission(bp) - == PERMISSION_OPERATION_FAILURE) { + if (!uidState.grantPermission(bp)) { wasChanged = true; } } @@ -2871,8 +2860,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { } if (!uidState.isPermissionGranted(bp.name) - && uidState.grantPermission(bp) - != PERMISSION_OPERATION_FAILURE) { + && uidState.grantPermission(bp)) { wasChanged = true; } @@ -2920,13 +2908,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { } break; } } else { - if (uidState.revokePermission(bp) != PERMISSION_OPERATION_FAILURE) { - // Also drop the permission flags. - uidState.updatePermissionFlags(bp, - MASK_PERMISSION_FLAGS_ALL, 0); - changedInstallPermission = true; - if (DEBUG_PERMISSIONS) { - Slog.i(TAG, "Un-granting permission " + perm + if (DEBUG_PERMISSIONS) { + boolean wasGranted = uidState.isPermissionGranted(bp.name); + if (wasGranted || bp.isAppOp()) { + Slog.i(TAG, (wasGranted ? "Un-granting" : "Not granting") + + " permission " + perm + " from package " + friendlyName + " (protectionLevel=" + bp.getProtectionLevel() + " flags=0x" @@ -2934,20 +2920,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { ps)) + ")"); } - } else if (bp.isAppOp()) { - // Don't print warning for app op permissions, since it is fine for them - // not to be granted, there is a UI for the user to decide. - if (DEBUG_PERMISSIONS - && (packageOfInterest == null - || packageOfInterest.equals(pkg.getPackageName()))) { - Slog.i(TAG, "Not granting permission " + perm - + " to package " + friendlyName - + " (protectionLevel=" + bp.getProtectionLevel() - + " flags=0x" - + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, - ps)) - + ")"); - } + } + if (uidState.removePermissionState(bp.name)) { + changedInstallPermission = true; } } } @@ -3026,8 +3001,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { if ((flags & BLOCKING_PERMISSION_FLAGS) == 0 && supportsRuntimePermissions) { - int revokeResult = ps.revokePermission(bp); - if (revokeResult != PERMISSION_OPERATION_FAILURE) { + if (ps.revokePermission(bp)) { if (DEBUG_PERMISSIONS) { Slog.i(TAG, "Revoking runtime permission " + permission + " for " + pkgName @@ -3895,14 +3869,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } - // The package is gone - no need to keep flags for applying policy. - uidState.updatePermissionFlags(bp, PackageManager.MASK_PERMISSION_FLAGS_ALL, 0); - - // Try to revoke as a runtime permission which is per user. - // TODO(zhanghai): This doesn't make sense. revokePermission() doesn't fail, and why are - // we only killing the uid when gids changed, instead of any permission change? - if (uidState.revokePermission(bp) - == UidPermissionState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) { + // TODO(zhanghai): Why are we only killing the UID when GIDs changed, instead of any + // permission change? + if (uidState.removePermissionState(bp.name) && bp.hasGids()) { affectedUserId = userId; } } @@ -3935,17 +3904,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { boolean runtimePermissionChanged = false; // Prune permissions - final List permissionStates = - uidState.getPermissionStates(); + final List permissionStates = uidState.getPermissionStates(); final int permissionStatesSize = permissionStates.size(); for (int i = permissionStatesSize - 1; i >= 0; i--) { PermissionState permissionState = permissionStates.get(i); if (!usedPermissions.contains(permissionState.getName())) { BasePermission bp = mSettings.getPermissionLocked(permissionState.getName()); if (bp != null) { - uidState.revokePermission(bp); - uidState.updatePermissionFlags(bp, MASK_PERMISSION_FLAGS_ALL, 0); - if (permissionState.isRuntime()) { + if (uidState.removePermissionState(bp.name) && permissionState.isRuntime()) { runtimePermissionChanged = true; } } @@ -4208,11 +4174,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { + p.getPackageName() + " and user " + userId); return; } - if (uidState.getPermissionState(bp.getName()) != null) { - uidState.revokePermission(bp); - uidState.updatePermissionFlags(bp, MASK_PERMISSION_FLAGS_ALL, - 0); - } + uidState.removePermissionState(bp.name); } }); } @@ -4771,7 +4733,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { Slog.e(TAG, "Missing permissions state for app ID " + appId + " and user ID " + userId); return EMPTY_INT_ARRAY; } - return uidState.computeGids(userId); + return uidState.computeGids(mGlobalGids, userId); } private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal { @@ -4834,7 +4796,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { @UserIdInt int userId) { return PermissionManagerService.this.getGrantedPermissions(packageName, userId); } - @Nullable + @NonNull @Override public int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId) { return PermissionManagerService.this.getPermissionGids(permissionName, userId); diff --git a/services/core/java/com/android/server/pm/permission/PermissionState.java b/services/core/java/com/android/server/pm/permission/PermissionState.java index 38264c83a15c1..59b204f7dfff2 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionState.java +++ b/services/core/java/com/android/server/pm/permission/PermissionState.java @@ -17,7 +17,6 @@ package com.android.server.pm.permission; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.UserIdInt; import com.android.internal.annotations.GuardedBy; @@ -62,7 +61,7 @@ public final class PermissionState { return mPermission.getName(); } - @Nullable + @NonNull public int[] computeGids(@UserIdInt int userId) { return mPermission.computeGids(userId); } diff --git a/services/core/java/com/android/server/pm/permission/UidPermissionState.java b/services/core/java/com/android/server/pm/permission/UidPermissionState.java index 06a7f8dbd2be7..c73e2f3e153b7 100644 --- a/services/core/java/com/android/server/pm/permission/UidPermissionState.java +++ b/services/core/java/com/android/server/pm/permission/UidPermissionState.java @@ -22,35 +22,19 @@ import android.annotation.UserIdInt; import android.content.pm.PackageManager; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.IntArray; import com.android.internal.annotations.GuardedBy; -import com.android.internal.util.ArrayUtils; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; /** * Permission state for a UID. - *

- * This class is also responsible for keeping track of the Linux GIDs per - * user for a package or a shared user. The GIDs are computed as a set of - * the GIDs for all granted permissions' GIDs on a per user basis. */ public final class UidPermissionState { - /** The permission operation failed. */ - public static final int PERMISSION_OPERATION_FAILURE = -1; - - /** The permission operation succeeded and no gids changed. */ - public static final int PERMISSION_OPERATION_SUCCESS = 0; - - /** The permission operation succeeded and gids changed. */ - public static final int PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED = 1; - - private static final int[] NO_GIDS = {}; - @NonNull private final Object mLock = new Object(); @@ -60,11 +44,6 @@ public final class UidPermissionState { @Nullable private ArrayMap mPermissions; - private boolean mPermissionReviewRequired; - - @NonNull - private int[] mGlobalGids = NO_GIDS; - public UidPermissionState() {} public UidPermissionState(@NonNull UidPermissionState other) { @@ -80,12 +59,6 @@ public final class UidPermissionState { mPermissions.put(name, new PermissionState(permissionState)); } } - - mPermissionReviewRequired = other.mPermissionReviewRequired; - - if (other.mGlobalGids != NO_GIDS) { - mGlobalGids = other.mGlobalGids.clone(); - } } } @@ -96,8 +69,6 @@ public final class UidPermissionState { synchronized (mLock) { mMissing = false; mPermissions = null; - mPermissionReviewRequired = false; - mGlobalGids = NO_GIDS; invalidateCache(); } } @@ -156,8 +127,8 @@ public final class UidPermissionState { /** * Gets the state for a permission or null if none. * - * @param name the permission name. - * @return the permission state. + * @param name the permission name + * @return the permission state */ @Nullable public PermissionState getPermissionState(@NonNull String name) { @@ -169,6 +140,22 @@ public final class UidPermissionState { } } + @NonNull + private PermissionState getOrCreatePermissionState(@NonNull BasePermission permission) { + synchronized (mLock) { + if (mPermissions == null) { + mPermissions = new ArrayMap<>(); + } + final String name = permission.getName(); + PermissionState permissionState = mPermissions.get(name); + if (permissionState == null) { + permissionState = new PermissionState(permission); + mPermissions.put(name, permissionState); + } + return permissionState; + } + } + /** * Get all permission states. * @@ -186,19 +173,44 @@ public final class UidPermissionState { /** * Put a permission state. + * + * @param permission the permission + * @param granted whether the permission is granted + * @param flags the permission flags */ - public void putPermissionState(@NonNull BasePermission permission, boolean isGranted, - int flags) { + public void putPermissionState(@NonNull BasePermission permission, boolean granted, int flags) { synchronized (mLock) { - ensureNoPermissionState(permission.name); - PermissionState permissionState = ensurePermissionState(permission); - if (isGranted) { + final String name = permission.getName(); + if (mPermissions == null) { + mPermissions = new ArrayMap<>(); + } else { + mPermissions.remove(name); + } + final PermissionState permissionState = new PermissionState(permission); + if (granted) { permissionState.grant(); } permissionState.updateFlags(flags, flags); - if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { - mPermissionReviewRequired = true; + mPermissions.put(name, permissionState); + } + } + + /** + * Remove a permission state. + * + * @param name the permission name + * @return whether the permission state changed + */ + public boolean removePermissionState(@NonNull String name) { + synchronized (mLock) { + if (mPermissions == null) { + return false; } + boolean changed = mPermissions.remove(name) != null; + if (changed && mPermissions.isEmpty()) { + mPermissions = null; + } + return changed; } } @@ -209,13 +221,8 @@ public final class UidPermissionState { * @return whether the permission is granted */ public boolean isPermissionGranted(@NonNull String name) { - synchronized (mLock) { - if (mPermissions == null) { - return false; - } - PermissionState permissionState = mPermissions.get(name); - return permissionState != null && permissionState.isGranted(); - } + final PermissionState permissionState = getPermissionState(name); + return permissionState != null && permissionState.isGranted(); } /** @@ -246,61 +253,37 @@ public final class UidPermissionState { /** * Grant a permission. * - * @param permission the permission to grantt - * @return the operation result, which is either {@link #PERMISSION_OPERATION_SUCCESS}, - * or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link - * #PERMISSION_OPERATION_FAILURE}. + * @param permission the permission to grant + * @return whether the permission grant state changed */ - public int grantPermission(@NonNull BasePermission permission) { - if (isPermissionGranted(permission.getName())) { - return PERMISSION_OPERATION_SUCCESS; - } - - PermissionState permissionState = ensurePermissionState(permission); - - if (!permissionState.grant()) { - return PERMISSION_OPERATION_FAILURE; - } - - return permission.hasGids() ? PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED - : PERMISSION_OPERATION_SUCCESS; + public boolean grantPermission(@NonNull BasePermission permission) { + PermissionState permissionState = getOrCreatePermissionState(permission); + return permissionState.grant(); } /** * Revoke a permission. * * @param permission the permission to revoke - * @return the operation result, which is either {@link #PERMISSION_OPERATION_SUCCESS}, - * or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link - * #PERMISSION_OPERATION_FAILURE}. + * @return whether the permission grant state changed */ - public int revokePermission(@NonNull BasePermission permission) { + public boolean revokePermission(@NonNull BasePermission permission) { final String name = permission.getName(); - if (!isPermissionGranted(name)) { - return PERMISSION_OPERATION_SUCCESS; + final PermissionState permissionState = getPermissionState(name); + if (permissionState == null) { + return false; } - - PermissionState permissionState; - synchronized (mLock) { - permissionState = mPermissions.get(name); + final boolean changed = permissionState.revoke(); + if (changed && permissionState.isDefault()) { + removePermissionState(name); } - - if (!permissionState.revoke()) { - return PERMISSION_OPERATION_FAILURE; - } - - if (permissionState.isDefault()) { - ensureNoPermissionState(name); - } - - return permission.hasGids() ? PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED - : PERMISSION_OPERATION_SUCCESS; + return changed; } /** * Get the flags for a permission. * - * @param name the permission name. + * @param name the permission name * @return the permission flags */ public int getPermissionFlags(@NonNull String name) { @@ -324,76 +307,36 @@ public final class UidPermissionState { if (flagMask == 0) { return false; } - - synchronized (mLock) { - final PermissionState permissionState = ensurePermissionState(permission); - final int oldFlags = permissionState.getFlags(); - - final boolean updated = permissionState.updateFlags(flagMask, flagValues); - if (updated) { - final int newFlags = permissionState.getFlags(); - if ((oldFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) == 0 - && (newFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { - mPermissionReviewRequired = true; - } else if ((oldFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0 - && (newFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { - if (mPermissionReviewRequired && !hasPermissionRequiringReview()) { - mPermissionReviewRequired = false; - } - } - } - return updated; + final PermissionState permissionState = getOrCreatePermissionState(permission); + final boolean changed = permissionState.updateFlags(flagMask, flagValues); + if (changed && permissionState.isDefault()) { + removePermissionState(permission.name); } + return changed; } public boolean updatePermissionFlagsForAllPermissions(int flagMask, int flagValues) { + if (flagMask == 0) { + return false; + } synchronized (mLock) { if (mPermissions == null) { return false; } - boolean changed = false; - final int permissionsSize = mPermissions.size(); - for (int i = 0; i < permissionsSize; i++) { + boolean anyChanged = false; + for (int i = mPermissions.size() - 1; i >= 0; i--) { final PermissionState permissionState = mPermissions.valueAt(i); - changed |= permissionState.updateFlags(flagMask, flagValues); - } - return changed; - } - } - - @NonNull - private PermissionState ensurePermissionState(@NonNull BasePermission permission) { - final String name = permission.getName(); - synchronized (mLock) { - if (mPermissions == null) { - mPermissions = new ArrayMap<>(); - } - PermissionState permissionState = mPermissions.get(name); - if (permissionState == null) { - permissionState = new PermissionState(permission); - mPermissions.put(name, permissionState); - } - return permissionState; - } - } - - private void ensureNoPermissionState(@NonNull String name) { - synchronized (mLock) { - if (mPermissions == null) { - return; - } - mPermissions.remove(name); - if (mPermissions.isEmpty()) { - mPermissions = null; + final boolean changed = permissionState.updateFlags(flagMask, flagValues); + if (changed && permissionState.isDefault()) { + mPermissions.removeAt(i); + } + anyChanged |= changed; } + return anyChanged; } } public boolean isPermissionReviewRequired() { - return mPermissionReviewRequired; - } - - private boolean hasPermissionRequiringReview() { synchronized (mLock) { final int permissionsSize = mPermissions.size(); for (int i = 0; i < permissionsSize; i++) { @@ -406,27 +349,6 @@ public final class UidPermissionState { } } - /** - * Gets the global gids, applicable to all users. - */ - @NonNull - public int[] getGlobalGids() { - return mGlobalGids; - } - - /** - * Sets the global gids, applicable to all users. - * - * @param globalGids The global gids. - */ - public void setGlobalGids(@NonNull int[] globalGids) { - if (!ArrayUtils.isEmpty(globalGids)) { - mGlobalGids = Arrays.copyOf(globalGids, globalGids.length); - } else { - mGlobalGids = NO_GIDS; - } - } - /** * Compute the Linux GIDs from the permissions granted to a user. * @@ -434,54 +356,25 @@ public final class UidPermissionState { * @return the GIDs for the user */ @NonNull - public int[] computeGids(@UserIdInt int userId) { - int[] gids = mGlobalGids; - + public int[] computeGids(@NonNull int[] globalGids, @UserIdInt int userId) { synchronized (mLock) { - if (mPermissions != null) { - final int permissionCount = mPermissions.size(); - for (int i = 0; i < permissionCount; i++) { - PermissionState permissionState = mPermissions.valueAt(i); - if (!permissionState.isGranted()) { - continue; - } - final int[] permGids = permissionState.computeGids(userId); - if (permGids != NO_GIDS) { - gids = appendInts(gids, permGids); - } + IntArray gids = IntArray.wrap(globalGids); + if (mPermissions == null) { + return gids.toArray(); + } + final int permissionsSize = mPermissions.size(); + for (int i = 0; i < permissionsSize; i++) { + PermissionState permissionState = mPermissions.valueAt(i); + if (!permissionState.isGranted()) { + continue; + } + final int[] permissionGids = permissionState.computeGids(userId); + if (permissionGids.length != 0) { + gids.addAll(permissionGids); } } + return gids.toArray(); } - - return gids; - } - - /** - * Compute the Linux GIDs from the permissions granted to specified users. - * - * @param userIds the user IDs - * @return the GIDs for the user - */ - @NonNull - public int[] computeGids(@NonNull int[] userIds) { - int[] gids = mGlobalGids; - - for (final int userId : userIds) { - final int[] userGids = computeGids(userId); - gids = appendInts(gids, userGids); - } - - return gids; - } - - // TODO: fix this to use arraycopy and append all ints in one go - private static int[] appendInts(int[] current, int[] added) { - if (current != null && added != null) { - for (int guid : added) { - current = ArrayUtils.appendInt(current, guid); - } - } - return current; } static void invalidateCache() {