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

Commit da2bd223 authored by Hai Zhang's avatar Hai Zhang
Browse files

Use FLAG_PERMISSION_GRANTED_BY_ROLE for permissions granted by role.

We should only revoke permission that is granted by role, not the ones
that were already granted before role is granted.

Bug: 124452117
Bug: 130231314
Bug: 131252995
Test: presubmit
Change-Id: I2f8a90bd3e0a8dca2e6000d290bcfe163ba75624
parent edf00ca3
Loading
Loading
Loading
Loading
+50 −11
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ public class Permissions {
     * @param overrideDisabledSystemPackage whether to ignore the permissions of a disabled system
     *                                      package (if this package is an updated system package)
     * @param overrideUserSetAndFixed whether to override user set and fixed flags on the permission
     * @param setGrantedByRole whether the permissions will be granted as granted-by-role
     * @param setGrantedByDefault whether the permissions will be granted as granted-by-default
     * @param setSystemFixed whether the permissions will be granted as system-fixed
     * @param context the {@code Context} to retrieve system services
@@ -76,7 +77,13 @@ public class Permissions {
     */
    public static boolean grant(@NonNull String packageName, @NonNull List<String> permissions,
            boolean overrideDisabledSystemPackage, boolean overrideUserSetAndFixed,
            boolean setGrantedByDefault, boolean setSystemFixed, @NonNull Context context) {
            boolean setGrantedByRole, boolean setGrantedByDefault, boolean setSystemFixed,
            @NonNull Context context) {
        if (setGrantedByRole == setGrantedByDefault) {
            throw new IllegalArgumentException("Permission must be either granted by role, or"
                    + " granted by default, but not both");
        }

        PackageInfo packageInfo = getPackageInfo(packageName, context);
        if (packageInfo == null) {
            return false;
@@ -162,7 +169,8 @@ public class Permissions {
            String permission = sortedPermissionsToGrant[i];

            permissionOrAppOpChanged |= grantSingle(packageName, permission,
                    overrideUserSetAndFixed, setGrantedByDefault, setSystemFixed, context);
                    overrideUserSetAndFixed, setGrantedByRole, setGrantedByDefault, setSystemFixed,
                    context);

            if ((smsPermissions.contains(permission) || callLogPermissions.contains(permission))
                    && whitelistedRestrictedPermissions.add(permission)) {
@@ -175,8 +183,8 @@ public class Permissions {
    }

    private static boolean grantSingle(@NonNull String packageName, @NonNull String permission,
            boolean overrideUserSetAndFixed, boolean setGrantedByDefault, boolean setSystemFixed,
            @NonNull Context context) {
            boolean overrideUserSetAndFixed, boolean setGrantedByRole, boolean setGrantedByDefault,
            boolean setSystemFixed, @NonNull Context context) {
        boolean wasPermissionOrAppOpGranted = isPermissionAndAppOpGranted(packageName, permission,
                context);
        if (isPermissionFixed(packageName, permission, false, overrideUserSetAndFixed, context)
@@ -210,6 +218,9 @@ public class Permissions {

        // Update permission flags.
        int newFlags = 0;
        if (!wasPermissionOrAppOpGranted && setGrantedByRole) {
            newFlags |= PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE;
        }
        if (setGrantedByDefault) {
            newFlags |= PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
        }
@@ -351,6 +362,8 @@ public class Permissions {
     *
     * @param packageName the package name of the application to be revoke permissions from
     * @param permissions the list of permissions to be revoked
     * @param onlyIfGrantedByRole revoke the permission only if it is granted by role
     * @param onlyIfGrantedByDefault revoke the permission only if it is granted by default
     * @param overrideSystemFixed whether system-fixed permissions can be revoked
     * @param context the {@code Context} to retrieve system services
     *
@@ -360,6 +373,7 @@ public class Permissions {
     *      String, java.util.Set, boolean, int)
     */
    public static boolean revoke(@NonNull String packageName, @NonNull List<String> permissions,
            boolean onlyIfGrantedByRole, boolean onlyIfGrantedByDefault,
            boolean overrideSystemFixed, @NonNull Context context) {
        PackageInfo packageInfo = getPackageInfo(packageName, context);
        if (packageInfo == null) {
@@ -406,8 +420,8 @@ public class Permissions {
        for (int i = 0; i < sortedPermissionsToRevokeLength; i++) {
            String permission = sortedPermissionsToRevoke[i];

            permissionOrAppOpChanged |= revokeSingle(packageName, permission,
                    overrideSystemFixed, context);
            permissionOrAppOpChanged |= revokeSingle(packageName, permission, onlyIfGrantedByRole,
                    onlyIfGrantedByDefault, overrideSystemFixed, context);

            // Remove from the system whitelist only if not granted by default.
            if (!isPermissionGrantedByDefault(packageName, permission, context)
@@ -421,12 +435,31 @@ public class Permissions {
    }

    private static boolean revokeSingle(@NonNull String packageName, @NonNull String permission,
            boolean onlyIfGrantedByRole, boolean onlyIfGrantedByDefault,
            boolean overrideSystemFixed, @NonNull Context context) {
        if (onlyIfGrantedByRole == onlyIfGrantedByDefault) {
            throw new IllegalArgumentException("Permission can be revoked only if either granted by"
                    + " role, or granted by default, but not both");
        }

        if (onlyIfGrantedByRole) {
            if (!isPermissionGrantedByRole(packageName, permission, context)) {
                return false;
            }
            setPermissionFlags(packageName, permission, 0,
                    PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE, context);
        }

        if (onlyIfGrantedByDefault) {
            if (!isPermissionGrantedByDefault(packageName, permission, context)) {
                return false;
            }
            // Remove the granted-by-default permission flag.
            setPermissionFlags(packageName, permission, 0,
                    PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, context);
            // Note that we do not revoke FLAG_PERMISSION_SYSTEM_FIXED. That bit remains sticky once
            // set.
        }

        if (isPermissionFixed(packageName, permission, overrideSystemFixed, false, context)
                && isPermissionAndAppOpGranted(packageName, permission, context)) {
@@ -566,6 +599,12 @@ public class Permissions {
        return (flags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0;
    }

    private static boolean isPermissionGrantedByRole(@NonNull String packageName,
            @NonNull String permission, @NonNull Context context) {
        int flags = getPermissionFlags(packageName, permission, context);
        return (flags & PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE) != 0;
    }

    private static boolean isPermissionReviewRequired(@NonNull String packageName,
            @NonNull String permission, @NonNull Context context) {
        int flags = getPermissionFlags(packageName, permission, context);
+3 −3
Original line number Diff line number Diff line
@@ -551,8 +551,8 @@ public class Role {
     */
    public void grant(@NonNull String packageName, boolean dontKillApp,
            boolean overrideUserSetAndFixedPermissions, @NonNull Context context) {
        boolean permissionOrAppOpChanged = Permissions.grant(packageName, mPermissions,
                true, overrideUserSetAndFixedPermissions, false, false, context);
        boolean permissionOrAppOpChanged = Permissions.grant(packageName, mPermissions, true,
                overrideUserSetAndFixedPermissions, true, false, false, context);

        int appOpsSize = mAppOps.size();
        for (int i = 0; i < appOpsSize; i++) {
@@ -599,7 +599,7 @@ public class Role {
            permissionsToRevoke.removeAll(role.getPermissions());
        }
        boolean permissionOrAppOpChanged = Permissions.revoke(packageName, permissionsToRevoke,
                overrideSystemFixedPermissions, context);
                true, false, overrideSystemFixedPermissions, context);

        List<AppOp> appOpsToRevoke = new ArrayList<>(mAppOps);
        for (int i = 0; i < otherRoleNamesSize; i++) {