From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: inthewaves <inthewaves@pm.me>
Date: Sat, 12 Sep 2020 12:28:34 -0700
Subject: [PATCH] support new special runtime permissions

These are treated as a runtime permission even for legacy apps. They
need to be granted by default for all apps to maintain compatibility.

Ported from 10: 4d5d82f4e2fb9ff68158bf30f3944591bb74dd04

Changes from 10:
- It seems like parts of PackageManagerService#resetUserChangesToRuntimePermissionsAndFlagsLPw
were refactored into PermissionManagerService#resetRuntimePermissionsInternal.
As a result, PackageManagerService is no longer modified.

[kdrag0n: Ported to Android 12]
Signed-off-by: Danny Lin <danny@kdrag0n.dev>
---
 .../permission/PermissionManagerService.java  | 25 +++++++++++++++----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 93f9e1c2295c..ab4f7821eba9 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1526,7 +1526,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
             // their permissions as always granted runtime ones since we need
             // to keep the review required permission flag per user while an
             // install permission's state is shared across all users.
-            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
+            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime() &&
+                    !isSpecialRuntimePermission(permName)) {
                 return;
             }
 
@@ -1569,7 +1570,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                             + " for package " + packageName);
                 }
 
-                if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
+                if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M &&
+                    !isSpecialRuntimePermission(permName)) {
                     Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
                     return;
                 }
@@ -1694,7 +1696,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
             // their permissions as always granted runtime ones since we need
             // to keep the review required permission flag per user while an
             // install permission's state is shared across all users.
-            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
+            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime() &&
+                    !isSpecialRuntimePermission(permName)) {
                 return;
             }
 
@@ -1899,7 +1902,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
 
             // If this permission was granted by default or role, make sure it is.
             if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0
-                    || (oldFlags & FLAG_PERMISSION_GRANTED_BY_ROLE) != 0) {
+                    || (oldFlags & FLAG_PERMISSION_GRANTED_BY_ROLE) != 0
+                    || isSpecialRuntimePermission(permName)) {
                 // PermissionPolicyService will handle the app op for runtime permissions later.
                 grantRuntimePermissionInternal(packageName, permName, false,
                         Process.SYSTEM_UID, userId, delayingPermCallback);
@@ -2628,6 +2632,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
         }
     }
 
+    public static boolean isSpecialRuntimePermission(final String permission) {
+        return false;
+    }
+
     /**
      * Restore the permission state for a package.
      *
@@ -2996,6 +3004,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                                     }
                                 }
                             }
+
+                            if (isSpecialRuntimePermission(permName) &&
+                                    origPermState == null) {
+                                if (uidState.grantPermission(bp)) {
+                                    wasChanged = true;
+                                }
+                            }
                         } else {
                             if (origPermState == null) {
                                 // New permission
@@ -3819,7 +3834,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
             if (shouldGrantPermission) {
                 final int flags = getPermissionFlagsInternal(pkg.getPackageName(), permission,
                         myUid, userId);
-                if (supportsRuntimePermissions) {
+                if (supportsRuntimePermissions || isSpecialRuntimePermission(permission)) {
                     // Installer cannot change immutable permissions.
                     if ((flags & immutableFlags) == 0) {
                         grantRuntimePermissionInternal(pkg.getPackageName(), permission, false,