diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/backup/BackupAgent.java | 60 | ||||
| -rw-r--r-- | core/java/android/app/backup/FullBackup.java | 189 |
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() + "\""); } } } |
