Merge "Generating missing permission state inside restorePermissionState()." into rvc-dev am: e0f524be6f

Change-Id: I49d9c26bafedd7d0b9eb72cfce641a6fb85b00c6
This commit is contained in:
Hai Zhang
2020-05-19 22:11:37 +00:00
committed by Automerger Merge Worker
3 changed files with 108 additions and 45 deletions

View File

@@ -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);

View File

@@ -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;
@@ -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) {

View File

@@ -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;
}