Loading src/com/android/launcher3/LauncherProvider.java +10 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 { Loading @@ -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. Loading @@ -107,6 +105,8 @@ public class LauncherProvider extends ContentProvider { protected DatabaseHelper mOpenHelper; private long mLastRestoreTimestamp = 0L; /** * $ adb shell dumpsys activity provider com.android.launcher3 */ Loading Loading @@ -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: { Loading src/com/android/launcher3/pm/InstallSessionHelper.java +2 −12 Original line number Diff line number Diff line Loading @@ -56,8 +56,6 @@ public class InstallSessionHelper { // 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; Loading Loading @@ -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; Loading @@ -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); } Loading src/com/android/launcher3/provider/RestoreDbTask.java +10 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); } Loading @@ -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); } } } Loading @@ -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(); Loading Loading @@ -210,6 +211,7 @@ public class RestoreDbTask { if (myProfileId != oldProfileId) { changeDefaultColumn(db, myProfileId); } return itemsDeleted; } /** Loading Loading
src/com/android/launcher3/LauncherProvider.java +10 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 { Loading @@ -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. Loading @@ -107,6 +105,8 @@ public class LauncherProvider extends ContentProvider { protected DatabaseHelper mOpenHelper; private long mLastRestoreTimestamp = 0L; /** * $ adb shell dumpsys activity provider com.android.launcher3 */ Loading Loading @@ -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: { Loading
src/com/android/launcher3/pm/InstallSessionHelper.java +2 −12 Original line number Diff line number Diff line Loading @@ -56,8 +56,6 @@ public class InstallSessionHelper { // 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; Loading Loading @@ -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; Loading @@ -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); } Loading
src/com/android/launcher3/provider/RestoreDbTask.java +10 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -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); } Loading @@ -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); } } } Loading @@ -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(); Loading Loading @@ -210,6 +211,7 @@ public class RestoreDbTask { if (myProfileId != oldProfileId) { changeDefaultColumn(db, myProfileId); } return itemsDeleted; } /** Loading