summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java27
-rw-r--r--services/tests/servicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java38
2 files changed, 53 insertions, 12 deletions
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 16484df9f328..f90d936a5f4d 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -76,6 +76,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -697,11 +698,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
mStageName = new File(backupManagerService.getDataDir(), packageName + ".stage");
mNewStateName = new File(mStateDir, packageName + ".new");
- // don't stage the 'android' package where the wallpaper data lives. this is
- // an optimization: we know there's no widget data hosted/published by that
- // package, and this way we avoid doing a spurious copy of MB-sized wallpaper
- // data following the download.
- boolean staging = !packageName.equals(PLATFORM_PACKAGE_NAME);
+ boolean staging = shouldStageBackupData(packageName);
ParcelFileDescriptor stage;
File downloadFile = (staging) ? mStageName : mBackupDataName;
boolean startedAgentRestore = false;
@@ -768,8 +765,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
startedAgentRestore = true;
mAgent.doRestoreWithExcludedKeys(mBackupData, appVersionCode, mNewState,
mEphemeralOpToken, backupManagerService.getBackupManagerBinder(),
- mExcludedKeys.containsKey(packageName)
- ? new ArrayList<>(mExcludedKeys.get(packageName)) : null);
+ new ArrayList<>(getExcludedKeysForPackage(packageName)));
} catch (Exception e) {
Slog.e(TAG, "Unable to call app for restore: " + packageName, e);
EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
@@ -785,9 +781,24 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
}
@VisibleForTesting
+ boolean shouldStageBackupData(String packageName) {
+ // Backup data is staged for 2 reasons:
+ // 1. We might need to exclude keys from the data before passing it to the agent
+ // 2. Widget metadata needs to be separated from the rest to be handled separately
+ // But 'android' package doesn't contain widget metadata so we want to skip staging for it
+ // when there are no keys to be excluded either.
+ return !packageName.equals(PLATFORM_PACKAGE_NAME) ||
+ !getExcludedKeysForPackage(PLATFORM_PACKAGE_NAME).isEmpty();
+ }
+
+ private Set<String> getExcludedKeysForPackage(String packageName) {
+ return mExcludedKeys.getOrDefault(packageName, Collections.emptySet());
+ }
+
+ @VisibleForTesting
void filterExcludedKeys(String packageName, BackupDataInput in, BackupDataOutput out)
throws Exception {
- Set<String> excludedKeysForPackage = mExcludedKeys.get(packageName);
+ Set<String> excludedKeysForPackage = getExcludedKeysForPackage(packageName);
byte[] buffer = new byte[8192]; // will grow when needed
while (in.readNextHeader()) {
diff --git a/services/tests/servicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java b/services/tests/servicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java
index 6359edf190b0..3d220432cc8e 100644
--- a/services/tests/servicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/restore/PerformUnifiedRestoreTaskTest.java
@@ -20,7 +20,6 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;
@@ -55,6 +54,8 @@ public class PerformUnifiedRestoreTaskTest {
private static final String INCLUDED_KEY = "included_key";
private static final String EXCLUDED_KEY_1 = "excluded_key_1";
private static final String EXCLUDED_KEY_2 = "excluded_key_2";
+ private static final String SYSTEM_PACKAGE_NAME = "android";
+ private static final String NON_SYSTEM_PACKAGE_NAME = "package";
@Mock private BackupDataInput mBackupDataInput;
@Mock private BackupDataOutput mBackupDataOutput;
@@ -98,9 +99,6 @@ public class PerformUnifiedRestoreTaskTest {
return null;
}
});
-
- mRestoreTask = new PerformUnifiedRestoreTask(Collections.singletonMap(
- PACKAGE_NAME, mExcludedkeys));
}
private void populateTestData() {
@@ -116,6 +114,8 @@ public class PerformUnifiedRestoreTaskTest {
@Test
public void testFilterExcludedKeys() throws Exception {
+ mRestoreTask = new PerformUnifiedRestoreTask(Collections.singletonMap(
+ PACKAGE_NAME, mExcludedkeys));
mRestoreTask.filterExcludedKeys(PACKAGE_NAME, mBackupDataInput, mBackupDataOutput);
// Verify only the correct were written into BackupDataOutput object.
@@ -123,4 +123,34 @@ public class PerformUnifiedRestoreTaskTest {
allowedBackupKeys.removeAll(mExcludedkeys);
assertEquals(allowedBackupKeys, mBackupDataDump);
}
+
+ @Test
+ public void testStageBackupData_stageForNonSystemPackageWithKeysToExclude() {
+ mRestoreTask = new PerformUnifiedRestoreTask(Collections.singletonMap(
+ PACKAGE_NAME, mExcludedkeys));
+
+ assertTrue(mRestoreTask.shouldStageBackupData(NON_SYSTEM_PACKAGE_NAME));
+ }
+
+ @Test
+ public void testStageBackupData_stageForNonSystemPackageWithNoKeysToExclude() {
+ mRestoreTask = new PerformUnifiedRestoreTask(Collections.emptyMap());
+
+ assertTrue(mRestoreTask.shouldStageBackupData(NON_SYSTEM_PACKAGE_NAME));
+ }
+
+ @Test
+ public void testStageBackupData_doNotStageForSystemPackageWithNoKeysToExclude() {
+ mRestoreTask = new PerformUnifiedRestoreTask(Collections.emptyMap());
+
+ assertFalse(mRestoreTask.shouldStageBackupData(SYSTEM_PACKAGE_NAME));
+ }
+
+ @Test
+ public void testStageBackupData_stageForSystemPackageWithKeysToExclude() {
+ mRestoreTask = new PerformUnifiedRestoreTask(Collections.singletonMap(
+ PACKAGE_NAME, mExcludedkeys));
+
+ assertTrue(mRestoreTask.shouldStageBackupData(NON_SYSTEM_PACKAGE_NAME));
+ }
}