Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e13529a4 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Slight API renaming, better behavior.

Rename APIs to reflect that they're storage-related.  Also move
credential-storage APIs to be system API.

Return a null Context when device-encrypted storage isn't
supported.  This is the easiest way to keep legacy apps working when
upgrading from M to N.

Reduce strictness of path checking so we don't crash when working
with special packages like "android".

Bug: 22358539, 26104027
Change-Id: I38c24fc003488186210a6ae3b64270f86e1efe56
parent 7a30a30e
Loading
Loading
Loading
Loading
+8 −12
Original line number Diff line number Diff line
@@ -7779,8 +7779,7 @@ package android.content {
    method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
    method public abstract deprecated void clearWallpaper() throws java.io.IOException;
    method public abstract android.content.Context createConfigurationContext(android.content.res.Configuration);
    method public abstract android.content.Context createCredentialEncryptedContext(android.content.Context);
    method public abstract android.content.Context createDeviceEncryptedContext(android.content.Context);
    method public abstract android.content.Context createDeviceEncryptedStorageContext();
    method public abstract android.content.Context createDisplayContext(android.view.Display);
    method public abstract android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract java.lang.String[] databaseList();
@@ -7836,8 +7835,7 @@ package android.content {
    method public abstract deprecated int getWallpaperDesiredMinimumHeight();
    method public abstract deprecated int getWallpaperDesiredMinimumWidth();
    method public abstract void grantUriPermission(java.lang.String, android.net.Uri, int);
    method public abstract boolean isCredentialEncrypted();
    method public abstract boolean isDeviceEncrypted();
    method public abstract boolean isDeviceEncryptedStorage();
    method public boolean isRestricted();
    method public final android.content.res.TypedArray obtainStyledAttributes(int[]);
    method public final android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
@@ -7969,8 +7967,7 @@ package android.content {
    method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
    method public deprecated void clearWallpaper() throws java.io.IOException;
    method public android.content.Context createConfigurationContext(android.content.res.Configuration);
    method public android.content.Context createCredentialEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedStorageContext();
    method public android.content.Context createDisplayContext(android.view.Display);
    method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.lang.String[] databaseList();
@@ -8020,8 +8017,7 @@ package android.content {
    method public deprecated int getWallpaperDesiredMinimumHeight();
    method public deprecated int getWallpaperDesiredMinimumWidth();
    method public void grantUriPermission(java.lang.String, android.net.Uri, int);
    method public boolean isCredentialEncrypted();
    method public boolean isDeviceEncrypted();
    method public boolean isDeviceEncryptedStorage();
    method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
    method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
    method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -28090,7 +28086,9 @@ package android.os {
    method public boolean isSystemUser();
    method public boolean isUserAGoat();
    method public boolean isUserRunning(android.os.UserHandle);
    method public boolean isUserRunningAndLocked();
    method public boolean isUserRunningAndLocked(android.os.UserHandle);
    method public boolean isUserRunningAndUnlocked();
    method public boolean isUserRunningAndUnlocked(android.os.UserHandle);
    method public boolean isUserRunningOrStopping(android.os.UserHandle);
    method public deprecated boolean setRestrictionsChallenge(java.lang.String);
@@ -36242,8 +36240,7 @@ package android.test.mock {
    method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
    method public void clearWallpaper();
    method public android.content.Context createConfigurationContext(android.content.res.Configuration);
    method public android.content.Context createCredentialEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedStorageContext();
    method public android.content.Context createDisplayContext(android.view.Display);
    method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.lang.String[] databaseList();
@@ -36292,8 +36289,7 @@ package android.test.mock {
    method public int getWallpaperDesiredMinimumHeight();
    method public int getWallpaperDesiredMinimumWidth();
    method public void grantUriPermission(java.lang.String, android.net.Uri, int);
    method public boolean isCredentialEncrypted();
    method public boolean isDeviceEncrypted();
    method public boolean isDeviceEncryptedStorage();
    method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
    method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
    method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
+14 −12
Original line number Diff line number Diff line
@@ -8023,8 +8023,8 @@ package android.content {
    method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
    method public abstract deprecated void clearWallpaper() throws java.io.IOException;
    method public abstract android.content.Context createConfigurationContext(android.content.res.Configuration);
    method public abstract android.content.Context createCredentialEncryptedContext(android.content.Context);
    method public abstract android.content.Context createDeviceEncryptedContext(android.content.Context);
    method public abstract android.content.Context createCredentialEncryptedStorageContext();
    method public abstract android.content.Context createDeviceEncryptedStorageContext();
    method public abstract android.content.Context createDisplayContext(android.view.Display);
    method public abstract android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract java.lang.String[] databaseList();
@@ -8080,8 +8080,8 @@ package android.content {
    method public abstract deprecated int getWallpaperDesiredMinimumHeight();
    method public abstract deprecated int getWallpaperDesiredMinimumWidth();
    method public abstract void grantUriPermission(java.lang.String, android.net.Uri, int);
    method public abstract boolean isCredentialEncrypted();
    method public abstract boolean isDeviceEncrypted();
    method public abstract boolean isCredentialEncryptedStorage();
    method public abstract boolean isDeviceEncryptedStorage();
    method public boolean isRestricted();
    method public final android.content.res.TypedArray obtainStyledAttributes(int[]);
    method public final android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
@@ -8221,8 +8221,8 @@ package android.content {
    method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
    method public deprecated void clearWallpaper() throws java.io.IOException;
    method public android.content.Context createConfigurationContext(android.content.res.Configuration);
    method public android.content.Context createCredentialEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedContext(android.content.Context);
    method public android.content.Context createCredentialEncryptedStorageContext();
    method public android.content.Context createDeviceEncryptedStorageContext();
    method public android.content.Context createDisplayContext(android.view.Display);
    method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.lang.String[] databaseList();
@@ -8272,8 +8272,8 @@ package android.content {
    method public deprecated int getWallpaperDesiredMinimumHeight();
    method public deprecated int getWallpaperDesiredMinimumWidth();
    method public void grantUriPermission(java.lang.String, android.net.Uri, int);
    method public boolean isCredentialEncrypted();
    method public boolean isDeviceEncrypted();
    method public boolean isCredentialEncryptedStorage();
    method public boolean isDeviceEncryptedStorage();
    method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
    method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
    method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -30081,7 +30081,9 @@ package android.os {
    method public boolean isSystemUser();
    method public boolean isUserAGoat();
    method public boolean isUserRunning(android.os.UserHandle);
    method public boolean isUserRunningAndLocked();
    method public boolean isUserRunningAndLocked(android.os.UserHandle);
    method public boolean isUserRunningAndUnlocked();
    method public boolean isUserRunningAndUnlocked(android.os.UserHandle);
    method public boolean isUserRunningOrStopping(android.os.UserHandle);
    method public deprecated boolean setRestrictionsChallenge(java.lang.String);
@@ -38566,8 +38568,8 @@ package android.test.mock {
    method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
    method public void clearWallpaper();
    method public android.content.Context createConfigurationContext(android.content.res.Configuration);
    method public android.content.Context createCredentialEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedContext(android.content.Context);
    method public android.content.Context createCredentialEncryptedStorageContext();
    method public android.content.Context createDeviceEncryptedStorageContext();
    method public android.content.Context createDisplayContext(android.view.Display);
    method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.lang.String[] databaseList();
@@ -38616,8 +38618,8 @@ package android.test.mock {
    method public int getWallpaperDesiredMinimumHeight();
    method public int getWallpaperDesiredMinimumWidth();
    method public void grantUriPermission(java.lang.String, android.net.Uri, int);
    method public boolean isCredentialEncrypted();
    method public boolean isDeviceEncrypted();
    method public boolean isCredentialEncryptedStorage();
    method public boolean isDeviceEncryptedStorage();
    method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
    method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
    method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
+8 −12
Original line number Diff line number Diff line
@@ -7779,8 +7779,7 @@ package android.content {
    method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
    method public abstract deprecated void clearWallpaper() throws java.io.IOException;
    method public abstract android.content.Context createConfigurationContext(android.content.res.Configuration);
    method public abstract android.content.Context createCredentialEncryptedContext(android.content.Context);
    method public abstract android.content.Context createDeviceEncryptedContext(android.content.Context);
    method public abstract android.content.Context createDeviceEncryptedStorageContext();
    method public abstract android.content.Context createDisplayContext(android.view.Display);
    method public abstract android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract java.lang.String[] databaseList();
@@ -7836,8 +7835,7 @@ package android.content {
    method public abstract deprecated int getWallpaperDesiredMinimumHeight();
    method public abstract deprecated int getWallpaperDesiredMinimumWidth();
    method public abstract void grantUriPermission(java.lang.String, android.net.Uri, int);
    method public abstract boolean isCredentialEncrypted();
    method public abstract boolean isDeviceEncrypted();
    method public abstract boolean isDeviceEncryptedStorage();
    method public boolean isRestricted();
    method public final android.content.res.TypedArray obtainStyledAttributes(int[]);
    method public final android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
@@ -7969,8 +7967,7 @@ package android.content {
    method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
    method public deprecated void clearWallpaper() throws java.io.IOException;
    method public android.content.Context createConfigurationContext(android.content.res.Configuration);
    method public android.content.Context createCredentialEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedStorageContext();
    method public android.content.Context createDisplayContext(android.view.Display);
    method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.lang.String[] databaseList();
@@ -8020,8 +8017,7 @@ package android.content {
    method public deprecated int getWallpaperDesiredMinimumHeight();
    method public deprecated int getWallpaperDesiredMinimumWidth();
    method public void grantUriPermission(java.lang.String, android.net.Uri, int);
    method public boolean isCredentialEncrypted();
    method public boolean isDeviceEncrypted();
    method public boolean isDeviceEncryptedStorage();
    method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
    method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
    method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -28090,7 +28086,9 @@ package android.os {
    method public boolean isSystemUser();
    method public boolean isUserAGoat();
    method public boolean isUserRunning(android.os.UserHandle);
    method public boolean isUserRunningAndLocked();
    method public boolean isUserRunningAndLocked(android.os.UserHandle);
    method public boolean isUserRunningAndUnlocked();
    method public boolean isUserRunningAndUnlocked(android.os.UserHandle);
    method public boolean isUserRunningOrStopping(android.os.UserHandle);
    method public deprecated boolean setRestrictionsChallenge(java.lang.String);
@@ -36244,8 +36242,7 @@ package android.test.mock {
    method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
    method public void clearWallpaper();
    method public android.content.Context createConfigurationContext(android.content.res.Configuration);
    method public android.content.Context createCredentialEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedContext(android.content.Context);
    method public android.content.Context createDeviceEncryptedStorageContext();
    method public android.content.Context createDisplayContext(android.view.Display);
    method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.lang.String[] databaseList();
@@ -36294,8 +36291,7 @@ package android.test.mock {
    method public int getWallpaperDesiredMinimumHeight();
    method public int getWallpaperDesiredMinimumWidth();
    method public void grantUriPermission(java.lang.String, android.net.Uri, int);
    method public boolean isCredentialEncrypted();
    method public boolean isDeviceEncrypted();
    method public boolean isDeviceEncryptedStorage();
    method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
    method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
    method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
+22 −20
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.storage.IMountService;
import android.os.storage.StorageManager;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.Log;
@@ -1744,17 +1745,21 @@ class ContextImpl extends Context {
    }

    @Override
    public Context createDeviceEncryptedContext(Context context) {
        final int flags = (mFlags & ~Context.CONTEXT_STORAGE_CREDENTIAL_ENCRYPTED)
                | Context.CONTEXT_STORAGE_DEVICE_ENCRYPTED;
    public Context createDeviceEncryptedStorageContext() {
        if (!StorageManager.isFileBasedEncryptionEnabled()) {
            return null;
        }

        final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE)
                | Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE;
        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
                mUser, flags, mDisplay, null, Display.INVALID_DISPLAY);
    }

    @Override
    public Context createCredentialEncryptedContext(Context context) {
        final int flags = (mFlags & ~Context.CONTEXT_STORAGE_DEVICE_ENCRYPTED)
                | Context.CONTEXT_STORAGE_CREDENTIAL_ENCRYPTED;
    public Context createCredentialEncryptedStorageContext() {
        final int flags = (mFlags & ~Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE)
                | Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE;
        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
                mUser, flags, mDisplay, null, Display.INVALID_DISPLAY);
    }
@@ -1765,13 +1770,13 @@ class ContextImpl extends Context {
    }

    @Override
    public boolean isDeviceEncrypted() {
        return (mFlags & Context.CONTEXT_STORAGE_DEVICE_ENCRYPTED) != 0;
    public boolean isDeviceEncryptedStorage() {
        return (mFlags & Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE) != 0;
    }

    @Override
    public boolean isCredentialEncrypted() {
        return (mFlags & Context.CONTEXT_STORAGE_CREDENTIAL_ENCRYPTED) != 0;
    public boolean isCredentialEncryptedStorage() {
        return (mFlags & Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE) != 0;
    }

    @Override
@@ -1781,13 +1786,12 @@ class ContextImpl extends Context {

    private File getDataDirFile() {
        if (mPackageInfo != null) {
            if (isCredentialEncrypted()) {
            if (isCredentialEncryptedStorage()) {
                return mPackageInfo.getCredentialEncryptedDataDirFile();
            } else if (isDeviceEncrypted()) {
            } else if (isDeviceEncryptedStorage()) {
                return mPackageInfo.getDeviceEncryptedDataDirFile();
            } else {
                throw new RuntimeException(
                        "Storage location is neither credential nor device encrypted");
                return mPackageInfo.getDataDirFile();
            }
        }
        throw new RuntimeException("Not supported in system context");
@@ -1840,15 +1844,13 @@ class ContextImpl extends Context {

        // If creator didn't specify which storage to use, use the default
        // location for application.
        if ((flags & Context.CONTEXT_STORAGE_MASK) == 0) {
        if ((flags & (Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE
                | Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE)) == 0) {
            final File dataDir = packageInfo.getDataDirFile();
            if (Objects.equals(dataDir, packageInfo.getCredentialEncryptedDataDirFile())) {
                flags |= Context.CONTEXT_STORAGE_CREDENTIAL_ENCRYPTED;
                flags |= Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE;
            } else if (Objects.equals(dataDir, packageInfo.getDeviceEncryptedDataDirFile())) {
                flags |= Context.CONTEXT_STORAGE_DEVICE_ENCRYPTED;
            } else {
                throw new IllegalStateException("Storage location " + dataDir
                        + " doesn't match either credential or device encrypted storage");
                flags |= Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE;
            }
        }

+23 −19
Original line number Diff line number Diff line
@@ -53,8 +53,8 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.view.DisplayAdjustments;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.ViewDebug;
import android.view.WindowManager;

@@ -3870,7 +3870,7 @@ public abstract class Context {
     *
     * @hide
     */
    public static final int CONTEXT_STORAGE_DEVICE_ENCRYPTED = 0x00000008;
    public static final int CONTEXT_DEVICE_ENCRYPTED_STORAGE = 0x00000008;

    /**
     * Flag for use with {@link #createPackageContext}: point all file APIs at
@@ -3878,11 +3878,7 @@ public abstract class Context {
     *
     * @hide
     */
    public static final int CONTEXT_STORAGE_CREDENTIAL_ENCRYPTED = 0x00000010;

    /** {@hide} */
    public static final int CONTEXT_STORAGE_MASK = CONTEXT_STORAGE_DEVICE_ENCRYPTED
            | CONTEXT_STORAGE_CREDENTIAL_ENCRYPTED;
    public static final int CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE = 0x00000010;

    /**
     * @hide Used to indicate we should tell the activity manager about the process
@@ -3987,19 +3983,23 @@ public abstract class Context {
     * Return a new Context object for the current Context but whose storage
     * APIs are backed by device-encrypted storage.
     * <p>
     * Data stored in device-encrypted storage is typically encrypted with a
     * key tied to the physical device, and they can be accessed whenever the
     * device has booted successfully, both <em>before and after</em> the user
     * has entered their credentials (such as a lock pattern or PIN).
     * Data stored in device-encrypted storage is typically encrypted with a key
     * tied to the physical device, and it can be accessed when the device has
     * booted successfully, both <em>before and after</em> the user has
     * authenticated with their credentials (such as a lock pattern or PIN).
     * Because device-encrypted data is available before user authentication,
     * you should carefully consider what data you store using this Context.
     * <p>
     * Each call to this method returns a new instance of a Context object;
     * Context objects are not shared, however common state (ClassLoader, other
     * Resources for the same configuration) may be so the Context itself can be
     * fairly lightweight.
     *
     * @see #isDeviceEncrypted()
     * @return new Context or {@code null} if device-encrypted storage is not
     *         supported or available on this device.
     * @see #isDeviceEncryptedStorage()
     */
    public abstract Context createDeviceEncryptedContext(Context context);
    public abstract Context createDeviceEncryptedStorageContext();

    /**
     * Return a new Context object for the current Context but whose storage
@@ -4015,9 +4015,11 @@ public abstract class Context {
     * Resources for the same configuration) may be so the Context itself can be
     * fairly lightweight.
     *
     * @see #isCredentialEncrypted()
     * @see #isCredentialEncryptedStorage()
     * @hide
     */
    public abstract Context createCredentialEncryptedContext(Context context);
    @SystemApi
    public abstract Context createCredentialEncryptedStorageContext();

    /**
     * Gets the display adjustments holder for this context.  This information
@@ -4045,15 +4047,17 @@ public abstract class Context {
     * Indicates if the storage APIs of this Context are backed by
     * device-encrypted storage.
     *
     * @see #createDeviceEncryptedContext(Context)
     * @see #createDeviceEncryptedStorageContext()
     */
    public abstract boolean isDeviceEncrypted();
    public abstract boolean isDeviceEncryptedStorage();

    /**
     * Indicates if the storage APIs of this Context are backed by
     * credential-encrypted storage.
     *
     * @see #createCredentialEncryptedContext(Context)
     * @see #createCredentialEncryptedStorageContext()
     * @hide
     */
    public abstract boolean isCredentialEncrypted();
    @SystemApi
    public abstract boolean isCredentialEncryptedStorage();
}
Loading