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

Commit c4986144 authored by Nick Kralevich's avatar Nick Kralevich
Browse files

PackageManagerService: update grantPermission / revokePermission

Currently, grantPermission / revokePermission only handles development
permissions. This change extends these two functions to handle normal
and dangerous permissions.

A normal / dangerous permission can modified if it is marked as
optional (android:required="false") using the "am grant" / "am revoke"
commands.

Currently, this change is a no-op. The package parser code
does not currently honor <uses-permission android:required="false"> in
the application's manifest, and assumes a permission is always required.

This change sets the ground for future optional permissions work.

Change-Id: I34f02ffd714e8a9a37b9f87df89cef915b1b6780
parent 10ac1d12
Loading
Loading
Loading
Loading
+38 −20
Original line number Diff line number Diff line
@@ -2236,6 +2236,34 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
    }

    private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
        int index = pkg.requestedPermissions.indexOf(bp.name);
        if (index == -1) {
            throw new SecurityException("Package " + pkg.packageName
                    + " has not requested permission " + bp.name);
        }
        boolean isNormal =
                ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
                        == PermissionInfo.PROTECTION_NORMAL);
        boolean isDangerous =
                ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
                        == PermissionInfo.PROTECTION_DANGEROUS);
        boolean isDevelopment =
                ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);

        if (!isNormal && !isDangerous && !isDevelopment) {
            throw new SecurityException("Permission " + bp.name
                    + " is not a changeable permission type");
        }

        if (isNormal || isDangerous) {
            if (pkg.requestedPermissionsRequired.get(index)) {
                throw new SecurityException("Can't change " + bp.name
                        + ". It is required by the application");
            }
        }
    }

    public void grantPermission(String packageName, String permissionName) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
@@ -2246,21 +2274,16 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
            final BasePermission bp = mSettings.mPermissions.get(permissionName);
            if (bp == null) {
                throw new IllegalArgumentException("Unknown permission: " + packageName);
            }
            if (!pkg.requestedPermissions.contains(permissionName)) {
                throw new SecurityException("Package " + packageName
                        + " has not requested permission " + permissionName);
            }
            if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
                throw new SecurityException("Permission " + permissionName
                        + " is not a development permission");
                throw new IllegalArgumentException("Unknown permission: " + permissionName);
            }

            checkGrantRevokePermissions(pkg, bp);

            final PackageSetting ps = (PackageSetting) pkg.mExtras;
            if (ps == null) {
                return;
            }
            final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
            final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
            if (gp.grantedPermissions.add(permissionName)) {
                if (ps.haveGids) {
                    gp.gids = appendInts(gp.gids, bp.gids);
@@ -2282,21 +2305,16 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
            final BasePermission bp = mSettings.mPermissions.get(permissionName);
            if (bp == null) {
                throw new IllegalArgumentException("Unknown permission: " + packageName);
            }
            if (!pkg.requestedPermissions.contains(permissionName)) {
                throw new SecurityException("Package " + packageName
                        + " has not requested permission " + permissionName);
            }
            if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
                throw new SecurityException("Permission " + permissionName
                        + " is not a development permission");
                throw new IllegalArgumentException("Unknown permission: " + permissionName);
            }

            checkGrantRevokePermissions(pkg, bp);

            final PackageSetting ps = (PackageSetting) pkg.mExtras;
            if (ps == null) {
                return;
            }
            final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
            final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
            if (gp.grantedPermissions.remove(permissionName)) {
                gp.grantedPermissions.remove(permissionName);
                if (ps.haveGids) {