Loading api/current.txt +5 −2 Original line number Diff line number Diff line Loading @@ -291,6 +291,7 @@ package android { field public static final int allowBackup = 16843392; // 0x1010280 field public static final int allowClearUserData = 16842757; // 0x1010005 field public static final int allowEmbedded = 16843765; // 0x10103f5 field public static final int allowExternalStorageSandbox = 16844201; // 0x10105a9 field public static final int allowParallelSyncs = 16843570; // 0x1010332 field public static final int allowSingleTap = 16843353; // 0x1010259 field public static final int allowTaskReparenting = 16843268; // 0x1010204 Loading Loading @@ -34659,9 +34660,11 @@ package android.os { method @NonNull public static java.io.File getRootDirectory(); method @Deprecated public static String getStorageState(java.io.File); method public static boolean isExternalStorageEmulated(); method public static boolean isExternalStorageEmulated(java.io.File); method public static boolean isExternalStorageEmulated(@NonNull java.io.File); method public static boolean isExternalStorageRemovable(); method public static boolean isExternalStorageRemovable(java.io.File); method public static boolean isExternalStorageRemovable(@NonNull java.io.File); method public static boolean isExternalStorageSandboxed(); method public static boolean isExternalStorageSandboxed(@NonNull java.io.File); field public static String DIRECTORY_ALARMS; field public static String DIRECTORY_AUDIOBOOKS; field public static String DIRECTORY_DCIM; core/java/android/content/pm/ApplicationInfo.java +20 −1 Original line number Diff line number Diff line Loading @@ -678,6 +678,14 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_IS_RESOURCE_OVERLAY = 1 << 28; /** * Value for {@link #privateFlags}: If {@code true} this app allows * shared/external storage media to be a sandboxed view that only contains * files owned by the app. * * @hide */ public static final int PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX = 1 << 29; /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = { Loading Loading @@ -707,7 +715,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { PRIVATE_FLAG_VIRTUAL_PRELOAD, PRIVATE_FLAG_HAS_FRAGILE_USER_DATA, PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE, PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE, PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX, }) @Retention(RetentionPolicy.SOURCE) public @interface ApplicationInfoPrivateFlags {} Loading Loading @@ -1822,6 +1831,16 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return (privateFlags & PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE) != 0; } /** * If {@code true} this app allows shared/external storage media to be a * sandboxed view that only contains files owned by the app. * * @hide */ public boolean isExternalStorageSandboxAllowed() { return (privateFlags & PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX) != 0; } private boolean isAllowedToUseHiddenApis() { if (isSignedWithPlatformKey()) { return true; Loading core/java/android/content/pm/PackageParser.java +6 −0 Original line number Diff line number Diff line Loading @@ -3689,6 +3689,12 @@ public class PackageParser { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE; } if (sa.getBoolean( R.styleable.AndroidManifestApplication_allowExternalStorageSandbox, owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q)) { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX; } ai.maxAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0); ai.minAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_minAspectRatio, 0); Loading core/java/android/os/Environment.java +42 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.os.storage.StorageManager; Loading Loading @@ -1060,7 +1062,7 @@ public class Environment { * @throws IllegalArgumentException if the path is not a valid storage * device. */ public static boolean isExternalStorageRemovable(File path) { public static boolean isExternalStorageRemovable(@NonNull File path) { final StorageVolume volume = StorageManager.getStorageVolume(path, UserHandle.myUserId()); if (volume != null) { return volume.isRemovable(); Loading Loading @@ -1103,7 +1105,7 @@ public class Environment { * @throws IllegalArgumentException if the path is not a valid storage * device. */ public static boolean isExternalStorageEmulated(File path) { public static boolean isExternalStorageEmulated(@NonNull File path) { final StorageVolume volume = StorageManager.getStorageVolume(path, UserHandle.myUserId()); if (volume != null) { return volume.isEmulated(); Loading @@ -1112,6 +1114,44 @@ public class Environment { } } /** * Returns whether the shared/external storage media at the given path is a * sandboxed view that only contains files owned by the app. * <p> * This value may be different from the value requested by * {@code allowExternalStorageSandbox} in the app's manifest, since an app * may inherit its sandboxed state based on when it was first installed. * <p> * Sandboxed apps can continue to discover and read media belonging to other * apps via {@link android.provider.MediaStore}. */ public static boolean isExternalStorageSandboxed() { final File externalDir = sCurrentUser.getExternalDirs()[0]; return isExternalStorageSandboxed(externalDir); } /** * Returns whether the shared/external storage media at the given path is a * sandboxed view that only contains files owned by the app. * <p> * This value may be different from the value requested by * {@code allowExternalStorageSandbox} in the app's manifest, since an app * may inherit its sandboxed state based on when it was first installed. * <p> * Sandboxed apps can continue to discover and read media belonging to other * apps via {@link android.provider.MediaStore}. * * @throws IllegalArgumentException if the path is not a valid storage * device. */ public static boolean isExternalStorageSandboxed(@NonNull File path) { final Context context = AppGlobals.getInitialApplication(); final AppOpsManager appOps = context.getSystemService(AppOpsManager.class); return appOps.noteOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, context.getApplicationInfo().uid, context.getPackageName()) != AppOpsManager.MODE_ALLOWED; } static File getDirectory(String variableName, String defaultPath) { String path = System.getenv(variableName); return path == null ? new File(defaultPath) : new File(path); Loading core/res/res/values/attrs_manifest.xml +11 −0 Original line number Diff line number Diff line Loading @@ -1687,6 +1687,17 @@ - {@code false} for apps with targetSdkVersion < 29. --> <attr name="allowAudioPlaybackCapture" format="boolean" /> <!-- If {@code true} this app allows shared/external storage media to be a sandboxed view that only contains files owned by the app. <p> Sandboxed apps can continue to discover and read media belonging to other apps via {@code MediaStore}. <p> The default value is: - {@code true} for apps with targetSdkVersion >= 29 (Q). - {@code false} for apps with targetSdkVersion < 29. --> <attr name="allowExternalStorageSandbox" format="boolean" /> </declare-styleable> <!-- The <code>permission</code> tag declares a security permission that can be used to control access from other packages to specific components or Loading Loading
api/current.txt +5 −2 Original line number Diff line number Diff line Loading @@ -291,6 +291,7 @@ package android { field public static final int allowBackup = 16843392; // 0x1010280 field public static final int allowClearUserData = 16842757; // 0x1010005 field public static final int allowEmbedded = 16843765; // 0x10103f5 field public static final int allowExternalStorageSandbox = 16844201; // 0x10105a9 field public static final int allowParallelSyncs = 16843570; // 0x1010332 field public static final int allowSingleTap = 16843353; // 0x1010259 field public static final int allowTaskReparenting = 16843268; // 0x1010204 Loading Loading @@ -34659,9 +34660,11 @@ package android.os { method @NonNull public static java.io.File getRootDirectory(); method @Deprecated public static String getStorageState(java.io.File); method public static boolean isExternalStorageEmulated(); method public static boolean isExternalStorageEmulated(java.io.File); method public static boolean isExternalStorageEmulated(@NonNull java.io.File); method public static boolean isExternalStorageRemovable(); method public static boolean isExternalStorageRemovable(java.io.File); method public static boolean isExternalStorageRemovable(@NonNull java.io.File); method public static boolean isExternalStorageSandboxed(); method public static boolean isExternalStorageSandboxed(@NonNull java.io.File); field public static String DIRECTORY_ALARMS; field public static String DIRECTORY_AUDIOBOOKS; field public static String DIRECTORY_DCIM;
core/java/android/content/pm/ApplicationInfo.java +20 −1 Original line number Diff line number Diff line Loading @@ -678,6 +678,14 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_IS_RESOURCE_OVERLAY = 1 << 28; /** * Value for {@link #privateFlags}: If {@code true} this app allows * shared/external storage media to be a sandboxed view that only contains * files owned by the app. * * @hide */ public static final int PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX = 1 << 29; /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = { Loading Loading @@ -707,7 +715,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { PRIVATE_FLAG_VIRTUAL_PRELOAD, PRIVATE_FLAG_HAS_FRAGILE_USER_DATA, PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE, PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE, PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX, }) @Retention(RetentionPolicy.SOURCE) public @interface ApplicationInfoPrivateFlags {} Loading Loading @@ -1822,6 +1831,16 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return (privateFlags & PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE) != 0; } /** * If {@code true} this app allows shared/external storage media to be a * sandboxed view that only contains files owned by the app. * * @hide */ public boolean isExternalStorageSandboxAllowed() { return (privateFlags & PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX) != 0; } private boolean isAllowedToUseHiddenApis() { if (isSignedWithPlatformKey()) { return true; Loading
core/java/android/content/pm/PackageParser.java +6 −0 Original line number Diff line number Diff line Loading @@ -3689,6 +3689,12 @@ public class PackageParser { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE; } if (sa.getBoolean( R.styleable.AndroidManifestApplication_allowExternalStorageSandbox, owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q)) { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX; } ai.maxAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0); ai.minAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_minAspectRatio, 0); Loading
core/java/android/os/Environment.java +42 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.os.storage.StorageManager; Loading Loading @@ -1060,7 +1062,7 @@ public class Environment { * @throws IllegalArgumentException if the path is not a valid storage * device. */ public static boolean isExternalStorageRemovable(File path) { public static boolean isExternalStorageRemovable(@NonNull File path) { final StorageVolume volume = StorageManager.getStorageVolume(path, UserHandle.myUserId()); if (volume != null) { return volume.isRemovable(); Loading Loading @@ -1103,7 +1105,7 @@ public class Environment { * @throws IllegalArgumentException if the path is not a valid storage * device. */ public static boolean isExternalStorageEmulated(File path) { public static boolean isExternalStorageEmulated(@NonNull File path) { final StorageVolume volume = StorageManager.getStorageVolume(path, UserHandle.myUserId()); if (volume != null) { return volume.isEmulated(); Loading @@ -1112,6 +1114,44 @@ public class Environment { } } /** * Returns whether the shared/external storage media at the given path is a * sandboxed view that only contains files owned by the app. * <p> * This value may be different from the value requested by * {@code allowExternalStorageSandbox} in the app's manifest, since an app * may inherit its sandboxed state based on when it was first installed. * <p> * Sandboxed apps can continue to discover and read media belonging to other * apps via {@link android.provider.MediaStore}. */ public static boolean isExternalStorageSandboxed() { final File externalDir = sCurrentUser.getExternalDirs()[0]; return isExternalStorageSandboxed(externalDir); } /** * Returns whether the shared/external storage media at the given path is a * sandboxed view that only contains files owned by the app. * <p> * This value may be different from the value requested by * {@code allowExternalStorageSandbox} in the app's manifest, since an app * may inherit its sandboxed state based on when it was first installed. * <p> * Sandboxed apps can continue to discover and read media belonging to other * apps via {@link android.provider.MediaStore}. * * @throws IllegalArgumentException if the path is not a valid storage * device. */ public static boolean isExternalStorageSandboxed(@NonNull File path) { final Context context = AppGlobals.getInitialApplication(); final AppOpsManager appOps = context.getSystemService(AppOpsManager.class); return appOps.noteOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, context.getApplicationInfo().uid, context.getPackageName()) != AppOpsManager.MODE_ALLOWED; } static File getDirectory(String variableName, String defaultPath) { String path = System.getenv(variableName); return path == null ? new File(defaultPath) : new File(path); Loading
core/res/res/values/attrs_manifest.xml +11 −0 Original line number Diff line number Diff line Loading @@ -1687,6 +1687,17 @@ - {@code false} for apps with targetSdkVersion < 29. --> <attr name="allowAudioPlaybackCapture" format="boolean" /> <!-- If {@code true} this app allows shared/external storage media to be a sandboxed view that only contains files owned by the app. <p> Sandboxed apps can continue to discover and read media belonging to other apps via {@code MediaStore}. <p> The default value is: - {@code true} for apps with targetSdkVersion >= 29 (Q). - {@code false} for apps with targetSdkVersion < 29. --> <attr name="allowExternalStorageSandbox" format="boolean" /> </declare-styleable> <!-- The <code>permission</code> tag declares a security permission that can be used to control access from other packages to specific components or Loading