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

Commit 7a097ff1 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Shared user retains permissions no longer used by any app on an app update" into mnc-dr-dev

parents 11af1878 ff7b92fc
Loading
Loading
Loading
Loading
+76 −2
Original line number Diff line number Diff line
@@ -8366,6 +8366,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
        boolean runtimePermissionsRevoked = false;
        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
        boolean changedInstallPermission = false;
@@ -8375,6 +8376,17 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (!ps.isSharedUser()) {
                origPermissions = new PermissionsState(permissionsState);
                permissionsState.reset();
            } else {
                // We need to know only about runtime permission changes since the
                // calling code always writes the install permissions state but
                // the runtime ones are written only if changed. The only cases of
                // changed runtime permissions here are promotion of an install to
                // runtime and revocation of a runtime from a shared user.
                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
                    runtimePermissionsRevoked = true;
                }
            }
        }
@@ -8590,9 +8602,11 @@ public class PackageManagerService extends IPackageManager.Stub {
            ps.installPermissionsFixed = true;
        }
        // Persist the runtime permissions state for users with changes.
        // Persist the runtime permissions state for users with changes. If permissions
        // were revoked because no app in the shared user declares them we have to
        // write synchronously to avoid losing runtime permissions state.
        for (int userId : changedRuntimePermissionUserIds) {
            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
        }
    }
@@ -12089,6 +12103,66 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
    }
    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
        // Collect all used permissions in the UID
        ArraySet<String> usedPermissions = new ArraySet<>();
        final int packageCount = su.packages.size();
        for (int i = 0; i < packageCount; i++) {
            PackageSetting ps = su.packages.valueAt(i);
            if (ps.pkg == null) {
                continue;
            }
            final int requestedPermCount = ps.pkg.requestedPermissions.size();
            for (int j = 0; j < requestedPermCount; j++) {
                String permission = ps.pkg.requestedPermissions.get(j);
                BasePermission bp = mSettings.mPermissions.get(permission);
                if (bp != null) {
                    usedPermissions.add(permission);
                }
            }
        }
        PermissionsState permissionsState = su.getPermissionsState();
        // Prune install permissions
        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
        final int installPermCount = installPermStates.size();
        for (int i = installPermCount - 1; i >= 0;  i--) {
            PermissionState permissionState = installPermStates.get(i);
            if (!usedPermissions.contains(permissionState.getName())) {
                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
                if (bp != null) {
                    permissionsState.revokeInstallPermission(bp);
                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
                            PackageManager.MASK_PERMISSION_FLAGS, 0);
                }
            }
        }
        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
        // Prune runtime permissions
        for (int userId : allUserIds) {
            List<PermissionState> runtimePermStates = permissionsState
                    .getRuntimePermissionStates(userId);
            final int runtimePermCount = runtimePermStates.size();
            for (int i = runtimePermCount - 1; i >= 0; i--) {
                PermissionState permissionState = runtimePermStates.get(i);
                if (!usedPermissions.contains(permissionState.getName())) {
                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
                    if (bp != null) {
                        permissionsState.revokeRuntimePermission(bp, userId);
                        permissionsState.updatePermissionFlags(bp, userId,
                                PackageManager.MASK_PERMISSION_FLAGS, 0);
                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
                                runtimePermissionChangedUserIds, userId);
                    }
                }
            }
        }
        return runtimePermissionChangedUserIds;
    }
    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
            String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
            UserHandle user) {