Merge "Full backup now saves getExternalFilesDir() content with the app data"
This commit is contained in:
committed by
Android (Google) Code Review
commit
afc43ed9a7
@ -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");
|
||||||
|
@ -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";
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user