diff --git a/api/current.txt b/api/current.txt index fa53d795f0d23..a5d8a930e40fe 100644 --- a/api/current.txt +++ b/api/current.txt @@ -8017,8 +8017,6 @@ package android.content { method public abstract java.lang.String getPackageResourcePath(); method public abstract android.content.res.Resources getResources(); method public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String, int); - method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int); - method public abstract java.io.File getSharedPreferencesPath(java.lang.String); method public final java.lang.String getString(int); method public final java.lang.String getString(int, java.lang.Object...); method public abstract java.lang.Object getSystemService(java.lang.String); @@ -29596,6 +29594,7 @@ package android.os.storage { method public java.lang.String getMountedObbPath(java.lang.String); method public android.os.storage.StorageVolume getPrimaryVolume(); method public android.os.storage.StorageVolume[] getVolumeList(); + method public boolean isEncrypted(java.io.File); method public boolean isObbMounted(java.lang.String); method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener); method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener); diff --git a/api/removed.txt b/api/removed.txt index 9b5d3ab0d81cf..36c8ce5cdf50c 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -22,6 +22,8 @@ package android.content { public abstract class Context { method public deprecated android.content.Context createCredentialEncryptedStorageContext(); method public deprecated android.content.Context createDeviceEncryptedStorageContext(); + method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int); + method public abstract java.io.File getSharedPreferencesPath(java.lang.String); method public deprecated boolean isCredentialEncryptedStorage(); method public deprecated boolean isDeviceEncryptedStorage(); method public deprecated boolean migrateDatabaseFrom(android.content.Context, java.lang.String); diff --git a/api/system-current.txt b/api/system-current.txt index 303c7c8cd5da3..97b7710edec84 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -8316,8 +8316,6 @@ package android.content { method public abstract java.lang.String getPackageResourcePath(); method public abstract android.content.res.Resources getResources(); method public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String, int); - method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int); - method public abstract java.io.File getSharedPreferencesPath(java.lang.String); method public final java.lang.String getString(int); method public final java.lang.String getString(int, java.lang.Object...); method public abstract java.lang.Object getSystemService(java.lang.String); @@ -31909,6 +31907,7 @@ package android.os.storage { method public java.lang.String getMountedObbPath(java.lang.String); method public android.os.storage.StorageVolume getPrimaryVolume(); method public android.os.storage.StorageVolume[] getVolumeList(); + method public boolean isEncrypted(java.io.File); method public boolean isObbMounted(java.lang.String); method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener); method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener); diff --git a/api/system-removed.txt b/api/system-removed.txt index 8bf59df2d8900..d48b9b3cd4030 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -20,6 +20,8 @@ package android.content { public abstract class Context { method public deprecated android.content.Context createCredentialEncryptedStorageContext(); method public deprecated android.content.Context createDeviceEncryptedStorageContext(); + method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int); + method public abstract java.io.File getSharedPreferencesPath(java.lang.String); method public deprecated boolean isCredentialEncryptedStorage(); method public deprecated boolean isDeviceEncryptedStorage(); method public deprecated boolean migrateDatabaseFrom(android.content.Context, java.lang.String); diff --git a/api/test-current.txt b/api/test-current.txt index 6973666d1e7e4..fa2669c26435e 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -8022,8 +8022,6 @@ package android.content { method public abstract java.lang.String getPackageResourcePath(); method public abstract android.content.res.Resources getResources(); method public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String, int); - method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int); - method public abstract java.io.File getSharedPreferencesPath(java.lang.String); method public final java.lang.String getString(int); method public final java.lang.String getString(int, java.lang.Object...); method public abstract java.lang.Object getSystemService(java.lang.String); @@ -29662,6 +29660,7 @@ package android.os.storage { method public java.lang.String getMountedObbPath(java.lang.String); method public android.os.storage.StorageVolume getPrimaryVolume(); method public android.os.storage.StorageVolume[] getVolumeList(); + method public boolean isEncrypted(java.io.File); method public boolean isObbMounted(java.lang.String); method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener); method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener); diff --git a/api/test-removed.txt b/api/test-removed.txt index 9b5d3ab0d81cf..36c8ce5cdf50c 100644 --- a/api/test-removed.txt +++ b/api/test-removed.txt @@ -22,6 +22,8 @@ package android.content { public abstract class Context { method public deprecated android.content.Context createCredentialEncryptedStorageContext(); method public deprecated android.content.Context createDeviceEncryptedStorageContext(); + method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int); + method public abstract java.io.File getSharedPreferencesPath(java.lang.String); method public deprecated boolean isCredentialEncryptedStorage(); method public deprecated boolean isDeviceEncryptedStorage(); method public deprecated boolean migrateDatabaseFrom(android.content.Context, java.lang.String); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index ca19b9bc668e2..15cc17da21500 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -691,6 +691,7 @@ public abstract class Context { * * @see #getSharedPreferencesPath(String) * @see #MODE_PRIVATE + * @removed */ public abstract SharedPreferences getSharedPreferences(File file, int mode); @@ -813,17 +814,16 @@ public abstract class Context { * to get a path. * @return An absolute path to the given file. * @see #getSharedPreferences(String, int) + * @removed */ public abstract File getSharedPreferencesPath(String name); /** * Returns the absolute path to the directory on the filesystem where all - * private files belonging to this app are stored. This is the top-level - * directory under which {@link #getFilesDir()}, {@link #getCacheDir()}, etc - * are contained. Apps should not create any files or directories - * as direct children of this directory, since it's a reserved namespace - * belonging to the platform. Instead, use {@link #getDir(String, int)} or - * other storage APIs. + * private files belonging to this app are stored. Apps should not use this + * path directly; they should instead use {@link #getFilesDir()}, + * {@link #getCacheDir()}, {@link #getDir(String, int)}, or other storage + * APIs on this class. *
* The returned path may change over time if the calling app is moved to an * adopted storage device, so only relative paths should be persisted. @@ -831,7 +831,7 @@ public abstract class Context { * No additional permissions are required for the calling app to read or * write files under the returned path. * - * @see #getDir(String, int) + * @see ApplicationInfo#dataDir */ public abstract File getDataDir(); @@ -4168,7 +4168,7 @@ public abstract class Context { * Return a new Context object for the current Context but whose storage * APIs are backed by device-protected storage. *
- * When a device is encrypted, data stored in this location is encrypted + * On devices with direct boot, data stored in this location is encrypted * with a key tied to the physical device, and it can be accessed * immediately after the device has booted successfully, both * before and after the user has authenticated with their @@ -4206,7 +4206,7 @@ public abstract class Context { * storage area for apps unless * {@link android.R.attr#defaultToDeviceProtectedStorage} was requested. *
- * When a device is encrypted, data stored in this location is encrypted + * On devices with direct boot, data stored in this location is encrypted * with a key tied to user credentials, which can be accessed * only after the user has entered their credentials (such as a * lock pattern or PIN). diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 09aad3b664280..57ab7a2f937cb 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -23,12 +23,14 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.ComponentInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Rect; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; @@ -1946,31 +1948,48 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED"; /** - * Broadcast Action: This is broadcast once, after the system has finished - * booting and the user is in a "locked" state. A user is locked when their - * credential-encrypted private app data storage is unavailable. Once the - * user has entered their credentials (such as a lock pattern or PIN) for - * the first time, the {@link #ACTION_BOOT_COMPLETED} broadcast will be - * sent. + * Broadcast Action: This is broadcast once, after the user has finished + * booting, but while still in the "locked" state. It can be used to perform + * application-specific initialization, such as installing alarms. You must + * hold the {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} + * permission in order to receive this broadcast. *
- * You must hold the - * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission in - * order to receive this broadcast. + * This broadcast is sent immediately at boot by all devices (regardless of + * direct boot support) running {@link android.os.Build.VERSION_CODES#N} or + * higher. Upon receipt of this broadcast, the user is still locked and only + * device-protected storage can be accessed safely. If you want to access + * credential-protected storage, you need to wait for the user to be + * unlocked (typically by entering their lock pattern or PIN for the first + * time), after which the {@link #ACTION_USER_UNLOCKED} and + * {@link #ACTION_BOOT_COMPLETED} broadcasts are sent. + *
+ * To receive this broadcast, your receiver component must be marked as + * being {@link ComponentInfo#directBootAware}. *
* This is a protected intent that can only be sent by the system. + * + * @see Context#createDeviceProtectedStorageContext() */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED"; /** - * Broadcast Action: This is broadcast once, after the system has finished - * booting. It can be used to perform application-specific initialization, - * such as installing alarms. You must hold the - * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission - * in order to receive this broadcast. - * - *
This is a protected intent that can only be sent - * by the system. + * Broadcast Action: This is broadcast once, after the user has finished + * booting. It can be used to perform application-specific initialization, + * such as installing alarms. You must hold the + * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission in + * order to receive this broadcast. + *
+ * This broadcast is sent at boot by all devices (both with and without + * direct boot support). Upon receipt of this broadcast, the user is + * unlocked and both device-protected and credential-protected storage can + * accessed safely. + *
+ * If you need to run while the user is still locked (before they've entered + * their lock pattern or PIN for the first time), you can listen for the + * {@link #ACTION_LOCKED_BOOT_COMPLETED} broadcast. + *
+ * This is a protected intent that can only be sent by the system. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED"; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 1079f974732fa..e89cbd7091ae6 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -2593,12 +2593,15 @@ public abstract class PackageManager { public abstract Intent getLeanbackLaunchIntentForPackage(String packageName); /** - * Return an array of all of the secondary group-ids that have been assigned - * to a package. + * Return an array of all of the POSIX secondary group IDs that have been + * assigned to the given package. + *
+ * Note that the same package may have different GIDs under different + * {@link UserHandle} on the same device. * * @param packageName The full name (i.e. com.google.apps.contacts) of the - * desired package. - * @return Returns an int array of the assigned gids, or null if there are + * desired package. + * @return Returns an int array of the assigned GIDs, or null if there are * none. * @throws NameNotFoundException if a package with the given name cannot be * found on the system. @@ -2607,8 +2610,11 @@ public abstract class PackageManager { throws NameNotFoundException; /** - * Return an array of all of the secondary group-ids that have been assigned - * to a package. + * Return an array of all of the POSIX secondary group IDs that have been + * assigned to the given package. + *
+ * Note that the same package may have different GIDs under different + * {@link UserHandle} on the same device. * * @param packageName The full name (i.e. com.google.apps.contacts) of the * desired package. @@ -2622,6 +2628,9 @@ public abstract class PackageManager { /** * Return the UID associated with the given package name. + *
+ * Note that the same package will have different UIDs under different + * {@link UserHandle} on the same device. * * @param packageName The full name (i.e. com.google.apps.contacts) of the * desired package. @@ -2634,6 +2643,9 @@ public abstract class PackageManager { /** * Return the UID associated with the given package name. + *
+ * Note that the same package will have different UIDs under different + * {@link UserHandle} on the same device. * * @param packageName The full name (i.e. com.google.apps.contacts) of the * desired package. @@ -2648,6 +2660,9 @@ public abstract class PackageManager { /** * Return the UID associated with the given package name. + *
+ * Note that the same package will have different UIDs under different + * {@link UserHandle} on the same device. * * @param packageName The full name (i.e. com.google.apps.contacts) of the * desired package. diff --git a/core/java/android/os/DeadSystemException.java b/core/java/android/os/DeadSystemException.java index 595365c554726..8fb53e2f4eb43 100644 --- a/core/java/android/os/DeadSystemException.java +++ b/core/java/android/os/DeadSystemException.java @@ -18,7 +18,7 @@ package android.os; /** * The core Android system has died and is going through a runtime restart. All - * running apps will be promptly be killed. + * running apps will be promptly killed. */ public class DeadSystemException extends DeadObjectException { public DeadSystemException() { diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 307bd2d13f83c..f6e8940db4087 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -34,6 +34,7 @@ public class Environment { private static final String ENV_EXTERNAL_STORAGE = "EXTERNAL_STORAGE"; private static final String ENV_ANDROID_ROOT = "ANDROID_ROOT"; private static final String ENV_ANDROID_DATA = "ANDROID_DATA"; + private static final String ENV_ANDROID_EXPAND = "ANDROID_EXPAND"; private static final String ENV_ANDROID_STORAGE = "ANDROID_STORAGE"; private static final String ENV_DOWNLOAD_CACHE = "DOWNLOAD_CACHE"; private static final String ENV_OEM_ROOT = "OEM_ROOT"; @@ -54,6 +55,7 @@ public class Environment { private static final File DIR_ANDROID_ROOT = getDirectory(ENV_ANDROID_ROOT, "/system"); private static final File DIR_ANDROID_DATA = getDirectory(ENV_ANDROID_DATA, "/data"); + private static final File DIR_ANDROID_EXPAND = getDirectory(ENV_ANDROID_EXPAND, "/mnt/expand"); private static final File DIR_ANDROID_STORAGE = getDirectory(ENV_ANDROID_STORAGE, "/storage"); private static final File DIR_DOWNLOAD_CACHE = getDirectory(ENV_DOWNLOAD_CACHE, "/cache"); private static final File DIR_OEM_ROOT = getDirectory(ENV_OEM_ROOT, "/oem"); @@ -228,6 +230,11 @@ public class Environment { } } + /** {@hide} */ + public static File getExpandDirectory() { + return DIR_ANDROID_EXPAND; + } + /** {@hide} */ public static File getDataSystemDirectory() { return new File(getDataDirectory(), "system"); diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 92e18622269b1..0ff0154f2ed04 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -918,11 +918,15 @@ public class UserManager { } /** - * Return whether the calling user is running in an "unlocked" state. A user - * is unlocked only after they've entered their credentials (such as a lock - * pattern or PIN), and credential-encrypted private app data storage is - * available. When a user is locked, only device-protected data storage is - * available. + * Return whether the calling user is running in an "unlocked" state. + *
+ * On devices with direct boot, a user is unlocked only after they've + * entered their credentials (such as a lock pattern or PIN). On devices + * without direct boot, a user is unlocked as soon as it starts. + *
+ * When a user is locked, only device-protected data storage is available. + * When a user is unlocked, both device-protected and credential-protected + * private app data storage is available. * * @see Intent#ACTION_USER_UNLOCKED * @see Context#createDeviceProtectedStorageContext() @@ -932,11 +936,15 @@ public class UserManager { } /** - * Return whether the given user is running in an "unlocked" state. A user - * is unlocked only after they've entered their credentials (such as a lock - * pattern or PIN), and credential-protected private app data storage is - * available. When a user is locked, only device-protected data storage is - * available. + * Return whether the given user is running in an "unlocked" state. + *
+ * On devices with direct boot, a user is unlocked only after they've + * entered their credentials (such as a lock pattern or PIN). On devices + * without direct boot, a user is unlocked as soon as it starts. + *
+ * When a user is locked, only device-protected data storage is available. + * When a user is unlocked, both device-protected and credential-protected + * private app data storage is available. * * @param user to retrieve the unlocked state for. * @see Intent#ACTION_USER_UNLOCKED diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 61e6b95cf89fd..22aec63a76a23 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -35,6 +35,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.provider.Settings; +import android.security.KeyStore; import android.text.TextUtils; import android.util.Log; import android.util.Slog; @@ -1025,6 +1026,20 @@ public class StorageManager { } } + /** + * Return if data stored at the given path will be encrypted while at rest. + * This can help apps avoid the overhead of double-encrypting data. + */ + public boolean isEncrypted(File file) { + if (FileUtils.contains(Environment.getDataDirectory(), file)) { + return isEncrypted(); + } else if (FileUtils.contains(Environment.getExpandDirectory(), file)) { + return true; + } + // TODO: extend to support shared storage + return false; + } + /** {@hide} * Is this device encryptable or already encrypted? * @return true for encryptable or encrypted diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java index c36680cdb210c..47dc6c367ebc8 100644 --- a/core/java/android/preference/PreferenceManager.java +++ b/core/java/android/preference/PreferenceManager.java @@ -362,8 +362,7 @@ public class PreferenceManager { * Explicitly set the storage location used internally by this class to be * device-protected storage. *
- *
- * When a device is encrypted, data stored in this location is encrypted + * On devices with direct boot, data stored in this location is encrypted * with a key tied to the physical device, and it can be accessed * immediately after the device has booted successfully, both * before and after the user has authenticated with their @@ -392,7 +391,7 @@ public class PreferenceManager { * credential-protected storage. This is the default storage area for apps * unless {@code forceDeviceProtectedStorage} was requested. *
- * When a device is encrypted, data stored in this location is encrypted + * On devices with direct boot, data stored in this location is encrypted * with a key tied to user credentials, which can be accessed * only after the user has entered their credentials (such as a * lock pattern or PIN).