OSDN Git Service

Clear app data before full restore for specified packages
authorArtem Iglikov <artikz@google.com>
Tue, 27 Mar 2018 14:12:18 +0000 (15:12 +0100)
committerArtem Iglikov <artikz@google.com>
Thu, 29 Mar 2018 10:01:50 +0000 (11:01 +0100)
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

core/java/android/provider/Settings.java
core/proto/android/providers/settings/secure.proto
core/tests/coretests/src/android/provider/SettingsBackupTest.java
packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java

index 70f343e..b7f6cde 100644 (file)
@@ -7809,6 +7809,14 @@ public final class Settings {
                 "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
index cfb8980..593747d 100644 (file)
@@ -145,6 +145,7 @@ message SecureSettingsProto {
         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;
 
index 2a3fcad..4b9465d 100644 (file)
@@ -587,7 +587,8 @@ public class SettingsBackupTest {
                  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() {
index a444ac8..f43e719 100644 (file)
@@ -1724,6 +1724,9 @@ class SettingsProtoDumpUtil {
         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.
index c1a1c1d..9607d24 100644 (file)
@@ -40,6 +40,8 @@ import android.content.pm.PackageManagerInternal;
 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 com.android.server.backup.utils.TarBackupReader;
 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 @@ public class FullRestoreEngine extends RestoreEngine {
                                             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 @@ public class FullRestoreEngine extends RestoreEngine {
         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 {