Loading services/core/java/com/android/server/pm/Settings.java +2 −44 Original line number Diff line number Diff line Loading @@ -5595,10 +5595,7 @@ public final class Settings { userId); } else if (packageSetting.sharedUser == null && !isUpgradeToR) { Slog.w(TAG, "Missing permission state for package: " + packageName); generateFallbackPermissionsStateLpr( packageSetting.pkg.getRequestedPermissions(), packageSetting.pkg.getTargetSdkVersion(), packageSetting.getPermissionsState(), userId); packageSetting.getPermissionsState().setMissing(true, userId); } } Loading @@ -5616,22 +5613,7 @@ public final class Settings { userId); } else if (!isUpgradeToR) { Slog.w(TAG, "Missing permission state for shared user: " + sharedUserName); ArraySet<String> requestedPermissions = new ArraySet<>(); int targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; int sharedUserPackagesSize = sharedUserSetting.packages.size(); for (int packagesI = 0; packagesI < sharedUserPackagesSize; packagesI++) { PackageSetting packageSetting = sharedUserSetting.packages.valueAt( packagesI); if (packageSetting == null || packageSetting.pkg == null || !packageSetting.getInstalled(userId)) { continue; } AndroidPackage pkg = packageSetting.pkg; requestedPermissions.addAll(pkg.getRequestedPermissions()); targetSdkVersion = Math.min(targetSdkVersion, pkg.getTargetSdkVersion()); } generateFallbackPermissionsStateLpr(requestedPermissions, targetSdkVersion, sharedUserSetting.getPermissionsState(), userId); sharedUserSetting.getPermissionsState().setMissing(true, userId); } } } Loading Loading @@ -5663,30 +5645,6 @@ public final class Settings { } } private void generateFallbackPermissionsStateLpr( @NonNull Collection<String> requestedPermissions, int targetSdkVersion, @NonNull PermissionsState permissionsState, @UserIdInt int userId) { for (String permissionName : requestedPermissions) { BasePermission permission = mPermissions.getPermission(permissionName); if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME) && permission.isRuntime() && !permission.isRemoved()) { if (permission.isHardOrSoftRestricted() || permission.isImmutablyRestricted()) { permissionsState.updatePermissionFlags(permission, userId, PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); } if (targetSdkVersion < Build.VERSION_CODES.M) { permissionsState.updatePermissionFlags(permission, userId, PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT); permissionsState.grantRuntimePermission(permission, userId); } } } } @GuardedBy("Settings.this.mLock") private void readLegacyStateForUserSyncLPr(int userId) { File permissionsFile = getUserRuntimePermissionsFile(userId); Loading services/core/java/com/android/server/pm/permission/PermissionManagerService.java +49 −1 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; Loading Loading @@ -2478,13 +2479,60 @@ public class PermissionManagerService extends IPermissionManager.Stub { } final PermissionsState permissionsState = ps.getPermissionsState(); PermissionsState origPermissions = permissionsState; final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); boolean runtimePermissionsRevoked = false; int[] updatedUserIds = EMPTY_INT_ARRAY; for (int userId : currentUserIds) { if (permissionsState.isMissing(userId)) { Collection<String> requestedPermissions; int targetSdkVersion; if (!ps.isSharedUser()) { requestedPermissions = pkg.getRequestedPermissions(); targetSdkVersion = pkg.getTargetSdkVersion(); } else { requestedPermissions = new ArraySet<>(); targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; List<AndroidPackage> packages = ps.getSharedUser().getPackages(); int packagesSize = packages.size(); for (int i = 0; i < packagesSize; i++) { AndroidPackage sharedUserPackage = packages.get(i); requestedPermissions.addAll(sharedUserPackage.getRequestedPermissions()); targetSdkVersion = Math.min(targetSdkVersion, sharedUserPackage.getTargetSdkVersion()); } } for (String permissionName : requestedPermissions) { BasePermission permission = mSettings.getPermission(permissionName); if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME) && permission.isRuntime() && !permission.isRemoved()) { if (permission.isHardOrSoftRestricted() || permission.isImmutablyRestricted()) { permissionsState.updatePermissionFlags(permission, userId, PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); } if (targetSdkVersion < Build.VERSION_CODES.M) { permissionsState.updatePermissionFlags(permission, userId, PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT); permissionsState.grantRuntimePermission(permission, userId); } } } permissionsState.setMissing(false, userId); updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); } } PermissionsState origPermissions = permissionsState; boolean changedInstallPermission = false; if (replace) { Loading services/core/java/com/android/server/pm/permission/PermissionsState.java +57 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.pm.permission; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.pm.PackageManager; import android.os.UserHandle; import android.util.ArrayMap; Loading @@ -30,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; /** Loading Loading @@ -70,6 +73,9 @@ public final class PermissionsState { private int[] mGlobalGids = NO_GIDS; @Nullable private SparseBooleanArray mMissing; private SparseBooleanArray mPermissionReviewRequired; public PermissionsState() { Loading Loading @@ -132,6 +138,23 @@ public final class PermissionsState { other.mGlobalGids.length); } if (mMissing != null) { if (other.mMissing == null) { mMissing = null; } else { mMissing.clear(); } } if (other.mMissing != null) { if (mMissing == null) { mMissing = new SparseBooleanArray(); } final int missingSize = other.mMissing.size(); for (int i = 0; i < missingSize; i++) { mMissing.put(other.mMissing.keyAt(i), other.mMissing.valueAt(i)); } } if (mPermissionReviewRequired != null) { if (other.mPermissionReviewRequired == null) { mPermissionReviewRequired = null; Loading Loading @@ -175,6 +198,10 @@ public final class PermissionsState { } } if (!Objects.equals(mMissing, other.mMissing)) { return false; } if (mPermissionReviewRequired == null) { if (other.mPermissionReviewRequired != null) { return false; Loading @@ -185,6 +212,35 @@ public final class PermissionsState { return Arrays.equals(mGlobalGids, other.mGlobalGids); } /** * Check whether the permissions state is missing for a user. This can happen if permission * state is rolled back and we'll need to generate a reasonable default state to keep the app * usable. */ public boolean isMissing(@UserIdInt int userId) { return mMissing != null && mMissing.get(userId); } /** * Set whether the permissions state is missing for a user. This can happen if permission state * is rolled back and we'll need to generate a reasonable default state to keep the app usable. */ public void setMissing(boolean missing, @UserIdInt int userId) { if (missing) { if (mMissing == null) { mMissing = new SparseBooleanArray(); } mMissing.put(userId, true); } else { if (mMissing != null) { mMissing.delete(userId); if (mMissing.size() == 0) { mMissing = null; } } } } public boolean isPermissionReviewRequired(int userId) { return mPermissionReviewRequired != null && mPermissionReviewRequired.get(userId); } Loading Loading @@ -569,6 +625,7 @@ public final class PermissionsState { invalidateCache(); } mMissing = null; mPermissionReviewRequired = null; } Loading Loading
services/core/java/com/android/server/pm/Settings.java +2 −44 Original line number Diff line number Diff line Loading @@ -5595,10 +5595,7 @@ public final class Settings { userId); } else if (packageSetting.sharedUser == null && !isUpgradeToR) { Slog.w(TAG, "Missing permission state for package: " + packageName); generateFallbackPermissionsStateLpr( packageSetting.pkg.getRequestedPermissions(), packageSetting.pkg.getTargetSdkVersion(), packageSetting.getPermissionsState(), userId); packageSetting.getPermissionsState().setMissing(true, userId); } } Loading @@ -5616,22 +5613,7 @@ public final class Settings { userId); } else if (!isUpgradeToR) { Slog.w(TAG, "Missing permission state for shared user: " + sharedUserName); ArraySet<String> requestedPermissions = new ArraySet<>(); int targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; int sharedUserPackagesSize = sharedUserSetting.packages.size(); for (int packagesI = 0; packagesI < sharedUserPackagesSize; packagesI++) { PackageSetting packageSetting = sharedUserSetting.packages.valueAt( packagesI); if (packageSetting == null || packageSetting.pkg == null || !packageSetting.getInstalled(userId)) { continue; } AndroidPackage pkg = packageSetting.pkg; requestedPermissions.addAll(pkg.getRequestedPermissions()); targetSdkVersion = Math.min(targetSdkVersion, pkg.getTargetSdkVersion()); } generateFallbackPermissionsStateLpr(requestedPermissions, targetSdkVersion, sharedUserSetting.getPermissionsState(), userId); sharedUserSetting.getPermissionsState().setMissing(true, userId); } } } Loading Loading @@ -5663,30 +5645,6 @@ public final class Settings { } } private void generateFallbackPermissionsStateLpr( @NonNull Collection<String> requestedPermissions, int targetSdkVersion, @NonNull PermissionsState permissionsState, @UserIdInt int userId) { for (String permissionName : requestedPermissions) { BasePermission permission = mPermissions.getPermission(permissionName); if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME) && permission.isRuntime() && !permission.isRemoved()) { if (permission.isHardOrSoftRestricted() || permission.isImmutablyRestricted()) { permissionsState.updatePermissionFlags(permission, userId, PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); } if (targetSdkVersion < Build.VERSION_CODES.M) { permissionsState.updatePermissionFlags(permission, userId, PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT); permissionsState.grantRuntimePermission(permission, userId); } } } } @GuardedBy("Settings.this.mLock") private void readLegacyStateForUserSyncLPr(int userId) { File permissionsFile = getUserRuntimePermissionsFile(userId); Loading
services/core/java/com/android/server/pm/permission/PermissionManagerService.java +49 −1 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; Loading Loading @@ -2478,13 +2479,60 @@ public class PermissionManagerService extends IPermissionManager.Stub { } final PermissionsState permissionsState = ps.getPermissionsState(); PermissionsState origPermissions = permissionsState; final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); boolean runtimePermissionsRevoked = false; int[] updatedUserIds = EMPTY_INT_ARRAY; for (int userId : currentUserIds) { if (permissionsState.isMissing(userId)) { Collection<String> requestedPermissions; int targetSdkVersion; if (!ps.isSharedUser()) { requestedPermissions = pkg.getRequestedPermissions(); targetSdkVersion = pkg.getTargetSdkVersion(); } else { requestedPermissions = new ArraySet<>(); targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; List<AndroidPackage> packages = ps.getSharedUser().getPackages(); int packagesSize = packages.size(); for (int i = 0; i < packagesSize; i++) { AndroidPackage sharedUserPackage = packages.get(i); requestedPermissions.addAll(sharedUserPackage.getRequestedPermissions()); targetSdkVersion = Math.min(targetSdkVersion, sharedUserPackage.getTargetSdkVersion()); } } for (String permissionName : requestedPermissions) { BasePermission permission = mSettings.getPermission(permissionName); if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME) && permission.isRuntime() && !permission.isRemoved()) { if (permission.isHardOrSoftRestricted() || permission.isImmutablyRestricted()) { permissionsState.updatePermissionFlags(permission, userId, PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); } if (targetSdkVersion < Build.VERSION_CODES.M) { permissionsState.updatePermissionFlags(permission, userId, PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT); permissionsState.grantRuntimePermission(permission, userId); } } } permissionsState.setMissing(false, userId); updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); } } PermissionsState origPermissions = permissionsState; boolean changedInstallPermission = false; if (replace) { Loading
services/core/java/com/android/server/pm/permission/PermissionsState.java +57 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.pm.permission; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.pm.PackageManager; import android.os.UserHandle; import android.util.ArrayMap; Loading @@ -30,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; /** Loading Loading @@ -70,6 +73,9 @@ public final class PermissionsState { private int[] mGlobalGids = NO_GIDS; @Nullable private SparseBooleanArray mMissing; private SparseBooleanArray mPermissionReviewRequired; public PermissionsState() { Loading Loading @@ -132,6 +138,23 @@ public final class PermissionsState { other.mGlobalGids.length); } if (mMissing != null) { if (other.mMissing == null) { mMissing = null; } else { mMissing.clear(); } } if (other.mMissing != null) { if (mMissing == null) { mMissing = new SparseBooleanArray(); } final int missingSize = other.mMissing.size(); for (int i = 0; i < missingSize; i++) { mMissing.put(other.mMissing.keyAt(i), other.mMissing.valueAt(i)); } } if (mPermissionReviewRequired != null) { if (other.mPermissionReviewRequired == null) { mPermissionReviewRequired = null; Loading Loading @@ -175,6 +198,10 @@ public final class PermissionsState { } } if (!Objects.equals(mMissing, other.mMissing)) { return false; } if (mPermissionReviewRequired == null) { if (other.mPermissionReviewRequired != null) { return false; Loading @@ -185,6 +212,35 @@ public final class PermissionsState { return Arrays.equals(mGlobalGids, other.mGlobalGids); } /** * Check whether the permissions state is missing for a user. This can happen if permission * state is rolled back and we'll need to generate a reasonable default state to keep the app * usable. */ public boolean isMissing(@UserIdInt int userId) { return mMissing != null && mMissing.get(userId); } /** * Set whether the permissions state is missing for a user. This can happen if permission state * is rolled back and we'll need to generate a reasonable default state to keep the app usable. */ public void setMissing(boolean missing, @UserIdInt int userId) { if (missing) { if (mMissing == null) { mMissing = new SparseBooleanArray(); } mMissing.put(userId, true); } else { if (mMissing != null) { mMissing.delete(userId); if (mMissing.size() == 0) { mMissing = null; } } } } public boolean isPermissionReviewRequired(int userId) { return mPermissionReviewRequired != null && mPermissionReviewRequired.get(userId); } Loading Loading @@ -569,6 +625,7 @@ public final class PermissionsState { invalidateCache(); } mMissing = null; mPermissionReviewRequired = null; } Loading