Make FullBackup::BackupScheme aware of operation type
We currently maintain an instance of FullBackup::BackupScheme (encapsulates full backup policies, including include / exclude rules) per package. In line with the new include / exclude config format, where the rules for each operation types are separate, create BackupScheme per (package; operation type) pair to make sure we're only dealing with the policies relevant to the current operation. Bug: 174216309 Test: atest FullBackupRulesHostSideTest Change-Id: I627584186a1d1faf3d699e734e45f5e943ec1f84
This commit is contained in:
@@ -401,7 +401,8 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
* @see #onRestoreFile(ParcelFileDescriptor, long, File, int, long, long)
|
||||
*/
|
||||
public void onFullBackup(FullBackupDataOutput data) throws IOException {
|
||||
FullBackup.BackupScheme backupScheme = FullBackup.getBackupScheme(this);
|
||||
FullBackup.BackupScheme backupScheme = FullBackup.getBackupScheme(this,
|
||||
mOperationType);
|
||||
if (!isDeviceToDeviceMigration() && !backupScheme.isFullBackupContentEnabled()) {
|
||||
return;
|
||||
}
|
||||
@@ -624,7 +625,8 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
if (includeMap == null || includeMap.size() == 0) {
|
||||
// Do entire sub-tree for the provided token.
|
||||
fullBackupFileTree(packageName, domainToken,
|
||||
FullBackup.getBackupScheme(this).tokenToDirectoryPath(domainToken),
|
||||
FullBackup.getBackupScheme(this, mOperationType)
|
||||
.tokenToDirectoryPath(domainToken),
|
||||
filterSet, traversalExcludeSet, data);
|
||||
} else if (includeMap.get(domainToken) != null) {
|
||||
// This will be null if the xml parsing didn't yield any rules for
|
||||
@@ -795,7 +797,8 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
ArraySet<String> systemExcludes,
|
||||
FullBackupDataOutput output) {
|
||||
// Pull out the domain and set it aside to use when making the tarball.
|
||||
String domainPath = FullBackup.getBackupScheme(this).tokenToDirectoryPath(domain);
|
||||
String domainPath = FullBackup.getBackupScheme(this, mOperationType)
|
||||
.tokenToDirectoryPath(domain);
|
||||
if (domainPath == null) {
|
||||
// Should never happen.
|
||||
return;
|
||||
@@ -911,7 +914,7 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
return true;
|
||||
}
|
||||
|
||||
FullBackup.BackupScheme bs = FullBackup.getBackupScheme(this);
|
||||
FullBackup.BackupScheme bs = FullBackup.getBackupScheme(this, mOperationType);
|
||||
if (!bs.isFullBackupContentEnabled()) {
|
||||
if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) {
|
||||
Log.v(FullBackup.TAG_XML_PARSER,
|
||||
@@ -985,7 +988,8 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
+ " domain=" + domain + " relpath=" + path + " mode=" + mode
|
||||
+ " mtime=" + mtime);
|
||||
|
||||
basePath = FullBackup.getBackupScheme(this).tokenToDirectoryPath(domain);
|
||||
basePath = FullBackup.getBackupScheme(this, mOperationType).tokenToDirectoryPath(
|
||||
domain);
|
||||
if (domain.equals(FullBackup.MANAGED_EXTERNAL_TREE_TOKEN)) {
|
||||
mode = -1; // < 0 is a token to skip attempting a chmod()
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package android.app.backup;
|
||||
|
||||
import static android.app.backup.BackupManager.OperationType;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -41,6 +44,7 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -89,6 +93,38 @@ public class FullBackup {
|
||||
public static final String FLAG_REQUIRED_FAKE_CLIENT_SIDE_ENCRYPTION =
|
||||
"fakeClientSideEncryption";
|
||||
|
||||
/**
|
||||
* Identify {@link BackupScheme} object by package and operation type
|
||||
* (see {@link OperationType}) it corresponds to.
|
||||
*/
|
||||
private static class BackupSchemeId {
|
||||
final String mPackageName;
|
||||
@OperationType final int mOperationType;
|
||||
|
||||
BackupSchemeId(String packageName, @OperationType int operationType) {
|
||||
mPackageName = packageName;
|
||||
mOperationType = operationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mPackageName, mOperationType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object == null || getClass() != object.getClass()) {
|
||||
return false;
|
||||
}
|
||||
BackupSchemeId that = (BackupSchemeId) object;
|
||||
return Objects.equals(mPackageName, that.mPackageName) &&
|
||||
Objects.equals(mOperationType, that.mOperationType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -96,21 +132,23 @@ public class FullBackup {
|
||||
static public native int backupToTar(String packageName, String domain,
|
||||
String linkdomain, String rootpath, String path, FullBackupDataOutput output);
|
||||
|
||||
private static final Map<String, BackupScheme> kPackageBackupSchemeMap =
|
||||
new ArrayMap<String, BackupScheme>();
|
||||
private static final Map<BackupSchemeId, BackupScheme> kPackageBackupSchemeMap =
|
||||
new ArrayMap<>();
|
||||
|
||||
static synchronized BackupScheme getBackupScheme(Context context) {
|
||||
static synchronized BackupScheme getBackupScheme(Context context,
|
||||
@OperationType int operationType) {
|
||||
BackupSchemeId backupSchemeId = new BackupSchemeId(context.getPackageName(), operationType);
|
||||
BackupScheme backupSchemeForPackage =
|
||||
kPackageBackupSchemeMap.get(context.getPackageName());
|
||||
kPackageBackupSchemeMap.get(backupSchemeId);
|
||||
if (backupSchemeForPackage == null) {
|
||||
backupSchemeForPackage = new BackupScheme(context);
|
||||
kPackageBackupSchemeMap.put(context.getPackageName(), backupSchemeForPackage);
|
||||
backupSchemeForPackage = new BackupScheme(context, operationType);
|
||||
kPackageBackupSchemeMap.put(backupSchemeId, backupSchemeForPackage);
|
||||
}
|
||||
return backupSchemeForPackage;
|
||||
}
|
||||
|
||||
public static BackupScheme getBackupSchemeForTest(Context context) {
|
||||
BackupScheme testing = new BackupScheme(context);
|
||||
BackupScheme testing = new BackupScheme(context, OperationType.BACKUP);
|
||||
testing.mExcludes = new ArraySet();
|
||||
testing.mIncludes = new ArrayMap();
|
||||
return testing;
|
||||
@@ -236,6 +274,7 @@ public class FullBackup {
|
||||
private final static String TAG_EXCLUDE = "exclude";
|
||||
|
||||
final int mFullBackupContent;
|
||||
@OperationType final int mOperationType;
|
||||
final PackageManager mPackageManager;
|
||||
final StorageManager mStorageManager;
|
||||
final String mPackageName;
|
||||
@@ -354,8 +393,9 @@ public class FullBackup {
|
||||
*/
|
||||
ArraySet<PathWithRequiredFlags> mExcludes;
|
||||
|
||||
BackupScheme(Context context) {
|
||||
BackupScheme(Context context, @OperationType int operationType) {
|
||||
mFullBackupContent = context.getApplicationInfo().fullBackupContent;
|
||||
mOperationType = operationType;
|
||||
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
|
||||
mPackageManager = context.getPackageManager();
|
||||
mPackageName = context.getPackageName();
|
||||
|
||||
Reference in New Issue
Block a user