Merge "Handle empty <cloud-backup> section in android:dataExtractionRules" into sc-dev

This commit is contained in:
Ruslan Tkhakokhov
2021-08-06 21:47:56 +00:00
committed by Android (Google) Code Review
2 changed files with 49 additions and 6 deletions

View File

@@ -116,7 +116,7 @@ public class FullBackup {
ConfigSection.CLOUD_BACKUP, ConfigSection.CLOUD_BACKUP,
ConfigSection.DEVICE_TRANSFER ConfigSection.DEVICE_TRANSFER
}) })
private @interface ConfigSection { @interface ConfigSection {
String CLOUD_BACKUP = "cloud-backup"; String CLOUD_BACKUP = "cloud-backup";
String DEVICE_TRANSFER = "device-transfer"; String DEVICE_TRANSFER = "device-transfer";
} }
@@ -528,7 +528,8 @@ public class FullBackup {
return mExcludes; return mExcludes;
} }
private synchronized int getRequiredTransportFlags() @VisibleForTesting
public synchronized int getRequiredTransportFlags()
throws IOException, XmlPullParserException { throws IOException, XmlPullParserException {
if (mRequiredTransportFlags == null) { if (mRequiredTransportFlags == null) {
maybeParseBackupSchemeLocked(); maybeParseBackupSchemeLocked();
@@ -587,11 +588,13 @@ public class FullBackup {
if (mDataExtractionRules != 0) { if (mDataExtractionRules != 0) {
// New config is present. Use it if it has configuration for this operation // New config is present. Use it if it has configuration for this operation
// type. // type.
boolean isSectionPresent;
try (XmlResourceParser parser = getParserForResource(mDataExtractionRules)) { try (XmlResourceParser parser = getParserForResource(mDataExtractionRules)) {
parseNewBackupSchemeFromXmlLocked(parser, configSection, mExcludes, mIncludes); isSectionPresent = parseNewBackupSchemeFromXmlLocked(parser, configSection,
mExcludes, mIncludes);
} }
if (!mExcludes.isEmpty() || !mIncludes.isEmpty()) { if (isSectionPresent) {
// Found configuration in the new config, we will use it. // Found the relevant section in the new config, we will use it.
mIsUsingNewScheme = true; mIsUsingNewScheme = true;
return; return;
} }
@@ -630,24 +633,31 @@ public class FullBackup {
.getXml(resourceId); .getXml(resourceId);
} }
private void parseNewBackupSchemeFromXmlLocked(XmlPullParser parser, @VisibleForTesting
public boolean parseNewBackupSchemeFromXmlLocked(XmlPullParser parser,
@ConfigSection String configSection, @ConfigSection String configSection,
Set<PathWithRequiredFlags> excludes, Set<PathWithRequiredFlags> excludes,
Map<String, Set<PathWithRequiredFlags>> includes) Map<String, Set<PathWithRequiredFlags>> includes)
throws IOException, XmlPullParserException { throws IOException, XmlPullParserException {
verifyTopLevelTag(parser, "data-extraction-rules"); verifyTopLevelTag(parser, "data-extraction-rules");
boolean isSectionPresent = false;
int event; int event;
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) { while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (event != XmlPullParser.START_TAG || !configSection.equals(parser.getName())) { if (event != XmlPullParser.START_TAG || !configSection.equals(parser.getName())) {
continue; continue;
} }
isSectionPresent = true;
parseRequiredTransportFlags(parser, configSection); parseRequiredTransportFlags(parser, configSection);
parseRules(parser, excludes, includes, Optional.of(0), configSection); parseRules(parser, excludes, includes, Optional.of(0), configSection);
} }
logParsingResults(excludes, includes); logParsingResults(excludes, includes);
return isSectionPresent;
} }
private void parseRequiredTransportFlags(XmlPullParser parser, private void parseRequiredTransportFlags(XmlPullParser parser,

View File

@@ -16,6 +16,8 @@
package android.app.backup; package android.app.backup;
import static android.app.backup.FullBackup.ConfigSection.CLOUD_BACKUP;
import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags; import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
import android.content.Context; import android.content.Context;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
@@ -414,6 +416,37 @@ public class FullBackupTest extends AndroidTestCase {
assertNull("Didn't throw away invalid \"..\" path.", fileDomainIncludes); assertNull("Didn't throw away invalid \"..\" path.", fileDomainIncludes);
} }
public void testParseNewBackupSchemeFromXml_emptyCloudSectionIsRespected() throws Exception {
mXpp.setInput(new StringReader(
"<data-extraction-rules>" +
"<cloud-backup>" +
"</cloud-backup>" +
"</data-extraction-rules>"));
FullBackup.BackupScheme backupScheme = FullBackup.getBackupSchemeForTest(mContext);
boolean result = backupScheme.parseNewBackupSchemeFromXmlLocked(mXpp, CLOUD_BACKUP,
excludesSet, includeMap);
assertTrue(result);
}
public void testParseNewBackupSchemeFromXml_emptyCloudSectionWithEncryptionFlagIsRespected()
throws Exception {
mXpp.setInput(new StringReader(
"<data-extraction-rules>" +
"<cloud-backup disableIfNoEncryptionCapabilities=\"true\">" +
"</cloud-backup>" +
"</data-extraction-rules>"));
FullBackup.BackupScheme backupScheme = FullBackup.getBackupSchemeForTest(mContext);
boolean result = backupScheme.parseNewBackupSchemeFromXmlLocked(mXpp, CLOUD_BACKUP,
excludesSet, includeMap);
assertTrue(result);
assertEquals(backupScheme.getRequiredTransportFlags(),
BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED);
}
public void testDoubleDotInPath_isIgnored() throws Exception { public void testDoubleDotInPath_isIgnored() throws Exception {
mXpp.setInput(new StringReader( mXpp.setInput(new StringReader(
"<full-backup-content>" + "<full-backup-content>" +