diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index 21cd04e20c..48b97fafd3 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -20,7 +20,6 @@ import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_A 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.net.Uri; 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.net.URISyntaxException; 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 @@ public class LauncherProvider extends ContentProvider { 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 @@ public class LauncherProvider extends ContentProvider { protected DatabaseHelper mOpenHelper; + private long mLastRestoreTimestamp = 0L; + /** * $ adb shell dumpsys activity provider com.android.launcher3 */ @@ -412,11 +412,12 @@ public class LauncherProvider extends ContentProvider { 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 976d7ba5a0..901d27f373 100644 --- a/src/com/android/launcher3/pm/InstallSessionHelper.java +++ b/src/com/android/launcher3/pm/InstallSessionHelper.java @@ -56,8 +56,6 @@ public class InstallSessionHelper { // Set 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 @@ public class InstallSessionHelper { } /** - * 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 @@ public class InstallSessionHelper { 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 33eff5716f..53183bf210 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 class RestoreDbTask { */ 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 @@ public class RestoreDbTask { */ 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 @@ public class RestoreDbTask { 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 @@ public class RestoreDbTask { * 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 @@ public class RestoreDbTask { if (myProfileId != oldProfileId) { changeDefaultColumn(db, myProfileId); } + return itemsDeleted; } /**