Loading api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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(); core/java/android/app/ContextImpl.java +32 −29 Original line number Diff line number Diff line Loading @@ -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") Loading Loading @@ -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); } } Loading Loading @@ -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 Loading core/java/android/app/backup/BackupAgent.java +42 −4 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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. Loading @@ -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; Loading @@ -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(); Loading @@ -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; } Loading Loading @@ -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); Loading core/java/android/app/backup/FullBackup.java +1 −0 Original line number Diff line number Diff line Loading @@ -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"; Loading core/java/android/content/Context.java +20 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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();
core/java/android/app/ContextImpl.java +32 −29 Original line number Diff line number Diff line Loading @@ -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") Loading Loading @@ -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); } } Loading Loading @@ -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 Loading
core/java/android/app/backup/BackupAgent.java +42 −4 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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. Loading @@ -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; Loading @@ -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(); Loading @@ -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; } Loading Loading @@ -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); Loading
core/java/android/app/backup/FullBackup.java +1 −0 Original line number Diff line number Diff line Loading @@ -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"; Loading
core/java/android/content/Context.java +20 −0 Original line number Diff line number Diff line Loading @@ -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