Adding a method to throttle backup manager calls
Notifying backup manager when a boolean preference changes

Bug: 22885775
Change-Id: I105013af1841f6cd87472f558fa490670ed1ba24
diff --git a/src/com/android/launcher3/LauncherBackupAgentHelper.java b/src/com/android/launcher3/LauncherBackupAgentHelper.java
index 6619aaf..2177f52 100644
--- a/src/com/android/launcher3/LauncherBackupAgentHelper.java
+++ b/src/com/android/launcher3/LauncherBackupAgentHelper.java
@@ -20,6 +20,7 @@
 import android.app.backup.BackupDataInput;
 import android.app.backup.BackupManager;
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
@@ -32,13 +33,13 @@
 
     private static final String TAG = "LauncherBAHelper";
 
+    private static final String KEY_LAST_NOTIFIED_TIME = "backup_manager_last_notified";
+
     private static final String LAUNCHER_DATA_PREFIX = "L";
 
     static final boolean VERBOSE = false;
     static final boolean DEBUG = false;
 
-    private static BackupManager sBackupManager;
-
     /**
      * Notify the backup manager that out database is dirty.
      *
@@ -47,10 +48,29 @@
      * @param context application context
      */
     public static void dataChanged(Context context) {
-        if (sBackupManager == null) {
-            sBackupManager = new BackupManager(context);
+        dataChanged(context, 0);
+    }
+
+    /**
+     * Notify the backup manager that out database is dirty.
+     *
+     * <P>This does not force an immediate backup.
+     *
+     * @param context application context
+     * @param throttleMs duration in ms for which two consecutive calls to backup manager should
+     *                   not be made.
+     */
+    public static void dataChanged(Context context, long throttleMs) {
+        SharedPreferences prefs = Utilities.getPrefs(context);
+        long now = System.currentTimeMillis();
+        long lastTime = prefs.getLong(KEY_LAST_NOTIFIED_TIME, 0);
+
+        // User can manually change the system time, which could lead to now < lastTime.
+        // Re-backup in that case, as the backup will have a wrong lastModifiedTime.
+        if (now < lastTime || now >= (lastTime + throttleMs)) {
+            BackupManager.dataChanged(context.getPackageName());
+            prefs.edit().putLong(KEY_LAST_NOTIFIED_TIME, now).apply();
         }
-        sBackupManager.dataChanged();
     }
 
     private LauncherBackupHelper mHelper;
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 7674d2a..4760930 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -270,6 +270,9 @@
                 if (mListener != null) {
                     mListener.onSettingsChanged(arg, value);
                 }
+                if (extras.getBoolean(LauncherSettings.Settings.NOTIFY_BACKUP)) {
+                    LauncherBackupAgentHelper.dataChanged(getContext());
+                }
                 Bundle result = new Bundle();
                 result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE, value);
                 return result;
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 8a5804f..01d670d 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -324,5 +324,8 @@
 
         public static final String EXTRA_VALUE = "value";
         public static final String EXTRA_DEFAULT_VALUE = "default_value";
+
+        // Extra for set_boolean method to also notify the backup manager of the change.
+        public static final String NOTIFY_BACKUP = "notify_backup";
     }
 }