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

Commit 6544279f authored by Hai Zhang's avatar Hai Zhang Committed by Android (Google) Code Review
Browse files

Merge "Second batch of permission in-process API refactoring."

parents 671688d3 0f3bd201
Loading
Loading
Loading
Loading
+19 −21
Original line number Diff line number Diff line
@@ -2216,14 +2216,15 @@ public class PackageManagerService extends IPackageManager.Stub
            // that the installer requested to be granted at install time.
            if (whitelistedRestrictedPermissions != null
                    && !whitelistedRestrictedPermissions.isEmpty()) {
                mPermissionManager.setWhitelistedRestrictedPermissions(
                        res.pkg, res.newUsers, whitelistedRestrictedPermissions,
                        Process.myUid(), FLAG_PERMISSION_WHITELIST_INSTALLER);
                mPermissionManager.setAllowlistedRestrictedPermissions(res.pkg,
                        whitelistedRestrictedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER,
                        res.newUsers);
            }
            if (autoRevokePermissionsMode == MODE_ALLOWED || autoRevokePermissionsMode == MODE_IGNORED) {
                mPermissionManager.setAutoRevokeWhitelisted(res.pkg.getPackageName(),
                        autoRevokePermissionsMode == MODE_IGNORED, UserHandle.myUserId());
            if (autoRevokePermissionsMode == MODE_ALLOWED
                    || autoRevokePermissionsMode == MODE_IGNORED) {
                mPermissionManager.setAutoRevokeExempted(res.pkg,
                        autoRevokePermissionsMode == MODE_IGNORED, res.newUsers);
            }
            // Now that we successfully installed the package, grant runtime
@@ -2233,8 +2234,9 @@ public class PackageManagerService extends IPackageManager.Stub
            // legacy apps.
            if (grantPermissions) {
                final int callingUid = Binder.getCallingUid();
                mPermissionManager.grantRequestedRuntimePermissions(
                        res.pkg, res.newUsers, grantedPermissions, callingUid);
                mPermissionManager.grantRequestedRuntimePermissions(res.pkg,
                        grantedPermissions != null ? Arrays.asList(grantedPermissions) : null,
                        res.newUsers);
            }
            final String installerPackageName =
@@ -13548,12 +13550,15 @@ public class PackageManagerService extends IPackageManager.Stub
            }
            if (installed) {
                if (pkgSetting.pkg != null) {
                    if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
                        != 0 && pkgSetting.pkg != null) {
                            != 0) {
                        whiteListedPermissions = pkgSetting.pkg.getRequestedPermissions();
                    }
                mPermissionManager.setWhitelistedRestrictedPermissions(packageName,
                        whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
                    mPermissionManager.setAllowlistedRestrictedPermissions(pkgSetting.pkg,
                            whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER,
                            new int[] { userId });
                }
                if (pkgSetting.pkg != null) {
                    synchronized (mInstallLock) {
@@ -25026,14 +25031,7 @@ public class PackageManagerService extends IPackageManager.Stub
        @Override
        public boolean isPermissionsReviewRequired(String packageName, int userId) {
            synchronized (mLock) {
                final AndroidPackage pkg = mPackages.get(packageName);
                if (pkg == null) {
                    return false;
                }
                return mPermissionManager.isPermissionsReviewRequired(pkg, userId);
            }
            return mPermissionManager.isPermissionsReviewRequired(packageName, userId);
        }
        @Override
+74 −58
Original line number Diff line number Diff line
@@ -1293,7 +1293,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
    public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
            @NonNull String permName, @PermissionWhitelistFlags int flags,
            @UserIdInt int userId) {
        // Other argument checks are done in get/setWhitelistedRestrictedPermissions
        // Other argument checks are done in get/setAllowlistedRestrictedPermissions
        Objects.requireNonNull(permName);

        if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
@@ -1307,7 +1307,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        }
        if (permissions.indexOf(permName) < 0) {
            permissions.add(permName);
            return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
            return setAllowlistedRestrictedPermissions(packageName, permissions,
                    flags, userId);
        }
        return false;
@@ -1338,7 +1338,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
    public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
            @NonNull String permName, @PermissionWhitelistFlags int flags,
            @UserIdInt int userId) {
        // Other argument checks are done in get/setWhitelistedRestrictedPermissions
        // Other argument checks are done in get/setAllowlistedRestrictedPermissions
        Objects.requireNonNull(permName);

        if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
@@ -1348,13 +1348,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        final List<String> permissions =
                getWhitelistedRestrictedPermissions(packageName, flags, userId);
        if (permissions != null && permissions.remove(permName)) {
            return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
            return setAllowlistedRestrictedPermissions(packageName, permissions,
                    flags, userId);
        }
        return false;
    }

    private boolean setWhitelistedRestrictedPermissionsInternal(@NonNull String packageName,
    private boolean setAllowlistedRestrictedPermissions(@NonNull String packageName,
            @Nullable List<String> permissions, @PermissionWhitelistFlags int flags,
            @UserIdInt int userId) {
        Objects.requireNonNull(packageName);
@@ -1369,7 +1369,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        if (UserHandle.getCallingUserId() != userId) {
            mContext.enforceCallingOrSelfPermission(
                    Manifest.permission.INTERACT_ACROSS_USERS,
                    "setWhitelistedRestrictedPermissions for user " + userId);
                    "setAllowlistedRestrictedPermissions for user " + userId);
        }

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
@@ -1431,8 +1431,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {

        final long identity = Binder.clearCallingIdentity();
        try {
            setWhitelistedRestrictedPermissionsForUsers(pkg, new int[]{ userId }, permissions,
                    Process.myUid(), flags, mDefaultPermissionCallback);
            setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags,
                    new int[] { userId });
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
@@ -1447,25 +1447,34 @@ public class PermissionManagerService extends IPermissionManager.Stub {

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        final int callingUid = Binder.getCallingUid();
        final int packageUid = UserHandle.getUid(userId, pkg.getUid());

        if (!checkAutoRevokeAccess(pkg, callingUid)) {
            return false;
        }

        if (mAppOpsManager
                .checkOpNoThrow(AppOpsManager.OP_AUTO_REVOKE_MANAGED_BY_INSTALLER,
                        packageUid, packageName)
                != MODE_ALLOWED) {
        return setAutoRevokeExemptedInternal(pkg, whitelisted, userId);
    }

    private void setAutoRevokeExemptedInternal(@NonNull AndroidPackage pkg, boolean exempted,
            @NonNull int[] userIds) {
        for (final int userId : userIds) {
            setAutoRevokeExemptedInternal(pkg, exempted, userId);
        }
    }

    private boolean setAutoRevokeExemptedInternal(@NonNull AndroidPackage pkg, boolean exempted,
            @UserIdInt int userId) {
        final int packageUid = UserHandle.getUid(userId, pkg.getUid());
        if (mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_AUTO_REVOKE_MANAGED_BY_INSTALLER,
                packageUid, pkg.getPackageName()) != MODE_ALLOWED) {
            // Whitelist user set - don't override
            return false;
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            mAppOpsManager.setMode(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
                    packageUid, packageName,
                    whitelisted ? MODE_IGNORED : MODE_ALLOWED);
            mAppOpsManager.setMode(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, packageUid,
                    pkg.getPackageName(), exempted ? MODE_IGNORED : MODE_ALLOWED);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
@@ -3741,8 +3750,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        return false;
    }

    private boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
    private boolean isPermissionsReviewRequiredInternal(@NonNull String packageName,
            @UserIdInt int userId) {
        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
            return false;
        }

        // Permission review applies only to apps not supporting the new permission model.
        if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
            return false;
@@ -3756,20 +3770,19 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                        + userId);
                return false;
            }
            return uidState.isPermissionReviewRequired();
            return uidState.isPermissionsReviewRequired();
        }
    }

    private void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
            String[] grantedPermissions, int callingUid, PermissionCallback callback) {
    private void grantRequestedRuntimePermissionsInternal(@NonNull AndroidPackage pkg,
            @Nullable List<String> permissions, @NonNull int[] userIds) {
        for (int userId : userIds) {
            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
                    callback);
            grantRequestedRuntimePermissionsForUser(pkg, permissions, userId);
        }
    }

    private void grantRequestedRuntimePermissionsForUser(AndroidPackage pkg, int userId,
            String[] grantedPermissions, int callingUid, PermissionCallback callback) {
    private void grantRequestedRuntimePermissionsForUser(@NonNull AndroidPackage pkg,
            @Nullable List<String> permissions, int userId) {
        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;

@@ -3781,6 +3794,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {

        final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId);

        final int myUid = Process.myUid();

        for (String permission : pkg.getRequestedPermissions()) {
            final boolean shouldGrantPermission;
            synchronized (mLock) {
@@ -3788,36 +3803,36 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                shouldGrantPermission = bp != null && (bp.isRuntime() || bp.isDevelopment())
                        && (!instantApp || bp.isInstant())
                        && (supportsRuntimePermissions || !bp.isRuntimeOnly())
                        && (grantedPermissions == null
                                || ArrayUtils.contains(grantedPermissions, permission));
                        && (permissions == null || permissions.contains(permission));
            }
            if (shouldGrantPermission) {
                final int flags = getPermissionFlagsInternal(permission, pkg.getPackageName(),
                        callingUid, userId);
                        myUid, userId);
                if (supportsRuntimePermissions) {
                    // Installer cannot change immutable permissions.
                    if ((flags & immutableFlags) == 0) {
                        grantRuntimePermissionInternal(permission, pkg.getPackageName(), false,
                                callingUid, userId, callback);
                                myUid, userId, mDefaultPermissionCallback);
                    }
                } else {
                    // In permission review mode we clear the review flag and the revoked compat
                    // flag when we are asked to install the app with all permissions granted.
                    if ((flags & compatFlags) != 0) {
                        updatePermissionFlagsInternal(permission, pkg.getPackageName(), compatFlags,
                                0, callingUid, userId, false, callback);
                                0, myUid, userId, false, mDefaultPermissionCallback);
                    }
                }
            }
        }
    }

    private void setWhitelistedRestrictedPermissionsForUsers(@NonNull AndroidPackage pkg,
            @UserIdInt int[] userIds, @Nullable List<String> permissions, int callingUid,
            @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
    private void setAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg,
            @Nullable List<String> permissions, @PermissionWhitelistFlags int allowlistFlags,
            @UserIdInt int[] userIds) {
        SparseArray<ArraySet<String>> oldGrantedRestrictedPermissions = new SparseArray<>();
        boolean updatePermissions = false;
        final int permissionCount = pkg.getRequestedPermissions().size();
        final int myUid = Process.myUid();

        for (int i = 0; i < userIds.length; i++) {
            int userId = userIds[i];
@@ -3849,11 +3864,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                }

                final int oldFlags = getPermissionFlagsInternal(permissionName,
                        pkg.getPackageName(), callingUid, userId);
                        pkg.getPackageName(), myUid, userId);

                int newFlags = oldFlags;
                int mask = 0;
                int whitelistFlagsCopy = whitelistFlags;
                int whitelistFlagsCopy = allowlistFlags;
                while (whitelistFlagsCopy != 0) {
                    final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
                    whitelistFlagsCopy &= ~flag;
@@ -3928,13 +3943,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                }

                updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
                        callingUid, userId, false, null /*callback*/);
                        myUid, userId, false, null /*callback*/);
            }
        }

        if (updatePermissions) {
            // Update permission of this app to take into account the new whitelist state.
            restorePermissionState(pkg, false, pkg.getPackageName(), callback);
            restorePermissionState(pkg, false, pkg.getPackageName(), mDefaultPermissionCallback);

            // If this resulted in losing a permission we need to kill the app.
            for (int i = 0; i < userIds.length; i++) {
@@ -3959,7 +3974,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                        isGranted = uidState.isPermissionGranted(permissionName);
                    }
                    if (!isGranted) {
                        callback.onPermissionRevoked(pkg.getUid(), userId, null);
                        mDefaultPermissionCallback.onPermissionRevoked(pkg.getUid(), userId, null);
                        break;
                    }
                }
@@ -4987,10 +5002,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        public void systemReady() {
            PermissionManagerService.this.systemReady();
        }

        @Override
        public boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
        public boolean isPermissionsReviewRequired(@NonNull String packageName,
                @UserIdInt int userId) {
            return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
            Objects.requireNonNull(packageName, "packageName");
            // TODO(b/173235285): Some caller may pass USER_ALL as userId.
            //Preconditions.checkArgumentNonnegative(userId, "userId");
            return isPermissionsReviewRequiredInternal(packageName, userId);
        }

        @Override
@@ -5063,29 +5082,26 @@ public class PermissionManagerService extends IPermissionManager.Stub {
            return PermissionManagerService.this.getAppOpPermissionPackagesInternal(permissionName);
        }
        @Override
        public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
                String[] grantedPermissions, int callingUid) {
            PermissionManagerService.this.grantRequestedRuntimePermissions(
                    pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback);
        }
        @Override
        public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
                @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
                @PackageManager.PermissionWhitelistFlags int flags) {
            setWhitelistedRestrictedPermissionsForUsers(pkg, userIds, permissions,
                    callingUid, flags, mDefaultPermissionCallback);
        public void grantRequestedRuntimePermissions(@NonNull AndroidPackage pkg,
                @Nullable List<String> permissions, @NonNull int[] userIds) {
            Objects.requireNonNull(pkg, "pkg");
            Objects.requireNonNull(userIds, "userIds");
            grantRequestedRuntimePermissionsInternal(pkg, permissions, userIds);
        }
        @Override
        public void setWhitelistedRestrictedPermissions(String packageName,
                List<String> permissions, int flags, int userId) {
            PermissionManagerService.this.setWhitelistedRestrictedPermissionsInternal(
                    packageName, permissions, flags, userId);
        public void setAllowlistedRestrictedPermissions(@NonNull AndroidPackage pkg,
                @Nullable List<String> permissions, @PermissionWhitelistFlags int allowlistFlags,
                @NonNull int[] userIds) {
            Objects.requireNonNull(pkg, "pkg");
            Objects.requireNonNull(userIds, "userIds");
            setAllowlistedRestrictedPermissionsInternal(pkg, permissions, allowlistFlags, userIds);
        }
        @Override
        public void setAutoRevokeWhitelisted(
                @NonNull String packageName, boolean whitelisted, int userId) {
            PermissionManagerService.this.setAutoRevokeWhitelisted(
                    packageName, whitelisted, userId);
        public void setAutoRevokeExempted(@NonNull AndroidPackage pkg, boolean exempted,
                @NonNull int[] userIds) {
            Objects.requireNonNull(pkg, "pkg");
            Objects.requireNonNull(userIds, "userIds");
            setAutoRevokeExemptedInternal(pkg, exempted, userIds);
        }
        @Override
        public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
+44 −14
Original line number Diff line number Diff line
@@ -179,22 +179,52 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager

    public abstract void systemReady();

    public abstract boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
    /**
     * Get whether permission review is required for a package.
     *
     * @param packageName the name of the package
     * @param userId the user ID
     * @return whether permission review is required
     */
    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
    public abstract boolean isPermissionsReviewRequired(@NonNull String packageName,
            @UserIdInt int userId);

    public abstract void grantRequestedRuntimePermissions(
            @NonNull AndroidPackage pkg, @NonNull int[] userIds,
            @NonNull String[] grantedPermissions, int callingUid);
    public abstract void setWhitelistedRestrictedPermissions(
            @NonNull AndroidPackage pkg, @NonNull int[] userIds,
            @NonNull List<String> permissions, int callingUid,
            @PackageManager.PermissionWhitelistFlags int whitelistFlags);
    /** Sets the allowlisted, restricted permissions for the given package. */
    public abstract void setWhitelistedRestrictedPermissions(
            @NonNull String packageName, @NonNull List<String> permissions,
            @PackageManager.PermissionWhitelistFlags int flags, int userId);
    public abstract void setAutoRevokeWhitelisted(
            @NonNull String packageName, boolean whitelisted, int userId);
    /**
     * Grant the requested runtime permissions for a package, or an explicit subset of them.
     *
     * @param pkg the package
     * @param permissions the names of the subset of permissions to be granted, or {@code null} for
     *                    granting all the requested permissions
     * @param userIds the user IDs
     */
    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
    public abstract void grantRequestedRuntimePermissions(@NonNull AndroidPackage pkg,
            @Nullable List<String> permissions, @NonNull int[] userIds);

    /**
     * Set the allowlisted restricted permissions for a package, or an explicit subset of them.
     *
     * @param pkg the package
     * @param permissions the names of the subset of permissions to be allowlisted, or {@code null}
     *                    for allowlisting all the requested restricted permissions
     * @param userIds the user IDs
     */
    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
    public abstract void setAllowlistedRestrictedPermissions(
            @NonNull AndroidPackage pkg, @Nullable List<String> permissions,
            @PackageManager.PermissionWhitelistFlags int allowlistFlags, @NonNull int[] userIds);

    /**
     * Set whether a package is exempted from auto revoke.
     *
     * @param pkg the package
     * @param exempted whether the package is exempted from auto revoke
     * @param userIds the user IDs
     */
    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
    public abstract void setAutoRevokeExempted(@NonNull AndroidPackage pkg, boolean exempted,
            @NonNull int[] userIds);

    /**
     * Update permissions when a package changed.
+1 −1
Original line number Diff line number Diff line
@@ -308,7 +308,7 @@ public final class UidPermissionState {
        return anyChanged;
    }

    public boolean isPermissionReviewRequired() {
    public boolean isPermissionsReviewRequired() {
        if (mPermissions == null) {
            return false;
        }