Merge "Mitigate 10 minutes delay in launcher restore for work apps." into ub-launcher3-rvc-dev
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 21cd04e..48b97fa 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -20,7 +20,6 @@
 import static com.android.launcher3.provider.LauncherDbUtils.copyTable;
 import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
 import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
 import android.annotation.TargetApi;
 import android.app.backup.BackupManager;
@@ -48,7 +47,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -85,6 +83,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Locale;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Supplier;
 
 public class LauncherProvider extends ContentProvider {
@@ -92,8 +91,7 @@
     private static final boolean LOGD = false;
 
     private static final String DOWNGRADE_SCHEMA_FILE = "downgrade_schema.json";
-    private static final String TOKEN_RESTORE_BACKUP_TABLE = "restore_backup_table";
-    private static final long RESTORE_BACKUP_TABLE_DELAY = 60000;
+    private static final long RESTORE_BACKUP_TABLE_DELAY = TimeUnit.SECONDS.toMillis(30);
 
     /**
      * Represents the schema of the database. Changes in scheme need not be backwards compatible.
@@ -107,6 +105,8 @@
 
     protected DatabaseHelper mOpenHelper;
 
+    private long mLastRestoreTimestamp = 0L;
+
     /**
      * $ adb shell dumpsys activity provider com.android.launcher3
      */
@@ -412,11 +412,12 @@
                 return null;
             }
             case LauncherSettings.Settings.METHOD_RESTORE_BACKUP_TABLE: {
-                final Handler handler = MODEL_EXECUTOR.getHandler();
-                handler.removeCallbacksAndMessages(TOKEN_RESTORE_BACKUP_TABLE);
-                handler.postDelayed(() -> RestoreDbTask.restoreIfPossible(
-                        getContext(), mOpenHelper, new BackupManager(getContext())),
-                        TOKEN_RESTORE_BACKUP_TABLE, RESTORE_BACKUP_TABLE_DELAY);
+                final long ts = System.currentTimeMillis();
+                if (ts - mLastRestoreTimestamp > RESTORE_BACKUP_TABLE_DELAY) {
+                    mLastRestoreTimestamp = ts;
+                    RestoreDbTask.restoreIfPossible(
+                            getContext(), mOpenHelper, new BackupManager(getContext()));
+                }
                 return null;
             }
             case LauncherSettings.Settings.METHOD_UPDATE_CURRENT_OPEN_HELPER: {
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 976d7ba..901d27f 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -56,8 +56,6 @@
     // Set<String> of session ids of promise icons that have been added to the home screen
     // as FLAG_PROMISE_NEW_INSTALLS.
     protected static final String PROMISE_ICON_IDS = "promise_icon_ids";
-    public static final String KEY_INSTALL_SESSION_CREATED_TIMESTAMP =
-            "key_install_session_created_timestamp";
 
     private static final boolean DEBUG = false;
 
@@ -166,14 +164,13 @@
     }
 
     /**
-     * Attempt to restore workspace layout if the session is triggered due to device restore and it
-     * has a newer timestamp.
+     * Attempt to restore workspace layout if the session is triggered due to device restore.
      */
     public boolean restoreDbIfApplicable(@NonNull final SessionInfo info) {
         if (!Utilities.ATLEAST_OREO || !FeatureFlags.ENABLE_DATABASE_RESTORE.get()) {
             return false;
         }
-        if (isRestore(info) && hasNewerTimestamp(mAppContext, info)) {
+        if (isRestore(info)) {
             LauncherSettings.Settings.call(mAppContext.getContentResolver(),
                     LauncherSettings.Settings.METHOD_RESTORE_BACKUP_TABLE);
             return true;
@@ -186,13 +183,6 @@
         return info.getInstallReason() == PackageManager.INSTALL_REASON_DEVICE_RESTORE;
     }
 
-    private static boolean hasNewerTimestamp(
-            @NonNull final Context context, @NonNull final SessionInfo info) {
-        return PackageManagerHelper.getSessionCreatedTimeInMillis(info)
-                > Utilities.getDevicePrefs(context).getLong(
-                        KEY_INSTALL_SESSION_CREATED_TIMESTAMP, 0);
-    }
-
     public boolean promiseIconAddedForId(int sessionId) {
         return mPromiseIconIds.contains(sessionId);
     }
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 33eff57..53183bf 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3.provider;
 
-import static com.android.launcher3.pm.InstallSessionHelper.KEY_INSTALL_SESSION_CREATED_TIMESTAMP;
 import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
 
 import android.app.backup.BackupManager;
@@ -87,13 +86,10 @@
      */
     public static boolean restoreIfPossible(@NonNull Context context,
             @NonNull DatabaseHelper helper, @NonNull BackupManager backupManager) {
-        Utilities.getDevicePrefs(context).edit().putLong(
-                KEY_INSTALL_SESSION_CREATED_TIMESTAMP, System.currentTimeMillis()).apply();
         final SQLiteDatabase db = helper.getWritableDatabase();
         try (SQLiteTransaction t = new SQLiteTransaction(db)) {
             RestoreDbTask task = new RestoreDbTask();
             task.restoreWorkspace(context, db, helper, backupManager);
-            task.restoreAppWidgetIdsIfExists(context);
             t.commit();
             return true;
         } catch (Exception e) {
@@ -107,7 +103,6 @@
      */
     private void backupWorkspace(Context context, SQLiteDatabase db) throws Exception {
         InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
-        // TODO(pinyaoting): Support backing up workspace with multiple grid options.
         new GridBackupTable(context, db, idp.numHotseatIcons, idp.numColumns, idp.numRows)
                 .doBackup(getDefaultProfileId(db), GridBackupTable.OPTION_REQUIRES_SANITIZATION);
     }
@@ -115,13 +110,17 @@
     private void restoreWorkspace(@NonNull Context context, @NonNull SQLiteDatabase db,
             @NonNull DatabaseHelper helper, @NonNull BackupManager backupManager)
             throws Exception {
-        // TODO(pinyaoting): Support restoring workspace with multiple grid options.
         final InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
         GridBackupTable backupTable = new GridBackupTable(context, db, idp.numHotseatIcons,
                 idp.numColumns, idp.numRows);
         if (backupTable.restoreFromRawBackupIfAvailable(getDefaultProfileId(db))) {
-            sanitizeDB(helper, db, backupManager);
+            int itemsDeleted = sanitizeDB(helper, db, backupManager);
             LauncherAppState.getInstance(context).getModel().forceReload();
+            restoreAppWidgetIdsIfExists(context);
+            if (itemsDeleted == 0) {
+                // all the items are restored, we no longer need the backup table
+                dropTable(db, Favorites.BACKUP_TABLE_NAME);
+            }
         }
     }
 
@@ -132,8 +131,10 @@
      *      the restored apps get installed.
      *   3. If the user serial for any restored profile is different than that of the previous
      *      device, update the entries to the new profile id.
+     *
+     * @return number of items deleted.
      */
-    private void sanitizeDB(DatabaseHelper helper, SQLiteDatabase db, BackupManager backupManager)
+    private int sanitizeDB(DatabaseHelper helper, SQLiteDatabase db, BackupManager backupManager)
             throws Exception {
         // Primary user ids
         long myProfileId = helper.getDefaultUserSerial();
@@ -210,6 +211,7 @@
         if (myProfileId != oldProfileId) {
             changeDefaultColumn(db, myProfileId);
         }
+        return itemsDeleted;
     }
 
     /**