Clear app data before full restore for specified packages
In some cases (deferred restore) the app data needs to be cleared even
if the app has implemented backup agent. As a quick fix introduce
PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE secure setting, which
transport can fill prior to restore.
Bug: 69069240
Test: adb shell settings put secure packages_to_clear_data_before_full_restore com.google.android.apps.nexuslauncher && adb shell bmgr restore com.google.android.apps.nexuslauncher
Change-Id: I2a4651365d9cf4747f32d2ba69312f54cd03d118
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 70f343e..b7f6cde 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7809,6 +7809,14 @@
"suppress_auto_battery_saver_suggestion";
/**
+ * List of packages, which data need to be unconditionally cleared before full restore.
+ * Type: string
+ * @hide
+ */
+ public static final String PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE =
+ "packages_to_clear_data_before_full_restore";
+
+ /**
* This are the settings to be backed up.
*
* NOTE: Settings are backed up and restored in the order they appear
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index cfb8980..593747d 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -145,6 +145,7 @@
optional SettingProto transport = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto manager_constants = 5;
optional SettingProto local_transport_parameters = 6;
+ optional SettingProto packages_to_clear_data_before_full_restore = 7;
}
optional Backup backup = 10;
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 2a3fcad..4b9465d 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -587,7 +587,8 @@
Settings.Secure.BLUETOOTH_ON_WHILE_DRIVING,
Settings.Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT,
Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
- Settings.Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION);
+ Settings.Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION,
+ Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE);
@Test
public void systemSettingsBackedUpOrBlacklisted() {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index a444ac8..f43e719 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1724,6 +1724,9 @@
dumpSetting(s, p,
Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS,
SecureSettingsProto.Backup.LOCAL_TRANSPORT_PARAMETERS);
+ dumpSetting(s, p,
+ Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE,
+ SecureSettingsProto.Backup.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE);
p.end(backupToken);
// Settings.Secure.BLUETOOTH_ON intentionally excluded since it's deprecated.
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index c1a1c1d..9607d24 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -40,6 +40,8 @@
import android.content.pm.Signature;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.provider.Settings;
+import android.text.TextUtils;
import android.util.Slog;
import com.android.server.LocalServices;
@@ -56,8 +58,11 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
/**
* Full restore engine, used by both adb restore and transport-based full restore.
@@ -320,12 +325,17 @@
pkg, 0);
// If we haven't sent any data to this app yet, we probably
- // need to clear it first. Check that.
+ // need to clear it first. Check that.
if (!mClearedPackages.contains(pkg)) {
- // apps with their own backup agents are
- // responsible for coherently managing a full
- // restore.
- if (mTargetApp.backupAgentName == null) {
+ // Apps with their own backup agents are responsible for coherently
+ // managing a full restore.
+ // In some rare cases they can't, especially in case of deferred
+ // restore. In this case check whether this app should be forced to
+ // clear up.
+ // TODO: Fix this properly with manifest parameter.
+ boolean forceClear = shouldForceClearAppDataOnFullRestore(
+ mTargetApp.packageName);
+ if (mTargetApp.backupAgentName == null || forceClear) {
if (DEBUG) {
Slog.d(TAG,
"Clearing app data preparatory to full restore");
@@ -623,6 +633,24 @@
return true;
}
+ /**
+ * Returns whether the package is in the list of the packages for which clear app data should
+ * be called despite the fact that they have backup agent.
+ *
+ * <p>The list is read from {@link Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE}.
+ */
+ private boolean shouldForceClearAppDataOnFullRestore(String packageName) {
+ String packageListString = Settings.Secure.getString(
+ mBackupManagerService.getContext().getContentResolver(),
+ Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE);
+ if (TextUtils.isEmpty(packageListString)) {
+ return false;
+ }
+
+ List<String> packages = Arrays.asList(packageListString.split(";"));
+ return packages.contains(packageName);
+ }
+
void sendOnRestorePackage(String name) {
if (mObserver != null) {
try {