Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67636269 authored by Charlie Anderson's avatar Charlie Anderson
Browse files

add metrics for when db grid migration fails

Flag: ACONFIG enable_launcher_br_metrics TEAMFOOD
Test: locally verified
Bug: 307527314

Change-Id: Iab84a337d76d63bb3bc2ed81fdf4b6fd50dc5661
parent 0f8d2802
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.launcher3.model;

import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN;
import static com.android.launcher3.Flags.enableSupportForArchiving;
import static com.android.launcher3.Flags.enableLauncherBrMetrics;
import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
import static com.android.launcher3.LauncherPrefs.SHOULD_SHOW_SMARTSPACE;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
@@ -232,8 +233,11 @@ public class LoaderTask implements Runnable {
        LoaderMemoryLogger memoryLogger = new LoaderMemoryLogger();
        mIsRestoreFromBackup =
                (Boolean) LauncherPrefs.get(mApp.getContext()).get(IS_FIRST_LOAD_AFTER_RESTORE);
        LauncherRestoreEventLogger restoreEventLogger = LauncherRestoreEventLogger
                .Companion.newInstance(mApp.getContext());
        LauncherRestoreEventLogger restoreEventLogger = null;
        if (enableLauncherBrMetrics()) {
            restoreEventLogger = LauncherRestoreEventLogger.Companion
                    .newInstance(mApp.getContext());
        }
        try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {

            List<ShortcutInfo> allShortcuts = new ArrayList<>();
@@ -364,9 +368,11 @@ public class LoaderTask implements Runnable {
            transaction.commit();
            memoryLogger.clearLogs();
            if (mIsRestoreFromBackup) {
                restoreEventLogger.reportLauncherRestoreResults();
                mIsRestoreFromBackup = false;
                LauncherPrefs.get(mApp.getContext()).putSync(IS_FIRST_LOAD_AFTER_RESTORE.to(false));
                if (restoreEventLogger != null) {
                    restoreEventLogger.reportLauncherRestoreResults();
                }
            }
        } catch (CancellationException e) {
            // Loader stopped, ignore
@@ -421,7 +427,7 @@ public class LoaderTask implements Runnable {
        final WidgetManagerHelper widgetHelper = new WidgetManagerHelper(context);

        ModelDbController dbController = mApp.getModel().getModelDbController();
        dbController.tryMigrateDB();
        dbController.tryMigrateDB(restoreEventLogger);
        Log.d(TAG, "loadWorkspace: loading default favorites");
        dbController.loadDefaultFavoritesIfNecessary();

+33 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import static android.util.Base64.NO_PADDING;
import static android.util.Base64.NO_WRAP;

import static com.android.launcher3.DefaultLayoutParser.RES_PARTNER_DEFAULT_LAYOUT;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE;
import static com.android.launcher3.LauncherSettings.Favorites.addTableToDb;
import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_KEY;
import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_LABEL;
@@ -48,6 +49,7 @@ import android.util.Base64;
import android.util.Log;
import android.util.Xml;

import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;

import com.android.launcher3.AutoInstallsLayout;
@@ -62,6 +64,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.pm.UserCache;
import com.android.launcher3.provider.LauncherDbUtils;
@@ -86,6 +89,7 @@ public class ModelDbController {
    private static final String TAG = "LauncherProvider";

    private static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
    private static final String RESTORE_ERROR_GRID_MIGRATION_FAILURE = "grid_migration_failed";
    public static final String EXTRA_DB_NAME = "db_name";

    protected DatabaseHelper mOpenHelper;
@@ -261,8 +265,12 @@ public class ModelDbController {
    /**
     * Migrates the DB if needed. If the migration failed, it clears the DB.
     */
    public void tryMigrateDB() {
    public void tryMigrateDB(@Nullable LauncherRestoreEventLogger restoreEventLogger) {

        if (!migrateGridIfNeeded()) {
            if (restoreEventLogger != null) {
                sendMetricsForFailedMigration(restoreEventLogger, getDb());
            }
            FileLog.d(TAG, "Migration failed: resetting launcher database");
            createEmptyDB();
            LauncherPrefs.get(mContext).putSync(
@@ -312,6 +320,30 @@ public class ModelDbController {
        }
    }

    /**
     * In case of migration failure, report metrics for the count of each itemType in the DB.
     * @param restoreEventLogger logger used to report Launcher restore metrics
     */
    private void sendMetricsForFailedMigration(LauncherRestoreEventLogger restoreEventLogger,
            SQLiteDatabase db) {
        try (Cursor cursor = db.rawQuery(
                "SELECT itemType, COUNT(*) AS count FROM favorites GROUP BY itemType",
                null
        )) {
            if (cursor.moveToFirst()) {
                do {
                    restoreEventLogger.logFavoritesItemsRestoreFailed(
                            cursor.getInt(cursor.getColumnIndexOrThrow(ITEM_TYPE)),
                            cursor.getInt(cursor.getColumnIndexOrThrow("count")),
                            RESTORE_ERROR_GRID_MIGRATION_FAILURE
                    );
                } while (cursor.moveToNext());
            }
        } catch (Exception e) {
            FileLog.e(TAG, "sendMetricsForFailedDb: Error reading from database", e);
        }
    }

    /**
     * Returns the underlying model database
     */
+1 −1
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ public class FavoriteItemsTransaction {
        runOnExecutorSync(MODEL_EXECUTOR, () -> {
            ModelDbController controller = model.getModelDbController();
            // Migrate any previous data so that the DB state is correct
            controller.tryMigrateDB();
            controller.tryMigrateDB(null /* restoreEventLogger */);

            // Create DB again to load fresh data
            controller.createEmptyDB();
+2 −2
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ object ModelTestExtensions {
        loadModelSync()
        TestUtil.runOnExecutorSync(Executors.MODEL_EXECUTOR) {
            modelDbController.run {
                tryMigrateDB()
                tryMigrateDB(null /* restoreEventLogger */)
                createEmptyDB()
                clearEmptyDbFlag()
            }
@@ -72,7 +72,7 @@ object ModelTestExtensions {
        loadModelSync()
        TestUtil.runOnExecutorSync(Executors.MODEL_EXECUTOR) {
            val controller: ModelDbController = modelDbController
            controller.tryMigrateDB()
            controller.tryMigrateDB(null /* restoreEventLogger */)
            modelDbController.newTransaction().use { transaction ->
                val values =
                    ContentValues().apply {