From a97f179909f2ad50b733084735f2ac581d5cfba3 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Wed, 19 Mar 2025 09:06:17 +0000 Subject: [PATCH 1/2] Add logs for the app binding flow. This can help debug issues like the blank all apps issue. Bug: 393406722 Test: Manual Flag: EXEMPT bugfix Change-Id: I0481531313d3633c46e63646511b59e081046cf8 --- .../allapps/ActivityAllAppsContainerView.java | 5 ++++- src/com/android/launcher3/allapps/AllAppsStore.java | 10 ++++++++++ .../android/launcher3/model/BaseLauncherBinder.java | 3 +++ src/com/android/launcher3/util/ViewOnDrawExecutor.java | 8 +++++++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java index f60896eb6d..3d8ebbc75b 100644 --- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java @@ -575,6 +575,7 @@ public class ActivityAllAppsContainerView } protected void rebindAdapters(boolean force) { + Log.d(TAG, "rebindAdapters: force: " + force); if (mSearchTransitionController.isRunning()) { mRebindAdaptersAfterSearchAnimation = true; return; @@ -583,6 +584,7 @@ public class ActivityAllAppsContainerView boolean showTabs = shouldShowTabs(); if (showTabs == mUsingTabs && !force) { + Log.d(TAG, "rebindAdapters: Not needed."); return; } @@ -678,6 +680,7 @@ public class ActivityAllAppsContainerView } private void replaceAppsRVContainer(boolean showTabs) { + Log.d(TAG, "replaceAppsRVContainer: showTabs: " + showTabs); for (int i = AdapterHolder.MAIN; i <= AdapterHolder.WORK; i++) { AdapterHolder adapterHolder = mAH.get(i); if (adapterHolder.mRecyclerView != null) { @@ -711,7 +714,6 @@ public class ActivityAllAppsContainerView mWorkManager.reset(); post(() -> mAH.get(AdapterHolder.WORK).applyPadding()); - } else { mWorkManager.detachWorkUtilityViews(); mViewPager = null; @@ -1017,6 +1019,7 @@ public class ActivityAllAppsContainerView @VisibleForTesting public void onAppsUpdated() { + Log.d(TAG, "onAppsUpdated; number of apps: " + mAllAppsStore.getApps().length); mHasWorkApps = Stream.of(mAllAppsStore.getApps()) .anyMatch(mWorkManager.getItemInfoMatcher()); mHasPrivateApps = Stream.of(mAllAppsStore.getApps()) diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java index d5a4022792..821027e2bd 100644 --- a/src/com/android/launcher3/allapps/AllAppsStore.java +++ b/src/com/android/launcher3/allapps/AllAppsStore.java @@ -20,6 +20,7 @@ import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY; import android.content.Context; import android.os.UserHandle; +import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -53,6 +54,7 @@ import java.util.function.Predicate; */ public class AllAppsStore { + private static final String TAG = "AllAppsStore"; // Defer updates flag used to defer all apps updates to the next draw. public static final int DEFER_UPDATES_NEXT_DRAW = 1 << 0; // Defer updates flag used to defer all apps updates by a test's request. @@ -102,6 +104,7 @@ public class AllAppsStore { public void setApps(@Nullable AppInfo[] apps, int flags, Map map, boolean shouldPreinflate) { mApps = apps == null ? EMPTY_ARRAY : apps; + Log.d(TAG, "setApps: apps.length=" + mApps.length); mModelFlags = flags; notifyUpdate(); mPackageUserKeytoUidMap = map; @@ -159,10 +162,12 @@ public class AllAppsStore { public void enableDeferUpdates(int flag) { mDeferUpdatesFlags |= flag; + Log.d(TAG, "enableDeferUpdates: " + flag + " mDeferUpdatesFlags=" + mDeferUpdatesFlags); } public void disableDeferUpdates(int flag) { mDeferUpdatesFlags &= ~flag; + Log.d(TAG, "disableDeferUpdates: " + flag + " mDeferUpdatesFlags=" + mDeferUpdatesFlags); if (mDeferUpdatesFlags == 0 && mUpdatePending) { notifyUpdate(); mUpdatePending = false; @@ -171,6 +176,9 @@ public class AllAppsStore { public void disableDeferUpdatesSilently(int flag) { mDeferUpdatesFlags &= ~flag; + Log.d(TAG, "disableDeferUpdatesSilently: " + flag + + " mDeferUpdatesFlags=" + mDeferUpdatesFlags); + } public int getDeferUpdatesFlags() { @@ -179,9 +187,11 @@ public class AllAppsStore { private void notifyUpdate() { if (mDeferUpdatesFlags != 0) { + Log.d(TAG, "notifyUpdate: deferring update"); mUpdatePending = true; return; } + Log.d(TAG, "notifyUpdate: notifying listeners"); for (OnUpdateListener listener : mUpdateListeners) { listener.onAppsUpdated(); } diff --git a/src/com/android/launcher3/model/BaseLauncherBinder.java b/src/com/android/launcher3/model/BaseLauncherBinder.java index c4bbae416b..1d19a17d42 100644 --- a/src/com/android/launcher3/model/BaseLauncherBinder.java +++ b/src/com/android/launcher3/model/BaseLauncherBinder.java @@ -323,8 +323,10 @@ public class BaseLauncherBinder { Executor pendingExecutor = pendingTasks::add; RunnableList onCompleteSignal = new RunnableList(); + onCompleteSignal.add(() -> Log.d(TAG, "Calling onCompleteSignal")); if (enableWorkspaceInflation() && inflater != null) { + Log.d(TAG, "Starting async inflation"); MODEL_EXECUTOR.execute(() -> { inflateAsyncAndBind(otherWorkspaceItems, inflater, pendingExecutor); inflateAsyncAndBind(otherAppWidgets, inflater, pendingExecutor); @@ -335,6 +337,7 @@ public class BaseLauncherBinder { MAIN_EXECUTOR.execute(onCompleteSignal::executeAllAndDestroy); }); } else { + Log.d(TAG, "Starting sync inflation"); bindItemsInChunks(otherWorkspaceItems, ITEMS_CHUNK, pendingExecutor); bindItemsInChunks(otherAppWidgets, 1, pendingExecutor); setupPendingBind(currentScreenIds, pendingExecutor); diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java index 26bfd36dcf..dad76299b7 100644 --- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java +++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java @@ -16,6 +16,7 @@ package com.android.launcher3.util; +import android.util.Log; import android.view.View; import android.view.View.OnAttachStateChangeListener; import android.view.ViewTreeObserver.OnDrawListener; @@ -32,6 +33,7 @@ import java.util.function.Consumer; public class ViewOnDrawExecutor implements OnDrawListener, Runnable, OnAttachStateChangeListener { + private static final String TAG = "ViewOnDrawExecutor"; private final RunnableList mTasks; private final Consumer mOnClearCallback; private View mAttachedView; @@ -88,7 +90,10 @@ public class ViewOnDrawExecutor implements OnDrawListener, Runnable, * Executes all tasks immediately */ public void markCompleted() { - if (!mCancelled) { + if (mCancelled) { + Log.d(TAG, "markCompleted ignored: cancelled"); + } else { + Log.d(TAG, "markCompleted: executing tasks"); mTasks.executeAllAndDestroy(); } mCompleted = true; @@ -101,6 +106,7 @@ public class ViewOnDrawExecutor implements OnDrawListener, Runnable, } public void cancel() { + Log.d(TAG, "Cancelling tasks"); mCancelled = true; markCompleted(); } From c966dd4ef6c61d958d64c0979f9cfe2c9e5f9205 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Thu, 20 Mar 2025 10:24:15 +0000 Subject: [PATCH 2/2] Do not defer All Apps updates with async inflation. With enableWorkspaceInflation, onCompleteSignal can be executed minutes after the initial bind, leaving All Apps in a stale empty state. And the async approach removes the need for this deferred rendering anyway. Bug: 393406722 Test: Wipe, add personal account in SUW, add work account. Flag: EXEMPT bugfix Change-Id: I0ad8d5c26f4b982403aead5cbd190482fcc42dfe --- src/com/android/launcher3/ModelCallbacks.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/ModelCallbacks.kt b/src/com/android/launcher3/ModelCallbacks.kt index 32b47d0b22..f38dc418a0 100644 --- a/src/com/android/launcher3/ModelCallbacks.kt +++ b/src/com/android/launcher3/ModelCallbacks.kt @@ -95,7 +95,7 @@ class ModelCallbacks(private var launcher: Launcher) : BgDataModel.Callbacks { synchronouslyBoundPages = boundPages pagesToBindSynchronously = LIntSet() clearPendingBinds() - if (!launcher.isInState(LauncherState.ALL_APPS)) { + if (!launcher.isInState(LauncherState.ALL_APPS) && !Flags.enableWorkspaceInflation()) { launcher.appsView.appsStore.enableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW) pendingTasks.add { launcher.appsView.appsStore.disableDeferUpdates(