RESTRICT AUTOMERGE: Revoke permissions defined in a to-be removed package.

Bug: 67319274
Test: run cts-dev --module CtsPermissionTestCases --test android.permission.cts.RemovePermissionTest#permissionShouldBeRevokedIfRemoved
Change-Id: I2771c048e13529e168121c5a5501aa26fc21e30f
(cherry picked from commit 821076440434443af4257c5ba0b7b1f037735041)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d6b5728..287bce5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -624,6 +624,8 @@
      */
     private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
 
+    private static final int PROTECTION_MASK_BASE = 0xf;
+
     final ServiceThread mHandlerThread;
 
     final PackageHandler mHandler;
@@ -5761,11 +5763,12 @@
 
     @Override
     public void revokeRuntimePermission(String packageName, String name, int userId) {
-        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
+        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */,
+                mSettings.getPermission(name));
     }
 
     private void revokeRuntimePermission(String packageName, String name, int userId,
-            boolean overridePolicy) {
+            boolean overridePolicy, BasePermission bp) {
         if (!sUserManager.exists(userId)) {
             Log.e(TAG, "No such user:" + userId);
             return;
@@ -5791,7 +5794,6 @@
                     || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
-            final BasePermission bp = mSettings.mPermissions.get(name);
             if (bp == null) {
                 throw new IllegalArgumentException("Unknown permission: " + name);
             }
@@ -5913,7 +5915,7 @@
 
                                 try {
                                     revokeRuntimePermission(packageName, permissionName, userId,
-                                           false);
+                                           false, mSettings.getPermission(permissionName));
                                 } catch (IllegalArgumentException e) {
                                     Slog.e(TAG, "Could not revoke " + permissionName + " from "
                                             + packageName, e);
@@ -12792,7 +12794,10 @@
             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
         }
 
+        final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
+
         N = pkg.permissions.size();
+        List<BasePermission> bps = new ArrayList<BasePermission>(N);
         r = null;
         for (i=0; i<N; i++) {
             PackageParser.Permission p = pkg.permissions.get(i);
@@ -12801,6 +12806,10 @@
                 bp = mSettings.mPermissionTrees.get(p.info.name);
             }
             if (bp != null && bp.perm == p) {
+                if (((p.info.protectionLevel & PROTECTION_MASK_BASE) &
+                        PermissionInfo.PROTECTION_DANGEROUS) != 0) {
+                    bps.add(bp);
+                }
                 bp.perm = null;
                 if (DEBUG_REMOVE && chatty) {
                     if (r == null) {
@@ -12818,6 +12827,45 @@
                 }
             }
         }
+
+        AsyncTask.execute(() -> {
+            final int numRemovedPermissions = bps.size();
+            for (int permissionNum = 0; permissionNum < numRemovedPermissions; permissionNum++) {
+                final int[] userIds = mUserManagerInternal.getUserIds();
+                final int numUserIds = userIds.length;
+
+                final int numPackages = allPackageNames.size();
+                for (int packageNum = 0; packageNum < numPackages; packageNum++) {
+                    final String packageName = allPackageNames.get(packageNum);
+                    final PackageManagerInternal packageManagerInt =
+                            LocalServices.getService(PackageManagerInternal.class);
+                    final ApplicationInfo applicationInfo = packageManagerInt.getApplicationInfo(
+                            packageName, 0, Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
+                    if (applicationInfo != null
+                            && applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
+                        continue;
+                    }
+                    for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
+                        final int userId = userIds[userIdNum];
+                        final String permissionName = bps.get(permissionNum).name;
+                        if (checkPermission(permissionName, packageName,
+                                userId) == PackageManager.PERMISSION_GRANTED) {
+                            try {
+                                revokeRuntimePermission(packageName,
+                                        permissionName,
+                                        userId,
+                                        false,
+                                        bps.get(permissionNum));
+                            } catch (IllegalArgumentException e) {
+                                Slog.e(TAG, "Could not revoke " + permissionName + " from "
+                                        + packageName, e);
+                            }
+                        }
+                    }
+                }
+            }
+        });
+
         if (r != null) {
             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
         }
@@ -25525,7 +25573,7 @@
         public void revokeRuntimePermission(String packageName, String name, int userId,
                 boolean overridePolicy) {
             PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
-                    overridePolicy);
+                    overridePolicy, mSettings.getPermission(name));
         }
 
         @Override
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 56835f6..c116d83 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -449,6 +449,17 @@
         mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
     }
 
+    public @Nullable BasePermission getPermission(@NonNull String permName) {
+        synchronized (mLock) {
+            return getPermissionLocked(permName);
+        }
+    }
+
+    @GuardedBy("mLock")
+    @Nullable BasePermission getPermissionLocked(@NonNull String permName) {
+        return mPermissions.get(permName);
+    }
+
     PackageSetting getPackageLPr(String pkgName) {
         return mPackages.get(pkgName);
     }