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

Commit df932933 authored by Nicholas Sauer's avatar Nicholas Sauer
Browse files

DO NOT MERGE Update permissions flags for all users before attempting to

restore permissions.

bug: 140274903
Test: cts-tradefed run cts-dev -m CtsPermissionTestCases -t android.permission.cts.SplitPermissionTest
on both user 0 and user 10.

Also (running on u10):
$ adb install out/.../CtsAppThatRequestsLocationPermission29.apk
$ adb shell pm grant --user 10 android.permission.cts.appthatrequestpermission android.permission.ACCESS_COARSE_LOCATION
$ adb install out/.../CtsAppThatRequestsLocationPermission28.apk
$ adb shell dumpsys package android.permission.cts.appthatrequestpermission

Verify that ACCESS_BACKGROUND_LOCATION is granted to user 10

Change-Id: I3cd4365ca5abce292a190ca7abca4e4e8fbf61c4
parent db1bad4a
Loading
Loading
Loading
Loading
+98 −90
Original line number Diff line number Diff line
@@ -2022,16 +2022,6 @@ public class PermissionManagerService {
        return whitelistedPermissions;
    }

    private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
            @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
            @PackageManager.PermissionWhitelistFlags int whitelistFlags,
            @NonNull PermissionCallback callback) {
        for (int userId : userIds) {
            setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
                    callingUid, whitelistFlags, callback);
        }
    }

    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
            String[] grantedPermissions, int callingUid, PermissionCallback callback) {
        PackageSetting ps = (PackageSetting) pkg.mExtras;
@@ -2312,20 +2302,22 @@ public class PermissionManagerService {
        }
    }

    private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg,
            @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
            @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
    private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
            @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
            @PackageManager.PermissionWhitelistFlags int whitelistFlags,
            @NonNull PermissionCallback callback) {

        final PackageSetting ps = (PackageSetting) pkg.mExtras;
        if (ps == null) {
            return;
        }

        final PermissionsState permissionsState = ps.getPermissionsState();

        ArraySet<String> oldGrantedRestrictedPermissions = null;
        SparseArray<ArraySet<String>> oldGrantedRestrictedPermissionsByUser = new SparseArray<>();
        boolean updatePermissions = false;

        final int permissionCount = pkg.requestedPermissions.size();
        for (int userId : userIds) {
            for (int i = 0; i < permissionCount; i++) {
                final String permissionName = pkg.requestedPermissions.get(i);

@@ -2340,10 +2332,10 @@ public class PermissionManagerService {
                }

                if (permissionsState.hasPermission(permissionName, userId)) {
                if (oldGrantedRestrictedPermissions == null) {
                    oldGrantedRestrictedPermissions = new ArraySet<>();
                    if (oldGrantedRestrictedPermissionsByUser.get(userId) == null) {
                        oldGrantedRestrictedPermissionsByUser.put(userId, new ArraySet<>());
                    }
                oldGrantedRestrictedPermissions.add(permissionName);
                    oldGrantedRestrictedPermissionsByUser.get(userId).add(permissionName);
                }

                final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
@@ -2358,27 +2350,36 @@ public class PermissionManagerService {
                        case FLAG_PERMISSION_WHITELIST_SYSTEM: {
                            mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                            if (permissions != null && permissions.contains(permissionName)) {
                            newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                                newFlags |=
                                        PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                            } else {
                            newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                                newFlags &=
                                        ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                            }
                    } break;
                        }
                        break;
                        case FLAG_PERMISSION_WHITELIST_UPGRADE: {
                            mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                            if (permissions != null && permissions.contains(permissionName)) {
                            newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                                newFlags |=
                                        PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                            } else {
                            newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                                newFlags &=
                                        ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                            }
                    } break;
                        }
                        break;
                        case FLAG_PERMISSION_WHITELIST_INSTALLER: {
                            mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                            if (permissions != null && permissions.contains(permissionName)) {
                            newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                                newFlags |=
                                        PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                            } else {
                            newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                                newFlags &= ~PackageManager
                                        .FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                            }
                    } break;
                        }
                        break;
                    }
                }

@@ -2398,7 +2399,8 @@ public class PermissionManagerService {
                // as whitelisting trumps policy i.e. policy cannot grant a non
                // grantable permission.
                if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
                final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
                    final boolean isGranted = permissionsState.hasPermission(permissionName,
                            userId);
                    if (!isWhitelisted && isGranted) {
                        mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
                        newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
@@ -2416,13 +2418,19 @@ public class PermissionManagerService {
                updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
                        callingUid, userId, false, null /*callback*/);
            }
        }

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

            // If this resulted in losing a permission we need to kill the app.
            if (oldGrantedRestrictedPermissions != null) {
            int oldGrantedRestrictedPermissionsByUserCount =
                    oldGrantedRestrictedPermissionsByUser.size();
            for (int j = 0; j < oldGrantedRestrictedPermissionsByUserCount; j++) {
                final int userId = oldGrantedRestrictedPermissionsByUser.keyAt(j);
                final ArraySet<String> oldGrantedRestrictedPermissions =
                        oldGrantedRestrictedPermissionsByUser.valueAt(j);
                final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
                for (int i = 0; i < oldGrantedCount; i++) {
                    final String permission = oldGrantedRestrictedPermissions.valueAt(i);