summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/Settings.java46
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java50
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionsState.java57
3 files changed, 108 insertions, 45 deletions
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 9de34a92cdf7..a5b1bf98cdb7 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -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);
}
}
@@ -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);
}
}
}
@@ -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);
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 7d49f788c063..567a3b6ae227 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -154,6 +154,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;
@@ -2473,13 +2474,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) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java
index 11e29a02068c..bad59cb1b567 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionsState.java
@@ -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;
@@ -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;
/**
@@ -70,6 +73,9 @@ public final class PermissionsState {
private int[] mGlobalGids = NO_GIDS;
+ @Nullable
+ private SparseBooleanArray mMissing;
+
private SparseBooleanArray mPermissionReviewRequired;
public PermissionsState() {
@@ -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;
@@ -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;
@@ -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);
}
@@ -569,6 +625,7 @@ public final class PermissionsState {
invalidateCache();
}
+ mMissing = null;
mPermissionReviewRequired = null;
}