summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java71
1 files changed, 56 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index cc369356c1c9..9026262db897 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -127,9 +127,11 @@ public abstract class SoftRestrictedPermissionPolicy {
final boolean isWhiteListed;
boolean shouldApplyRestriction;
final int targetSDK;
+ final boolean hasLegacyExternalStorage;
final boolean hasRequestedLegacyExternalStorage;
- final boolean shouldPreserveLegacyExternalStorage;
+ final boolean hasRequestedPreserveLegacyExternalStorage;
final boolean hasWriteMediaStorageGrantedForUid;
+ final boolean isForcedScopedStorage;
if (appInfo != null) {
PackageManager pm = context.getPackageManager();
@@ -137,27 +139,27 @@ public abstract class SoftRestrictedPermissionPolicy {
LocalServices.getService(StorageManagerInternal.class);
int flags = pm.getPermissionFlags(permission, appInfo.packageName, user);
isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
+ hasLegacyExternalStorage = smInternal.hasLegacyExternalStorage(appInfo.uid);
hasRequestedLegacyExternalStorage = hasUidRequestedLegacyExternalStorage(
appInfo.uid, context);
hasWriteMediaStorageGrantedForUid = hasWriteMediaStorageGrantedForUid(
appInfo.uid, context);
- shouldPreserveLegacyExternalStorage = pkg.hasPreserveLegacyExternalStorage()
- && smInternal.hasLegacyExternalStorage(appInfo.uid);
+ hasRequestedPreserveLegacyExternalStorage =
+ pkg.hasPreserveLegacyExternalStorage();
targetSDK = getMinimumTargetSDK(context, appInfo, user);
- shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0
- || (targetSDK > Build.VERSION_CODES.Q
- && !shouldPreserveLegacyExternalStorage)
- // If the device is configured to force this app into scoped storage,
- // then we should apply the restriction
- || sForcedScopedStorageAppWhitelist.contains(appInfo.packageName);
+ shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+ isForcedScopedStorage = sForcedScopedStorageAppWhitelist
+ .contains(appInfo.packageName);
} else {
isWhiteListed = false;
shouldApplyRestriction = false;
targetSDK = 0;
+ hasLegacyExternalStorage = false;
hasRequestedLegacyExternalStorage = false;
- shouldPreserveLegacyExternalStorage = false;
+ hasRequestedPreserveLegacyExternalStorage = false;
hasWriteMediaStorageGrantedForUid = false;
+ isForcedScopedStorage = false;
}
// We have a check in PermissionPolicyService.PermissionToOpSynchroniser.setUidMode
@@ -175,14 +177,53 @@ public abstract class SoftRestrictedPermissionPolicy {
}
@Override
public boolean mayAllowExtraAppOp() {
- return !shouldApplyRestriction
- && (hasRequestedLegacyExternalStorage
- || hasWriteMediaStorageGrantedForUid
- || shouldPreserveLegacyExternalStorage);
+ // The only way to get LEGACY_STORAGE (if you didn't already have it)
+ // is that all of the following must be true:
+ // 1. The flag shouldn't be restricted
+ if (shouldApplyRestriction) {
+ return false;
+ }
+
+ // 2. The app shouldn't be in sForcedScopedStorageAppWhitelist
+ if (isForcedScopedStorage) {
+ return false;
+ }
+
+ // 3. The app has WRITE_MEDIA_STORAGE, OR
+ // the app already has legacy external storage or requested it,
+ // and is < R.
+ return hasWriteMediaStorageGrantedForUid
+ || ((hasLegacyExternalStorage || hasRequestedLegacyExternalStorage)
+ && targetSDK < Build.VERSION_CODES.R);
}
@Override
public boolean mayDenyExtraAppOpIfGranted() {
- return shouldApplyRestriction;
+ // If you're an app targeting < R, you can keep the app op for
+ // as long as you meet the conditions required to acquire it.
+ if (targetSDK < Build.VERSION_CODES.R) {
+ return !mayAllowExtraAppOp();
+ }
+
+ // For an app targeting R, the only way to lose LEGACY_STORAGE if you
+ // already had it is in one or more of the following conditions:
+ // 1. The flag became restricted
+ if (shouldApplyRestriction) {
+ return true;
+ }
+
+ // The package is now a part of the forced scoped storage whitelist
+ if (isForcedScopedStorage) {
+ return true;
+ }
+
+ // The package doesn't have WRITE_MEDIA_STORAGE,
+ // AND didn't request legacy storage to be preserved
+ if (!hasWriteMediaStorageGrantedForUid
+ && !hasRequestedPreserveLegacyExternalStorage) {
+ return true;
+ }
+
+ return false;
}
};
}