Loading src/com/android/launcher3/backuprestore/LauncherRestoreEventLogger.kt +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ open class LauncherRestoreEventLogger : ResourceBasedOverride { const val RESTORE_ERROR_SHORTCUT_NOT_FOUND = "shortcut_not_found" const val RESTORE_ERROR_APP_NOT_INSTALLED = "app_not_installed" const val RESTORE_ERROR_WIDGETS_DISABLED = "widgets_disabled" const val RESTORE_ERROR_PROFILE_NOT_RESTORED = "profile_not_restored" const val RESTORE_ERROR_WIDGET_REMOVED = "widget_not_found" fun newInstance(context: Context?): LauncherRestoreEventLogger { return ResourceBasedOverride.Overrides.getObject( Loading src/com/android/launcher3/provider/RestoreDbTask.java +71 −20 Original line number Diff line number Diff line Loading @@ -18,12 +18,18 @@ package com.android.launcher3.provider; import static android.os.Process.myUserHandle; import static com.android.launcher3.Flags.enableLauncherBrMetrics; import static com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY; import static com.android.launcher3.LauncherPrefs.APP_WIDGET_IDS; import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE; import static com.android.launcher3.LauncherPrefs.OLD_APP_WIDGET_IDS; import static com.android.launcher3.LauncherPrefs.RESTORE_DEVICE; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET; import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_PROFILE_NOT_RESTORED; import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_WIDGETS_DISABLED; import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_WIDGET_REMOVED; import static com.android.launcher3.provider.LauncherDbUtils.dropTable; import static com.android.launcher3.widget.LauncherWidgetHolder.APPWIDGET_HOST_ID; Loading Loading @@ -53,6 +59,7 @@ import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.Utilities; import com.android.launcher3.backuprestore.LauncherRestoreEventLogger; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.DeviceGridState; import com.android.launcher3.model.LoaderTask; Loading Loading @@ -124,8 +131,11 @@ public class RestoreDbTask { FileLog.d(TAG, "performRestore: starting restore from db"); try (SQLiteTransaction t = new SQLiteTransaction(db)) { RestoreDbTask task = new RestoreDbTask(); task.sanitizeDB(context, controller, db, new BackupManager(context)); task.restoreAppWidgetIdsIfExists(context, controller); BackupManager backupManager = new BackupManager(context); LauncherRestoreEventLogger restoreEventLogger = LauncherRestoreEventLogger.Companion.newInstance(context); task.sanitizeDB(context, controller, db, backupManager, restoreEventLogger); task.restoreAppWidgetIdsIfExists(context, controller, restoreEventLogger); t.commit(); return true; } catch (Exception e) { Loading @@ -148,7 +158,8 @@ public class RestoreDbTask { */ @VisibleForTesting protected int sanitizeDB(Context context, ModelDbController controller, SQLiteDatabase db, BackupManager backupManager) throws Exception { BackupManager backupManager, LauncherRestoreEventLogger restoreEventLogger) throws Exception { logFavoritesTable(db, "Old Launcher Database before sanitizing:", null, null); // Primary user ids long myProfileId = controller.getSerialNumberForUser(myUserHandle()); Loading Loading @@ -187,6 +198,9 @@ public class RestoreDbTask { Arrays.fill(args, "?"); final String where = "profileId NOT IN (" + TextUtils.join(", ", Arrays.asList(args)) + ")"; logFavoritesTable(db, "items to delete from unrestored profiles:", where, profileIds); if (enableLauncherBrMetrics()) { reportUnrestoredProfiles(db, where, profileIds, restoreEventLogger); } int itemsDeletedCount = db.delete(Favorites.TABLE_NAME, where, profileIds); FileLog.d(TAG, itemsDeletedCount + " total items from unrestored user(s) were deleted"); Loading Loading @@ -346,21 +360,24 @@ public class RestoreDbTask { DeviceGridState deviceGridState = new DeviceGridState(context); FileLog.d(TAG, "restore initiated from backup: DeviceGridState=" + deviceGridState); LauncherPrefs.get(context).putSync(RESTORE_DEVICE.to(deviceGridState.getDeviceType())); if (enableLauncherBrMetrics()) { LauncherPrefs.get(context).putSync(IS_FIRST_LOAD_AFTER_RESTORE.to(true)); } } @WorkerThread @VisibleForTesting void restoreAppWidgetIdsIfExists(Context context, ModelDbController controller) { void restoreAppWidgetIdsIfExists(Context context, ModelDbController controller, LauncherRestoreEventLogger restoreEventLogger) { LauncherPrefs lp = LauncherPrefs.get(context); if (lp.has(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS)) { AppWidgetHost host = new AppWidgetHost(context, APPWIDGET_HOST_ID); restoreAppWidgetIds(context, controller, restoreAppWidgetIds(context, controller, restoreEventLogger, IntArray.fromConcatString(lp.get(OLD_APP_WIDGET_IDS)).toArray(), IntArray.fromConcatString(lp.get(APP_WIDGET_IDS)).toArray(), host); } else { FileLog.d(TAG, "No app widget ids were received from backup to restore."); FileLog.d(TAG, "Did not receive new app widget id map during Launcher restore"); } lp.remove(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS); Loading @@ -371,10 +388,13 @@ public class RestoreDbTask { */ @WorkerThread private void restoreAppWidgetIds(Context context, ModelDbController controller, int[] oldWidgetIds, int[] newWidgetIds, @NonNull AppWidgetHost host) { LauncherRestoreEventLogger launcherRestoreEventLogger, int[] oldWidgetIds, int[] newWidgetIds, @NonNull AppWidgetHost host) { if (WidgetsModel.GO_DISABLE_WIDGETS) { FileLog.e(TAG, "Skipping widget ID remap as widgets not supported"); host.deleteHost(); launcherRestoreEventLogger.logFavoritesItemsRestoreFailed(Favorites.ITEM_TYPE_APPWIDGET, oldWidgetIds.length, RESTORE_ERROR_WIDGETS_DISABLED); return; } if (!RestoreDbTask.isPending(context)) { Loading Loading @@ -438,11 +458,16 @@ public class RestoreDbTask { FileLog.d(TAG, "Deleting widgetId: " + newWidgetIds[i] + " with old id: " + oldWidgetId); host.deleteAppWidgetId(newWidgetIds[i]); launcherRestoreEventLogger.logSingleFavoritesItemRestoreFailed( ITEM_TYPE_APPWIDGET, RESTORE_ERROR_WIDGET_REMOVED ); } } } } logFavoritesTable(controller.getDb(), "launcher db after remap widget ids", null, null); LauncherAppState app = LauncherAppState.getInstanceNoCreate(); if (app != null) { app.getModel().forceReload(); Loading Loading @@ -477,17 +502,16 @@ public class RestoreDbTask { StringBuilder builder = new StringBuilder(); builder.append("["); for (int i = 0; i < widgetIdList.size(); i++) { builder.append("[") builder.append("[appWidgetId=") .append(widgetIdList.get(i)) .append(", ") .append(", restoreFlag=") .append(widgetRestoreList.get(i)) .append(", ") .append(", profileId=") .append(widgetProfileIdList.get(i)) .append("]"); } builder.append("]"); Log.d(TAG, "restoreAppWidgetIds: all widget ids in database: " + builder); Log.d(TAG, "restoreAppWidgetIds: all widget ids in database: " + builder); } catch (Exception ex) { Log.e(TAG, "Getting widget ids from the database failed", ex); } Loading Loading @@ -546,7 +570,7 @@ public class RestoreDbTask { */ public static void logFavoritesTable(SQLiteDatabase database, @NonNull String logHeader, String where, String[] profileIds) { try (Cursor itemsToDelete = database.query( try (Cursor cursor = database.query( /* table */ Favorites.TABLE_NAME, /* columns */ DB_COLUMNS_TO_LOG, /* selection */ where, Loading @@ -555,19 +579,19 @@ public class RestoreDbTask { /* having */ null, /* orderBy */ null )) { if (itemsToDelete.moveToFirst()) { String[] columnNames = itemsToDelete.getColumnNames(); if (cursor.moveToFirst()) { String[] columnNames = cursor.getColumnNames(); StringBuilder stringBuilder = new StringBuilder(logHeader + "\n"); do { for (String columnName : columnNames) { stringBuilder.append(columnName) .append("=") .append(itemsToDelete.getString( itemsToDelete.getColumnIndex(columnName))) .append(cursor.getString( cursor.getColumnIndex(columnName))) .append(" "); } stringBuilder.append("\n"); } while (itemsToDelete.moveToNext()); } while (cursor.moveToNext()); FileLog.d(TAG, stringBuilder.toString()); } else { FileLog.d(TAG, "logFavoritesTable: No items found from query for " Loading @@ -577,4 +601,31 @@ public class RestoreDbTask { FileLog.e(TAG, "logFavoritesTable: Error reading from database", e); } } /** * Queries and reports the count of each itemType to be removed due to unrestored profiles. * @param database The Launcher db to query from. * @param where Query being used for to find unrestored profiles * @param profileIds profile ids that were not restored * @param restoreEventLogger Backup/Restore Logger to report metrics */ private void reportUnrestoredProfiles(SQLiteDatabase database, String where, String[] profileIds, LauncherRestoreEventLogger restoreEventLogger) { final String query = "SELECT itemType, COUNT(*) AS count FROM favorites WHERE " + where + " GROUP BY itemType"; try (Cursor cursor = database.rawQuery(query, profileIds)) { if (cursor.moveToFirst()) { do { restoreEventLogger.logFavoritesItemsRestoreFailed( cursor.getInt(cursor.getColumnIndexOrThrow(ITEM_TYPE)), cursor.getInt(cursor.getColumnIndexOrThrow("count")), RESTORE_ERROR_PROFILE_NOT_RESTORED ); } while (cursor.moveToNext()); } } catch (Exception e) { FileLog.e(TAG, "reportUnrestoredProfiles: Error reading from database", e); } } } tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java +10 −6 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.backuprestore.LauncherRestoreEventLogger; import com.android.launcher3.model.ModelDbController; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.LauncherModelHelper; Loading Loading @@ -90,6 +91,7 @@ public class RestoreDbTaskTest { private SQLiteDatabase mMockDb; private Cursor mMockCursor; private LauncherPrefs mPrefs; private LauncherRestoreEventLogger mMockRestoreEventLogger; @Before public void setup() { Loading @@ -100,6 +102,7 @@ public class RestoreDbTaskTest { mMockDb = mock(SQLiteDatabase.class); mMockCursor = mock(Cursor.class); mPrefs = new LauncherPrefs(mContext); mMockRestoreEventLogger = mock(LauncherRestoreEventLogger.class); } @After Loading Loading @@ -178,7 +181,7 @@ public class RestoreDbTaskTest { assertEquals(10, getItemCountForProfile(db, myProfileId_old)); assertEquals(6, getItemCountForProfile(db, workProfileId_old)); mTask.sanitizeDB(mContext, controller, controller.getDb(), bm); mTask.sanitizeDB(mContext, controller, controller.getDb(), bm, mMockRestoreEventLogger); // All the data has been migrated to the new user ids assertEquals(0, getItemCountForProfile(db, myProfileId_old)); Loading Loading @@ -207,7 +210,7 @@ public class RestoreDbTaskTest { assertEquals(10, getItemCountForProfile(db, myProfileId_old)); assertEquals(6, getItemCountForProfile(db, workProfileId_old)); mTask.sanitizeDB(mContext, controller, controller.getDb(), bm); mTask.sanitizeDB(mContext, controller, controller.getDb(), bm, mMockRestoreEventLogger); // All the data has been migrated to the new user ids assertEquals(0, getItemCountForProfile(db, myProfileId_old)); Loading @@ -219,7 +222,7 @@ public class RestoreDbTaskTest { @Test public void givenLauncherPrefsHasNoIds_whenRestoreAppWidgetIdsIfExists_thenIdsAreRemoved() { // When mTask.restoreAppWidgetIdsIfExists(mContext, mMockController); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController, mMockRestoreEventLogger); // Then assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse(); } Loading @@ -235,7 +238,7 @@ public class RestoreDbTaskTest { // When setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController, mMockRestoreEventLogger); // Then assertThat(expectedHost.getAppWidgetIds()).isEqualTo(expectedOldIds); Loading @@ -257,7 +260,7 @@ public class RestoreDbTaskTest { // When setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController, mMockRestoreEventLogger); // Then assertThat(expectedHost.getAppWidgetIds()).isEqualTo(expectedOldIds); Loading @@ -280,12 +283,13 @@ public class RestoreDbTaskTest { when(mMockDb.query(any(), any(), any(), any(), any(), any(), any())) .thenReturn(mMockCursor); when(mMockCursor.moveToFirst()).thenReturn(true); when(mMockCursor.getColumnNames()).thenReturn(new String[] {}); when(mMockCursor.isAfterLast()).thenReturn(true); RestoreDbTask.setPending(mContext); // When setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController, mMockRestoreEventLogger); // Then assertThat(expectedHost.getAppWidgetIds()).isEqualTo(allExpectedIds); Loading Loading
src/com/android/launcher3/backuprestore/LauncherRestoreEventLogger.kt +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ open class LauncherRestoreEventLogger : ResourceBasedOverride { const val RESTORE_ERROR_SHORTCUT_NOT_FOUND = "shortcut_not_found" const val RESTORE_ERROR_APP_NOT_INSTALLED = "app_not_installed" const val RESTORE_ERROR_WIDGETS_DISABLED = "widgets_disabled" const val RESTORE_ERROR_PROFILE_NOT_RESTORED = "profile_not_restored" const val RESTORE_ERROR_WIDGET_REMOVED = "widget_not_found" fun newInstance(context: Context?): LauncherRestoreEventLogger { return ResourceBasedOverride.Overrides.getObject( Loading
src/com/android/launcher3/provider/RestoreDbTask.java +71 −20 Original line number Diff line number Diff line Loading @@ -18,12 +18,18 @@ package com.android.launcher3.provider; import static android.os.Process.myUserHandle; import static com.android.launcher3.Flags.enableLauncherBrMetrics; import static com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY; import static com.android.launcher3.LauncherPrefs.APP_WIDGET_IDS; import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE; import static com.android.launcher3.LauncherPrefs.OLD_APP_WIDGET_IDS; import static com.android.launcher3.LauncherPrefs.RESTORE_DEVICE; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET; import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_PROFILE_NOT_RESTORED; import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_WIDGETS_DISABLED; import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_WIDGET_REMOVED; import static com.android.launcher3.provider.LauncherDbUtils.dropTable; import static com.android.launcher3.widget.LauncherWidgetHolder.APPWIDGET_HOST_ID; Loading Loading @@ -53,6 +59,7 @@ import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.Utilities; import com.android.launcher3.backuprestore.LauncherRestoreEventLogger; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.DeviceGridState; import com.android.launcher3.model.LoaderTask; Loading Loading @@ -124,8 +131,11 @@ public class RestoreDbTask { FileLog.d(TAG, "performRestore: starting restore from db"); try (SQLiteTransaction t = new SQLiteTransaction(db)) { RestoreDbTask task = new RestoreDbTask(); task.sanitizeDB(context, controller, db, new BackupManager(context)); task.restoreAppWidgetIdsIfExists(context, controller); BackupManager backupManager = new BackupManager(context); LauncherRestoreEventLogger restoreEventLogger = LauncherRestoreEventLogger.Companion.newInstance(context); task.sanitizeDB(context, controller, db, backupManager, restoreEventLogger); task.restoreAppWidgetIdsIfExists(context, controller, restoreEventLogger); t.commit(); return true; } catch (Exception e) { Loading @@ -148,7 +158,8 @@ public class RestoreDbTask { */ @VisibleForTesting protected int sanitizeDB(Context context, ModelDbController controller, SQLiteDatabase db, BackupManager backupManager) throws Exception { BackupManager backupManager, LauncherRestoreEventLogger restoreEventLogger) throws Exception { logFavoritesTable(db, "Old Launcher Database before sanitizing:", null, null); // Primary user ids long myProfileId = controller.getSerialNumberForUser(myUserHandle()); Loading Loading @@ -187,6 +198,9 @@ public class RestoreDbTask { Arrays.fill(args, "?"); final String where = "profileId NOT IN (" + TextUtils.join(", ", Arrays.asList(args)) + ")"; logFavoritesTable(db, "items to delete from unrestored profiles:", where, profileIds); if (enableLauncherBrMetrics()) { reportUnrestoredProfiles(db, where, profileIds, restoreEventLogger); } int itemsDeletedCount = db.delete(Favorites.TABLE_NAME, where, profileIds); FileLog.d(TAG, itemsDeletedCount + " total items from unrestored user(s) were deleted"); Loading Loading @@ -346,21 +360,24 @@ public class RestoreDbTask { DeviceGridState deviceGridState = new DeviceGridState(context); FileLog.d(TAG, "restore initiated from backup: DeviceGridState=" + deviceGridState); LauncherPrefs.get(context).putSync(RESTORE_DEVICE.to(deviceGridState.getDeviceType())); if (enableLauncherBrMetrics()) { LauncherPrefs.get(context).putSync(IS_FIRST_LOAD_AFTER_RESTORE.to(true)); } } @WorkerThread @VisibleForTesting void restoreAppWidgetIdsIfExists(Context context, ModelDbController controller) { void restoreAppWidgetIdsIfExists(Context context, ModelDbController controller, LauncherRestoreEventLogger restoreEventLogger) { LauncherPrefs lp = LauncherPrefs.get(context); if (lp.has(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS)) { AppWidgetHost host = new AppWidgetHost(context, APPWIDGET_HOST_ID); restoreAppWidgetIds(context, controller, restoreAppWidgetIds(context, controller, restoreEventLogger, IntArray.fromConcatString(lp.get(OLD_APP_WIDGET_IDS)).toArray(), IntArray.fromConcatString(lp.get(APP_WIDGET_IDS)).toArray(), host); } else { FileLog.d(TAG, "No app widget ids were received from backup to restore."); FileLog.d(TAG, "Did not receive new app widget id map during Launcher restore"); } lp.remove(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS); Loading @@ -371,10 +388,13 @@ public class RestoreDbTask { */ @WorkerThread private void restoreAppWidgetIds(Context context, ModelDbController controller, int[] oldWidgetIds, int[] newWidgetIds, @NonNull AppWidgetHost host) { LauncherRestoreEventLogger launcherRestoreEventLogger, int[] oldWidgetIds, int[] newWidgetIds, @NonNull AppWidgetHost host) { if (WidgetsModel.GO_DISABLE_WIDGETS) { FileLog.e(TAG, "Skipping widget ID remap as widgets not supported"); host.deleteHost(); launcherRestoreEventLogger.logFavoritesItemsRestoreFailed(Favorites.ITEM_TYPE_APPWIDGET, oldWidgetIds.length, RESTORE_ERROR_WIDGETS_DISABLED); return; } if (!RestoreDbTask.isPending(context)) { Loading Loading @@ -438,11 +458,16 @@ public class RestoreDbTask { FileLog.d(TAG, "Deleting widgetId: " + newWidgetIds[i] + " with old id: " + oldWidgetId); host.deleteAppWidgetId(newWidgetIds[i]); launcherRestoreEventLogger.logSingleFavoritesItemRestoreFailed( ITEM_TYPE_APPWIDGET, RESTORE_ERROR_WIDGET_REMOVED ); } } } } logFavoritesTable(controller.getDb(), "launcher db after remap widget ids", null, null); LauncherAppState app = LauncherAppState.getInstanceNoCreate(); if (app != null) { app.getModel().forceReload(); Loading Loading @@ -477,17 +502,16 @@ public class RestoreDbTask { StringBuilder builder = new StringBuilder(); builder.append("["); for (int i = 0; i < widgetIdList.size(); i++) { builder.append("[") builder.append("[appWidgetId=") .append(widgetIdList.get(i)) .append(", ") .append(", restoreFlag=") .append(widgetRestoreList.get(i)) .append(", ") .append(", profileId=") .append(widgetProfileIdList.get(i)) .append("]"); } builder.append("]"); Log.d(TAG, "restoreAppWidgetIds: all widget ids in database: " + builder); Log.d(TAG, "restoreAppWidgetIds: all widget ids in database: " + builder); } catch (Exception ex) { Log.e(TAG, "Getting widget ids from the database failed", ex); } Loading Loading @@ -546,7 +570,7 @@ public class RestoreDbTask { */ public static void logFavoritesTable(SQLiteDatabase database, @NonNull String logHeader, String where, String[] profileIds) { try (Cursor itemsToDelete = database.query( try (Cursor cursor = database.query( /* table */ Favorites.TABLE_NAME, /* columns */ DB_COLUMNS_TO_LOG, /* selection */ where, Loading @@ -555,19 +579,19 @@ public class RestoreDbTask { /* having */ null, /* orderBy */ null )) { if (itemsToDelete.moveToFirst()) { String[] columnNames = itemsToDelete.getColumnNames(); if (cursor.moveToFirst()) { String[] columnNames = cursor.getColumnNames(); StringBuilder stringBuilder = new StringBuilder(logHeader + "\n"); do { for (String columnName : columnNames) { stringBuilder.append(columnName) .append("=") .append(itemsToDelete.getString( itemsToDelete.getColumnIndex(columnName))) .append(cursor.getString( cursor.getColumnIndex(columnName))) .append(" "); } stringBuilder.append("\n"); } while (itemsToDelete.moveToNext()); } while (cursor.moveToNext()); FileLog.d(TAG, stringBuilder.toString()); } else { FileLog.d(TAG, "logFavoritesTable: No items found from query for " Loading @@ -577,4 +601,31 @@ public class RestoreDbTask { FileLog.e(TAG, "logFavoritesTable: Error reading from database", e); } } /** * Queries and reports the count of each itemType to be removed due to unrestored profiles. * @param database The Launcher db to query from. * @param where Query being used for to find unrestored profiles * @param profileIds profile ids that were not restored * @param restoreEventLogger Backup/Restore Logger to report metrics */ private void reportUnrestoredProfiles(SQLiteDatabase database, String where, String[] profileIds, LauncherRestoreEventLogger restoreEventLogger) { final String query = "SELECT itemType, COUNT(*) AS count FROM favorites WHERE " + where + " GROUP BY itemType"; try (Cursor cursor = database.rawQuery(query, profileIds)) { if (cursor.moveToFirst()) { do { restoreEventLogger.logFavoritesItemsRestoreFailed( cursor.getInt(cursor.getColumnIndexOrThrow(ITEM_TYPE)), cursor.getInt(cursor.getColumnIndexOrThrow("count")), RESTORE_ERROR_PROFILE_NOT_RESTORED ); } while (cursor.moveToNext()); } } catch (Exception e) { FileLog.e(TAG, "reportUnrestoredProfiles: Error reading from database", e); } } }
tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java +10 −6 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.backuprestore.LauncherRestoreEventLogger; import com.android.launcher3.model.ModelDbController; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.LauncherModelHelper; Loading Loading @@ -90,6 +91,7 @@ public class RestoreDbTaskTest { private SQLiteDatabase mMockDb; private Cursor mMockCursor; private LauncherPrefs mPrefs; private LauncherRestoreEventLogger mMockRestoreEventLogger; @Before public void setup() { Loading @@ -100,6 +102,7 @@ public class RestoreDbTaskTest { mMockDb = mock(SQLiteDatabase.class); mMockCursor = mock(Cursor.class); mPrefs = new LauncherPrefs(mContext); mMockRestoreEventLogger = mock(LauncherRestoreEventLogger.class); } @After Loading Loading @@ -178,7 +181,7 @@ public class RestoreDbTaskTest { assertEquals(10, getItemCountForProfile(db, myProfileId_old)); assertEquals(6, getItemCountForProfile(db, workProfileId_old)); mTask.sanitizeDB(mContext, controller, controller.getDb(), bm); mTask.sanitizeDB(mContext, controller, controller.getDb(), bm, mMockRestoreEventLogger); // All the data has been migrated to the new user ids assertEquals(0, getItemCountForProfile(db, myProfileId_old)); Loading Loading @@ -207,7 +210,7 @@ public class RestoreDbTaskTest { assertEquals(10, getItemCountForProfile(db, myProfileId_old)); assertEquals(6, getItemCountForProfile(db, workProfileId_old)); mTask.sanitizeDB(mContext, controller, controller.getDb(), bm); mTask.sanitizeDB(mContext, controller, controller.getDb(), bm, mMockRestoreEventLogger); // All the data has been migrated to the new user ids assertEquals(0, getItemCountForProfile(db, myProfileId_old)); Loading @@ -219,7 +222,7 @@ public class RestoreDbTaskTest { @Test public void givenLauncherPrefsHasNoIds_whenRestoreAppWidgetIdsIfExists_thenIdsAreRemoved() { // When mTask.restoreAppWidgetIdsIfExists(mContext, mMockController); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController, mMockRestoreEventLogger); // Then assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse(); } Loading @@ -235,7 +238,7 @@ public class RestoreDbTaskTest { // When setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController, mMockRestoreEventLogger); // Then assertThat(expectedHost.getAppWidgetIds()).isEqualTo(expectedOldIds); Loading @@ -257,7 +260,7 @@ public class RestoreDbTaskTest { // When setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController, mMockRestoreEventLogger); // Then assertThat(expectedHost.getAppWidgetIds()).isEqualTo(expectedOldIds); Loading @@ -280,12 +283,13 @@ public class RestoreDbTaskTest { when(mMockDb.query(any(), any(), any(), any(), any(), any(), any())) .thenReturn(mMockCursor); when(mMockCursor.moveToFirst()).thenReturn(true); when(mMockCursor.getColumnNames()).thenReturn(new String[] {}); when(mMockCursor.isAfterLast()).thenReturn(true); RestoreDbTask.setPending(mContext); // When setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController); mTask.restoreAppWidgetIdsIfExists(mContext, mMockController, mMockRestoreEventLogger); // Then assertThat(expectedHost.getAppWidgetIds()).isEqualTo(allExpectedIds); Loading