From 27c631b50a9544fd7097d5556eb290fbc27acd9e Mon Sep 17 00:00:00 2001 From: Manjeet Rulhania Date: Mon, 27 Feb 2023 20:06:42 -0800 Subject: [PATCH] Read permissions state from pm/Settings adding ag/21644247 back (was reverted due to test failures) Permissions are written to disk asynchronously, when migrated in pm/Settings.java. New permission subsystem should read it from settings instead of disk during migration. Bug: 266163862 Test: manual Change-Id: I0373a82037f1cdcd9247a26ce729c9a8566f59f0 --- .../content/pm/PackageManagerInternal.java | 8 ++ .../server/pm/PackageManagerService.java | 11 ++ .../java/com/android/server/pm/Settings.java | 103 ++++++++++++------ .../PermissionMigrationHelperImpl.java | 13 +-- 4 files changed, 94 insertions(+), 41 deletions(-) diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index b673fb6010eab..97af17dc2e8b3 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -44,6 +44,7 @@ import android.util.ArraySet; import android.util.SparseArray; import com.android.internal.util.function.pooled.PooledLambda; +import com.android.permission.persistence.RuntimePermissionsState; import com.android.server.pm.Installer.LegacyDexoptDisabledException; import com.android.server.pm.KnownPackages; import com.android.server.pm.PackageList; @@ -1077,9 +1078,16 @@ public abstract class PackageManagerInternal { /** * Read legacy permission definitions for permissions migration to new permission subsystem. + * Note that this api is supposed to be used for permissions migration only. */ public abstract LegacyPermissionSettings getLegacyPermissions(); + /** + * Read legacy permission states for permissions migration to new permission subsystem. + * Note that this api is supposed to be used for permissions state migration only. + */ + public abstract RuntimePermissionsState getLegacyPermissionsState(@UserIdInt int userId); + /** * Returns {@code true} if the caller is the installer of record for the given package. * Otherwise, {@code false}. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 47e0edffb246e..a6d2b39df24f9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -188,6 +188,7 @@ import com.android.internal.util.Preconditions; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import com.android.permission.persistence.RuntimePermissionsPersistence; +import com.android.permission.persistence.RuntimePermissionsState; import com.android.server.EventLogTags; import com.android.server.FgThread; import com.android.server.LocalManagerRegistry; @@ -6747,6 +6748,16 @@ public class PackageManagerService implements PackageSender, TestUtilityService } } + /** + * Read legacy permission states for permissions migration to new permission subsystem. + */ + @Override + public RuntimePermissionsState getLegacyPermissionsState(int userId) { + synchronized (mLock) { + return mSettings.getLegacyPermissionsState(userId); + } + } + @Override @SuppressWarnings("GuardedBy") public boolean isPermissionUpgradeNeeded(int userId) { diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 770360167eea9..65e93fa62c729 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -3292,6 +3292,11 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile mPackages, mSharedUsers, getUserRuntimePermissionsFile(userId)); } + RuntimePermissionsState getLegacyPermissionsState(@UserIdInt int userId) { + return mRuntimePermissionsPersistence.getLegacyPermissionsState( + userId, mPackages, mSharedUsers); + } + void applyDefaultPreferredAppsLPw(int userId) { // First pull data from any pre-installed apps. final PackageManagerInternal pmInternal = @@ -5726,44 +5731,16 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile Runnable writer = () -> { boolean isLegacyPermissionStateStale = mIsLegacyPermissionStateStale.getAndSet( false); + Map> packagePermissions; + Map> sharedUserPermissions; - final Map> - packagePermissions = new ArrayMap<>(); - final Map> - sharedUserPermissions = new ArrayMap<>(); synchronized (pmLock) { if (sync || isLegacyPermissionStateStale) { legacyPermissionDataProvider.writeLegacyPermissionStateTEMP(); } - int packagesSize = packageStates.size(); - for (int i = 0; i < packagesSize; i++) { - String packageName = packageStates.keyAt(i); - PackageStateInternal packageState = packageStates.valueAt(i); - if (!packageState.hasSharedUser()) { - List permissions = - getPermissionsFromPermissionsState( - packageState.getLegacyPermissionState(), userId); - if (permissions.isEmpty() - && !packageState.isInstallPermissionsFixed()) { - // Storing an empty state means the package is known to the - // system and its install permissions have been granted and fixed. - // If this is not the case, we should not store anything. - continue; - } - packagePermissions.put(packageName, permissions); - } - } - - final int sharedUsersSize = sharedUsers.size(); - for (int i = 0; i < sharedUsersSize; i++) { - String sharedUserName = sharedUsers.keyAt(i); - SharedUserSetting sharedUserSetting = sharedUsers.valueAt(i); - List permissions = - getPermissionsFromPermissionsState( - sharedUserSetting.getLegacyPermissionState(), userId); - sharedUserPermissions.put(sharedUserName, permissions); - } + packagePermissions = getPackagePermissions(userId, packageStates); + sharedUserPermissions = getShareUsersPermissions(userId, sharedUsers); } synchronized (mLock) { int version = mVersions.get(userId, INITIAL_VERSION); @@ -5791,6 +5768,68 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile } } + @NonNull + RuntimePermissionsState getLegacyPermissionsState(int userId, + @NonNull WatchedArrayMap packageStates, + @NonNull WatchedArrayMap sharedUsers) { + int version; + String fingerprint; + synchronized (mLock) { + version = mVersions.get(userId, INITIAL_VERSION); + fingerprint = mFingerprints.get(userId); + } + + return new RuntimePermissionsState( + version, fingerprint, getPackagePermissions(userId, packageStates), + getShareUsersPermissions(userId, sharedUsers)); + } + + @NonNull + private Map> getPackagePermissions( + int userId, + @NonNull WatchedArrayMap packageStates) { + final Map> + packagePermissions = new ArrayMap<>(); + + final int packagesSize = packageStates.size(); + for (int i = 0; i < packagesSize; i++) { + String packageName = packageStates.keyAt(i); + PackageStateInternal packageState = packageStates.valueAt(i); + if (!packageState.hasSharedUser()) { + List permissions = + getPermissionsFromPermissionsState( + packageState.getLegacyPermissionState(), userId); + if (permissions.isEmpty() + && !packageState.isInstallPermissionsFixed()) { + // Storing an empty state means the package is known to the + // system and its install permissions have been granted and fixed. + // If this is not the case, we should not store anything. + continue; + } + packagePermissions.put(packageName, permissions); + } + } + return packagePermissions; + } + + @NonNull + private Map> getShareUsersPermissions( + int userId, @NonNull WatchedArrayMap sharedUsers) { + final Map> + sharedUserPermissions = new ArrayMap<>(); + + final int sharedUsersSize = sharedUsers.size(); + for (int i = 0; i < sharedUsersSize; i++) { + String sharedUserName = sharedUsers.keyAt(i); + SharedUserSetting sharedUserSetting = sharedUsers.valueAt(i); + List permissions = + getPermissionsFromPermissionsState( + sharedUserSetting.getLegacyPermissionState(), userId); + sharedUserPermissions.put(sharedUserName, permissions); + } + return sharedUserPermissions; + } + private void writePendingStates() { while (true) { final RuntimePermissionsState runtimePermissions; diff --git a/services/core/java/com/android/server/pm/permission/PermissionMigrationHelperImpl.java b/services/core/java/com/android/server/pm/permission/PermissionMigrationHelperImpl.java index 1282b6ad0a484..60ac0b06abdef 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionMigrationHelperImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionMigrationHelperImpl.java @@ -18,11 +18,9 @@ package com.android.server.pm.permission; import android.annotation.NonNull; import android.content.pm.PackageManagerInternal; -import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; -import com.android.permission.persistence.RuntimePermissionsPersistence; import com.android.permission.persistence.RuntimePermissionsState; import com.android.server.LocalManagerRegistry; import com.android.server.LocalServices; @@ -81,15 +79,12 @@ public class PermissionMigrationHelperImpl implements PermissionMigrationHelper */ @NonNull public Map> getLegacyPermissionStates(int userId) { - RuntimePermissionsPersistence legacyPersistence = - RuntimePermissionsPersistence.createInstance(); + PackageManagerInternal mPackageManagerInternal = + LocalServices.getService(PackageManagerInternal.class); Map> appIdPermissionStates = new ArrayMap<>(); - RuntimePermissionsState legacyState = legacyPersistence.readForUser(UserHandle.of(userId)); - if (legacyState == null) { - return appIdPermissionStates; - } - + RuntimePermissionsState legacyState = + mPackageManagerInternal.getLegacyPermissionsState(userId); PackageManagerLocal packageManagerLocal = LocalManagerRegistry.getManager(PackageManagerLocal.class);