summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/backup/BackupAgent.java60
-rw-r--r--core/java/android/app/backup/FullBackup.java189
2 files changed, 70 insertions, 179 deletions
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index d1c957b8fedc..d36a794ac046 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -18,7 +18,6 @@ package android.app.backup;
import android.app.IBackupAgent;
import android.app.QueuedWork;
-import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
@@ -344,8 +343,8 @@ public abstract class BackupAgent extends ContextWrapper {
return;
}
- Map<String, Set<PathWithRequiredFlags>> manifestIncludeMap;
- ArraySet<PathWithRequiredFlags> manifestExcludeSet;
+ Map<String, Set<String>> manifestIncludeMap;
+ ArraySet<String> manifestExcludeSet;
try {
manifestIncludeMap =
backupScheme.maybeParseAndGetCanonicalIncludePaths();
@@ -515,13 +514,14 @@ public abstract class BackupAgent extends ContextWrapper {
/**
* Check whether the xml yielded any <include/> tag for the provided <code>domainToken</code>.
* If so, perform a {@link #fullBackupFileTree} which backs up the file or recurses if the path
- * is a directory, but only if all the required flags of the include rule are satisfied by
- * the transport.
+ * is a directory.
*/
private void applyXmlFiltersAndDoFullBackupForDomain(String packageName, String domainToken,
- Map<String, Set<PathWithRequiredFlags>> includeMap,
- ArraySet<PathWithRequiredFlags> filterSet, ArraySet<String> traversalExcludeSet,
- FullBackupDataOutput data) throws IOException {
+ Map<String, Set<String>> includeMap,
+ ArraySet<String> filterSet,
+ ArraySet<String> traversalExcludeSet,
+ FullBackupDataOutput data)
+ throws IOException {
if (includeMap == null || includeMap.size() == 0) {
// Do entire sub-tree for the provided token.
fullBackupFileTree(packageName, domainToken,
@@ -530,22 +530,13 @@ public abstract class BackupAgent extends ContextWrapper {
} else if (includeMap.get(domainToken) != null) {
// This will be null if the xml parsing didn't yield any rules for
// this domain (there may still be rules for other domains).
- for (PathWithRequiredFlags includeFile : includeMap.get(domainToken)) {
- if (areIncludeRequiredTransportFlagsSatisfied(includeFile.getRequiredFlags(),
- data.getTransportFlags())) {
- fullBackupFileTree(packageName, domainToken, includeFile.getPath(), filterSet,
- traversalExcludeSet, data);
- }
+ for (String includeFile : includeMap.get(domainToken)) {
+ fullBackupFileTree(packageName, domainToken, includeFile, filterSet,
+ traversalExcludeSet, data);
}
}
}
- private boolean areIncludeRequiredTransportFlagsSatisfied(int includeFlags,
- int transportFlags) {
- // all bits that are set in includeFlags must also be set in transportFlags
- return (transportFlags & includeFlags) == includeFlags;
- }
-
/**
* Write an entire file as part of a full-backup operation. The file's contents
* will be delivered to the backup destination along with the metadata necessary
@@ -692,7 +683,7 @@ public abstract class BackupAgent extends ContextWrapper {
* @hide
*/
protected final void fullBackupFileTree(String packageName, String domain, String startingPath,
- ArraySet<PathWithRequiredFlags> manifestExcludes,
+ ArraySet<String> manifestExcludes,
ArraySet<String> systemExcludes,
FullBackupDataOutput output) {
// Pull out the domain and set it aside to use when making the tarball.
@@ -723,8 +714,7 @@ public abstract class BackupAgent extends ContextWrapper {
filePath = file.getCanonicalPath();
// prune this subtree?
- if (manifestExcludes != null
- && manifestExcludesContainFilePath(manifestExcludes, filePath)) {
+ if (manifestExcludes != null && manifestExcludes.contains(filePath)) {
continue;
}
if (systemExcludes != null && systemExcludes.contains(filePath)) {
@@ -760,17 +750,6 @@ public abstract class BackupAgent extends ContextWrapper {
}
}
- private boolean manifestExcludesContainFilePath(
- ArraySet<PathWithRequiredFlags> manifestExcludes, String filePath) {
- for (PathWithRequiredFlags exclude : manifestExcludes) {
- String excludePath = exclude.getPath();
- if (excludePath != null && excludePath.equals(filePath)) {
- return true;
- }
- }
- return false;
- }
-
/**
* Handle the data delivered via the given file descriptor during a full restore
* operation. The agent is given the path to the file's original location as well
@@ -817,8 +796,8 @@ public abstract class BackupAgent extends ContextWrapper {
return false;
}
- Map<String, Set<PathWithRequiredFlags>> includes = null;
- ArraySet<PathWithRequiredFlags> excludes = null;
+ Map<String, Set<String>> includes = null;
+ ArraySet<String> excludes = null;
final String destinationCanonicalPath = destination.getCanonicalPath();
try {
includes = bs.maybeParseAndGetCanonicalIncludePaths();
@@ -847,7 +826,7 @@ public abstract class BackupAgent extends ContextWrapper {
// Rather than figure out the <include/> domain based on the path (a lot of code, and
// it's a small list), we'll go through and look for it.
boolean explicitlyIncluded = false;
- for (Set<PathWithRequiredFlags> domainIncludes : includes.values()) {
+ for (Set<String> domainIncludes : includes.values()) {
explicitlyIncluded |= isFileSpecifiedInPathList(destination, domainIncludes);
if (explicitlyIncluded) {
break;
@@ -870,10 +849,9 @@ public abstract class BackupAgent extends ContextWrapper {
* @return True if the provided file is either directly in the provided list, or the provided
* file is within a directory in the list.
*/
- private boolean isFileSpecifiedInPathList(File file,
- Collection<PathWithRequiredFlags> canonicalPathList) throws IOException {
- for (PathWithRequiredFlags canonical : canonicalPathList) {
- String canonicalPath = canonical.getPath();
+ private boolean isFileSpecifiedInPathList(File file, Collection<String> canonicalPathList)
+ throws IOException {
+ for (String canonicalPath : canonicalPathList) {
File fileFromList = new File(canonicalPath);
if (fileFromList.isDirectory()) {
if (file.isDirectory()) {
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index fb1c2d085df6..a5dd5bd30d63 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -82,9 +82,6 @@ public class FullBackup {
public static final String FULL_RESTORE_INTENT_ACTION = "fullrest";
public static final String CONF_TOKEN_INTENT_EXTRA = "conftoken";
- public static final String FLAG_REQUIRED_CLIENT_SIDE_ENCRYPTION = "clientSideEncryption";
- public static final String FLAG_REQUIRED_DEVICE_TO_DEVICE_TRANSFER = "deviceToDeviceTransfer";
-
/**
* @hide
*/
@@ -227,9 +224,6 @@ public class FullBackup {
private final File EXTERNAL_DIR;
- private final static String TAG_INCLUDE = "include";
- private final static String TAG_EXCLUDE = "exclude";
-
final int mFullBackupContent;
final PackageManager mPackageManager;
final StorageManager mStorageManager;
@@ -309,45 +303,15 @@ public class FullBackup {
}
/**
- * Represents a path attribute specified in an <include /> rule along with optional
- * transport flags required from the transport to include file(s) under that path as
- * specified by requiredFlags attribute. If optional requiredFlags attribute is not
- * provided, default requiredFlags to 0.
- * Note: since our parsing codepaths were the same for <include /> and <exclude /> tags,
- * this structure is also used for <exclude /> tags to preserve that, however you can expect
- * the getRequiredFlags() to always return 0 for exclude rules.
- */
- public static class PathWithRequiredFlags {
- private final String mPath;
- private final int mRequiredFlags;
-
- public PathWithRequiredFlags(String path, int requiredFlags) {
- mPath = path;
- mRequiredFlags = requiredFlags;
- }
-
- public String getPath() {
- return mPath;
- }
-
- public int getRequiredFlags() {
- return mRequiredFlags;
- }
- }
-
- /**
- * A map of domain -> set of pairs (canonical file; required transport flags) in that
- * domain that are to be included if the transport has decared the required flags.
- * We keep track of the domain so that we can go through the file system in order later on.
- */
- Map<String, Set<PathWithRequiredFlags>> mIncludes;
-
- /**
- * Set that will be populated with pairs (canonical file; requiredFlags=0) for each file or
- * directory that is to be excluded. Note that for excludes, the requiredFlags attribute is
- * ignored and the value should be always set to 0.
+ * A map of domain -> list of canonical file names in that domain that are to be included.
+ * We keep track of the domain so that we can go through the file system in order later on.
+ */
+ Map<String, Set<String>> mIncludes;
+ /**e
+ * List that will be populated with the canonical names of each file or directory that is
+ * to be excluded.
*/
- ArraySet<PathWithRequiredFlags> mExcludes;
+ ArraySet<String> mExcludes;
BackupScheme(Context context) {
mFullBackupContent = context.getApplicationInfo().fullBackupContent;
@@ -392,14 +356,13 @@ public class FullBackup {
}
/**
- * @return A mapping of domain -> set of pairs (canonical file; required transport flags)
- * in that domain that are to be included if the transport has decared the required flags.
- * Each of these paths specifies a file that the client has explicitly included in their
- * backup set. If this map is empty we will back up the entire data directory (including
- * managed external storage).
+ * @return A mapping of domain -> canonical paths within that domain. Each of these paths
+ * specifies a file that the client has explicitly included in their backup set. If this
+ * map is empty we will back up the entire data directory (including managed external
+ * storage).
*/
- public synchronized Map<String, Set<PathWithRequiredFlags>>
- maybeParseAndGetCanonicalIncludePaths() throws IOException, XmlPullParserException {
+ public synchronized Map<String, Set<String>> maybeParseAndGetCanonicalIncludePaths()
+ throws IOException, XmlPullParserException {
if (mIncludes == null) {
maybeParseBackupSchemeLocked();
}
@@ -407,10 +370,9 @@ public class FullBackup {
}
/**
- * @return A set of (canonical paths; requiredFlags=0) that are to be excluded from the
- * backup/restore set.
+ * @return A set of canonical paths that are to be excluded from the backup/restore set.
*/
- public synchronized ArraySet<PathWithRequiredFlags> maybeParseAndGetCanonicalExcludePaths()
+ public synchronized ArraySet<String> maybeParseAndGetCanonicalExcludePaths()
throws IOException, XmlPullParserException {
if (mExcludes == null) {
maybeParseBackupSchemeLocked();
@@ -420,8 +382,8 @@ public class FullBackup {
private void maybeParseBackupSchemeLocked() throws IOException, XmlPullParserException {
// This not being null is how we know that we've tried to parse the xml already.
- mIncludes = new ArrayMap<String, Set<PathWithRequiredFlags>>();
- mExcludes = new ArraySet<PathWithRequiredFlags>();
+ mIncludes = new ArrayMap<String, Set<String>>();
+ mExcludes = new ArraySet<String>();
if (mFullBackupContent == 0) {
// android:fullBackupContent="true" which means that we'll do everything.
@@ -453,8 +415,8 @@ public class FullBackup {
@VisibleForTesting
public void parseBackupSchemeFromXmlLocked(XmlPullParser parser,
- Set<PathWithRequiredFlags> excludes,
- Map<String, Set<PathWithRequiredFlags>> includes)
+ Set<String> excludes,
+ Map<String, Set<String>> includes)
throws IOException, XmlPullParserException {
int event = parser.getEventType(); // START_DOCUMENT
while (event != XmlPullParser.START_TAG) {
@@ -479,7 +441,8 @@ public class FullBackup {
case XmlPullParser.START_TAG:
validateInnerTagContents(parser);
final String domainFromXml = parser.getAttributeValue(null, "domain");
- final File domainDirectory = getDirectoryForCriteriaDomain(domainFromXml);
+ final File domainDirectory =
+ getDirectoryForCriteriaDomain(domainFromXml);
if (domainDirectory == null) {
if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
Log.v(TAG_XML_PARSER, "...parsing \"" + parser.getName() + "\": "
@@ -494,23 +457,12 @@ public class FullBackup {
break;
}
- int requiredFlags = 0; // no transport flags are required by default
- if (TAG_INCLUDE.equals(parser.getName())) {
- // requiredFlags are only supported for <include /> tag, for <exclude />
- // we should always leave them as the default = 0
- requiredFlags = getRequiredFlagsFromString(
- parser.getAttributeValue(null, "requireFlags"));
- }
-
- // retrieve the include/exclude set we'll be adding this rule to
- Set<PathWithRequiredFlags> activeSet = parseCurrentTagForDomain(
+ Set<String> activeSet = parseCurrentTagForDomain(
parser, excludes, includes, domainFromXml);
- activeSet.add(new PathWithRequiredFlags(canonicalFile.getCanonicalPath(),
- requiredFlags));
+ activeSet.add(canonicalFile.getCanonicalPath());
if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
Log.v(TAG_XML_PARSER, "...parsed " + canonicalFile.getCanonicalPath()
- + " for domain \"" + domainFromXml + "\", requiredFlags + \""
- + requiredFlags + "\"");
+ + " for domain \"" + domainFromXml + "\"");
}
// Special case journal files (not dirs) for sqlite database. frowny-face.
@@ -520,16 +472,14 @@ public class FullBackup {
if ("database".equals(domainFromXml) && !canonicalFile.isDirectory()) {
final String canonicalJournalPath =
canonicalFile.getCanonicalPath() + "-journal";
- activeSet.add(new PathWithRequiredFlags(canonicalJournalPath,
- requiredFlags));
+ activeSet.add(canonicalJournalPath);
if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
Log.v(TAG_XML_PARSER, "...automatically generated "
+ canonicalJournalPath + ". Ignore if nonexistent.");
}
final String canonicalWalPath =
canonicalFile.getCanonicalPath() + "-wal";
- activeSet.add(new PathWithRequiredFlags(canonicalWalPath,
- requiredFlags));
+ activeSet.add(canonicalWalPath);
if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
Log.v(TAG_XML_PARSER, "...automatically generated "
+ canonicalWalPath + ". Ignore if nonexistent.");
@@ -541,8 +491,7 @@ public class FullBackup {
!canonicalFile.getCanonicalPath().endsWith(".xml")) {
final String canonicalXmlPath =
canonicalFile.getCanonicalPath() + ".xml";
- activeSet.add(new PathWithRequiredFlags(canonicalXmlPath,
- requiredFlags));
+ activeSet.add(canonicalXmlPath);
if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
Log.v(TAG_XML_PARSER, "...automatically generated "
+ canonicalXmlPath + ". Ignore if nonexistent.");
@@ -559,12 +508,10 @@ public class FullBackup {
Log.v(TAG_XML_PARSER, " ...nothing specified (This means the entirety of app"
+ " data minus excludes)");
} else {
- for (Map.Entry<String, Set<PathWithRequiredFlags>> entry
- : includes.entrySet()) {
+ for (Map.Entry<String, Set<String>> entry : includes.entrySet()) {
Log.v(TAG_XML_PARSER, " domain=" + entry.getKey());
- for (PathWithRequiredFlags includeData : entry.getValue()) {
- Log.v(TAG_XML_PARSER, " path: " + includeData.getPath()
- + " requiredFlags: " + includeData.getRequiredFlags());
+ for (String includeData : entry.getValue()) {
+ Log.v(TAG_XML_PARSER, " " + includeData);
}
}
}
@@ -573,9 +520,8 @@ public class FullBackup {
if (excludes.isEmpty()) {
Log.v(TAG_XML_PARSER, " ...nothing to exclude.");
} else {
- for (PathWithRequiredFlags excludeData : excludes) {
- Log.v(TAG_XML_PARSER, " path: " + excludeData.getPath()
- + " requiredFlags: " + excludeData.getRequiredFlags());
+ for (String excludeData : excludes) {
+ Log.v(TAG_XML_PARSER, " " + excludeData);
}
}
@@ -585,41 +531,20 @@ public class FullBackup {
}
}
- private int getRequiredFlagsFromString(String requiredFlags) {
- int flags = 0;
- if (requiredFlags == null || requiredFlags.length() == 0) {
- // requiredFlags attribute was missing or empty in <include /> tag
- return flags;
- }
- String[] flagsStr = requiredFlags.split("\\|");
- for (String f : flagsStr) {
- switch (f) {
- case FLAG_REQUIRED_CLIENT_SIDE_ENCRYPTION:
- flags |= BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED;
- break;
- case FLAG_REQUIRED_DEVICE_TO_DEVICE_TRANSFER:
- flags |= BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER;
- break;
- default:
- Log.w(TAG, "Unrecognized requiredFlag provided, value: \"" + f + "\"");
- }
- }
- return flags;
- }
-
- private Set<PathWithRequiredFlags> parseCurrentTagForDomain(XmlPullParser parser,
- Set<PathWithRequiredFlags> excludes,
- Map<String, Set<PathWithRequiredFlags>> includes, String domain)
+ private Set<String> parseCurrentTagForDomain(XmlPullParser parser,
+ Set<String> excludes,
+ Map<String, Set<String>> includes,
+ String domain)
throws XmlPullParserException {
- if (TAG_INCLUDE.equals(parser.getName())) {
+ if ("include".equals(parser.getName())) {
final String domainToken = getTokenForXmlDomain(domain);
- Set<PathWithRequiredFlags> includeSet = includes.get(domainToken);
+ Set<String> includeSet = includes.get(domainToken);
if (includeSet == null) {
- includeSet = new ArraySet<PathWithRequiredFlags>();
+ includeSet = new ArraySet<String>();
includes.put(domainToken, includeSet);
}
return includeSet;
- } else if (TAG_EXCLUDE.equals(parser.getName())) {
+ } else if ("exclude".equals(parser.getName())) {
return excludes;
} else {
// Unrecognised tag => hard failure.
@@ -664,8 +589,8 @@ public class FullBackup {
/**
*
* @param domain Directory where the specified file should exist. Not null.
- * @param filePathFromXml parsed from xml. Not sanitised before calling this function so may
- * be null.
+ * @param filePathFromXml parsed from xml. Not sanitised before calling this function so may be
+ * null.
* @return The canonical path of the file specified or null if no such file exists.
*/
private File extractCanonicalFile(File domain, String filePathFromXml) {
@@ -725,27 +650,15 @@ public class FullBackup {
* Let's be strict about the type of xml the client can write. If we see anything untoward,
* throw an XmlPullParserException.
*/
- private void validateInnerTagContents(XmlPullParser parser) throws XmlPullParserException {
- if (parser == null) {
- return;
+ private void validateInnerTagContents(XmlPullParser parser)
+ throws XmlPullParserException {
+ if (parser.getAttributeCount() > 2) {
+ throw new XmlPullParserException("At most 2 tag attributes allowed for \""
+ + parser.getName() + "\" tag (\"domain\" & \"path\".");
}
- switch (parser.getName()) {
- case TAG_INCLUDE:
- if (parser.getAttributeCount() > 3) {
- throw new XmlPullParserException("At most 3 tag attributes allowed for "
- + "\"include\" tag (\"domain\" & \"path\""
- + " & optional \"requiredFlags\").");
- }
- break;
- case TAG_EXCLUDE:
- if (parser.getAttributeCount() > 2) {
- throw new XmlPullParserException("At most 2 tag attributes allowed for "
- + "\"exclude\" tag (\"domain\" & \"path\".");
- }
- break;
- default:
- throw new XmlPullParserException("A valid tag is one of \"<include/>\" or" +
- " \"<exclude/>. You provided \"" + parser.getName() + "\"");
+ if (!"include".equals(parser.getName()) && !"exclude".equals(parser.getName())) {
+ throw new XmlPullParserException("A valid tag is one of \"<include/>\" or" +
+ " \"<exclude/>. You provided \"" + parser.getName() + "\"");
}
}
}