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
This commit is contained in:
Charlie Anderson
2023-10-26 11:22:26 -04:00
parent 83d42f71ca
commit 511421c12f
7 changed files with 182 additions and 30 deletions
+96 -16
View File
@@ -17,9 +17,16 @@
package com.android.launcher3.model;
import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN;
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;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_APP_NOT_INSTALLED;
import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_INVALID_LOCATION;
import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_MISSING_INFO;
import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_PROFILE_DELETED;
import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_SHORTCUT_NOT_FOUND;
import static com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RESTORE_ERROR_WIDGETS_DISABLED;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
import static com.android.launcher3.config.FeatureFlags.SMARTSPACE_AS_A_WIDGET;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
@@ -69,6 +76,7 @@ import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderGridOrganizer;
@@ -134,6 +142,7 @@ public class LoaderTask implements Runnable {
private final AllAppsList mBgAllAppsList;
protected final BgDataModel mBgDataModel;
private final ModelDelegate mModelDelegate;
private boolean mIsRestoreFromBackup;
private FirstScreenBroadcast mFirstScreenBroadcast;
@@ -148,7 +157,6 @@ public class LoaderTask implements Runnable {
private final IconCache mIconCache;
private final UserManagerState mUserManagerState;
protected final Map<ComponentKey, AppWidgetProviderInfo> mWidgetProvidersMap = new ArrayMap<>();
private Map<ShortcutKey, ShortcutInfo> mShortcutKeyToPinnedShortcuts;
@@ -172,7 +180,6 @@ public class LoaderTask implements Runnable {
mBgDataModel = bgModel;
mModelDelegate = modelDelegate;
mLauncherBinder = launcherBinder;
mLauncherApps = mApp.getContext().getSystemService(LauncherApps.class);
mUserManager = mApp.getContext().getSystemService(UserManager.class);
mUserCache = UserCache.getInstance(mApp.getContext());
@@ -221,9 +228,14 @@ public class LoaderTask implements Runnable {
TraceHelper.INSTANCE.beginSection(TAG);
LoaderMemoryLogger memoryLogger = new LoaderMemoryLogger();
mIsRestoreFromBackup =
(Boolean) LauncherPrefs.get(mApp.getContext()).get(IS_FIRST_LOAD_AFTER_RESTORE);
LauncherRestoreEventLogger restoreEventLogger = LauncherRestoreEventLogger
.Companion.newInstance(mApp.getContext());
try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
List<ShortcutInfo> allShortcuts = new ArrayList<>();
loadWorkspace(allShortcuts, "", memoryLogger);
loadWorkspace(allShortcuts, "", memoryLogger, restoreEventLogger);
// Sanitize data re-syncs widgets/shortcuts based on the workspace loaded from db.
// sanitizeData should not be invoked if the workspace is loaded from a db different
@@ -314,8 +326,8 @@ public class LoaderTask implements Runnable {
mLauncherBinder.bindWidgets();
logASplit("bindWidgets");
verifyNotStopped();
LauncherPrefs prefs = LauncherPrefs.get(mApp.getContext());
if (SMARTSPACE_AS_A_WIDGET.get() && prefs.get(SHOULD_SHOW_SMARTSPACE)) {
mLauncherBinder.bindSmartspaceWidget();
// Turn off pref.
@@ -349,6 +361,11 @@ public class LoaderTask implements Runnable {
mModelDelegate.modelLoadComplete();
transaction.commit();
memoryLogger.clearLogs();
if (mIsRestoreFromBackup) {
restoreEventLogger.reportLauncherRestoreResults();
mIsRestoreFromBackup = false;
LauncherPrefs.get(mApp.getContext()).putSync(IS_FIRST_LOAD_AFTER_RESTORE.to(false));
}
} catch (CancellationException e) {
// Loader stopped, ignore
logASplit("Cancelled");
@@ -367,10 +384,12 @@ public class LoaderTask implements Runnable {
protected void loadWorkspace(
List<ShortcutInfo> allDeepShortcuts,
String selection,
LoaderMemoryLogger memoryLogger) {
LoaderMemoryLogger memoryLogger,
@Nullable LauncherRestoreEventLogger restoreEventLogger
) {
Trace.beginSection("LoadWorkspace");
try {
loadWorkspaceImpl(allDeepShortcuts, selection, memoryLogger);
loadWorkspaceImpl(allDeepShortcuts, selection, memoryLogger, restoreEventLogger);
} finally {
Trace.endSection();
}
@@ -391,7 +410,8 @@ public class LoaderTask implements Runnable {
private void loadWorkspaceImpl(
List<ShortcutInfo> allDeepShortcuts,
String selection,
@Nullable LoaderMemoryLogger memoryLogger) {
@Nullable LoaderMemoryLogger memoryLogger,
@Nullable LauncherRestoreEventLogger restoreEventLogger) {
final Context context = mApp.getContext();
final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
final boolean isSafeMode = pmHelper.isSafeMode();
@@ -458,8 +478,8 @@ public class LoaderTask implements Runnable {
List<IconRequestInfo<WorkspaceItemInfo>> iconRequestInfos = new ArrayList<>();
while (!mStopped && c.moveToNext()) {
processWorkspaceItem(c, memoryLogger, installingPkgs, isSdCardReady,
tempPackageKey, widgetHelper, pmHelper,
processWorkspaceItem(c, memoryLogger, restoreEventLogger, installingPkgs,
isSdCardReady, tempPackageKey, widgetHelper, pmHelper,
iconRequestInfos, unlockedUsers, isSafeMode, allDeepShortcuts);
}
tryLoadWorkspaceIconsInBulk(iconRequestInfos);
@@ -518,6 +538,7 @@ public class LoaderTask implements Runnable {
private void processWorkspaceItem(LoaderCursor c,
LoaderMemoryLogger memoryLogger,
@Nullable LauncherRestoreEventLogger restoreEventLogger,
HashMap<PackageUserKey, SessionInfo> installingPkgs,
boolean isSdCardReady,
PackageUserKey tempPackageKey,
@@ -531,7 +552,11 @@ public class LoaderTask implements Runnable {
try {
if (c.user == null) {
// User has been deleted, remove the item.
c.markDeleted("User has been deleted");
c.markDeleted("User of this item has been deleted");
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_PROFILE_DELETED);
}
return;
}
@@ -542,6 +567,10 @@ public class LoaderTask implements Runnable {
Intent intent = c.parseIntent();
if (intent == null) {
c.markDeleted("Invalid or null intent");
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_MISSING_INFO);
}
return;
}
@@ -552,6 +581,10 @@ public class LoaderTask implements Runnable {
if (TextUtils.isEmpty(targetPkg)) {
c.markDeleted("Shortcuts can't have null package");
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_MISSING_INFO);
}
return;
}
@@ -569,6 +602,9 @@ public class LoaderTask implements Runnable {
if (mLauncherApps.isActivityEnabled(cn, c.user)) {
// no special handling necessary for this item
c.markRestored();
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestored(c.itemType);
}
} else {
// Gracefully try to find a fallback activity.
intent = pmHelper.getAppLaunchIntent(targetPkg, c.user);
@@ -579,7 +615,11 @@ public class LoaderTask implements Runnable {
intent.toUri(0)).commit();
cn = intent.getComponent();
} else {
c.markDeleted("Unable to find a launch target");
c.markDeleted("Intent null, unable to find a launch target");
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_MISSING_INFO);
}
return;
}
}
@@ -606,6 +646,10 @@ public class LoaderTask implements Runnable {
} else {
c.markDeleted("removing app that is not restored and not "
+ "installing. package: " + targetPkg);
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_APP_NOT_INSTALLED);
}
return;
}
} else if (pmHelper.isAppOnSdcard(targetPkg, c.user)) {
@@ -623,6 +667,10 @@ public class LoaderTask implements Runnable {
} else {
// Do not wait for external media load anymore.
c.markDeleted("Invalid package removed: " + targetPkg);
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_APP_NOT_INSTALLED);
}
return;
}
}
@@ -652,8 +700,12 @@ public class LoaderTask implements Runnable {
ShortcutInfo pinnedShortcut = mShortcutKeyToPinnedShortcuts.get(key);
if (pinnedShortcut == null) {
// The shortcut is no longer valid.
c.markDeleted("Pinned shortcut not found for package: "
+ key.getPackageName());
c.markDeleted("Pinned shortcut not found from request."
+ " package=" + key.getPackageName() + ", user=" + c.user);
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_SHORTCUT_NOT_FOUND);
}
return;
}
info = new WorkspaceItemInfo(pinnedShortcut, mApp.getContext());
@@ -672,6 +724,9 @@ public class LoaderTask implements Runnable {
info = c.loadSimpleWorkspaceItem();
info.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
}
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestored(c.itemType);
}
} else { // item type == ITEM_TYPE_SHORTCUT
info = c.loadSimpleWorkspaceItem();
@@ -751,13 +806,19 @@ public class LoaderTask implements Runnable {
// no special handling required for restored folders
c.markRestored();
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestored(c.itemType);
}
c.checkAndAddItem(folderInfo, mBgDataModel, memoryLogger);
break;
case Favorites.ITEM_TYPE_APPWIDGET:
if (WidgetsModel.GO_DISABLE_WIDGETS) {
c.markDeleted("Only legacy shortcuts can have null package");
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_WIDGETS_DISABLED);
}
return;
}
// Follow through
@@ -774,6 +835,10 @@ public class LoaderTask implements Runnable {
component = QsbContainerView.getSearchComponentName(mApp.getContext());
if (component == null) {
c.markDeleted("Discarding SearchWidget without packagename ");
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_MISSING_INFO);
}
return;
}
} else {
@@ -799,6 +864,10 @@ public class LoaderTask implements Runnable {
final boolean isProviderReady = isValidProvider(provider);
if (!isSafeMode && !customWidget && wasProviderReady && !isProviderReady) {
c.markDeleted("Deleting widget that isn't installed anymore: " + provider);
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_APP_NOT_INSTALLED);
}
} else {
LauncherAppWidgetInfo appWidgetInfo;
if (isProviderReady) {
@@ -841,6 +910,10 @@ public class LoaderTask implements Runnable {
|= LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
} else if (!isSafeMode) {
c.markDeleted("Unrestored widget removed: " + component);
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_APP_NOT_INSTALLED);
}
return;
}
@@ -862,6 +935,10 @@ public class LoaderTask implements Runnable {
if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) {
c.markDeleted("Widget has invalid size: "
+ appWidgetInfo.spanX + "x" + appWidgetInfo.spanY);
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_INVALID_LOCATION);
}
return;
}
LauncherAppWidgetProviderInfo widgetProviderInfo =
@@ -875,12 +952,15 @@ public class LoaderTask implements Runnable {
+ "x" + appWidgetInfo.spanY + " minSpan="
+ widgetProviderInfo.minSpanX + "x"
+ widgetProviderInfo.minSpanY);
logWidgetInfo(mApp.getInvariantDeviceProfile(),
widgetProviderInfo);
logWidgetInfo(mApp.getInvariantDeviceProfile(), widgetProviderInfo);
}
if (!c.isOnWorkspaceOrHotseat()) {
c.markDeleted("Widget found where container != CONTAINER_DESKTOP"
+ "nor CONTAINER_HOTSEAT - ignoring!");
if (mIsRestoreFromBackup && restoreEventLogger != null) {
restoreEventLogger.logSingleFavoritesItemRestoreFailed(
c.itemType, RESTORE_ERROR_INVALID_LOCATION);
}
return;
}