summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hai Zhang <zhanghai@google.com> 2020-05-18 16:06:58 -0700
committer Hai Zhang <zhanghai@google.com> 2020-05-18 16:24:15 -0700
commit4c0d15b9588ca194de7857288bae2bc889dc97c2 (patch)
tree51bbba3e068d05b5c122f7bf31d9d3482834bfd8
parentc8cd1ad532a972dc5804c5800afc995b1a794d51 (diff)
Generating missing permission state inside restorePermissionState().
PackageSettings.pkg isn't scanned yet when reading package settings, but the generation needs information about the package, so we need to defer it to restorePermissionState(). Fixes: 156204380 Test: devices boots Change-Id: Id77222b2843395bbba17794a275df641d0d85d63
-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;
}