Use a separate fingerprint for DefaultPermissionGrantPolicy.

History here is that initially DefaultPermissionGrantPolicy and
RuntimePermissionsUpgradeController were both using Build.FINGERPRINT
as the fingerprint to determine if they need to re-run, because they
both can only change upon OTAs. Then when we made PermissionController
updatable via Mainline, we added PermissionController version code to
that fingerprint and started calling it extended fingerprint. That
made sure RuntimePermissionsUpgradeController can run upon
PermissionController upgrade, but also unnecessarily re-runs
DefaultPermissionGrantPolicy as the platform class itself and
preloaded apps can't change without an OTA.

In the new subsystem, we are moving the functionality of
RuntimePermissionsUpgradeController back into system server because it
has been a performance bottleneck, and we also no longer need the
existing fingerprint for it because we can now directly let the
upgrade logic check if the permission state is latest (this other
numeric version is also changed from per-user to be per-user-package),
compared to previously we needed this fingerprint to determine if we
need to call into PermissionController and let
RuntimePermissionsUpgradeController look at the latest numeric version
in its APK code.

But we still need the fingerprint for DefaultPermissionGrantPolicy
which is part of the platform, and it is currently missing in the new
subsystem, so this CL adds it to the new subsystem. Since
DefaultPermissionGrantPolicy only applies to what's on the system
image, we are also changing the fingerprint for it back to
Build.FINGERPRINT (instead of the extended fingerprint) when running
the new subsystem. Whereas for the old system, the fingerprint is
simply emulated to be either null or Build.FINGERPRINT depending on
whether the old subsystem wants to run DefaultPermissionGrantPolicy.

Bug: 284205103
Test: presubmit
Change-Id: Ib3358be57d7dd401fd2014ade3e58f9fc6c2b6a7
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4123481..c8a99fc 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4110,7 +4110,10 @@
         final int livingUserCount = livingUsers.size();
         for (int i = 0; i < livingUserCount; i++) {
             final int userId = livingUsers.get(i).id;
-            if (mSettings.isPermissionUpgradeNeeded(userId)) {
+            final boolean isPermissionUpgradeNeeded = !Objects.equals(
+                    mPermissionManager.getDefaultPermissionGrantFingerprint(userId),
+                    Build.FINGERPRINT);
+            if (isPermissionUpgradeNeeded) {
                 grantPermissionsUserIds = ArrayUtils.appendInt(
                         grantPermissionsUserIds, userId);
             }
@@ -4118,6 +4121,7 @@
         // If we upgraded grant all default permissions before kicking off.
         for (int userId : grantPermissionsUserIds) {
             mLegacyPermissionManager.grantDefaultPermissions(userId);
+            mPermissionManager.setDefaultPermissionGrantFingerprint(Build.FINGERPRINT, userId);
         }
         if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
             // If we did not grant default permissions, we preload from this the
@@ -4286,6 +4290,7 @@
         if (!convertedFromPreCreated || !readPermissionStateForUser(userId)) {
             mPermissionManager.onUserCreated(userId);
             mLegacyPermissionManager.grantDefaultPermissions(userId);
+            mPermissionManager.setDefaultPermissionGrantFingerprint(Build.FINGERPRINT, userId);
             mDomainVerificationManager.clearUser(userId);
         }
     }
@@ -4295,7 +4300,10 @@
             mPermissionManager.writeLegacyPermissionStateTEMP();
             mSettings.readPermissionStateForUserSyncLPr(userId);
             mPermissionManager.readLegacyPermissionStateTEMP();
-            return mSettings.isPermissionUpgradeNeeded(userId);
+            final boolean isPermissionUpgradeNeeded = !Objects.equals(
+                    mPermissionManager.getDefaultPermissionGrantFingerprint(userId),
+                    Build.FINGERPRINT);
+            return isPermissionUpgradeNeeded;
         }
     }
 
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 956bcf2..30afb0b 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -687,6 +687,18 @@
             mPermissionManagerServiceImpl.writeLegacyPermissionsTEMP(legacyPermissionSettings);
         }
 
+        @Nullable
+        @Override
+        public String getDefaultPermissionGrantFingerprint(@UserIdInt int userId) {
+            return mPermissionManagerServiceImpl.getDefaultPermissionGrantFingerprint(userId);
+        }
+
+        @Override
+        public void setDefaultPermissionGrantFingerprint(@NonNull String fingerprint,
+                @UserIdInt int userId) {
+            mPermissionManagerServiceImpl.setDefaultPermissionGrantFingerprint(fingerprint, userId);
+        }
+
         @Override
         public void onPackageAdded(@NonNull PackageState packageState, boolean isInstantApp,
                 @Nullable AndroidPackage oldPkg) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index b4e4ce0..fa2cef1 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -4599,6 +4599,19 @@
         }
     }
 
+    @Nullable
+    @Override
+    public String getDefaultPermissionGrantFingerprint(@UserIdInt int userId) {
+        return mPackageManagerInt.isPermissionUpgradeNeeded(userId) ? null : Build.FINGERPRINT;
+    }
+
+    @Override
+    public void setDefaultPermissionGrantFingerprint(@NonNull String fingerprint,
+            @UserIdInt int userId) {
+        // Ignored - default permission grant here shares the same version with runtime permission
+        // upgrade, and the new version is set by that later.
+    }
+
     private void onPackageAddedInternal(@NonNull PackageState packageState,
             @NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg) {
         if (!pkg.getAdoptPermissions().isEmpty()) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
index 8d8df96..128f847 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
@@ -523,6 +523,17 @@
     void writeLegacyPermissionsTEMP(@NonNull LegacyPermissionSettings legacyPermissionSettings);
 
     /**
+     * Get the fingerprint for default permission grants.
+     */
+    @Nullable
+    String getDefaultPermissionGrantFingerprint(@UserIdInt int userId);
+
+    /**
+     * Set the fingerprint for default permission grants.
+     */
+    void setDefaultPermissionGrantFingerprint(@NonNull String fingerprint, @UserIdInt int userId);
+
+    /**
      * Callback when the system is ready.
      */
     void onSystemReady();
@@ -603,6 +614,6 @@
      * @param userId the user ID the package is uninstalled for
      */
     void onPackageUninstalled(@NonNull String packageName, int appId,
-            @NonNull PackageState packageState, @NonNull AndroidPackage pkg,
+            @NonNull PackageState packageState, @Nullable AndroidPackage pkg,
             @NonNull List<AndroidPackage> sharedUserPkgs, @UserIdInt int userId);
 }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 240a73a..cf2b69c 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -215,6 +215,17 @@
     void writeLegacyPermissionsTEMP(@NonNull LegacyPermissionSettings legacyPermissionSettings);
 
     /**
+     * Get the fingerprint for default permission grants.
+     */
+    @Nullable
+    String getDefaultPermissionGrantFingerprint(@UserIdInt int userId);
+
+    /**
+     * Set the fingerprint for default permission grants.
+     */
+    void setDefaultPermissionGrantFingerprint(@NonNull String fingerprint, @UserIdInt int userId);
+
+    /**
      * Callback when the system is ready.
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java
index 83ddde5..7f98e21 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java
@@ -356,6 +356,20 @@
         mService.writeLegacyPermissionsTEMP(legacyPermissionSettings);
     }
 
+    @Nullable
+    @Override
+    public String getDefaultPermissionGrantFingerprint(int userId) {
+        Log.i(LOG_TAG, "getDefaultPermissionGrantFingerprint(userId = " + userId + ")");
+        return mService.getDefaultPermissionGrantFingerprint(userId);
+    }
+
+    @Override
+    public void setDefaultPermissionGrantFingerprint(@NonNull String fingerprint, int userId) {
+        Log.i(LOG_TAG, "setDefaultPermissionGrantFingerprint(fingerprint = " + fingerprint
+                + ", userId = " + userId + ")");
+        mService.setDefaultPermissionGrantFingerprint(fingerprint, userId);
+    }
+
     @Override
     public void onSystemReady() {
         Log.i(LOG_TAG, "onSystemReady()");
@@ -412,7 +426,7 @@
 
     @Override
     public void onPackageUninstalled(@NonNull String packageName, int appId,
-            @NonNull PackageState packageState, @NonNull AndroidPackage pkg,
+            @NonNull PackageState packageState, @Nullable AndroidPackage pkg,
             @NonNull List<AndroidPackage> sharedUserPkgs, int userId) {
         Log.i(LOG_TAG, "onPackageUninstalled(packageName = " + packageName + ", appId = " + appId
                 + ", packageState = " + packageState + ", pkg = " + pkg + ", sharedUserPkgs = "
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java
index 317fbe77..d4c6d42 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java
@@ -22,6 +22,7 @@
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
 import android.content.pm.permission.SplitPermissionInfoParcelable;
+import android.os.Build;
 import android.permission.IOnPermissionsChangeListener;
 
 import com.android.server.pm.pkg.AndroidPackage;
@@ -483,6 +484,26 @@
         mNewImplementation.writeLegacyPermissionsTEMP(legacyPermissionSettings);
     }
 
+    @Nullable
+    @Override
+    public String getDefaultPermissionGrantFingerprint(@UserIdInt int userId) {
+        String oldVal = mOldImplementation.getDefaultPermissionGrantFingerprint(userId);
+        String newVal = mNewImplementation.getDefaultPermissionGrantFingerprint(userId);
+
+        if (Objects.equals(oldVal, Build.FINGERPRINT)
+                != Objects.equals(newVal, Build.FINGERPRINT)) {
+            signalImplDifference("getDefaultPermissionGrantFingerprint");
+        }
+        return newVal;
+    }
+
+    @Override
+    public void setDefaultPermissionGrantFingerprint(@NonNull String fingerprint,
+            @UserIdInt int userId) {
+        mOldImplementation.setDefaultPermissionGrantFingerprint(fingerprint, userId);
+        mNewImplementation.setDefaultPermissionGrantFingerprint(fingerprint, userId);
+    }
+
     @Override
     public void onSystemReady() {
         mOldImplementation.onSystemReady();
diff --git a/services/permission/java/com/android/server/permission/access/AccessPolicy.kt b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
index cbf0d12..44a29e5 100644
--- a/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
@@ -372,6 +372,8 @@
                     forEachTag {
                         when (tagName) {
                             TAG_PACKAGE_VERSIONS -> parsePackageVersions(state, userId)
+                            TAG_DEFAULT_PERMISSION_GRANT ->
+                                parseDefaultPermissionGrant(state, userId)
                             else -> {
                                 forEachSchemePolicy {
                                     with(it) { parseUserState(state, userId) }
@@ -416,12 +418,24 @@
         packageVersions[packageName] = version
     }
 
+    private fun BinaryXmlPullParser.parseDefaultPermissionGrant(
+        state: MutableAccessState,
+        userId: Int
+    ) {
+        val userState = state.mutateUserState(userId, WriteMode.NONE)!!
+        val fingerprint = getAttributeValueOrThrow(ATTR_FINGERPRINT).intern()
+        userState.setDefaultPermissionGrantFingerprint(fingerprint)
+    }
+
     fun BinaryXmlSerializer.serializeUserState(state: AccessState, userId: Int) {
         tag(TAG_ACCESS) {
+            serializePackageVersions(state.userStates[userId]!!.packageVersions)
+            serializeDefaultPermissionGrantFingerprint(
+                state.userStates[userId]!!.defaultPermissionGrantFingerprint
+            )
             forEachSchemePolicy {
                 with(it) { serializeUserState(state, userId) }
             }
-            serializePackageVersions(state.userStates[userId]!!.packageVersions)
         }
     }
 
@@ -438,6 +452,16 @@
         }
     }
 
+    private fun BinaryXmlSerializer.serializeDefaultPermissionGrantFingerprint(
+        fingerprint: String?
+    ) {
+        if (fingerprint != null) {
+            tag(TAG_DEFAULT_PERMISSION_GRANT) {
+                attributeInterned(ATTR_FINGERPRINT, fingerprint)
+            }
+        }
+    }
+
     private fun getSchemePolicy(subject: AccessUri, `object`: AccessUri): SchemePolicy =
         getSchemePolicy(subject.scheme, `object`.scheme)
 
@@ -455,9 +479,11 @@
         internal const val VERSION_LATEST = 14
 
         private const val TAG_ACCESS = "access"
+        private const val TAG_DEFAULT_PERMISSION_GRANT = "default-permission-grant"
         private const val TAG_PACKAGE_VERSIONS = "package-versions"
         private const val TAG_PACKAGE = "package"
 
+        private const val ATTR_FINGERPRINT = "fingerprint"
         private const val ATTR_NAME = "name"
         private const val ATTR_VERSION = "version"
     }
diff --git a/services/permission/java/com/android/server/permission/access/AccessState.kt b/services/permission/java/com/android/server/permission/access/AccessState.kt
index 77c3194..4ec32ea 100644
--- a/services/permission/java/com/android/server/permission/access/AccessState.kt
+++ b/services/permission/java/com/android/server/permission/access/AccessState.kt
@@ -348,6 +348,7 @@
     internal val appIdPermissionFlagsReference: AppIdPermissionFlagsReference,
     internal val appIdAppOpModesReference: AppIdAppOpModesReference,
     internal val packageAppOpModesReference: PackageAppOpModesReference,
+    defaultPermissionGrantFingerprint: String?,
     writeMode: Int
 ) : WritableState, Immutable<MutableUserState> {
     val packageVersions: IndexedMap<String, Int>
@@ -362,6 +363,9 @@
     val packageAppOpModes: PackageAppOpModes
         get() = packageAppOpModesReference.get()
 
+    var defaultPermissionGrantFingerprint: String? = defaultPermissionGrantFingerprint
+        protected set
+
     override var writeMode: Int = writeMode
         protected set
 
@@ -373,12 +377,14 @@
     appIdPermissionFlagsReference: AppIdPermissionFlagsReference,
     appIdAppOpModesReference: AppIdAppOpModesReference,
     packageAppOpModesReference: PackageAppOpModesReference,
+    defaultPermissionGrantFingerprint: String?,
     writeMode: Int
 ) : UserState(
     packageVersionsReference,
     appIdPermissionFlagsReference,
     appIdAppOpModesReference,
     packageAppOpModesReference,
+    defaultPermissionGrantFingerprint,
     writeMode
 ), MutableWritableState {
     constructor() : this(
@@ -386,6 +392,7 @@
         AppIdPermissionFlagsReference(MutableAppIdPermissionFlags()),
         AppIdAppOpModesReference(MutableAppIdAppOpModes()),
         PackageAppOpModesReference(MutablePackageAppOpModes()),
+        null,
         WriteMode.NONE
     )
 
@@ -394,6 +401,7 @@
         userState.appIdPermissionFlagsReference.toImmutable(),
         userState.appIdAppOpModesReference.toImmutable(),
         userState.packageAppOpModesReference.toImmutable(),
+        userState.defaultPermissionGrantFingerprint,
         WriteMode.NONE
     )
 
@@ -406,6 +414,11 @@
 
     fun mutatePackageAppOpModes(): MutablePackageAppOpModes = packageAppOpModesReference.mutate()
 
+    @JvmName("setDefaultPermissionGrantFingerprintPublic")
+    fun setDefaultPermissionGrantFingerprint(defaultPermissionGrantFingerprint: String?) {
+        this.defaultPermissionGrantFingerprint = defaultPermissionGrantFingerprint
+    }
+
     override fun requestWriteMode(writeMode: Int) {
         this.writeMode = maxOf(this.writeMode, writeMode)
     }
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index fa2bccf0..82fe0a4 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -1992,6 +1992,15 @@
 
     override fun writeLegacyPermissionStateTEMP() {}
 
+    override fun getDefaultPermissionGrantFingerprint(userId: Int): String? =
+        service.getState { state.userStates[userId]!!.defaultPermissionGrantFingerprint }
+
+    override fun setDefaultPermissionGrantFingerprint(fingerprint: String, userId: Int) {
+        service.mutateState {
+            newState.mutateUserState(userId)!!.setDefaultPermissionGrantFingerprint(fingerprint)
+        }
+    }
+
     override fun onSystemReady() {
         service.onSystemReady()
         permissionControllerManager = PermissionControllerManager(