Merge "Full backup now saves getExternalFilesDir() content with the app data"

This commit is contained in:
Christopher Tate
2013-02-15 19:38:03 +00:00
committed by Android (Google) Code Review
3 changed files with 25 additions and 1 deletions

View File

@ -227,6 +227,7 @@ public abstract class BackupAgent extends ContextWrapper {
String libDir = (appInfo.nativeLibraryDir != null) String libDir = (appInfo.nativeLibraryDir != null)
? new File(appInfo.nativeLibraryDir).getCanonicalPath() ? new File(appInfo.nativeLibraryDir).getCanonicalPath()
: null; : null;
String externalFilesDir = getExternalFilesDir(null).getCanonicalPath();
// Filters, the scan queue, and the set of resulting entities // Filters, the scan queue, and the set of resulting entities
HashSet<String> filterSet = new HashSet<String>(); HashSet<String> filterSet = new HashSet<String>();
@ -254,6 +255,12 @@ public abstract class BackupAgent extends ContextWrapper {
filterSet.add(databaseDir); filterSet.add(databaseDir);
filterSet.remove(sharedPrefsDir); filterSet.remove(sharedPrefsDir);
fullBackupFileTree(packageName, FullBackup.SHAREDPREFS_TREE_TOKEN, sharedPrefsDir, filterSet, data); fullBackupFileTree(packageName, FullBackup.SHAREDPREFS_TREE_TOKEN, sharedPrefsDir, filterSet, data);
// getExternalFilesDir() location associated with this app. Technically there should
// not be any files here if the app does not properly have permission to access
// external storage, but edge cases happen. fullBackupFileTree() catches
// IOExceptions and similar, and treats them as non-fatal, so we rely on that here.
fullBackupFileTree(packageName, FullBackup.MANAGED_EXTERNAL_TREE_TOKEN, externalFilesDir, null, data);
} }
/** /**
@ -274,6 +281,7 @@ public abstract class BackupAgent extends ContextWrapper {
String spDir; String spDir;
String cacheDir; String cacheDir;
String libDir; String libDir;
String efDir;
String filePath; String filePath;
ApplicationInfo appInfo = getApplicationInfo(); ApplicationInfo appInfo = getApplicationInfo();
@ -287,6 +295,7 @@ public abstract class BackupAgent extends ContextWrapper {
libDir = (appInfo.nativeLibraryDir == null) libDir = (appInfo.nativeLibraryDir == null)
? null ? null
: new File(appInfo.nativeLibraryDir).getCanonicalPath(); : new File(appInfo.nativeLibraryDir).getCanonicalPath();
efDir = getExternalFilesDir(null).getCanonicalPath();
// Now figure out which well-defined tree the file is placed in, working from // Now figure out which well-defined tree the file is placed in, working from
// most to least specific. We also specifically exclude the lib and cache dirs. // most to least specific. We also specifically exclude the lib and cache dirs.
@ -315,6 +324,9 @@ public abstract class BackupAgent extends ContextWrapper {
} else if (filePath.startsWith(mainDir)) { } else if (filePath.startsWith(mainDir)) {
domain = FullBackup.ROOT_TREE_TOKEN; domain = FullBackup.ROOT_TREE_TOKEN;
rootpath = mainDir; rootpath = mainDir;
} else if (filePath.startsWith(efDir)) {
domain = FullBackup.MANAGED_EXTERNAL_TREE_TOKEN;
rootpath = efDir;
} else { } else {
Log.w(TAG, "File " + filePath + " is in an unsupported location; skipping"); Log.w(TAG, "File " + filePath + " is in an unsupported location; skipping");
return; return;
@ -438,6 +450,8 @@ public abstract class BackupAgent extends ContextWrapper {
basePath = getSharedPrefsFile("foo").getParentFile().getCanonicalPath(); basePath = getSharedPrefsFile("foo").getParentFile().getCanonicalPath();
} else if (domain.equals(FullBackup.CACHE_TREE_TOKEN)) { } else if (domain.equals(FullBackup.CACHE_TREE_TOKEN)) {
basePath = getCacheDir().getCanonicalPath(); basePath = getCacheDir().getCanonicalPath();
} else if (domain.equals(FullBackup.MANAGED_EXTERNAL_TREE_TOKEN)) {
basePath = getExternalFilesDir(null).getCanonicalPath();
} else { } else {
// Not a supported location // Not a supported location
Log.i(TAG, "Data restored from non-app domain " + domain + ", ignoring"); Log.i(TAG, "Data restored from non-app domain " + domain + ", ignoring");

View File

@ -46,6 +46,7 @@ public class FullBackup {
public static final String DATA_TREE_TOKEN = "f"; public static final String DATA_TREE_TOKEN = "f";
public static final String DATABASE_TREE_TOKEN = "db"; public static final String DATABASE_TREE_TOKEN = "db";
public static final String SHAREDPREFS_TREE_TOKEN = "sp"; public static final String SHAREDPREFS_TREE_TOKEN = "sp";
public static final String MANAGED_EXTERNAL_TREE_TOKEN = "ef";
public static final String CACHE_TREE_TOKEN = "c"; public static final String CACHE_TREE_TOKEN = "c";
public static final String SHARED_STORAGE_TOKEN = "shared"; public static final String SHARED_STORAGE_TOKEN = "shared";

View File

@ -4,6 +4,7 @@ import android.app.backup.FullBackupAgent;
import android.app.backup.FullBackup; import android.app.backup.FullBackup;
import android.app.backup.FullBackupDataOutput; import android.app.backup.FullBackupDataOutput;
import android.content.Context; import android.content.Context;
import android.os.Environment;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.storage.StorageManager; import android.os.storage.StorageManager;
import android.os.storage.StorageVolume; import android.os.storage.StorageVolume;
@ -11,6 +12,7 @@ import android.util.Slog;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet;
public class SharedStorageAgent extends FullBackupAgent { public class SharedStorageAgent extends FullBackupAgent {
static final String TAG = "SharedStorageAgent"; static final String TAG = "SharedStorageAgent";
@ -38,13 +40,20 @@ public class SharedStorageAgent extends FullBackupAgent {
// "primary" shared storage volume is first in the list. // "primary" shared storage volume is first in the list.
if (mVolumes != null) { if (mVolumes != null) {
if (DEBUG) Slog.i(TAG, "Backing up " + mVolumes.length + " shared volumes"); if (DEBUG) Slog.i(TAG, "Backing up " + mVolumes.length + " shared volumes");
// Ignore all apps' getExternalFilesDir() content; it is backed up as part of
// each app-specific payload.
HashSet<String> externalFilesDirFilter = new HashSet<String>();
final File externalAndroidRoot = new File(Environment.getExternalStorageDirectory(),
Environment.DIRECTORY_ANDROID);
externalFilesDirFilter.add(externalAndroidRoot.getCanonicalPath());
for (int i = 0; i < mVolumes.length; i++) { for (int i = 0; i < mVolumes.length; i++) {
StorageVolume v = mVolumes[i]; StorageVolume v = mVolumes[i];
// Express the contents of volume N this way in the tar stream: // Express the contents of volume N this way in the tar stream:
// shared/N/path/to/file // shared/N/path/to/file
// The restore will then extract to the given volume // The restore will then extract to the given volume
String domain = FullBackup.SHARED_PREFIX + i; String domain = FullBackup.SHARED_PREFIX + i;
fullBackupFileTree(null, domain, v.getPath(), null, output); fullBackupFileTree(null, domain, v.getPath(), externalFilesDirFilter, output);
} }
} }
} }