Support disableIfNoEncryptionCapabilities attribute

Support disableIfNoEncryptionCapabilities attribute in the
XML config specified by android:dataExtractionRules.The attribute, only applicable to <cloudBackup>, will disable cloud backup if the transport doesn't offer encryption.

Bug: 180523028
Test: atest FullbackupRulesHostSideTest
Change-Id: Ic6dab65834b51ff62c1e1a17b34b850f720681a1
This commit is contained in:
Ruslan Tkhakokhov
2021-03-03 09:42:53 +00:00
parent 5d3166d403
commit 04b8fd0229
4 changed files with 81 additions and 3 deletions

View File

@@ -403,7 +403,7 @@ public abstract class BackupAgent extends ContextWrapper {
public void onFullBackup(FullBackupDataOutput data) throws IOException {
FullBackup.BackupScheme backupScheme = FullBackup.getBackupScheme(this,
mOperationType);
if (!isDeviceToDeviceMigration() && !backupScheme.isFullBackupContentEnabled()) {
if (!backupScheme.isFullBackupEnabled(data.getTransportFlags())) {
return;
}
@@ -911,7 +911,7 @@ public abstract class BackupAgent extends ContextWrapper {
}
FullBackup.BackupScheme bs = FullBackup.getBackupScheme(this, mOperationType);
if (!bs.isFullBackupContentEnabled()) {
if (!bs.isFullRestoreEnabled()) {
if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) {
Log.v(FullBackup.TAG_XML_PARSER,
"onRestoreFile \"" + destination.getCanonicalPath()

View File

@@ -99,6 +99,8 @@ public class FullBackup {
public static final String FLAG_REQUIRED_DEVICE_TO_DEVICE_TRANSFER = "deviceToDeviceTransfer";
public static final String FLAG_REQUIRED_FAKE_CLIENT_SIDE_ENCRYPTION =
"fakeClientSideEncryption";
private static final String FLAG_DISABLE_IF_NO_ENCRYPTION_CAPABILITIES
= "disableIfNoEncryptionCapabilities";
/**
* When this change is enabled, include / exclude rules specified via
@@ -307,6 +309,10 @@ public class FullBackup {
// lazy initialized, only when needed
private StorageVolume[] mVolumes = null;
// Properties the transport must have (e.g. encryption) for the operation to go ahead.
@Nullable private Integer mRequiredTransportFlags;
@Nullable private Boolean mIsUsingNewScheme;
/**
* Parse out the semantic domains into the correct physical location.
*/
@@ -453,6 +459,35 @@ public class FullBackup {
}
}
boolean isFullBackupEnabled(int transportFlags) {
try {
if (isUsingNewScheme()) {
int requiredTransportFlags = getRequiredTransportFlags();
// All bits that are set in requiredTransportFlags must be set in
// transportFlags.
return (transportFlags & requiredTransportFlags) == requiredTransportFlags;
}
} catch (IOException | XmlPullParserException e) {
Slog.w(TAG, "Failed to interpret the backup scheme: " + e);
return false;
}
return isFullBackupContentEnabled();
}
boolean isFullRestoreEnabled() {
try {
if (isUsingNewScheme()) {
return true;
}
} catch (IOException | XmlPullParserException e) {
Slog.w(TAG, "Failed to interpret the backup scheme: " + e);
return false;
}
return isFullBackupContentEnabled();
}
boolean isFullBackupContentEnabled() {
if (mFullBackupContent < 0) {
// android:fullBackupContent="false", bail.
@@ -491,10 +526,30 @@ public class FullBackup {
return mExcludes;
}
private synchronized int getRequiredTransportFlags()
throws IOException, XmlPullParserException {
if (mRequiredTransportFlags == null) {
maybeParseBackupSchemeLocked();
}
return mRequiredTransportFlags;
}
private synchronized boolean isUsingNewScheme()
throws IOException, XmlPullParserException {
if (mIsUsingNewScheme == null) {
maybeParseBackupSchemeLocked();
}
return mIsUsingNewScheme;
}
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>();
mRequiredTransportFlags = 0;
mIsUsingNewScheme = false;
if (mFullBackupContent == 0 && mDataExtractionRules == 0) {
// No scheme specified via either new or legacy config, will copy everything.
@@ -535,12 +590,14 @@ public class FullBackup {
}
if (!mExcludes.isEmpty() || !mIncludes.isEmpty()) {
// Found configuration in the new config, we will use it.
mIsUsingNewScheme = true;
return;
}
}
if (operationType == OperationType.MIGRATION
&& CompatChanges.isChangeEnabled(IGNORE_FULL_BACKUP_CONTENT_IN_D2D)) {
mIsUsingNewScheme = true;
return;
}
@@ -584,13 +641,24 @@ public class FullBackup {
continue;
}
// TODO(b/180523028): Parse required attributes for rules (e.g. encryption).
parseRequiredTransportFlags(parser, configSection);
parseRules(parser, excludes, includes, Optional.of(0), configSection);
}
logParsingResults(excludes, includes);
}
private void parseRequiredTransportFlags(XmlPullParser parser,
@ConfigSection String configSection) {
if (ConfigSection.CLOUD_BACKUP.equals(configSection)) {
String encryptionAttribute = parser.getAttributeValue(/* namespace */ null,
FLAG_DISABLE_IF_NO_ENCRYPTION_CAPABILITIES);
if ("true".equals(encryptionAttribute)) {
mRequiredTransportFlags = BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED;
}
}
}
@VisibleForTesting
public void parseBackupSchemeFromXmlLocked(XmlPullParser parser,
Set<PathWithRequiredFlags> excludes,

View File

@@ -165,6 +165,9 @@ public class LocalTransport extends BackupTransport {
if (mParameters.isDeviceTransfer()) {
flags |= BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER;
}
if (mParameters.isEncrypted()) {
flags |= BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED;
}
return flags;
}

View File

@@ -28,10 +28,12 @@ public class LocalTransportParameters extends KeyValueSettingObserver {
private static final String KEY_FAKE_ENCRYPTION_FLAG = "fake_encryption_flag";
private static final String KEY_NON_INCREMENTAL_ONLY = "non_incremental_only";
private static final String KEY_IS_DEVICE_TRANSFER = "is_device_transfer";
private static final String KEY_IS_ENCRYPTED = "is_encrypted";
private boolean mFakeEncryptionFlag;
private boolean mIsNonIncrementalOnly;
private boolean mIsDeviceTransfer;
private boolean mIsEncrypted;
public LocalTransportParameters(Handler handler, ContentResolver resolver) {
super(handler, resolver, Settings.Secure.getUriFor(SETTING));
@@ -49,6 +51,10 @@ public class LocalTransportParameters extends KeyValueSettingObserver {
return mIsDeviceTransfer;
}
boolean isEncrypted() {
return mIsEncrypted;
}
public String getSettingValue(ContentResolver resolver) {
return Settings.Secure.getString(resolver, SETTING);
}
@@ -57,5 +63,6 @@ public class LocalTransportParameters extends KeyValueSettingObserver {
mFakeEncryptionFlag = parser.getBoolean(KEY_FAKE_ENCRYPTION_FLAG, false);
mIsNonIncrementalOnly = parser.getBoolean(KEY_NON_INCREMENTAL_ONLY, false);
mIsDeviceTransfer = parser.getBoolean(KEY_IS_DEVICE_TRANSFER, false);
mIsEncrypted = parser.getBoolean(KEY_IS_ENCRYPTED, false);
}
}