Support disabled/log/enforce in ro.control_privapp_permissions

Possible values:
 - disable - the feature is completely disabled - signature|privileged
   permissions are granted automatically without logging. Default behavior
 - log - log grants of signature|privileged permissions to privileged apps
   that were not whitelisted in /etc/permissions/privapp-permissions.xml.
 - enforce - enforce that only whitelisted permissions are granted.
   Only devices with ro.control_privapp_permission=enforce will pass CTS tests.

Test: Manual - device boots, permissions are granted
Bug:31008485
Change-Id: I24e0c75d2efc326c9fbec35efc92489313667212
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 7591488..1d26df0 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -27,8 +27,8 @@
             SystemProperties.getInt("ro.debuggable", 0) == 1;
     public static final int FACTORYTEST =
             SystemProperties.getInt("ro.factorytest", 0);
-    public static final boolean CONTROL_PRIVAPP_PERMISSIONS =
-            SystemProperties.getBoolean("ro.control_privapp_permissions", false);
+    public static final String CONTROL_PRIVAPP_PERMISSIONS =
+            SystemProperties.get("ro.control_privapp_permissions");
 
     // ------ ro.config.* -------- //
     public static final boolean CONFIG_LOW_RAM =
@@ -50,4 +50,12 @@
             "file".equalsIgnoreCase(CRYPTO_TYPE);
     public static final boolean CRYPTO_BLOCK_ENCRYPTED =
             "block".equalsIgnoreCase(CRYPTO_TYPE);
+
+    public static final boolean CONTROL_PRIVAPP_PERMISSIONS_LOG =
+            "log".equalsIgnoreCase(CONTROL_PRIVAPP_PERMISSIONS);
+    public static final boolean CONTROL_PRIVAPP_PERMISSIONS_ENFORCE =
+            "enforce".equalsIgnoreCase(CONTROL_PRIVAPP_PERMISSIONS);
+    public static final boolean CONTROL_PRIVAPP_PERMISSIONS_DISABLE =
+            !CONTROL_PRIVAPP_PERMISSIONS_LOG && !CONTROL_PRIVAPP_PERMISSIONS_ENFORCE;
+
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e31df52..eee01b2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -10522,18 +10522,21 @@
             BasePermission bp, PermissionsState origPermissions) {
         boolean privilegedPermission = (bp.protectionLevel
                 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
-        boolean controlPrivappPermissions = RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS;
+        boolean privappPermissionsDisable =
+                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
         boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
         boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
-        if (controlPrivappPermissions && privilegedPermission && pkg.isPrivilegedApp()
+        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
                 && !platformPackage && platformPermission) {
             ArraySet<String> wlPermissions = SystemConfig.getInstance()
                     .getPrivAppPermissions(pkg.packageName);
             boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
             if (!whitelisted) {
-                // Log for now. TODO Enforce permissions
                 Slog.w(TAG, "Privileged permission " + perm + " for package "
                         + pkg.packageName + " - not in privapp-permissions whitelist");
+                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
+                    return false;
+                }
             }
         }
         boolean allowed = (compareSignatures(
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
index 379d4fe..f773c15 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
@@ -90,9 +90,9 @@
                 boolean granted = (packageInfo.requestedPermissionsFlags[i]
                         & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
                 assertTrue("Permission " + pName + " should be granted to " + testPackage, granted);
-                // if CONTROL_PRIVAPP_PERMISSIONS enabled, platform permissions must be whitelisted
+                // if privapp permissions are enforced, platform permissions must be whitelisted
                 // in SystemConfig
-                if (platformPermission && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS) {
+                if (platformPermission && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
                     assertTrue("Permission " + pName
                                     + " should be declared in the xml file for package "
                                     + testPackage,