Loading core/java/android/os/Environment.java +42 −20 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ 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 @@ -88,6 +89,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 @@ -1191,12 +1202,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 @@ -1207,12 +1219,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 @@ -1232,24 +1245,23 @@ public class Environment { return false; } if (packageManager.checkPermission(Manifest.permission.WRITE_MEDIA_STORAGE, context.getPackageName()) == PackageManager.PERMISSION_GRANTED) { return true; } if (packageManager.checkPermission(Manifest.permission.INSTALL_PACKAGES, 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; } 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) { // 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); return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED; } Loading Loading @@ -1298,6 +1310,16 @@ public class Environment { } } private static boolean isScopedStorageEnforced(boolean defaultScopedStorage, boolean forceEnableScopedStorage) { return defaultScopedStorage && forceEnableScopedStorage; } 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 +42 −20 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ 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 @@ -88,6 +89,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 @@ -1191,12 +1202,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 @@ -1207,12 +1219,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 @@ -1232,24 +1245,23 @@ public class Environment { return false; } if (packageManager.checkPermission(Manifest.permission.WRITE_MEDIA_STORAGE, context.getPackageName()) == PackageManager.PERMISSION_GRANTED) { return true; } if (packageManager.checkPermission(Manifest.permission.INSTALL_PACKAGES, 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; } 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) { // 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); return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED; } Loading Loading @@ -1298,6 +1310,16 @@ public class Environment { } } private static boolean isScopedStorageEnforced(boolean defaultScopedStorage, boolean forceEnableScopedStorage) { return defaultScopedStorage && forceEnableScopedStorage; } 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