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

Commit d4d02282 authored by Christopher Tate's avatar Christopher Tate Committed by Android (Google) Code Review
Browse files

Merge "Add Context.getNoBackupFilesDir()" into lmp-dev

parents dc433540 a7835b6b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -7061,6 +7061,7 @@ package android.content {
    method public abstract java.io.File getFileStreamPath(java.lang.String);
    method public abstract java.io.File getFilesDir();
    method public abstract android.os.Looper getMainLooper();
    method public abstract java.io.File getNoBackupFilesDir();
    method public abstract java.io.File getObbDir();
    method public abstract java.io.File[] getObbDirs();
    method public abstract java.lang.String getPackageCodePath();
@@ -7230,6 +7231,7 @@ package android.content {
    method public java.io.File getFileStreamPath(java.lang.String);
    method public java.io.File getFilesDir();
    method public android.os.Looper getMainLooper();
    method public java.io.File getNoBackupFilesDir();
    method public java.io.File getObbDir();
    method public java.io.File[] getObbDirs();
    method public java.lang.String getPackageCodePath();
@@ -29309,6 +29311,7 @@ package android.test.mock {
    method public java.io.File getFileStreamPath(java.lang.String);
    method public java.io.File getFilesDir();
    method public android.os.Looper getMainLooper();
    method public java.io.File getNoBackupFilesDir();
    method public java.io.File getObbDir();
    method public java.io.File[] getObbDirs();
    method public java.lang.String getPackageCodePath();
+32 −29
Original line number Diff line number Diff line
@@ -247,6 +247,8 @@ class ContextImpl extends Context {
    @GuardedBy("mSync")
    private File mFilesDir;
    @GuardedBy("mSync")
    private File mNoBackupFilesDir;
    @GuardedBy("mSync")
    private File mCacheDir;

    @GuardedBy("mSync")
@@ -963,27 +965,42 @@ class ContextImpl extends Context {
        return f.delete();
    }

    // Common-path handling of app data dir creation
    private static File createFilesDirLocked(File file) {
        if (!file.exists()) {
            if (!file.mkdirs()) {
                if (file.exists()) {
                    // spurious failure; probably racing with another process for this app
                    return file;
                }
                Log.w(TAG, "Unable to create files subdir " + file.getPath());
                return null;
            }
            FileUtils.setPermissions(
                    file.getPath(),
                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                    -1, -1);
        }
        return file;
    }

    @Override
    public File getFilesDir() {
        synchronized (mSync) {
            if (mFilesDir == null) {
                mFilesDir = new File(getDataDirFile(), "files");
            }
            if (!mFilesDir.exists()) {
                if(!mFilesDir.mkdirs()) {
                    if (mFilesDir.exists()) {
                        // spurious failure; probably racing with another process for this app
                        return mFilesDir;
            return createFilesDirLocked(mFilesDir);
        }
                    Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
                    return null;
    }
                FileUtils.setPermissions(
                        mFilesDir.getPath(),
                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                        -1, -1);

    @Override
    public File getNoBackupFilesDir() {
        synchronized (mSync) {
            if (mNoBackupFilesDir == null) {
                mNoBackupFilesDir = new File(getDataDirFile(), "no_backup");
            }
            return mFilesDir;
            return createFilesDirLocked(mNoBackupFilesDir);
        }
    }

@@ -1035,22 +1052,8 @@ class ContextImpl extends Context {
            if (mCacheDir == null) {
                mCacheDir = new File(getDataDirFile(), "cache");
            }
            if (!mCacheDir.exists()) {
                if(!mCacheDir.mkdirs()) {
                    if (mCacheDir.exists()) {
                        // spurious failure; probably racing with another process for this app
                        return mCacheDir;
                    }
                    Log.w(TAG, "Unable to create cache directory " + mCacheDir.getAbsolutePath());
                    return null;
                }
                FileUtils.setPermissions(
                        mCacheDir.getPath(),
                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                        -1, -1);
            }
            return createFilesDirLocked(mCacheDir);
        }
        return mCacheDir;
    }

    @Override
+42 −4
Original line number Diff line number Diff line
@@ -247,12 +247,40 @@ public abstract class BackupAgent extends ContextWrapper {
            throws IOException;

    /**
     * The default implementation backs up the entirety of the application's "owned"
     * file system trees to the output.
     * The application is having its entire file system contents backed up.  {@code data}
     * points to the backup destination, and the app has the opportunity to choose which
     * files are to be stored.  To commit a file as part of the backup, call the
     * {@link #fullBackupFile(File, FullBackupDataOutput)} helper method.  After all file
     * data is written to the output, the agent returns from this method and the backup
     * operation concludes.
     *
     * <p>Certain parts of the app's data are never backed up even if the app explicitly
     * sends them to the output:
     *
     * <ul>
     * <li>The contents of the {@link #getCacheDir()} directory</li>
     * <li>The contents of the {@link #getNoBackupFilesDir()} directory</li>
     * <li>The contents of the app's shared library directory</li>
     * </ul>
     *
     * <p>The default implementation of this method backs up the entirety of the
     * application's "owned" file system trees to the output other than the few exceptions
     * listed above.  Apps only need to override this method if they need to impose special
     * limitations on which files are being stored beyond the control that
     * {@link #getNoBackupFilesDir()} offers.
     *
     * @param data A structured wrapper pointing to the backup destination.
     * @throws IOException
     *
     * @see Context#getNoBackupFilesDir()
     * @see #fullBackupFile(File, FullBackupDataOutput)
     * @see #onRestoreFile(ParcelFileDescriptor, long, File, int, long, long)
     */
    public void onFullBackup(FullBackupDataOutput data) throws IOException {
        ApplicationInfo appInfo = getApplicationInfo();

        // Note that we don't need to think about the no_backup dir because it's outside
        // all of the ones we will be traversing
        String rootDir = new File(appInfo.dataDir).getCanonicalPath();
        String filesDir = getFilesDir().getCanonicalPath();
        String databaseDir = getDatabasePath("foo").getParentFile().getCanonicalPath();
@@ -311,6 +339,10 @@ public abstract class BackupAgent extends ContextWrapper {
     * to place it with the proper location and permissions on the device where the
     * data is restored.
     *
     * <p class="note">It is safe to explicitly back up files underneath your application's
     * {@link #getNoBackupFilesDir()} directory, and they will be restored to that
     * location correctly.
     *
     * @param file The file to be backed up.  The file must exist and be readable by
     *     the caller.
     * @param output The destination to which the backed-up file data will be sent.
@@ -319,6 +351,7 @@ public abstract class BackupAgent extends ContextWrapper {
        // Look up where all of our various well-defined dir trees live on this device
        String mainDir;
        String filesDir;
        String nbFilesDir;
        String dbDir;
        String spDir;
        String cacheDir;
@@ -331,6 +364,7 @@ public abstract class BackupAgent extends ContextWrapper {
        try {
            mainDir = new File(appInfo.dataDir).getCanonicalPath();
            filesDir = getFilesDir().getCanonicalPath();
            nbFilesDir = getNoBackupFilesDir().getCanonicalPath();
            dbDir = getDatabasePath("foo").getParentFile().getCanonicalPath();
            spDir = getSharedPrefsFile("foo").getParentFile().getCanonicalPath();
            cacheDir = getCacheDir().getCanonicalPath();
@@ -354,8 +388,10 @@ public abstract class BackupAgent extends ContextWrapper {
            return;
        }

        if (filePath.startsWith(cacheDir) || filePath.startsWith(libDir)) {
            Log.w(TAG, "lib and cache files are not backed up");
        if (filePath.startsWith(cacheDir)
                || filePath.startsWith(libDir)
                || filePath.startsWith(nbFilesDir)) {
            Log.w(TAG, "lib, cache, and no_backup files are not backed up");
            return;
        }

@@ -508,6 +544,8 @@ public abstract class BackupAgent extends ContextWrapper {
                    mode = -1;  // < 0 is a token to skip attempting a chmod()
                }
            }
        } else if (domain.equals(FullBackup.NO_BACKUP_TREE_TOKEN)) {
            basePath = getNoBackupFilesDir().getCanonicalPath();
        } else {
            // Not a supported location
            Log.i(TAG, "Unrecognized domain " + domain);
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ public class FullBackup {
    public static final String OBB_TREE_TOKEN = "obb";
    public static final String ROOT_TREE_TOKEN = "r";
    public static final String DATA_TREE_TOKEN = "f";
    public static final String NO_BACKUP_TREE_TOKEN = "nb";
    public static final String DATABASE_TREE_TOKEN = "db";
    public static final String SHAREDPREFS_TREE_TOKEN = "sp";
    public static final String MANAGED_EXTERNAL_TREE_TOKEN = "ef";
+20 −0
Original line number Diff line number Diff line
@@ -646,6 +646,26 @@ public abstract class Context {
     */
    public abstract File getFilesDir();

    /**
     * Returns the absolute path to the directory on the filesystem similar to
     * {@link #getFilesDir()}.  The difference is that files placed under this
     * directory will be excluded from automatic backup to remote storage.  See
     * {@link android.app.backup.BackupAgent BackupAgent} for a full discussion
     * of the automatic backup mechanism in Android.
     *
     * <p>No permissions are required to read or write to the returned path, since this
     * path is internal storage.
     *
     * @return The path of the directory holding application files that will not be
     *         automatically backed up to remote storage.
     *
     * @see #openFileOutput
     * @see #getFileStreamPath
     * @see #getDir
     * @see android.app.backup.BackupAgent
     */
    public abstract File getNoBackupFilesDir();

    /**
     * Returns the absolute path to the directory on the primary external filesystem
     * (that is somewhere on {@link android.os.Environment#getExternalStorageDirectory()
Loading