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

Commit 511421c1 authored by Charlie Anderson's avatar Charlie Anderson
Browse files

Adds logging for Launcher restore metrics in Launcher and LoaderTask

- Adds flag for indicating when we are loading after a restore, separate from the pending restore flag
- Adds many success/failure scenario metrics when loading and binding items

Flag: ACONFIG enable_launcher_br_metrics DEVELOPMENT
Test: locally verified
Bug: 307527314
Change-Id: I9d2660f6d9d7cd5813072201e96b1a64aec4ea4b
parent 83d42f71
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -29,8 +29,8 @@ class LauncherRestoreEventLoggerImpl(val context: Context) : LauncherRestoreEven
        @BackupRestoreDataType private const val DATA_TYPE_APP_PAIR = "app_pair"
    }

    private val backupManager: BackupManager = BackupManager(context)
    private val restoreEventLogger: BackupRestoreEventLogger = backupManager.delayedRestoreLogger
    private val restoreEventLogger: BackupRestoreEventLogger =
        BackupManager(context).delayedRestoreLogger

    /**
     * For logging when multiple items of a given data type failed to restore.
@@ -72,6 +72,18 @@ class LauncherRestoreEventLoggerImpl(val context: Context) : LauncherRestoreEven
        }
    }

    /**
     * Helper to log successfully restoring multiple items from the Favorites table.
     *
     * @param favoritesId The id of the item type from [Favorites] that was restored.
     * @param count number of items that restored.
     */
    override fun logFavoritesItemsRestored(favoritesId: Int, count: Int) {
        if (Flags.enableLauncherBrMetrics()) {
            restoreEventLogger.logItemsRestored(favoritesIdToDataType(favoritesId), count)
        }
    }

    /**
     * Helper to log a failure to restore a single item from the Favorites table.
     *
@@ -114,7 +126,7 @@ class LauncherRestoreEventLoggerImpl(val context: Context) : LauncherRestoreEven
     */
    override fun reportLauncherRestoreResults() {
        if (Flags.enableLauncherBrMetrics()) {
            backupManager.reportDelayedRestoreResult(restoreEventLogger)
            BackupManager(context).reportDelayedRestoreResult(restoreEventLogger)
        }
    }

+37 −7
Original line number Diff line number Diff line
@@ -52,8 +52,10 @@ import static com.android.launcher3.LauncherConstants.TraceEvents.ON_CREATE_EVT;
import static com.android.launcher3.LauncherConstants.TraceEvents.ON_NEW_INTENT_EVT;
import static com.android.launcher3.LauncherConstants.TraceEvents.ON_RESUME_EVT;
import static com.android.launcher3.LauncherConstants.TraceEvents.ON_START_EVT;
import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
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.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.EDIT_MODE;
import static com.android.launcher3.LauncherState.FLAG_MULTI_PAGE;
@@ -63,6 +65,8 @@ import static com.android.launcher3.LauncherState.NO_OFFSET;
import static com.android.launcher3.LauncherState.NO_SCALE;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_BIND_FAILURE;
import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_INVALID_LOCATION;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
import static com.android.launcher3.config.FeatureFlags.MULTI_SELECT_EDIT_MODE;
@@ -162,6 +166,7 @@ import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.apppairs.AppPairIcon;
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger;
import com.android.launcher3.celllayout.CellPosMapper;
import com.android.launcher3.celllayout.CellPosMapper.CellPos;
import com.android.launcher3.celllayout.CellPosMapper.TwoPanelCellPosMapper;
@@ -2158,9 +2163,15 @@ public class Launcher extends StatefulActivity<LauncherState>
        int newItemsScreenId = -1;
        int end = items.size();
        View newView = null;
        LauncherRestoreEventLogger restoreEventLogger = null;
        Boolean isRestoreFromBackup = (Boolean) LauncherPrefs.get(getApplicationContext())
                .get(IS_FIRST_LOAD_AFTER_RESTORE);
        if (isRestoreFromBackup) {
            restoreEventLogger = LauncherRestoreEventLogger.Companion
                    .newInstance(getApplicationContext());
        }
        for (int i = 0; i < end; i++) {
            final ItemInfo item = items.get(i);

            // Short circuit if we are loading dock items for a configuration which has no dock
            if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
                    mHotseat == null) {
@@ -2187,12 +2198,17 @@ public class Launcher extends StatefulActivity<LauncherState>
                            (FolderInfo) item);
                    break;
                }
                case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
                case ITEM_TYPE_APPWIDGET:
                case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: {
                    view = inflateAppWidget((LauncherAppWidgetInfo) item);
                    view = inflateAppWidget((LauncherAppWidgetInfo) item, restoreEventLogger);
                    if (view == null) {
                        continue;
                    }
                    // Widgets have more checks when inflating, so we have to wait until here
                    // to mark restored, instead of logging in LoaderTask.
                    if (restoreEventLogger != null) {
                        restoreEventLogger.logSingleFavoritesItemRestored(item.itemType);
                    }
                    break;
                }
                default:
@@ -2216,6 +2232,10 @@ public class Launcher extends StatefulActivity<LauncherState>
                    if (FeatureFlags.IS_STUDIO_BUILD) {
                        throw (new RuntimeException(desc));
                    } else {
                        if (restoreEventLogger != null) {
                            restoreEventLogger.logSingleFavoritesItemRestoreFailed(item.itemType,
                                    RESTORE_ERROR_INVALID_LOCATION);
                        }
                        getModelWriter().deleteItemFromDatabase(item, desc);
                        continue;
                    }
@@ -2274,6 +2294,9 @@ public class Launcher extends StatefulActivity<LauncherState>
        } else if (focusFirstItemForAccessibility && viewToFocus != null) {
            viewToFocus.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
        }
        if (restoreEventLogger != null) {
            restoreEventLogger.reportLauncherRestoreResults();
        }
        workspace.requestLayout();
    }

@@ -2281,14 +2304,15 @@ public class Launcher extends StatefulActivity<LauncherState>
     * Add the views for a widget to the workspace.
     */
    public void bindAppWidget(LauncherAppWidgetInfo item) {
        View view = inflateAppWidget(item);
        View view = inflateAppWidget(item, null);
        if (view != null) {
            mWorkspace.addInScreen(view, item);
            mWorkspace.requestLayout();
        }
    }

    private View inflateAppWidget(LauncherAppWidgetInfo item) {
    private View inflateAppWidget(LauncherAppWidgetInfo item,
            @Nullable LauncherRestoreEventLogger restoreEventLogger) {
        if (item.hasOptionFlag(LauncherAppWidgetInfo.OPTION_SEARCH_WIDGET)) {
            item.providerName = QsbContainerView.getSearchComponentName(this);
            if (item.providerName == null) {
@@ -2305,11 +2329,9 @@ public class Launcher extends StatefulActivity<LauncherState>
        }

        TraceHelper.INSTANCE.beginSection("BIND_WIDGET_id=" + item.appWidgetId);

        try {
            final LauncherAppWidgetProviderInfo appWidgetInfo;
            String removalReason = "";

            if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) {
                // If the provider is not ready, bind as a pending widget.
                appWidgetInfo = null;
@@ -2349,6 +2371,10 @@ public class Launcher extends StatefulActivity<LauncherState>
                            "Removing restored widget: id=" + item.appWidgetId
                            + " belongs to component " + item.providerName + " user " + item.user
                            + ", as the provider is null and " + removalReason);
                    if (restoreEventLogger != null) {
                        restoreEventLogger.logSingleFavoritesItemRestoreFailed(
                                ITEM_TYPE_APPWIDGET, RESTORE_ERROR_BIND_FAILURE);
                    }
                    return null;
                }

@@ -2419,6 +2445,10 @@ public class Launcher extends StatefulActivity<LauncherState>
                if (appWidgetInfo == null) {
                    FileLog.e(TAG, "Removing invalid widget: id=" + item.appWidgetId);
                    getModelWriter().deleteWidgetInfo(item, getAppWidgetHolder(), removalReason);
                    if (restoreEventLogger != null) {
                        restoreEventLogger.logSingleFavoritesItemRestoreFailed(
                                ITEM_TYPE_APPWIDGET, RESTORE_ERROR_BIND_FAILURE);
                    }
                    return null;
                }

+8 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import com.android.launcher3.config.FeatureFlags.LPNH_TIMEOUT_MS
import com.android.launcher3.model.DeviceGridState
import com.android.launcher3.pm.InstallSessionHelper
import com.android.launcher3.provider.RestoreDbTask
import com.android.launcher3.provider.RestoreDbTask.FIRST_LOAD_AFTER_RESTORE_KEY
import com.android.launcher3.states.RotationHelper
import com.android.launcher3.util.DisplayController
import com.android.launcher3.util.MainThreadInitializedObject
@@ -417,6 +418,13 @@ class LauncherPrefs(private val encryptedContext: Context) {
                InvariantDeviceProfile.TYPE_PHONE,
                EncryptionType.MOVE_TO_DEVICE_PROTECTED
            )
        @JvmField
        val IS_FIRST_LOAD_AFTER_RESTORE =
            backedUpItem(
                FIRST_LOAD_AFTER_RESTORE_KEY,
                false,
                EncryptionType.MOVE_TO_DEVICE_PROTECTED
            )
        @JvmField val APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_IDS, "")
        @JvmField val OLD_APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_OLD_IDS, "")
        @JvmField
+19 −0
Original line number Diff line number Diff line
@@ -14,6 +14,15 @@ open class LauncherRestoreEventLogger : ResourceBasedOverride {
    companion object {
        const val TAG = "LauncherRestoreEventLogger"

        // Restore Errors
        const val RESTORE_ERROR_PROFILE_DELETED = "user_profile_deleted"
        const val RESTORE_ERROR_MISSING_INFO = "missing_information_when_loading"
        const val RESTORE_ERROR_BIND_FAILURE = "binding_to_view_failed"
        const val RESTORE_ERROR_INVALID_LOCATION = "invalid_size_or_location"
        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"

        fun newInstance(context: Context?): LauncherRestoreEventLogger {
            return ResourceBasedOverride.Overrides.getObject(
                LauncherRestoreEventLogger::class.java,
@@ -53,6 +62,16 @@ open class LauncherRestoreEventLogger : ResourceBasedOverride {
        // no-op
    }

    /**
     * Helper to log successfully restoring multiple items from the Favorites table.
     *
     * @param favoritesId The id of the item type from [Favorites] that was restored.
     * @param count number of items that restored.
     */
    open fun logFavoritesItemsRestored(favoritesId: Int, count: Int) {
        // no-op
    }

    /**
     * Helper to log a failure to restore a single item from the Favorites table.
     *
+1 −1
Original line number Diff line number Diff line
@@ -259,7 +259,7 @@ public class PreviewSurfaceRenderer {
                        query += " or " + LauncherSettings.Favorites.SCREEN + " = "
                                + Workspace.SECOND_SCREEN_ID;
                    }
                    loadWorkspace(new ArrayList<>(), query, null);
                    loadWorkspace(new ArrayList<>(), query, null, null);

                    final SparseArray<Size> spanInfo =
                            getLoadedLauncherWidgetInfo(previewContext.getBaseContext());
Loading