Merge "Update the colors for gesture navigation tutorial." into udc-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index bf84820..55301ff 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -135,7 +135,7 @@
   }
 }
 
-// Next value 44
+// Next value 45
 enum Attribute {
   option allow_alias = true;
 
@@ -173,6 +173,7 @@
   ALL_APPS_SEARCH_RESULT_SLICE = 19;
   ALL_APPS_SEARCH_RESULT_WIDGETS = 20;
   ALL_APPS_SEARCH_RESULT_PLAY = 21;
+  ALL_APPS_SEARCH_RESULT_PLAY_GMS = 44;
   ALL_APPS_SEARCH_RESULT_FALLBACK = 22;
   ALL_APPS_SEARCH_RESULT_SUGGEST = 22 [deprecated = true];
   ALL_APPS_SEARCH_RESULT_ASSISTANT = 23;
diff --git a/protos/launcher_trace.proto b/protos/launcher_trace.proto
index 65fcfe5..e5a86a0 100644
--- a/protos/launcher_trace.proto
+++ b/protos/launcher_trace.proto
@@ -63,5 +63,6 @@
         RECENTS = 2;
         NEW_TASK = 3;
         LAST_TASK = 4;
+        ALL_APPS = 5;
     }
 }
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 18fe30d..5d4e19d 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -196,14 +196,13 @@
                         finish();
                     }
                 });
-                mAnimator.start();
-
                 if (skipFirstFrame) {
                     // Because t=0 has the app icon in its original spot, we can skip the
                     // first frame and have the same movement one frame earlier.
                     mAnimator.setCurrentPlayTime(
                             Math.min(getSingleFrameMs(context), mAnimator.getTotalDuration()));
                 }
+                mAnimator.start();
             }
         }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
index 8dbc51a..83a3343 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
@@ -38,14 +38,21 @@
         view.post {
             val popupView = createAndPopulate(view, context)
             popupView.requestFocus()
-            popupView.onCloseCallback = {
-                context.onPopupVisibilityChanged(false)
-                if (launcherPrefs.get(TASKBAR_PINNING)) {
-                    animateTransientToPersistentTaskBar()
-                } else {
-                    animatePersistentToTransientTaskbar()
+
+            popupView.onCloseCallback =
+                callback@{ didPreferenceChange ->
+                    context.dragLayer.post { context.onPopupVisibilityChanged(false) }
+
+                    if (!didPreferenceChange) {
+                        return@callback
+                    }
+
+                    if (launcherPrefs.get(TASKBAR_PINNING)) {
+                        animateTransientToPersistentTaskbar()
+                    } else {
+                        animatePersistentToTransientTaskbar()
+                    }
                 }
-            }
             popupView.changePreference = {
                 launcherPrefs.put(TASKBAR_PINNING, !launcherPrefs.get(TASKBAR_PINNING))
             }
@@ -55,7 +62,7 @@
     }
 
     // TODO(b/265436799): provide animation/transition from transient taskbar to persistent one
-    private fun animateTransientToPersistentTaskBar() {}
+    private fun animateTransientToPersistentTaskbar() {}
 
     // TODO(b/265436799): provide animation/transition from persistent taskbar to transient one
     private fun animatePersistentToTransientTaskbar() {}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
index 2000d98..e07f0c0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
@@ -17,6 +17,7 @@
 
 import android.annotation.SuppressLint
 import android.content.Context
+import android.content.Intent
 import android.graphics.Rect
 import android.util.AttributeSet
 import android.view.Gravity
@@ -42,6 +43,9 @@
     companion object {
         private const val TAG = "TaskbarDividerPopupView"
         private const val DIVIDER_POPUP_CLOSING_DELAY = 500L
+        private const val SETTINGS_PACKAGE_NAME = "com.android.settings"
+        private const val CHANGE_NAVIGATION_MODE_ACTION =
+            "com.android.settings.NAVIGATION_MODE_SETTINGS"
 
         @JvmStatic
         fun createAndPopulate(
@@ -71,7 +75,7 @@
     private var didPreferenceChange = false
 
     /** Callback invoked when the pinning popup view is closing. */
-    var onCloseCallback: () -> Unit = {}
+    var onCloseCallback: (preferenceChanged: Boolean) -> Unit = {}
 
     /**
      * Callback invoked when the user preference changes in popup view. Preference change will be
@@ -98,12 +102,21 @@
         super.onFinishInflate()
         val taskbarSwitchOption = findViewById<LinearLayout>(R.id.taskbar_switch_option)
         val alwaysShowTaskbarSwitch = findViewById<Switch>(R.id.taskbar_pinning_switch)
+        val navigationModeChangeOption =
+            findViewById<LinearLayout>(R.id.navigation_mode_switch_option)
         alwaysShowTaskbarSwitch.isChecked = alwaysShowTaskbarOn
         taskbarSwitchOption.setOnClickListener {
             alwaysShowTaskbarSwitch.isClickable = true
             alwaysShowTaskbarSwitch.isChecked = !alwaysShowTaskbarOn
             onClickAlwaysShowTaskbarSwitchOption()
         }
+        navigationModeChangeOption.setOnClickListener {
+            context.startActivity(
+                Intent(CHANGE_NAVIGATION_MODE_ACTION)
+                    .setPackage(SETTINGS_PACKAGE_NAME)
+                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+            )
+        }
     }
 
     /** Orient object as usual and then center object horizontally. */
@@ -156,9 +169,7 @@
     }
 
     override fun closeComplete() {
-        if (didPreferenceChange) {
-            onCloseCallback()
-        }
+        onCloseCallback(didPreferenceChange)
         super.closeComplete()
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 1d90a43..e334d05 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -66,7 +66,6 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatedFloat;
 import com.android.launcher3.anim.AnimatorListeners;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
 import com.android.quickstep.SystemUiProxy;
@@ -1022,10 +1021,6 @@
      *                unstashed.
      */
     public void updateStateForFlag(int flag, boolean enabled) {
-        if (flag == FLAG_IN_APP && TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.TASKBAR_IN_APP_STATE, String.format(
-                    "setting flag FLAG_IN_APP to: %b", enabled), new Exception());
-        }
         if (enabled) {
             mState |= flag;
         } else {
@@ -1250,16 +1245,6 @@
                     && animationType != TRANSITION_DEFAULT;
 
             if (mIsStashed != isStashed || transitionTypeChanged) {
-                if (TestProtocol.sDebugTracing) {
-                    Log.d(TestProtocol.TASKBAR_IN_APP_STATE, String.format(
-                            "setState: mIsStashed=%b, isStashed=%b, "
-                                    + "mAnimationType=%d, animationType=%d, duration=%d",
-                            mIsStashed,
-                            isStashed,
-                            mLastStartedTransitionType,
-                            animationType,
-                            duration));
-                }
                 mIsStashed = isStashed;
                 mLastStartedTransitionType = animationType;
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index d69769a..f0d28df 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -71,13 +71,6 @@
         } else {
             mTranslationShift = TRANSLATION_SHIFT_OPENED;
         }
-
-        if (FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get()) {
-            mAppsView.getAppsRecyclerViewContainer().setOutlineProvider(mViewOutlineProvider);
-            mAppsView.getAppsRecyclerViewContainer().setClipToOutline(true);
-            findOnBackInvokedDispatcher().registerOnBackInvokedCallback(
-                    OnBackInvokedDispatcher.PRIORITY_DEFAULT, this);
-        }
     }
 
     /** The apps container inside this view. */
@@ -88,9 +81,6 @@
     @Override
     protected void handleClose(boolean animate) {
         handleClose(animate, mAllAppsCallbacks.getCloseDuration());
-        if (FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get()) {
-            findOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(this);
-        }
     }
 
     @Override
@@ -121,12 +111,29 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mActivityContext.addOnDeviceProfileChangeListener(this);
+        if (FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get()) {
+            mAppsView.getAppsRecyclerViewContainer().setOutlineProvider(mViewOutlineProvider);
+            mAppsView.getAppsRecyclerViewContainer().setClipToOutline(true);
+            OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
+            if (dispatcher != null) {
+                dispatcher.registerOnBackInvokedCallback(
+                        OnBackInvokedDispatcher.PRIORITY_DEFAULT, this);
+            }
+        }
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         mActivityContext.removeOnDeviceProfileChangeListener(this);
+        if (FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get()) {
+            mAppsView.getAppsRecyclerViewContainer().setOutlineProvider(null);
+            mAppsView.getAppsRecyclerViewContainer().setClipToOutline(false);
+            OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
+            if (dispatcher != null) {
+                dispatcher.unregisterOnBackInvokedCallback(this);
+            }
+        }
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index 3990dad..0eef70e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -402,8 +402,9 @@
         PredictedAppIcon icon = (PredictedAppIcon) LayoutInflater.from(parent.getContext())
                 .inflate(R.layout.predicted_app_icon, parent, false);
         icon.applyFromWorkspaceItem(info);
-        icon.setOnClickListener(ItemClickHandler.INSTANCE);
-        icon.setOnFocusChangeListener(Launcher.getLauncher(parent.getContext()).getFocusHandler());
+        Launcher launcher = Launcher.getLauncher(parent.getContext());
+        icon.setOnClickListener(launcher.getItemOnClickListener());
+        icon.setOnFocusChangeListener(launcher.getFocusHandler());
         return icon;
     }
 
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index d64347f..b7a29e0 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -39,6 +39,7 @@
 import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
 import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
 import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.quickstep.GestureState.GestureEndTarget.ALL_APPS;
 import static com.android.quickstep.GestureState.GestureEndTarget.HOME;
 import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
 import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
@@ -161,6 +162,9 @@
 
     private static final ArrayList<String> STATE_NAMES = new ArrayList<>();
 
+    /** Shift distance to transition to All Apps if ENABLE_ALL_APPS_FROM_OVERVIEW. */
+    public static final float ALL_APPS_SHIFT_THRESHOLD = 2f;
+
     protected final BaseActivityInterface<S, T> mActivityInterface;
     protected final InputConsumerProxy mInputConsumerProxy;
     protected final ActivityInitListener mActivityInitListener;
@@ -247,6 +251,8 @@
             getNextStateFlag("STATE_CURRENT_TASK_FINISHED");
     private static final int STATE_FINISH_WITH_NO_END =
             getNextStateFlag("STATE_FINISH_WITH_NO_END");
+    private static final int STATE_SETTLED_ON_ALL_APPS =
+            getNextStateFlag("STATE_SETTLED_ON_ALL_APPS");
 
     private static final int LAUNCHER_UI_STATES =
             STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED |
@@ -299,6 +305,7 @@
     private boolean mGestureStarted;
     private boolean mLogDirectionUpOrLeft = true;
     private boolean mIsLikelyToStartNewTask;
+    private boolean mIsInAllAppsRegion;
 
     private final long mTouchTimeMs;
     private long mLauncherFrameDrawnTime;
@@ -432,6 +439,9 @@
                 this::finishCurrentTransitionToHome);
         mStateCallback.runOnceAtState(STATE_SCALED_CONTROLLER_HOME | STATE_CURRENT_TASK_FINISHED,
                 this::reset);
+        mStateCallback.runOnceAtState(STATE_SETTLED_ON_ALL_APPS | STATE_SCREENSHOT_CAPTURED
+                        | STATE_GESTURE_COMPLETED,
+                this::finishCurrentTransitionToAllApps);
 
         mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
                         | STATE_LAUNCHER_DRAWN | STATE_SCALED_CONTROLLER_RECENTS
@@ -681,7 +691,9 @@
                 maybeUpdateRecentsAttachedState(true/* animate */, true/* moveRunningTask */);
                 Optional.ofNullable(mActivityInterface.getTaskbarController())
                         .ifPresent(TaskbarUIController::startTranslationSpring);
-                performHapticFeedback();
+                if (!mIsInAllAppsRegion) {
+                    performHapticFeedback();
+                }
             }
 
             @Override
@@ -695,7 +707,7 @@
         maybeUpdateRecentsAttachedState(true /* animate */);
     }
 
-    private void maybeUpdateRecentsAttachedState(boolean animate) {
+    protected void maybeUpdateRecentsAttachedState(boolean animate) {
         maybeUpdateRecentsAttachedState(animate, false /* moveRunningTask */);
     }
 
@@ -716,7 +728,9 @@
                 ? mRecentsAnimationTargets.findTask(mGestureState.getRunningTaskId())
                 : null;
         final boolean recentsAttachedToAppWindow;
-        if (mGestureState.getEndTarget() != null) {
+        if (mIsInAllAppsRegion) {
+            recentsAttachedToAppWindow = false;
+        } else if (mGestureState.getEndTarget() != null) {
             recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
         } else if (mContinuingLastGesture
                 && mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
@@ -772,6 +786,26 @@
         }
     }
 
+    /**
+     * Update whether user is currently dragging in a region that will trigger all apps.
+     */
+    private void setIsInAllAppsRegion(boolean isInAllAppsRegion) {
+        if (mIsInAllAppsRegion == isInAllAppsRegion
+                || !mActivityInterface.allowAllAppsFromOverview()) {
+            return;
+        }
+        mIsInAllAppsRegion = isInAllAppsRegion;
+
+        // Newly entering or exiting the zone - do haptic and animate recent tasks.
+        VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
+        maybeUpdateRecentsAttachedState(true);
+
+        // Draw active task below Launcher so that All Apps can appear over it.
+        runActionOnRemoteHandles(remoteTargetHandle ->
+                remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(isInAllAppsRegion));
+    }
+
+
     private void buildAnimationController() {
         if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
             return;
@@ -792,10 +826,15 @@
     @Override
     public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
         WindowInsets result = view.onApplyWindowInsets(windowInsets);
+        // Don't rebuild animation when we are animating the IME, because it will cause a loop
+        // where the insets change -> animation changes (updating ime) -> insets change -> ...
+        if (windowInsets.isVisible(WindowInsets.Type.ime())) {
+            return result;
+        }
         buildAnimationController();
         // Reapply the current shift to ensure it takes new insets into account, e.g. when long
         // pressing to stash taskbar without moving the finger.
-        updateFinalShift();
+        onCurrentShiftUpdated();
         return result;
     }
 
@@ -822,7 +861,8 @@
      */
     @UiThread
     @Override
-    public void updateFinalShift() {
+    public void onCurrentShiftUpdated() {
+        setIsInAllAppsRegion(mCurrentShift.value >= ALL_APPS_SHIFT_THRESHOLD);
         updateSysUiFlags(mCurrentShift.value);
         applyScrollAndTransform();
 
@@ -1085,6 +1125,9 @@
         }
 
         switch (endTarget) {
+            case ALL_APPS:
+                mStateCallback.setState(STATE_SETTLED_ON_ALL_APPS | STATE_CAPTURE_SCREENSHOT);
+                break;
             case HOME:
                 mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
                 // Notify the SysUI to use fade-in animation when entering PiP
@@ -1173,6 +1216,9 @@
         final boolean willGoToNewTask =
                 isScrollingToNewTask() && Math.abs(velocity.x) > Math.abs(endVelocity);
         final boolean isSwipeUp = endVelocity < 0;
+        if (mIsInAllAppsRegion) {
+            return isSwipeUp ? ALL_APPS : LAST_TASK;
+        }
         if (!isSwipeUp) {
             final boolean isCenteredOnNewTask =
                     mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
@@ -1188,7 +1234,9 @@
         // Fully gestural mode.
         final boolean isFlingX = Math.abs(velocity.x) > mContext.getResources()
                 .getDimension(R.dimen.quickstep_fling_threshold_speed);
-        if (isScrollingToNewTask && isFlingX) {
+        if (mIsInAllAppsRegion) {
+            return ALL_APPS;
+        } else if (isScrollingToNewTask && isFlingX) {
             // Flinging towards new task takes precedence over mIsMotionPaused (which only
             // checks y-velocity).
             return NEW_TASK;
@@ -1236,7 +1284,8 @@
         mGestureState.setEndTarget(endTarget, false /* isAtomic */);
         mAnimationFactory.setEndTarget(endTarget);
 
-        float endShift = endTarget.isLauncher ? 1 : 0;
+        float endShift = endTarget == ALL_APPS ? mDragLengthFactor
+                : endTarget.isLauncher ? 1 : 0;
         final float startShift;
         if (!isFling) {
             long expectedDuration = Math.abs(Math.round((endShift - currentShift)
@@ -1793,6 +1842,12 @@
         reset();
     }
 
+    @UiThread
+    private void finishCurrentTransitionToAllApps() {
+        finishCurrentTransitionToHome();
+        reset();
+    }
+
     private void reset() {
         mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
         if (mActivity != null) {
@@ -1926,7 +1981,8 @@
     private boolean updateThumbnail(int runningTaskId, boolean refreshView) {
         boolean finishTransitionPosted = false;
         final TaskView taskView;
-        if (mGestureState.getEndTarget() == HOME || mGestureState.getEndTarget() == NEW_TASK) {
+        if (mGestureState.getEndTarget() == HOME || mGestureState.getEndTarget() == NEW_TASK
+                || mGestureState.getEndTarget() == ALL_APPS) {
             // Capture the screenshot before finishing the transition to home or quickswitching to
             // ensure it's taken in the correct orientation, but no need to update the thumbnail.
             taskView = null;
@@ -2072,7 +2128,7 @@
 
     private void onRecentsViewScroll() {
         if (moveWindowWithRecentsScroll()) {
-            updateFinalShift();
+            onCurrentShiftUpdated();
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index fd7aa58..60083c6 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -187,6 +187,9 @@
 
     public abstract boolean allowMinimizeSplitScreen();
 
+    /** @return whether to allow going to All Apps from Overview. */
+    public abstract boolean allowAllAppsFromOverview();
+
     public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
         return deviceState.isInDeferredGestureRegion(ev) || deviceState.isImeRenderingNavButtons()
                 || isTrackpadMultiFingerSwipe(ev);
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 8bb189a..5c96000 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -139,6 +139,11 @@
     }
 
     @Override
+    public boolean allowAllAppsFromOverview() {
+        return false;
+    }
+
+    @Override
     public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
         // In non-gesture mode, user might be clicking on the home button which would directly
         // start the home activity instead of going through recents. In that case, defer starting
@@ -196,6 +201,7 @@
             case LAST_TASK:
                 return BACKGROUND_APP;
             case HOME:
+            case ALL_APPS:
             default:
                 return HOME;
         }
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 02f9f57..9d7ccb4 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -18,11 +18,13 @@
 import static com.android.launcher3.MotionEventsUtils.isTrackpadFourFingerSwipe;
 import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
 import static com.android.launcher3.MotionEventsUtils.isTrackpadThreeFingerSwipe;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
 import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
 import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_ALL_APPS;
 import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_HOME;
 import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_NEW_TASK;
 
@@ -68,7 +70,9 @@
                 GestureStateProto.GestureEndTarget.NEW_TASK),
 
         LAST_TASK(false, LAUNCHER_STATE_BACKGROUND, true,
-                GestureStateProto.GestureEndTarget.LAST_TASK);
+                GestureStateProto.GestureEndTarget.LAST_TASK),
+
+        ALL_APPS(true, LAUNCHER_STATE_ALLAPPS, false, GestureStateProto.GestureEndTarget.ALL_APPS);
 
         GestureEndTarget(boolean isLauncher, int containerType, boolean recentsAttachedToAppWindow,
                 GestureStateProto.GestureEndTarget protoEndTarget) {
@@ -385,6 +389,9 @@
             case NEW_TASK:
                 ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_NEW_TASK);
                 break;
+            case ALL_APPS:
+                ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_ALL_APPS);
+                break;
             case LAST_TASK:
             case RECENTS:
             default:
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index ea9f032..0e0b022 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -15,6 +15,7 @@
  */
 package com.android.quickstep;
 
+import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.BACKGROUND_APP;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -39,6 +40,7 @@
 import com.android.launcher3.LauncherInitListener;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.statehandlers.DepthController;
 import com.android.launcher3.statehandlers.DesktopVisibilityController;
 import com.android.launcher3.statemanager.StateManager;
@@ -264,6 +266,11 @@
     }
 
     @Override
+    public boolean allowAllAppsFromOverview() {
+        return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get();
+    }
+
+    @Override
     public boolean isInLiveTileMode() {
         Launcher launcher = getCreatedActivity();
         return launcher != null && launcher.getStateManager().getState() == OVERVIEW &&
@@ -347,6 +354,8 @@
             case NEW_TASK:
             case LAST_TASK:
                 return BACKGROUND_APP;
+            case ALL_APPS:
+                return ALL_APPS;
             case HOME:
             default:
                 return NORMAL;
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 5df4734..4e892e2 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -1,6 +1,5 @@
 package com.android.quickstep;
 
-import static com.android.launcher3.testing.shared.TestProtocol.NPE_TRANSIENT_TASKBAR;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 
 import android.app.Activity;
@@ -8,7 +7,6 @@
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.util.Log;
 
 import androidx.annotation.Nullable;
 
@@ -184,13 +182,9 @@
             TouchInteractionService.TISBinder tisBinder, boolean enable) {
         TaskbarActivityContext context = tisBinder.getTaskbarManager().getCurrentActivityContext();
         if (context == null) {
-            if (TestProtocol.sDebugTracing) {
-                Log.d(NPE_TRANSIENT_TASKBAR, "enableBlockingTimeout: enable=" + enable,
-                        new Exception());
-            }
-        } else {
-            context.enableBlockingTimeoutDuringTests(enable);
+            return;
         }
+        context.enableBlockingTimeoutDuringTests(enable);
     }
 
     private void enableTransientTaskbar(boolean enable) {
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index f30d3f1..d9c269a 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -52,9 +52,10 @@
      */
     public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
         if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
-            // TODO: binder call, only for prototyping. Creating the gluer should be postponed so
-            //  we can create it when we have the remote animation targets ready.
-            int desktopTasks = SystemUiProxy.INSTANCE.get(context).getVisibleDesktopTaskCount();
+            // TODO(279931899): binder call, only for prototyping. Creating the gluer should be
+            //  postponed so we can create it when we have the remote animation targets ready.
+            int desktopTasks = SystemUiProxy.INSTANCE.get(context).getVisibleDesktopTaskCount(
+                    context.getDisplayId());
             if (desktopTasks > 0) {
                 init(context, sizingStrategy, desktopTasks, true /* forDesktop */);
                 return;
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index 66d1e1e..8626c40 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -350,7 +350,8 @@
                 enableMultipleRegions(true);
             }
             activityInterface.onExitOverview(this, mExitOverviewRunnable);
-        } else if (endTarget == GestureState.GestureEndTarget.HOME) {
+        } else if (endTarget == GestureState.GestureEndTarget.HOME
+                || endTarget == GestureState.GestureEndTarget.ALL_APPS) {
             enableMultipleRegions(false);
         } else if (endTarget == GestureState.GestureEndTarget.NEW_TASK) {
             if (mOrientationTouchTransformer.getQuickStepStartingRotation() == -1) {
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index f913aff..1b4fdc4 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -67,7 +67,7 @@
     // 0 => preview snapShot is completely visible, and hotseat is completely translated down
     // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
     // visible.
-    protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
+    protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::onCurrentShiftUpdated);
     protected float mCurrentDisplacement;
 
     // The distance needed to drag to reach the task size in recents.
@@ -148,7 +148,7 @@
      * Called when the value of {@link #mCurrentShift} changes
      */
     @UiThread
-    public abstract void updateFinalShift();
+    public abstract void onCurrentShiftUpdated();
 
     protected PagedOrientationHandler getOrientationHandler() {
         // OrientationHandler should be independent of remote target, can directly take one
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 512d47e..616ddef 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -967,7 +967,7 @@
             IRemoteAnimationRunner runner) {
         mBackToLauncherCallback = callback;
         mBackToLauncherRunner = runner;
-        if (mBackAnimation == null) {
+        if (mBackAnimation == null || mBackToLauncherCallback == null) {
             return;
         }
         try {
@@ -1060,10 +1060,10 @@
     //
 
     /** Call shell to show all apps active on the desktop */
-    public void showDesktopApps() {
+    public void showDesktopApps(int displayId) {
         if (mDesktopMode != null) {
             try {
-                mDesktopMode.showDesktopApps();
+                mDesktopMode.showDesktopApps(displayId);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed call showDesktopApps", e);
             }
@@ -1071,10 +1071,10 @@
     }
 
     /** Call shell to get number of visible freeform tasks */
-    public int getVisibleDesktopTaskCount() {
+    public int getVisibleDesktopTaskCount(int displayId) {
         if (mDesktopMode != null) {
             try {
-                return mDesktopMode.getVisibleTaskCount();
+                return mDesktopMode.getVisibleTaskCount(displayId);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed call getVisibleDesktopTaskCount", e);
             }
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 64165b6..cd98e7a 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -61,6 +61,14 @@
 
         mTarget = activity.getDragLayer();
         mTarget.getLocationOnScreen(mLocationOnScreen);
+
+        // When Overview is launched via meta+tab or swipe up from an app,
+        // the touch mode somehow is not changed to false by the Android framework.
+        // The subsequent key events (e.g. DPAD_LEFT, DPAD_RIGHT) can only be dispatched to
+        // focused views, while focus can only be requested in
+        // {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To note,
+        // here we launch overview with live tile.
+        mActivity.getRootView().getViewRootImpl().touchModeChanged(false);
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java
index f3d2a60..898aa86 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/StatusBarInputConsumer.java
@@ -33,6 +33,7 @@
     private final SystemUiProxy mSystemUiProxy;
     private final float mTouchSlop;
     private final PointF mDown = new PointF();
+    private boolean mHasPassedTouchSlop;
 
     public StatusBarInputConsumer(Context context, InputConsumer delegate,
             InputMonitorCompat inputMonitor) {
@@ -53,13 +54,21 @@
             mDelegate.onMotionEvent(ev);
 
             switch (ev.getActionMasked()) {
-                case ACTION_DOWN -> mDown.set(ev.getX(), ev.getY());
+                case ACTION_DOWN -> {
+                    mDown.set(ev.getX(), ev.getY());
+                    mHasPassedTouchSlop = false;
+                }
                 case ACTION_MOVE -> {
-                    float displacementY = ev.getY() - mDown.y;
-                    if (displacementY > mTouchSlop) {
-                        setActive(ev);
-                        ev.setAction(ACTION_DOWN);
-                        dispatchTouchEvent(ev);
+                    if (!mHasPassedTouchSlop) {
+                        float displacementY = ev.getY() - mDown.y;
+                        if (Math.abs(displacementY) > mTouchSlop) {
+                            mHasPassedTouchSlop = true;
+                            if (displacementY > 0) {
+                                setActive(ev);
+                                ev.setAction(ACTION_DOWN);
+                                dispatchTouchEvent(ev);
+                            }
+                        }
                     }
                 }
             }
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index b3243ff..a8af05e 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -309,7 +309,7 @@
         }
 
         @Override
-        public void updateFinalShift() {
+        public void onCurrentShiftUpdated() {
             mRemoteTargetHandles[0].getPlaybackController()
                     .setProgress(mCurrentShift.value, mDragLengthFactor);
             mRemoteTargetHandles[0].getTaskViewSimulator().apply(
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
index 6eadd2b..8335523 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
@@ -33,10 +33,11 @@
      */
     public enum GestureEvent {
         MOTION_DOWN, MOTION_UP, MOTION_MOVE, SET_END_TARGET, SET_END_TARGET_HOME,
-        SET_END_TARGET_NEW_TASK, ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION,
-        FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK,
-        CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT, SCROLLER_ANIMATION_ABORTED, TASK_APPEARED,
-        EXPECTING_TASK_APPEARED, FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
+        SET_END_TARGET_NEW_TASK, SET_END_TARGET_ALL_APPS, ON_SETTLED_ON_END_TARGET,
+        START_RECENTS_ANIMATION, FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION,
+        SET_ON_PAGE_TRANSITION_END_CALLBACK, CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT,
+        SCROLLER_ANIMATION_ABORTED, TASK_APPEARED, EXPECTING_TASK_APPEARED,
+        FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
 
         /**
          * These GestureEvents are specifically associated to state flags that get set in
@@ -220,6 +221,7 @@
                 case MOTION_DOWN:
                 case SET_END_TARGET:
                 case SET_END_TARGET_HOME:
+                case SET_END_TARGET_ALL_APPS:
                 case SET_END_TARGET_NEW_TASK:
                 case START_RECENTS_ANIMATION:
                 case SET_ON_PAGE_TRANSITION_END_CALLBACK:
diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
index baca76c..a92ab2a 100644
--- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
+++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
@@ -17,9 +17,11 @@
 
 import static com.android.launcher3.anim.Interpolators.DEACCEL;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.AbsSwipeUpHandler.ALL_APPS_SHIFT_THRESHOLD;
 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
 import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
 
+import android.animation.AnimatorSet;
 import android.animation.TimeInterpolator;
 import android.content.Context;
 import android.graphics.Matrix;
@@ -32,11 +34,15 @@
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.statemanager.StateManager;
+import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.touch.AllAppsSwipeController;
 import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.quickstep.LauncherActivityInterface;
 import com.android.quickstep.views.RecentsView;
 
 /**
@@ -49,7 +55,9 @@
 
     private enum RecentsResistanceParams {
         FROM_APP(0.75f, 0.5f, 1f, false),
+        FROM_APP_TO_ALL_APPS(0.75f, 0.5f, 0.8f, false),
         FROM_APP_TABLET(1f, 0.7f, 1f, true),
+        FROM_APP_TO_ALL_APPS_TABLET(1f, 0.5f, 0.5f, false),
         FROM_OVERVIEW(1f, 0.75f, 0.5f, false);
 
         RecentsResistanceParams(float scaleStartResist, float scaleMaxResist,
@@ -86,6 +94,8 @@
     private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
     private static final TimeInterpolator RECENTS_TRANSLATE_RESIST_INTERPOLATOR = LINEAR;
 
+    private static final Rect TEMP_RECT = new Rect();
+
     private final AnimatorPlaybackController mNormalController;
     private final AnimatorPlaybackController mResistanceController;
 
@@ -145,10 +155,42 @@
                 scaleProperty, translationTarget, translationProperty);
         PendingAnimation resistAnim = createRecentsResistanceAnim(params);
 
+        // Apply All Apps animation during the resistance animation.
+        if (recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()) {
+            StatefulActivity activity =
+                    recentsOrientedState.getActivityInterface().getCreatedActivity();
+            if (activity != null) {
+                StateManager<LauncherState> stateManager = activity.getStateManager();
+                if (stateManager.isInStableState(LauncherState.BACKGROUND_APP)
+                        && stateManager.isInTransition()) {
+
+                    // Calculate the resistance progress threshold where All Apps will trigger.
+                    float threshold = getAllAppsThreshold(context, recentsOrientedState, dp);
+
+                    StateAnimationConfig config = new StateAnimationConfig();
+                    AllAppsSwipeController.applyOverviewToAllAppsAnimConfig(dp, config, threshold);
+                    AnimatorSet allAppsAnimator = stateManager.createAnimationToNewWorkspace(
+                            LauncherState.ALL_APPS, config).getTarget();
+                    resistAnim.add(allAppsAnimator);
+                }
+            }
+        }
+
         AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController();
         return new AnimatorControllerWithResistance(normalController, resistanceController);
     }
 
+    private static float getAllAppsThreshold(Context context,
+            RecentsOrientedState recentsOrientedState, DeviceProfile dp) {
+        int transitionDragLength =
+                recentsOrientedState.getActivityInterface().getSwipeUpDestinationAndLength(
+                        dp, context, TEMP_RECT,
+                        recentsOrientedState.getOrientationHandler());
+        float dragLengthFactor = (float) dp.heightPx / transitionDragLength;
+        // -1s are because 0-1 is reserved for the normal transition.
+        return (ALL_APPS_SHIFT_THRESHOLD - 1) / (dragLengthFactor - 1);
+    }
+
     /**
      * Creates the resistance animation for {@link #createForRecents}, or can be used separately
      * when starting from recents, i.e. {@link #createRecentsResistanceFromOverviewAnim}.
@@ -158,8 +200,8 @@
         Rect startRect = new Rect();
         PagedOrientationHandler orientationHandler = params.recentsOrientedState
                 .getOrientationHandler();
-        LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect,
-                orientationHandler);
+        params.recentsOrientedState.getActivityInterface()
+                .calculateTaskSize(params.context, params.dp, startRect, orientationHandler);
         long distanceToCover = startRect.bottom;
         PendingAnimation resistAnim = params.resistAnim != null
                 ? params.resistAnim
@@ -257,9 +299,15 @@
             this.translationTarget = translationTarget;
             this.translationProperty = translationProperty;
             if (dp.isTablet) {
-                resistanceParams = RecentsResistanceParams.FROM_APP_TABLET;
+                resistanceParams =
+                        recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
+                                ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS_TABLET
+                                : RecentsResistanceParams.FROM_APP_TABLET;
             } else {
-                resistanceParams = RecentsResistanceParams.FROM_APP;
+                resistanceParams =
+                        recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
+                                ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS
+                                : RecentsResistanceParams.FROM_APP;
             }
         }
 
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index c4ba39a..f6ad692 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -116,6 +116,7 @@
                     | FLAG_SWIPE_UP_NOT_RUNNING;
 
     private final Context mContext;
+    private final BaseActivityInterface mActivityInterface;
     private final OrientationEventListener mOrientationListener;
     private final SettingsCache mSettingsCache;
     private final SettingsCache.OnChangeListener mRotationChangeListener =
@@ -135,9 +136,10 @@
      *                              is enabled
      * @see #setRotationWatcherEnabled(boolean)
      */
-    public RecentsOrientedState(Context context, BaseActivityInterface sizeStrategy,
+    public RecentsOrientedState(Context context, BaseActivityInterface activityInterface,
             IntConsumer rotationChangeListener) {
         mContext = context;
+        mActivityInterface = activityInterface;
         mOrientationListener = new OrientationEventListener(context) {
             @Override
             public void onOrientationChanged(int degrees) {
@@ -149,7 +151,7 @@
             }
         };
 
-        mFlags = sizeStrategy.rotationSupportedByActivity
+        mFlags = mActivityInterface.rotationSupportedByActivity
                 ? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0;
 
         mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
@@ -157,6 +159,10 @@
         initFlags();
     }
 
+    public BaseActivityInterface getActivityInterface() {
+        return mActivityInterface;
+    }
+
     /**
      * Sets the device profile for the current state.
      */
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index ccc2df6..379722b 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -309,7 +309,7 @@
 
     @Override
     public RunnableList launchTasks() {
-        SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps();
+        SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps(mActivity.getDisplayId());
         Launcher.getLauncher(mActivity).getStateManager().goToState(NORMAL, false /* animated */);
         return null;
     }
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index c165acc..8ff0e9b 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -17,6 +17,7 @@
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 
+import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -129,7 +130,7 @@
 
     @Override
     public void onStateTransitionComplete(LauncherState finalState) {
-        if (finalState == NORMAL || finalState == SPRING_LOADED) {
+        if (finalState == NORMAL || finalState == SPRING_LOADED || finalState == ALL_APPS) {
             // Clean-up logic that occurs when recents is no longer in use/visible.
             reset();
         }
@@ -244,7 +245,7 @@
             desktopVisibilityController.setGestureInProgress(false);
         }
         if (showDesktopApps) {
-            SystemUiProxy.INSTANCE.get(mActivity).showDesktopApps();
+            SystemUiProxy.INSTANCE.get(mActivity).showDesktopApps(mActivity.getDisplayId());
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 42589ce..53660b5 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -581,6 +581,7 @@
                 mIconView, STAGE_POSITION_UNDEFINED);
         mSnapshotView.bind(task);
         setOrientationState(orientedState);
+        mDigitalWellBeingToast.initialize(mTask);
     }
 
     /**
@@ -984,10 +985,7 @@
             }
             if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
                 mIconLoadRequest = iconCache.updateIconInBackground(mTask,
-                        (task) -> {
-                            setIcon(mIconView, task.icon);
-                            mDigitalWellBeingToast.initialize(mTask);
-                        });
+                        (task) -> setIcon(mIconView, task.icon));
             }
         } else {
             if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
index 6243471..4540eee 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
@@ -27,6 +27,7 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.launcher3.tapl.Overview;
 import com.android.launcher3.tapl.Taskbar;
 import com.android.launcher3.ui.TaplTestsLauncher3;
 import com.android.launcher3.util.LauncherLayoutBuilder;
@@ -63,6 +64,10 @@
                 "com.android.launcher3.testcomponent.BaseTestingActivity");
         mLauncherLayout = TestUtil.setLauncherDefaultLayout(mTargetContext, layoutBuilder);
         TaplTestsLauncher3.initialize(this);
+        Overview overview = mLauncher.getWorkspace().switchToOverview();
+        if (overview.hasTasks()) {
+            overview.dismissAllTasks();
+        }
 
         startAppFast(CALCULATOR_APP_PACKAGE);
         mLauncher.enableBlockTimeout(true);
diff --git a/res/drawable/ic_note_taking_widget_category.xml b/res/drawable/ic_note_taking_widget_category.xml
new file mode 100644
index 0000000..2b59157
--- /dev/null
+++ b/res/drawable/ic_note_taking_widget_category.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48">
+
+    <path
+        android:fillColor="#F5F5F5"
+        android:pathData="M 0 0 H 48 V 48 H 0 V 0 Z" />
+    <group>
+        <path
+            android:fillColor="#0B57D0"
+            android:pathData="M48 24C48 10.7452 37.2548 0 24 0C10.7452 0 0 10.7452 0 24C0 37.2548 10.7452 48 24 48C37.2548 48 48 37.2548 48 24Z" />
+        <path
+            android:fillColor="#ffffff"
+            android:pathData="M32.892 16.8L31.2 15.108C30.756 14.652 30.144 14.4 29.508 14.4C28.872 14.4 28.26 14.652 27.816 15.108L18.468 24.456L15.708 27.216L14.448 32.28C14.412 32.352 14.4 32.448 14.4 32.532C14.4 33.12 14.88 33.6 15.468 33.6C15.552 33.6 15.648 33.588 15.732 33.564L20.796 32.304L23.556 29.544L32.904 20.196C33.348 19.74 33.6 19.128 33.6 18.492C33.6 17.856 33.348 17.244 32.892 16.8ZM21.852 27.852L20.652 29.052L18.96 27.36L20.16 26.16L29.508 16.8L31.2 18.492L21.852 27.852Z" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index 039d8d3..a709fbc 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -69,15 +69,15 @@
             android:background="@android:color/transparent" />
 
         <include
+            android:id="@+id/overview_panel"
+            layout="@layout/overview_panel" />
+
+        <include
             android:id="@+id/apps_view"
             layout="@layout/all_apps"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />
 
-        <include
-            android:id="@+id/overview_panel"
-            layout="@layout/overview_panel" />
-
     </com.android.launcher3.dragndrop.DragLayer>
 
 </com.android.launcher3.LauncherRootView>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b54d4f7..c2eb373 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -106,6 +106,9 @@
     <!-- A widget category label for grouping widgets related to conversations. [CHAR_LIMIT=30] -->
     <string name="widget_category_conversations">Conversations</string>
 
+    <!-- A widget category label for grouping widgets related to note taking. [CHAR_LIMIT=30] -->
+    <string name="widget_category_note_taking">Note-taking</string>
+
     <!-- Title of a dialog. This dialog lets a user know how they can use widgets on their phone.
          [CHAR_LIMIT=NONE] -->
     <string name="widget_education_header">Useful info at your fingertips</string>
diff --git a/res/xml/widget_sections.xml b/res/xml/widget_sections.xml
index d755de6..6165bf7 100644
--- a/res/xml/widget_sections.xml
+++ b/res/xml/widget_sections.xml
@@ -22,4 +22,10 @@
         launcher:sectionTitle="@string/widget_category_conversations">
         <widget launcher:provider="com.android.systemui/.people.widget.PeopleSpaceWidgetProvider" />
     </section>
+    <section
+        launcher:category="1"
+        launcher:sectionDrawable="@drawable/ic_note_taking_widget_category"
+        launcher:sectionTitle="@string/widget_category_note_taking">
+        <widget launcher:provider="com.android.settings/com.android.settings.notetask.shortcut.CreateNoteTaskShortcutActivity" />
+    </section>
 </widget-sections>
\ No newline at end of file
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index 98ecf3a..bb6d8b0 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.TypedValue;
 import android.view.Gravity;
 import android.view.View;
@@ -31,13 +30,10 @@
 import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 
-import androidx.annotation.NonNull;
-
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragController.DragListener;
 import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.testing.shared.TestProtocol;
 
 /*
  * The top bar containing various drop targets: Delete/App Info/Uninstall.
@@ -299,9 +295,6 @@
     }
 
     public void animateToVisibility(boolean isVisible) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NO_DROP_TARGET, "8");
-        }
         if (mVisible != isVisible) {
             mVisible = isVisible;
 
@@ -328,9 +321,6 @@
      */
     @Override
     public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NO_DROP_TARGET, "7");
-        }
         animateToVisibility(true);
     }
 
@@ -354,16 +344,4 @@
     public ButtonDropTarget[] getDropTargets() {
         return getVisibility() == View.VISIBLE ? mDropTargets : new ButtonDropTarget[0];
     }
-
-    @Override
-    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
-        super.onVisibilityChanged(changedView, visibility);
-        if (TestProtocol.sDebugTracing) {
-            if (visibility == VISIBLE) {
-                Log.d(TestProtocol.NO_DROP_TARGET, "9");
-            } else {
-                Log.d(TestProtocol.NO_DROP_TARGET, "Hiding drop target", new Exception());
-            }
-        }
-    }
 }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index a548992..4dfd918 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1836,9 +1836,6 @@
     }
 
     private void setWorkspaceLoading(boolean value) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING, "running: setWorkspaceLoading=" + value);
-        }
         mWorkspaceLoading = value;
     }
 
@@ -2211,10 +2208,6 @@
 
         IntSet result = new IntSet();
         if (visibleIds.isEmpty()) {
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.NULL_INT_SET, "getPagesToBindSynchronously (1): "
-                        + result);
-            }
             return result;
         }
         for (int id : orderedScreenIds.toArray()) {
@@ -2235,10 +2228,6 @@
             // pages being hidden in single panel.
             result.add(pairId);
         }
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NULL_INT_SET, "getPagesToBindSynchronously (2): "
-                    + result);
-        }
         return result;
     }
 
@@ -2260,14 +2249,11 @@
 
     /**
      * Refreshes the shortcuts shown on the workspace.
-     *
+     * <p>
      * Implementation of the method from LauncherModel.Callbacks.
      */
     public void startBinding() {
         Object traceToken = TraceHelper.INSTANCE.beginSection("startBinding");
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING, "running: startBinding");
-        }
         // Floating panels (except the full widget sheet) are associated with individual icons. If
         // we are starting a fresh bind, close all such panels as all the icons are about
         // to go away.
@@ -2452,10 +2438,6 @@
                         throw (new RuntimeException(desc));
                     } else {
                         getModelWriter().deleteItemFromDatabase(item, desc);
-                        if (TestProtocol.sDebugTracing) {
-                            Log.d(TestProtocol.MISSING_PROMISE_ICON,
-                                    TAG + "bindItems failed for item=" + item);
-                        }
                         continue;
                     }
                 }
@@ -2741,14 +2723,11 @@
 
     /**
      * Callback saying that there aren't any more items to bind.
-     *
+     * <p>
      * Implementation of the method from LauncherModel.Callbacks.
      */
     public void finishBindingItems(IntSet pagesBoundFirst) {
         Object traceToken = TraceHelper.INSTANCE.beginSection("finishBindingItems");
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING, "running: finishBindingItems");
-        }
         mWorkspace.restoreInstanceStateForRemainingPages();
 
         setWorkspaceLoading(false);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 0e027f8..6798667d 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -383,12 +383,6 @@
     public void addCallbacks(@NonNull final Callbacks callbacks) {
         Preconditions.assertUIThread();
         synchronized (mCallbacksList) {
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.NULL_INT_SET, "addCallbacks pointer: "
-                        + callbacks
-                        + ", name: "
-                        + callbacks.getClass().getName(), new Exception());
-            }
             mCallbacksList.add(callbacks);
         }
     }
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index 32c8968..aaccb7d 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -24,14 +24,12 @@
 import android.content.pm.PackageManager;
 import android.os.UserHandle;
 import android.text.TextUtils;
-import android.util.Log;
 
 import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.ItemInstallQueue;
 import com.android.launcher3.pm.InstallSessionHelper;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.Executors;
 
 /**
@@ -53,9 +51,6 @@
     private static void processIntent(Context context, Intent intent) {
         if (!isEnabled(context)) {
             // User has decided to not add icons on homescreen.
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " not enabled");
-            }
             return;
         }
 
@@ -64,9 +59,6 @@
         if (!PackageInstaller.ACTION_SESSION_COMMITTED.equals(intent.getAction())
                 || info == null || user == null) {
             // Invalid intent.
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " invalid intent");
-            }
             return;
         }
 
@@ -75,15 +67,6 @@
                 || info.getInstallReason() != PackageManager.INSTALL_REASON_USER
                 || packageInstallerCompat.promiseIconAddedForId(info.getSessionId())) {
             packageInstallerCompat.removePromiseIconId(info.getSessionId());
-            if (TestProtocol.sDebugTracing) {
-                int id = info.getSessionId();
-                Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG
-                        + ", TextUtils.isEmpty=" + TextUtils.isEmpty(info.getAppPackageName())
-                        + ", info.getInstallReason()=" + info.getInstallReason()
-                        + ", INSTALL_REASON_USER=" + PackageManager.INSTALL_REASON_USER
-                        + ", icon added=" + packageInstallerCompat.promiseIconAddedForId(id)
-                );
-            }
             return;
         }
 
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 470a75c..01a4876 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -40,6 +40,7 @@
 import android.os.Process;
 import android.os.UserManager;
 import android.util.AttributeSet;
+import android.util.FloatProperty;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.TypedValue;
@@ -101,6 +102,20 @@
         OnDeviceProfileChangeListener, PersonalWorkSlidingTabStrip.OnActivePageChangedListener,
         ScrimView.ScrimDrawingController {
 
+
+    public static final FloatProperty<ActivityAllAppsContainerView<?>> BOTTOM_SHEET_ALPHA =
+            new FloatProperty<>("bottomSheetAlpha") {
+                @Override
+                public Float get(ActivityAllAppsContainerView<?> containerView) {
+                    return containerView.mBottomSheetAlpha;
+                }
+
+                @Override
+                public void setValue(ActivityAllAppsContainerView<?> containerView, float v) {
+                    containerView.setBottomSheetAlpha(v);
+                }
+            };
+
     public static final float PULL_MULTIPLIER = .02f;
     public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
     protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
@@ -159,6 +174,8 @@
     private ScrimView mScrimView;
     private int mHeaderColor;
     private int mBottomSheetBackgroundColor;
+    private float mBottomSheetAlpha = 1f;
+    private boolean mForceBottomSheetVisible;
     private int mTabsProtectionAlpha;
     @Nullable private AllAppsTransitionController mAllAppsTransitionController;
 
@@ -258,7 +275,7 @@
         final TypedValue value = new TypedValue();
         getContext().getTheme().resolveAttribute(android.R.attr.colorBackground, value, true);
         mBottomSheetBackgroundColor = value.data;
-        updateBackground(mActivityContext.getDeviceProfile());
+        updateBackgroundVisibility(mActivityContext.getDeviceProfile());
         mSearchUiManager.initializeSearch(this);
     }
 
@@ -282,6 +299,16 @@
         return mBottomSheetBackground;
     }
 
+    /**
+     * Temporarily force the bottom sheet to be visible on non-tablets.
+     *
+     * @param force {@code true} means bottom sheet will be visible on phones until {@code reset()}.
+     **/
+    public void forceBottomSheetVisible(boolean force) {
+        mForceBottomSheetVisible = force;
+        updateBackgroundVisibility(mActivityContext.getDeviceProfile());
+    }
+
     public View getSearchView() {
         return mSearchContainer;
     }
@@ -408,6 +435,7 @@
         if (mHeader != null && mHeader.getVisibility() == VISIBLE) {
             mHeader.reset(animate);
         }
+        forceBottomSheetVisible(false);
         // Reset the base recycler view after transitioning home.
         updateHeaderScroll(0);
         if (exitSearch) {
@@ -830,7 +858,7 @@
                 holder.mRecyclerView.getRecycledViewPool().clear();
             }
         }
-        updateBackground(dp);
+        updateBackgroundVisibility(dp);
 
         int navBarScrimColor = Themes.getNavBarScrimColor(mActivityContext);
         if (mNavBarScrimPaint.getColor() != navBarScrimColor) {
@@ -839,13 +867,19 @@
         }
     }
 
-    protected void updateBackground(DeviceProfile deviceProfile) {
-        mBottomSheetBackground.setVisibility(deviceProfile.isTablet ? View.VISIBLE : View.GONE);
+    protected void updateBackgroundVisibility(DeviceProfile deviceProfile) {
+        boolean visible = deviceProfile.isTablet || mForceBottomSheetVisible;
+        mBottomSheetBackground.setVisibility(visible ? View.VISIBLE : View.GONE);
         // Note: For tablets, the opaque background and header protection are added in drawOnScrim.
         // For the taskbar entrypoint, the scrim is drawn differently, so a static background is
         // added in TaskbarAllAppsContainerView and header protection is not yet supported.
     }
 
+    private void setBottomSheetAlpha(float alpha) {
+        // Bottom sheet alpha is always 1 for tablets.
+        mBottomSheetAlpha = mActivityContext.getDeviceProfile().isTablet ? 1f : alpha;
+    }
+
     private void onAppsUpdated() {
         mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
         if (TestProtocol.sDebugTracing) {
@@ -1148,8 +1182,8 @@
 
     @Override
     public void drawOnScrimWithScale(Canvas canvas, float scale) {
-        final boolean isTablet = mActivityContext.getDeviceProfile().isTablet;
         final View panel = mBottomSheetBackground;
+        final boolean hasBottomSheet = panel.getVisibility() == VISIBLE;
         final float translationY = ((View) panel.getParent()).getTranslationY();
 
         final float horizontalScaleOffset = (1 - scale) * panel.getWidth() / 2;
@@ -1160,8 +1194,9 @@
         final float leftWithScale = panel.getLeft() + horizontalScaleOffset;
         final float rightWithScale = panel.getRight() - horizontalScaleOffset;
         // Draw full background panel for tablets.
-        if (isTablet) {
+        if (hasBottomSheet) {
             mHeaderPaint.setColor(mBottomSheetBackgroundColor);
+            mHeaderPaint.setAlpha((int) (255 * mBottomSheetAlpha));
 
             mTmpRectF.set(
                     leftWithScale,
@@ -1192,7 +1227,7 @@
         final float headerBottomOffset = (getVisibleContainerView().getHeight() * (1 - scale) / 2);
         final float headerBottomWithScaleOnPhone = headerBottomNoScale * scale + headerBottomOffset;
         final FloatingHeaderView headerView = getFloatingHeaderView();
-        if (isTablet) {
+        if (hasBottomSheet) {
             // Start adding header protection if search bar or tabs will attach to the top.
             if (!FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() || mUsingTabs) {
                 mTmpRectF.set(
@@ -1219,12 +1254,12 @@
             }
             float left = 0f;
             float right = canvas.getWidth();
-            if (isTablet) {
+            if (hasBottomSheet) {
                 left = mBottomSheetBackground.getLeft() + horizontalScaleOffset;
                 right = mBottomSheetBackground.getRight() - horizontalScaleOffset;
             }
 
-            final float tabTopWithScale = isTablet
+            final float tabTopWithScale = hasBottomSheet
                     ? headerBottomWithScaleOnTablet
                     : headerBottomWithScaleOnPhone;
             final float tabBottomWithScale = tabTopWithScale + tabsHeight * scale;
@@ -1263,7 +1298,7 @@
      * Returns a view that denotes the visible part of all apps container view.
      */
     public View getVisibleContainerView() {
-        return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
+        return mBottomSheetBackground.getVisibility() == VISIBLE ? mBottomSheetBackground : this;
     }
 
     protected void onInitializeRecyclerView(RecyclerView rv) {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 4d1006a..d4f152a 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -21,8 +21,10 @@
 import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
+import static com.android.launcher3.anim.Interpolators.INSTANT;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
 import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
@@ -410,8 +412,12 @@
         setter.setFloat(getAppsViewPullbackAlpha(), MultiPropertyFactory.MULTI_PROPERTY_VALUE,
                 hasAllAppsContent ? 1 : 0, allAppsFade);
 
-        boolean shouldProtectHeader =
-                ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS;
+        setter.setFloat(mLauncher.getAppsView(),
+                ActivityAllAppsContainerView.BOTTOM_SHEET_ALPHA, hasAllAppsContent ? 1 : 0,
+                config.getInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE, INSTANT));
+
+        boolean shouldProtectHeader = !config.hasAnimationFlag(StateAnimationConfig.SKIP_SCRIM)
+                && (ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS);
         mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null);
     }
 
diff --git a/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java
index 684e98e..d7f5463 100644
--- a/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java
@@ -41,7 +41,7 @@
     }
 
     @Override
-    protected void updateBackground(DeviceProfile deviceProfile) {}
+    protected void updateBackgroundVisibility(DeviceProfile deviceProfile) {}
 
     @Override
     public boolean isInAllApps() {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index cdebe44..2a3ad9a 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -35,6 +35,12 @@
 /**
  * Defines a set of flags used to control various launcher behaviors.
  *
+ * Please only add flags to your assigned block to prevent merge conflicts. If you do not have
+ * a block, please update the current empty block and add a new empty block below to prevent
+ * merge conflicts with the previous block.
+ * List of blocks can be found:
+ * <a href="http://go/gnl-flags-block-directory">here</a>
+ *
  * <p>All the flags should be defined here with appropriate default values.
  */
 public final class FeatureFlags {
@@ -74,16 +80,13 @@
      * Declare a new ToggleableFlag below. Give it a unique key (e.g. "QSB_ON_FIRST_SCREEN"),
      * and set a default value for the flag. This will be the default value on Debug builds.
      * <p>
-     * Please only add flags to your assigned block to prevent merge conflicts. If you do not have
-     * a block, please update the current empty block and add a new empty block below to prevent
-     * merge conflicts with the previous block.
      */
     // TODO(Block 1): Clean up flags
     public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = getReleaseFlag(270394223,
             "ENABLE_ONE_SEARCH_MOTION", ENABLED, "Enables animations in OneSearch.");
 
     public static final BooleanFlag ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES = getReleaseFlag(
-            270394041, "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", DISABLED,
+            270394041, "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", TEAMFOOD,
             "Enable option to replace decorator-based search result backgrounds with drawables");
 
     public static final BooleanFlag ENABLE_SEARCH_RESULT_LAUNCH_TRANSITION = getReleaseFlag(
@@ -115,9 +118,13 @@
 
     // TODO(Block 4): Cleanup flags
     public static final BooleanFlag ENABLE_FLOATING_SEARCH_BAR =
-            getReleaseFlag(270390286, "ENABLE_FLOATING_SEARCH_BAR", DISABLED,
+            getReleaseFlag(268388460, "ENABLE_FLOATING_SEARCH_BAR", DISABLED,
                     "Keep All Apps search bar at the bottom (but above keyboard if open)");
 
+    public static final BooleanFlag ENABLE_ALL_APPS_FROM_OVERVIEW =
+            getDebugFlag(275132633, "ENABLE_ALL_APPS_FROM_OVERVIEW", DISABLED,
+                    "Allow entering All Apps from Overview (e.g. long swipe up from app)");
+
     public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
             270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
             "Enable option to show keyboard when going to all-apps");
@@ -179,7 +186,7 @@
     // TODO(Block 10): Clean up flags
     public static final BooleanFlag ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION = getDebugFlag(270614790,
             "ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION", DISABLED,
-            "Enables predictive back aniamtion from all apps and widgets to home");
+            "Enables predictive back animation from all apps and widgets to home");
 
     // TODO(Block 11): Clean up flags
     public static final BooleanFlag ENABLE_TWO_PANEL_HOME = getDebugFlag(270392643,
@@ -312,6 +319,10 @@
             "ENABLE_GRID_ONLY_OVERVIEW", DISABLED,
             "Enable a grid-only overview without a focused task.");
 
+    public static final BooleanFlag ENABLE_CURSOR_HOVER_STATES = getDebugFlag(243191650,
+            "ENABLE_CURSOR_HOVER_STATES", DISABLED,
+            "Enables cursor hover states for certain elements.");
+
     // TODO(Block 24): Clean up flags
     public static final BooleanFlag ENABLE_NEW_MIGRATION_LOGIC = getDebugFlag(270393455,
             "ENABLE_NEW_MIGRATION_LOGIC", ENABLED,
@@ -398,10 +409,6 @@
 
     // TODO(Block 31): Empty block
 
-    public static final BooleanFlag ENABLE_CURSOR_HOVER_STATES = getDebugFlag(243191650,
-            "ENABLE_CURSOR_HOVER_STATES", DISABLED,
-            "Enables cursor hover states for certain elements.");
-
     public static class BooleanFlag {
 
         private final boolean mCurrentValue;
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index 5368397..328d769 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -21,7 +21,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 import android.view.DragEvent;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -35,7 +34,6 @@
 import com.android.launcher3.logging.InstanceId;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.views.ActivityContext;
 
@@ -150,9 +148,6 @@
             float initialDragViewScale,
             float dragViewScaleOnDrop,
             DragOptions options) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NO_DROP_TARGET, "4");
-        }
         return startDrag(drawable, /* view= */ null, originalView, dragLayerX, dragLayerY,
                 source, dragInfo, dragOffset, dragRegion, initialDragViewScale, dragViewScaleOnDrop,
                 options);
@@ -210,9 +205,6 @@
             DragOptions options);
 
     protected void callOnDragStart() {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NO_DROP_TARGET, "6");
-        }
         if (mOptions.preDragCondition != null) {
             mOptions.preDragCondition.onPreDragEnd(mDragObject, true /* dragStarted*/);
         }
diff --git a/src/com/android/launcher3/dragndrop/LauncherDragController.java b/src/com/android/launcher3/dragndrop/LauncherDragController.java
index 75f4ad6..0e8b0a5 100644
--- a/src/com/android/launcher3/dragndrop/LauncherDragController.java
+++ b/src/com/android/launcher3/dragndrop/LauncherDragController.java
@@ -24,7 +24,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 import android.view.HapticFeedbackConstants;
 import android.view.View;
 
@@ -37,7 +36,6 @@
 import com.android.launcher3.R;
 import com.android.launcher3.accessibility.DragViewStateAnnouncer;
 import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.testing.shared.TestProtocol;
 
 /**
  * Drag controller for Launcher activity
@@ -67,9 +65,6 @@
             float initialDragViewScale,
             float dragViewScaleOnDrop,
             DragOptions options) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NO_DROP_TARGET, "5");
-        }
         if (PROFILE_DRAWING_DURING_DRAG) {
             android.os.Debug.startMethodTracing("Launcher");
         }
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 86f4beb..48239ae 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -205,7 +205,7 @@
         lp.topMargin = grid.iconSizePx + grid.iconDrawablePaddingPx;
 
         icon.setTag(folderInfo);
-        icon.setOnClickListener(ItemClickHandler.INSTANCE);
+        icon.setOnClickListener(activity.getItemOnClickListener());
         icon.mInfo = folderInfo;
         icon.mActivity = activity;
         icon.mDotRenderer = grid.mDotRendererWorkSpace;
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index d43731b..6ff8ece 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -216,7 +216,7 @@
         final BubbleTextView textView = mViewCache.getView(
                 R.layout.folder_application, getContext(), null);
         textView.applyFromWorkspaceItem(item);
-        textView.setOnClickListener(ItemClickHandler.INSTANCE);
+        textView.setOnClickListener(mFolder.mActivityContext.getItemOnClickListener());
         textView.setOnLongClickListener(mFolder);
         textView.setOnFocusChangeListener(mFocusIndicatorHelper);
         CellLayoutLayoutParams lp = (CellLayoutLayoutParams) textView.getLayoutParams();
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 0d978e1..27d1f78 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -20,7 +20,6 @@
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.os.UserHandle;
-import android.util.Log;
 import android.util.Pair;
 
 import androidx.annotation.NonNull;
@@ -39,7 +38,6 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pm.InstallSessionHelper;
 import com.android.launcher3.pm.PackageInstallInfo;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.PackageManagerHelper;
 
@@ -97,20 +95,12 @@
                         item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
                     // Short-circuit this logic if the icon exists somewhere on the workspace
                     if (shortcutExists(dataModel, item.getIntent(), item.user)) {
-                        if (TestProtocol.sDebugTracing) {
-                            Log.d(TestProtocol.MISSING_PROMISE_ICON,
-                                    LOG + " Item already on workspace.");
-                        }
                         continue;
                     }
 
                     // b/139663018 Short-circuit this logic if the icon is a system app
                     if (PackageManagerHelper.isSystemApp(app.getContext(),
                             Objects.requireNonNull(item.getIntent()))) {
-                        if (TestProtocol.sDebugTracing) {
-                            Log.d(TestProtocol.MISSING_PROMISE_ICON,
-                                    LOG + " Item is a system app.");
-                        }
                         continue;
                     }
                 }
@@ -150,9 +140,6 @@
                     String packageName = item.getTargetComponent() != null
                             ? item.getTargetComponent().getPackageName() : null;
                     if (packageName == null) {
-                        if (TestProtocol.sDebugTracing) {
-                            Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " Null packageName.");
-                        }
                         continue;
                     }
                     SessionInfo sessionInfo = packageInstaller.getActiveSessionInfo(item.user,
@@ -161,9 +148,6 @@
                     if (!packageInstaller.verifySessionInfo(sessionInfo)) {
                         FileLog.d(LOG, "Item info failed session info verification. "
                                 + "Skipping : " + workspaceInfo);
-                        if (TestProtocol.sDebugTracing) {
-                            Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + "Failed verification.");
-                        }
                         continue;
                     }
 
@@ -174,9 +158,6 @@
                     if (sessionInfo == null) {
                         if (!hasActivity) {
                             // Session was cancelled, do not add.
-                            if (TestProtocol.sDebugTracing) {
-                                Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + "Session cancelled");
-                            }
                             continue;
                         }
                     } else {
@@ -196,9 +177,6 @@
                             // workspace items as promise icons. At this point we now have the
                             // correct intent to compare against existing workspace icons.
                             // Icon already exists on the workspace and should not be auto-added.
-                            if (TestProtocol.sDebugTracing) {
-                                Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + "shortcutExists");
-                            }
                             continue;
                         }
 
diff --git a/src/com/android/launcher3/model/BaseLauncherBinder.java b/src/com/android/launcher3/model/BaseLauncherBinder.java
index 358992e..c946e2c 100644
--- a/src/com/android/launcher3/model/BaseLauncherBinder.java
+++ b/src/com/android/launcher3/model/BaseLauncherBinder.java
@@ -34,7 +34,6 @@
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.LooperExecutor;
@@ -258,20 +257,8 @@
             ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
             ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
 
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.NULL_INT_SET, "bind (1) currentScreenIds: "
-                        + currentScreenIds
-                        + ", pointer: "
-                        + mCallbacks
-                        + ", name: "
-                        + mCallbacks.getClass().getName());
-            }
             filterCurrentWorkspaceItems(currentScreenIds, mWorkspaceItems, currentWorkspaceItems,
                     otherWorkspaceItems);
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.NULL_INT_SET, "bind (2) currentScreenIds: "
-                        + currentScreenIds);
-            }
             filterCurrentWorkspaceItems(currentScreenIds, mAppWidgets, currentAppWidgets,
                     otherAppWidgets);
             final InvariantDeviceProfile idp = mApp.getInvariantDeviceProfile();
@@ -279,9 +266,6 @@
             sortWorkspaceItemsSpatially(idp, otherWorkspaceItems);
 
             // Tell the workspace that we're about to start binding items
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.FLAKY_BINDING, "scheduling: startBinding");
-            }
             executeCallbacksTask(c -> {
                 c.clearPendingBinds();
                 c.startBinding();
@@ -302,9 +286,6 @@
             Executor pendingExecutor = pendingTasks::add;
             bindWorkspaceItems(otherWorkspaceItems, pendingExecutor);
             bindAppWidgets(otherAppWidgets, pendingExecutor);
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.FLAKY_BINDING, "scheduling: finishBindingItems");
-            }
             executeCallbacksTask(c -> c.finishBindingItems(currentScreenIds), pendingExecutor);
             pendingExecutor.execute(
                     () -> {
diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java
index bf839bf..70c9802 100644
--- a/src/com/android/launcher3/model/BaseModelUpdateTask.java
+++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java
@@ -151,7 +151,12 @@
     }
 
     public void bindApplicationsIfNeeded() {
-        if (mAllAppsList.getAndResetChangeFlag()) {
+        boolean changeFlag = mAllAppsList.getAndResetChangeFlag();
+        if (TestProtocol.sDebugTracing) {
+            Log.d(WORK_TAB_MISSING, "bindApplicationsIfNeeded changeFlag? " +
+                    changeFlag);
+        }
+        if (changeFlag) {
             AppInfo[] apps = mAllAppsList.copyData();
             int flags = mAllAppsList.getFlags();
             scheduleCallbackTask(c -> c.bindAllApplications(apps, flags));
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index 69f9b53..fa0511c 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -49,7 +49,6 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.PersistedItemArray;
 import com.android.launcher3.util.Preconditions;
@@ -119,18 +118,10 @@
         Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
         if (launcher == null) {
             // Launcher not loaded
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.MISSING_PROMISE_ICON,
-                        LOG + " flushQueueInBackground launcher not loaded");
-            }
             return;
         }
         ensureQueueLoaded();
         if (mItems.isEmpty()) {
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.MISSING_PROMISE_ICON,
-                        LOG + " flushQueueInBackground no items to load");
-            }
             return;
         }
 
@@ -140,10 +131,6 @@
 
         // Add the items and clear queue
         if (!installQueue.isEmpty()) {
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.MISSING_PROMISE_ICON,
-                        LOG + " flushQueueInBackground launcher addAndBindAddedWorkspaceItems");
-            }
             // add log
             launcher.getModel().addAndBindAddedWorkspaceItems(installQueue);
         }
@@ -204,10 +191,6 @@
         // Queue the item up for adding if launcher has not loaded properly yet
         MODEL_EXECUTOR.post(() -> {
             Pair<ItemInfo, Object> itemInfo = info.getItemInfo(mContext);
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " queuePendingShortcutInfo"
-                        + ", itemInfo=" + itemInfo);
-            }
             if (itemInfo == null) {
                 FileLog.d(LOG,
                         "Adding PendingInstallShortcutInfo with no attached info to queue.",
diff --git a/src/com/android/launcher3/model/ModelUtils.java b/src/com/android/launcher3/model/ModelUtils.java
index 48fb537..bc51c9b 100644
--- a/src/com/android/launcher3/model/ModelUtils.java
+++ b/src/com/android/launcher3/model/ModelUtils.java
@@ -15,11 +15,8 @@
  */
 package com.android.launcher3.model;
 
-import android.util.Log;
-
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
 
@@ -34,8 +31,6 @@
  */
 public class ModelUtils {
 
-    private static final String TAG = "ModelUtils";
-
     /**
      * Filters the set of items who are directly or indirectly (via another container) on the
      * specified screen.
@@ -55,10 +50,6 @@
                 (lhs, rhs) -> Integer.compare(lhs.container, rhs.container));
         for (T info : allWorkspaceItems) {
             if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                if (TestProtocol.sDebugTracing) {
-                    Log.d(TestProtocol.NULL_INT_SET, "filterCurrentWorkspaceItems: "
-                            + currentScreenIds);
-                }
                 if (currentScreenIds.contains(info.screenId)) {
                     currentScreenItems.add(info);
                     itemsOnScreen.add(info.id);
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 1ab64df..d4a5e1b 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -44,6 +44,7 @@
 import com.android.launcher3.pm.PackageInstallInfo;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.shortcuts.ShortcutRequest;
+import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.FlagOp;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.ItemInfoMatcher;
@@ -67,7 +68,7 @@
  */
 public class PackageUpdatedTask extends BaseModelUpdateTask {
 
-    private static final boolean DEBUG = false;
+    private static boolean DEBUG = false;
     private static final String TAG = "PackageUpdatedTask";
 
     public static final int OP_NONE = 0;
@@ -92,6 +93,11 @@
         mOp = op;
         mUser = user;
         mPackages = packages;
+        if (TestProtocol.sDebugTracing) {
+            Log.d(TestProtocol.WORK_TAB_MISSING, "PackageUpdatedTask mOp: " + mOp +
+                    " packageCount: " + mPackages.length);
+            DEBUG = true;
+        }
     }
 
     @Override
@@ -136,6 +142,9 @@
                         // The update may have changed which shortcuts/widgets are available.
                         // Refresh the widgets for the package if we have an activity running.
                         Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
+                        if (TestProtocol.sDebugTracing) {
+                            Log.d(TestProtocol.WORK_TAB_MISSING, "launcher: " + launcher);
+                        }
                         if (launcher != null) {
                             launcher.refreshAndBindWidgetsForPackageUser(
                                     new PackageUserKey(packages[i], mUser));
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 47bfe85..cb3c16c 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -25,7 +25,6 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.text.TextUtils;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -36,7 +35,6 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.ItemInstallQueue;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.MainThreadInitializedObject;
@@ -156,16 +154,6 @@
         if (sessionInfo == null
                 || sessionInfo.getInstallerPackageName() == null
                 || TextUtils.isEmpty(sessionInfo.getAppPackageName())) {
-            if (TestProtocol.sDebugTracing) {
-                Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " verify"
-                        + ", info=" + (sessionInfo == null)
-                        + ", info install name" + (sessionInfo == null
-                                ? null
-                                : sessionInfo.getInstallerPackageName())
-                        + ", empty pkg name" + TextUtils.isEmpty((sessionInfo == null
-                                ? null
-                                : sessionInfo.getAppPackageName())));
-            }
             return null;
         }
         return isTrustedPackage(sessionInfo.getInstallerPackageName(), getUserHandle(sessionInfo))
@@ -224,13 +212,6 @@
      */
     @WorkerThread
     void tryQueuePromiseAppIcon(@Nullable final PackageInstaller.SessionInfo sessionInfo) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " tryQueuePromiseAppIcon"
-                    + ", SessionCommitReceiveEnabled" + SessionCommitReceiver.isEnabled(mAppContext)
-                    + ", verifySessionInfo(sessionInfo)=" + verifySessionInfo(sessionInfo)
-                    + ", !promiseIconAdded=" + (sessionInfo != null
-                    && !promiseIconAddedForId(sessionInfo.getSessionId())));
-        }
         if (SessionCommitReceiver.isEnabled(mAppContext)
                 && verifySessionInfo(sessionInfo)
                 && !promiseIconAddedForId(sessionInfo.getSessionId())) {
@@ -246,20 +227,6 @@
     }
 
     public boolean verifySessionInfo(@Nullable final PackageInstaller.SessionInfo sessionInfo) {
-        if (TestProtocol.sDebugTracing) {
-            boolean appNotInstalled = sessionInfo == null
-                    || !new PackageManagerHelper(mAppContext)
-                    .isAppInstalled(sessionInfo.getAppPackageName(), getUserHandle(sessionInfo));
-            boolean labelNotEmpty = sessionInfo != null
-                    && !TextUtils.isEmpty(sessionInfo.getAppLabel());
-            Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " verifySessionInfo"
-                    + ", verify(sessionInfo)=" + verify(sessionInfo)
-                    + ", reason=" + (sessionInfo == null ? null : sessionInfo.getInstallReason())
-                    + ", PackageManager.INSTALL_REASON_USER=" + PackageManager.INSTALL_REASON_USER
-                    + ", hasIcon=" + (sessionInfo != null && sessionInfo.getAppIcon() != null)
-                    + ", label is ! empty=" + labelNotEmpty
-                    + " +, app not installed="  + appNotInstalled);
-        }
         return verify(sessionInfo) != null
                 && sessionInfo.getInstallReason() == PackageManager.INSTALL_REASON_USER
                 && sessionInfo.getAppIcon() != null
diff --git a/src/com/android/launcher3/pm/InstallSessionTracker.java b/src/com/android/launcher3/pm/InstallSessionTracker.java
index aeaa320..41908d3 100644
--- a/src/com/android/launcher3/pm/InstallSessionTracker.java
+++ b/src/com/android/launcher3/pm/InstallSessionTracker.java
@@ -25,14 +25,12 @@
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.os.Build;
 import android.os.UserHandle;
-import android.util.Log;
 import android.util.SparseArray;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.PackageUserKey;
 
 import java.lang.ref.WeakReference;
@@ -70,19 +68,10 @@
     public void onCreated(final int sessionId) {
         InstallSessionHelper helper = mWeakHelper.get();
         Callback callback = mWeakCallback.get();
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.MISSING_PROMISE_ICON, "Session created sessionId=" + sessionId
-                    + ", callback=" + callback
-                    + ", helper=" + helper);
-        }
         if (callback == null || helper == null) {
             return;
         }
         SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId, helper, callback);
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.MISSING_PROMISE_ICON, "Session created sessionId=" + sessionId
-                    + ", sessionInfo=" + sessionInfo);
-        }
         if (sessionInfo != null) {
             callback.onInstallSessionCreated(PackageInstallInfo.fromInstallingState(sessionInfo));
         }
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragController.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragController.java
index 9bf2764..b1a9b86 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragController.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragController.java
@@ -20,7 +20,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 import android.view.HapticFeedbackConstants;
 import android.view.View;
 
@@ -37,7 +36,6 @@
 import com.android.launcher3.dragndrop.DragView;
 import com.android.launcher3.dragndrop.DraggableView;
 import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.testing.shared.TestProtocol;
 
 /**
  * Drag controller for Secondary Launcher activity
@@ -55,11 +53,6 @@
             DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source,
             ItemInfo dragInfo, Point dragOffset, Rect dragRegion, float initialDragViewScale,
             float dragViewScaleOnDrop, DragOptions options) {
-
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NO_DROP_TARGET, "5");
-        }
-
         if (PROFILE_DRAWING_DURING_DRAG) {
             android.os.Debug.startMethodTracing("Launcher");
         }
diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java
index 54735f0..d1e816b 100644
--- a/src/com/android/launcher3/states/StateAnimationConfig.java
+++ b/src/com/android/launcher3/states/StateAnimationConfig.java
@@ -65,7 +65,8 @@
             ANIM_OVERVIEW_ACTIONS_FADE,
             ANIM_WORKSPACE_PAGE_TRANSLATE_X,
             ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
-            ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE
+            ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
+            ANIM_ALL_APPS_BOTTOM_SHEET_FADE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface AnimType {}
@@ -88,8 +89,9 @@
     public static final int ANIM_WORKSPACE_PAGE_TRANSLATE_X = 15;
     public static final int ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN = 17;
     public static final int ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE = 18;
+    public static final int ANIM_ALL_APPS_BOTTOM_SHEET_FADE = 19;
 
-    private static final int ANIM_TYPES_COUNT = 19;
+    private static final int ANIM_TYPES_COUNT = 20;
 
     protected final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT];
 
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index a53751f..d028f24 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -23,6 +23,8 @@
 import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
 import static com.android.launcher3.anim.Interpolators.INSTANT;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.clampToProgress;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
@@ -32,11 +34,14 @@
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
+import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
 
 import android.view.MotionEvent;
 import android.view.animation.Interpolator;
 
 import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.anim.Interpolators;
@@ -269,4 +274,44 @@
                             : ALL_APPS_VERTICAL_PROGRESS_ATOMIC);
         }
     }
+
+    /**
+     * Applies Animation config values for transition from overview to all apps.
+     *
+     * @param threshold progress at which all apps will open upon release
+     */
+    public static void applyOverviewToAllAppsAnimConfig(
+            DeviceProfile deviceProfile, StateAnimationConfig config, float threshold) {
+        config.userControlled = true;
+        config.animFlags = SKIP_OVERVIEW;
+        if (deviceProfile.isTablet) {
+            config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
+            config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER);
+            // The fact that we end on Workspace is not very ideal, but since we do, fade it in at
+            // the end of the transition. Don't scale/translate it.
+            config.setInterpolator(ANIM_WORKSPACE_FADE, clampToProgress(LINEAR, 0.8f, 1));
+            config.setInterpolator(ANIM_WORKSPACE_SCALE, INSTANT);
+            config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, INSTANT);
+        } else {
+            // Remove scrim for this transition.
+            config.setInterpolator(ANIM_SCRIM_FADE, progress -> 0);
+
+            // For now, pop the background panel in at full opacity at the threshold.
+            config.setInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE,
+                    thresholdInterpolator(threshold, INSTANT));
+
+            // Fade the apps in when the scrim normally does, so it's apparent sooner what is
+            // happening (in this case we are fading them on top of the background panel).
+            config.setInterpolator(ANIM_ALL_APPS_FADE,
+                    thresholdInterpolator(threshold, SCRIM_FADE_MANUAL));
+
+            config.setInterpolator(ANIM_VERTICAL_PROGRESS,
+                    thresholdInterpolator(threshold, ALL_APPS_VERTICAL_PROGRESS_MANUAL));
+        }
+    }
+
+    /** Creates an interpolator that is 0 until the threshold, then follows given interpolator. */
+    private static Interpolator thresholdInterpolator(float threshold, Interpolator interpolator) {
+        return progress -> progress <= threshold ? 0 : interpolator.getInterpolation(progress);
+    }
 }
diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
index 3fa5799..c2767be 100644
--- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java
+++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
@@ -16,13 +16,11 @@
 
 package com.android.launcher3.util;
 
-import android.util.Log;
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewTreeObserver.OnDrawListener;
 
 import com.android.launcher3.Launcher;
-import com.android.launcher3.testing.shared.TestProtocol;
 
 import java.util.function.Consumer;
 
@@ -44,9 +42,6 @@
     private boolean mCancelled;
 
     public ViewOnDrawExecutor(RunnableList tasks) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING, "Initialize ViewOnDrawExecutor");
-        }
         mTasks = tasks;
     }
 
@@ -54,11 +49,6 @@
         mOnClearCallback = launcher::clearPendingExecutor;
         mAttachedView = launcher.getWorkspace();
 
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING, "ViewOnDrawExecutor.attachTo: launcher=" + launcher
-                    + ", isAttachedToWindow=" + mAttachedView.isAttachedToWindow());
-        }
-
         mAttachedView.addOnAttachStateChangeListener(this);
 
         if (mAttachedView.isAttachedToWindow()) {
@@ -67,10 +57,6 @@
     }
 
     private void attachObserver() {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING,
-                    "ViewOnDrawExecutor.attachObserver: mCompleted=" + mCompleted);
-        }
         if (!mCompleted) {
             mAttachedView.getViewTreeObserver().addOnDrawListener(this);
         }
@@ -78,9 +64,6 @@
 
     @Override
     public void onViewAttachedToWindow(View v) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING, "ViewOnDrawExecutor.onViewAttachedToWindow");
-        }
         attachObserver();
     }
 
@@ -89,19 +72,11 @@
 
     @Override
     public void onDraw() {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING, "ViewOnDrawExecutor.onDraw");
-        }
         mFirstDrawCompleted = true;
         mAttachedView.post(this);
     }
 
     public void onLoadAnimationCompleted() {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING,
-                    "ViewOnDrawExecutor.onLoadAnimationCompleted: mAttachedView != null="
-                            + (mAttachedView != null));
-        }
         mLoadAnimationCompleted = true;
         if (mAttachedView != null) {
             mAttachedView.post(this);
@@ -110,12 +85,6 @@
 
     @Override
     public void run() {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING,
-                    "ViewOnDrawExecutor.run: mLoadAnimationCompleted=" + mLoadAnimationCompleted
-                            + ", mFirstDrawCompleted=" + mFirstDrawCompleted
-                            + ", mCompleted=" + mCompleted);
-        }
         // Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
         if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
             markCompleted();
@@ -126,12 +95,6 @@
      * Executes all tasks immediately
      */
     public void markCompleted() {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING,
-                    "ViewOnDrawExecutor.markCompleted: mCancelled=" + mCancelled
-                            + ", mOnClearCallback != null=" + (mOnClearCallback != null)
-                            + ", mAttachedView != null=" + (mAttachedView != null));
-        }
         if (!mCancelled) {
             mTasks.executeAllAndDestroy();
         }
@@ -146,9 +109,6 @@
     }
 
     public void cancel() {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.FLAKY_BINDING, "ViewOnDrawExecutor.cancel");
-        }
         mCancelled = true;
         markCompleted();
     }
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 4d38464..049131e 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -24,7 +24,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.View.OnLongClickListener;
@@ -136,9 +135,6 @@
 
     @Override
     public boolean onLongClick(View v) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NO_DROP_TARGET, "1");
-        }
         TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Widgets.onLongClick");
         v.cancelLongPress();
         if (!ItemLongClickListener.canStartDrag(mActivityContext)) return false;
@@ -220,9 +216,6 @@
     }
 
     private boolean beginDraggingWidget(WidgetCell v) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NO_DROP_TARGET, "2");
-        }
         // Get the widget preview as the drag representation
         WidgetImageView image = v.getWidgetView();
 
diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
index 130ee3a..1c88c4a 100644
--- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
@@ -86,7 +86,7 @@
         setWillNotDraw(false);
 
         super.updateAppWidget(null);
-        setOnClickListener(ItemClickHandler.INSTANCE);
+        setOnClickListener(mLauncher.getItemOnClickListener());
 
         if (info.pendingItemInfo == null) {
             info.pendingItemInfo = new PackageItemInfo(info.providerName.getPackageName(),
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index 2dedd12..410a555 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -22,7 +22,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 import android.util.Size;
 import android.view.View;
 import android.view.View.MeasureSpec;
@@ -43,7 +42,6 @@
 import com.android.launcher3.icons.FastBitmapDrawable;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.icons.RoundDrawableWrapper;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.widget.dragndrop.AppWidgetHostViewDragListener;
 import com.android.launcher3.widget.util.WidgetSizes;
 
@@ -97,9 +95,6 @@
      */
     public void startDrag(Rect previewBounds, int previewBitmapWidth, int previewViewWidth,
             Point screenPos, DragSource source, DragOptions options) {
-        if (TestProtocol.sDebugTracing) {
-            Log.d(TestProtocol.NO_DROP_TARGET, "3");
-        }
         final Launcher launcher = Launcher.getLauncher(mView.getContext());
         LauncherAppState app = LauncherAppState.getInstance(launcher);
 
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index 8c95d12..36255b4 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -147,12 +147,6 @@
     public static final String REQUEST_MOCK_SENSOR_ROTATION = "mock-sensor-rotation";
 
     public static final String PERMANENT_DIAG_TAG = "TaplTarget";
-    public static final String NO_DROP_TARGET = "b/195031154";
-    public static final String NULL_INT_SET = "b/200572078";
-    public static final String MISSING_PROMISE_ICON = "b/202985412";
-    public static final String TASKBAR_IN_APP_STATE = "b/227657604";
-    public static final String NPE_TRANSIENT_TASKBAR = "b/257549303";
-    public static final String FLAKY_BINDING = "b/270216650";
     public static final String VIEW_AND_ACTIVITY_LEAKS = "b/260260325";
     public static final String WORK_TAB_MISSING = "b/243688989";
 
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
index e8dd3c0..243edc3 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
@@ -28,7 +28,6 @@
 import com.android.launcher3.celllayout.testcases.MultipleCellLayoutsSimpleReorder;
 import com.android.launcher3.tapl.Widget;
 import com.android.launcher3.tapl.WidgetResizeFrame;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.ui.TaplTestsLauncher3;
 import com.android.launcher3.util.rule.ShellCommandRule;
@@ -116,14 +115,7 @@
         // waitForLauncherCondition to wait for that condition, otherwise the condition would
         // always be true and it wouldn't wait for the changes to be applied.
         resetLoaderState();
-        Log.d(TestProtocol.FLAKY_BINDING, "waiting for: isWorkspaceLoading=false");
-        waitForLauncherCondition("Workspace didn't finish loading", l -> {
-            boolean isWorkspaceLoading = l.isWorkspaceLoading();
-
-            Log.d(TestProtocol.FLAKY_BINDING, "checking: isWorkspaceLoading=" + isWorkspaceLoading);
-
-            return !isWorkspaceLoading;
-        });
+        waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading());
         Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.getCellX(),
                 mainWidgetCellPos.getCellY());
         assertNotNull(widget);
diff --git a/tests/src/com/android/launcher3/ui/WorkProfileTest.java b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
index 54da7de..c83820b 100644
--- a/tests/src/com/android/launcher3/ui/WorkProfileTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
@@ -105,6 +105,8 @@
     }
 
     private void waitForWorkTabSetup() {
+        // Added for b/243688989 flake to determine if we really are in allApps or not at this point
+        mLauncher.getAllApps();
         waitForLauncherCondition("Work tab not setup", launcher -> {
             if (launcher.getAppsView().getContentView() instanceof AllAppsPagedView) {
                 Log.d(WORK_TAB_MISSING, "Deferring AppsStore updates");