Loading core/java/android/os/Environment.java +43 −21 Original line number Diff line number Diff line Loading @@ -16,13 +16,13 @@ package android.os; import android.Manifest; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.compat.Compatibility; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; Loading Loading @@ -87,6 +87,16 @@ public class Environment { private static final File DIR_APEX_ROOT = getDirectory(ENV_APEX_ROOT, "/apex"); /** * See definition in com.android.providers.media.LocalCallingIdentity */ private static final long DEFAULT_SCOPED_STORAGE = 149924527L; /** * See definition in com.android.providers.media.LocalCallingIdentity */ private static final long FORCE_ENABLE_SCOPED_STORAGE = 132649864L; @UnsupportedAppUsage private static UserEnvironment sCurrentUser; private static boolean sUserRequired; Loading Loading @@ -1190,12 +1200,13 @@ public class Environment { } /** * Returns whether the primary shared/external storage media is a legacy * view that includes files not owned by the app. * Returns whether the shared/external storage media is a * legacy view that includes files not owned by the app. * <p> * This value may be different from the value requested by * {@code requestLegacyExternalStorage} in the app's manifest, since an app * may inherit its legacy state based on when it was first installed. * may inherit its legacy state based on when it was first installed, target sdk and other * factors. * <p> * Non-legacy apps can continue to discover and read media belonging to * other apps via {@link android.provider.MediaStore}. Loading @@ -1206,12 +1217,13 @@ public class Environment { } /** * Returns whether the shared/external storage media at the given path is a * Returns whether the shared/external storage media is a * legacy view that includes files not owned by the app. * <p> * This value may be different from the value requested by * {@code requestLegacyExternalStorage} in the app's manifest, since an app * may inherit its legacy state based on when it was first installed. * may inherit its legacy state based on when it was first installed, target sdk and other * factors. * <p> * Non-legacy apps can continue to discover and read media belonging to * other apps via {@link android.provider.MediaStore}. Loading @@ -1231,28 +1243,38 @@ public class Environment { return false; } if (packageManager.checkPermission(Manifest.permission.WRITE_MEDIA_STORAGE, context.getPackageName()) == PackageManager.PERMISSION_GRANTED) { return true; // TODO(b/150672994): Compat flags do not override instant app and isolated process's // behavior. boolean defaultScopedStorage = Compatibility.isChangeEnabled(DEFAULT_SCOPED_STORAGE); boolean forceEnableScopedStorage = Compatibility.isChangeEnabled( FORCE_ENABLE_SCOPED_STORAGE); // if Scoped Storage is strictly enforced, the app does *not* have legacy storage access // Note: does not require packagename/uid as this is directly called from an app process if (isScopedStorageEnforced(defaultScopedStorage, forceEnableScopedStorage)) { return false; } if (packageManager.checkPermission(Manifest.permission.INSTALL_PACKAGES, context.getPackageName()) == PackageManager.PERMISSION_GRANTED) { // if Scoped Storage is strictly disabled, the app has legacy storage access // Note: does not require packagename/uid as this is directly called from an app process if (isScopedStorageDisabled(defaultScopedStorage, forceEnableScopedStorage)) { return true; } final AppOpsManager appOps = context.getSystemService(AppOpsManager.class); final String[] packagesForUid = packageManager.getPackagesForUid(uid); for (String packageName : packagesForUid) { if (appOps.checkOpNoThrow(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, uid, packageName) == AppOpsManager.MODE_ALLOWED) { return true; return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED; } private static boolean isScopedStorageEnforced(boolean defaultScopedStorage, boolean forceEnableScopedStorage) { return defaultScopedStorage && forceEnableScopedStorage; } return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED; private static boolean isScopedStorageDisabled(boolean defaultScopedStorage, boolean forceEnableScopedStorage) { return !defaultScopedStorage && !forceEnableScopedStorage; } static File getDirectory(String variableName, String defaultPath) { String path = System.getenv(variableName); return path == null ? new File(defaultPath) : new File(path); Loading Loading
core/java/android/os/Environment.java +43 −21 Original line number Diff line number Diff line Loading @@ -16,13 +16,13 @@ package android.os; import android.Manifest; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.compat.Compatibility; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; Loading Loading @@ -87,6 +87,16 @@ public class Environment { private static final File DIR_APEX_ROOT = getDirectory(ENV_APEX_ROOT, "/apex"); /** * See definition in com.android.providers.media.LocalCallingIdentity */ private static final long DEFAULT_SCOPED_STORAGE = 149924527L; /** * See definition in com.android.providers.media.LocalCallingIdentity */ private static final long FORCE_ENABLE_SCOPED_STORAGE = 132649864L; @UnsupportedAppUsage private static UserEnvironment sCurrentUser; private static boolean sUserRequired; Loading Loading @@ -1190,12 +1200,13 @@ public class Environment { } /** * Returns whether the primary shared/external storage media is a legacy * view that includes files not owned by the app. * Returns whether the shared/external storage media is a * legacy view that includes files not owned by the app. * <p> * This value may be different from the value requested by * {@code requestLegacyExternalStorage} in the app's manifest, since an app * may inherit its legacy state based on when it was first installed. * may inherit its legacy state based on when it was first installed, target sdk and other * factors. * <p> * Non-legacy apps can continue to discover and read media belonging to * other apps via {@link android.provider.MediaStore}. Loading @@ -1206,12 +1217,13 @@ public class Environment { } /** * Returns whether the shared/external storage media at the given path is a * Returns whether the shared/external storage media is a * legacy view that includes files not owned by the app. * <p> * This value may be different from the value requested by * {@code requestLegacyExternalStorage} in the app's manifest, since an app * may inherit its legacy state based on when it was first installed. * may inherit its legacy state based on when it was first installed, target sdk and other * factors. * <p> * Non-legacy apps can continue to discover and read media belonging to * other apps via {@link android.provider.MediaStore}. Loading @@ -1231,28 +1243,38 @@ public class Environment { return false; } if (packageManager.checkPermission(Manifest.permission.WRITE_MEDIA_STORAGE, context.getPackageName()) == PackageManager.PERMISSION_GRANTED) { return true; // TODO(b/150672994): Compat flags do not override instant app and isolated process's // behavior. boolean defaultScopedStorage = Compatibility.isChangeEnabled(DEFAULT_SCOPED_STORAGE); boolean forceEnableScopedStorage = Compatibility.isChangeEnabled( FORCE_ENABLE_SCOPED_STORAGE); // if Scoped Storage is strictly enforced, the app does *not* have legacy storage access // Note: does not require packagename/uid as this is directly called from an app process if (isScopedStorageEnforced(defaultScopedStorage, forceEnableScopedStorage)) { return false; } if (packageManager.checkPermission(Manifest.permission.INSTALL_PACKAGES, context.getPackageName()) == PackageManager.PERMISSION_GRANTED) { // if Scoped Storage is strictly disabled, the app has legacy storage access // Note: does not require packagename/uid as this is directly called from an app process if (isScopedStorageDisabled(defaultScopedStorage, forceEnableScopedStorage)) { return true; } final AppOpsManager appOps = context.getSystemService(AppOpsManager.class); final String[] packagesForUid = packageManager.getPackagesForUid(uid); for (String packageName : packagesForUid) { if (appOps.checkOpNoThrow(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES, uid, packageName) == AppOpsManager.MODE_ALLOWED) { return true; return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED; } private static boolean isScopedStorageEnforced(boolean defaultScopedStorage, boolean forceEnableScopedStorage) { return defaultScopedStorage && forceEnableScopedStorage; } return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED; private static boolean isScopedStorageDisabled(boolean defaultScopedStorage, boolean forceEnableScopedStorage) { return !defaultScopedStorage && !forceEnableScopedStorage; } static File getDirectory(String variableName, String defaultPath) { String path = System.getenv(variableName); return path == null ? new File(defaultPath) : new File(path); Loading