Merge "[-1] Show toast when user trys to swipe to -1 on extreme battery saver mode" into main
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index e51c956..621d226 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -56,7 +56,6 @@
 import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAUNCH;
 import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
 import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
 import static com.android.launcher3.testing.shared.TestProtocol.WALLPAPER_OPEN_ANIMATION_FINISHED_MESSAGE;
 import static com.android.launcher3.util.DisplayController.isTransientTaskbar;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -138,8 +137,8 @@
 import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.ActivityOptionsWrapper;
 import com.android.launcher3.util.DynamicResource;
-import com.android.launcher3.util.ObjectWrapper;
 import com.android.launcher3.util.RunnableList;
+import com.android.launcher3.util.StableViewInfo;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.FloatingIconView;
 import com.android.launcher3.views.ScrimView;
@@ -174,6 +173,7 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 
@@ -434,7 +434,7 @@
      */
     private void addLaunchCookie(IBinder cookie, ItemInfo info, ActivityOptions options) {
         if (cookie == null) {
-            cookie = mLauncher.getLaunchCookie(info);
+            cookie = StableViewInfo.toLaunchCookie(info);
         }
 
         if (cookie != null) {
@@ -1433,20 +1433,12 @@
 
         // Find the associated item info for the launch cookie (if available), note that predicted
         // apps actually have an id of -1, so use another default id here
-        final ArrayList<IBinder> launchCookies = runningTaskTarget.taskInfo.launchCookies == null
-                ? new ArrayList<>()
+        final List<IBinder> launchCookies = runningTaskTarget.taskInfo.launchCookies == null
+                ? Collections.EMPTY_LIST
                 : runningTaskTarget.taskInfo.launchCookies;
 
-        int launchCookieItemId = NO_MATCHING_ID;
-        for (IBinder cookie : launchCookies) {
-            Integer itemId = ObjectWrapper.unwrap(cookie);
-            if (itemId != null) {
-                launchCookieItemId = itemId;
-                break;
-            }
-        }
-
-        return mLauncher.getFirstMatchForAppClose(launchCookieItemId, packageName,
+        return mLauncher.getFirstMatchForAppClose(
+                StableViewInfo.fromLaunchCookies(launchCookies), packageName,
                 UserHandle.of(runningTaskTarget.taskInfo.userId), true /* supportsAllAppsState */);
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index ec710c5..fabf3a5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -94,6 +94,7 @@
     // States that affect whether region sampling is enabled or not
     private boolean mIsStashed;
     private boolean mIsLumaSamplingEnabled;
+    private boolean mIsAppTransitionPending;
     private boolean mTaskbarHidden;
 
     private float mTranslationYForSwipe;
@@ -267,6 +268,11 @@
         updateSamplingState();
     }
 
+    public void setIsAppTransitionPending(boolean pending) {
+        mIsAppTransitionPending = pending;
+        updateSamplingState();
+    }
+
     private void updateSamplingState() {
         updateRegionSamplingWindowVisibility();
         if (shouldSample()) {
@@ -278,7 +284,7 @@
     }
 
     private boolean shouldSample() {
-        return mIsStashed && mIsLumaSamplingEnabled;
+        return mIsStashed && mIsLumaSamplingEnabled && !mIsAppTransitionPending;
     }
 
     protected void updateStashedHandleHintScale() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 5f733b0..b10a59f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -914,11 +914,16 @@
         mControllers.navbarButtonsViewController.transitionTo(barMode, animate);
     }
 
+    public void appTransitionPending(boolean pending) {
+        mControllers.stashedHandleViewController.setIsAppTransitionPending(pending);
+    }
+
     /**
      * Called when this instance of taskbar is no longer needed
      */
     public void onDestroy() {
         mIsDestroyed = true;
+        mTaskbarFeatureEvaluator.onDestroy();
         setUIController(TaskbarUIController.DEFAULT);
         mControllers.onDestroy();
         if (!enableTaskbarNoRecreate() && !ENABLE_TASKBAR_NAVBAR_UNIFICATION) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 8c87fa6..8ecac96 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -549,7 +549,15 @@
 
     public void transitionTo(@BarTransitions.TransitionMode int barMode,
             boolean animate) {
-        mTaskbarActivityContext.transitionTo(barMode, animate);
+        if (mTaskbarActivityContext != null) {
+            mTaskbarActivityContext.transitionTo(barMode, animate);
+        }
+    }
+
+    public void appTransitionPending(boolean pending) {
+        if (mTaskbarActivityContext != null) {
+            mTaskbarActivityContext.appTransitionPending(pending);
+        }
     }
 
     private boolean isTaskbarEnabled(DeviceProfile deviceProfile) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
index 25939e1..f08318e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
@@ -71,6 +71,27 @@
             }
         }
 
+    /**
+     * Scale of the background in the x direction. Pivot is at the left edge if [anchorLeft] is
+     * `true` and at the right edge if it is `false`
+     */
+    var scaleX: Float = 1f
+        set(value) {
+            if (field != value) {
+                field = value
+                invalidateSelf()
+            }
+        }
+
+    /** Scale of the background in the y direction. Pivot is at the bottom edge. */
+    var scaleY: Float = 1f
+        set(value) {
+            if (field != value) {
+                field = value
+                invalidateSelf()
+            }
+        }
+
     init {
         val res = context.resources
         // configure fill paint
@@ -123,13 +144,17 @@
         )
         // Create background path
         val backgroundPath = Path()
-        val topOffset = backgroundHeight - bounds.height().toFloat()
+        val scaledBackgroundHeight = backgroundHeight * scaleY
+        val scaledWidth = width * scaleX
+        val topOffset = scaledBackgroundHeight - bounds.height().toFloat()
         val radius = backgroundHeight / 2f
-        val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - width)
-        val right = bounds.left + (if (anchorLeft) width else bounds.width().toFloat())
-        val top = bounds.top - topOffset + arrowVisibleHeight
 
-        val bottom = bounds.top + bounds.height().toFloat()
+        val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - scaledWidth)
+        val right = bounds.left + (if (anchorLeft) scaledWidth else bounds.width().toFloat())
+        // Calculate top with scaled heights for background and arrow to align with stash handle
+        val top = bounds.bottom - scaledBackgroundHeight + getScaledArrowVisibleHeight()
+        val bottom = bounds.bottom.toFloat()
+
         backgroundPath.addRoundRect(left, top, right, bottom, radius, radius, Path.Direction.CW)
         addArrowPathIfNeeded(backgroundPath, topOffset)
 
@@ -142,19 +167,20 @@
     private fun addArrowPathIfNeeded(sourcePath: Path, topOffset: Float) {
         if (!showingArrow || arrowHeightFraction <= 0) return
         val arrowPath = Path()
+        val scaledHeight = getScaledArrowHeight()
         RoundedArrowDrawable.addDownPointingRoundedTriangleToPath(
             arrowWidth,
-            arrowHeight,
+            scaledHeight,
             arrowTipRadius,
             arrowPath
         )
         // flip it horizontally
         val pathTransform = Matrix()
-        pathTransform.setRotate(180f, arrowWidth * 0.5f, arrowHeight * 0.5f)
+        pathTransform.setRotate(180f, arrowWidth * 0.5f, scaledHeight * 0.5f)
         arrowPath.transform(pathTransform)
         // shift to arrow position
         val arrowStart = bounds.left + arrowPositionX - (arrowWidth / 2f)
-        val arrowTop = (1 - arrowHeightFraction) * arrowVisibleHeight - topOffset
+        val arrowTop = (1 - arrowHeightFraction) * getScaledArrowVisibleHeight() - topOffset
         arrowPath.offset(arrowStart, arrowTop)
         // union with rectangle
         sourcePath.op(arrowPath, Path.Op.UNION)
@@ -183,6 +209,7 @@
 
     fun setBackgroundHeight(newHeight: Float) {
         backgroundHeight = newHeight
+        invalidateSelf()
     }
 
     /**
@@ -199,6 +226,14 @@
         invalidateSelf()
     }
 
+    private fun getScaledArrowHeight(): Float {
+        return arrowHeight * scaleY
+    }
+
+    private fun getScaledArrowVisibleHeight(): Float {
+        return max(0f, getScaledArrowHeight() - (arrowHeight - arrowVisibleHeight))
+    }
+
     companion object {
         private const val DARK_THEME_STROKE_ALPHA = 51
         private const val LIGHT_THEME_STROKE_ALPHA = 41
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index 06301c7..9c6ba8b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -306,6 +306,20 @@
     }
 
     /**
+     * Set scale for bubble bar background in x direction
+     */
+    public void setBackgroundScaleX(float scaleX) {
+        mBubbleBarBackground.setScaleX(scaleX);
+    }
+
+    /**
+     * Set scale for bubble bar background in y direction
+     */
+    public void setBackgroundScaleY(float scaleY) {
+        mBubbleBarBackground.setScaleY(scaleY);
+    }
+
+    /**
      * Sets new icon sizes and newBubbleBarPadding between icons and bubble bar borders.
      *
      * @param newIconSize         new icon size
@@ -322,7 +336,7 @@
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             View childView = getChildAt(i);
-            childView.setScaleY(mIconScale);
+            childView.setScaleX(mIconScale);
             childView.setScaleY(mIconScale);
             FrameLayout.LayoutParams params = (LayoutParams) childView.getLayoutParams();
             params.height = (int) mIconSize;
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index d9e3406..d0be5ec 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -82,6 +82,10 @@
     private final MultiValueAlpha mBubbleBarAlpha;
     private final AnimatedFloat mBubbleBarScaleX = new AnimatedFloat(this::updateScaleX);
     private final AnimatedFloat mBubbleBarScaleY = new AnimatedFloat(this::updateScaleY);
+    private final AnimatedFloat mBubbleBarBackgroundScaleX = new AnimatedFloat(
+            this::updateBackgroundScaleX);
+    private final AnimatedFloat mBubbleBarBackgroundScaleY = new AnimatedFloat(
+            this::updateBackgroundScaleY);
     private final AnimatedFloat mBubbleBarTranslationY = new AnimatedFloat(
             this::updateTranslationY);
 
@@ -266,6 +270,14 @@
         return mBubbleBarScaleY;
     }
 
+    public AnimatedFloat getBubbleBarBackgroundScaleX() {
+        return mBubbleBarBackgroundScaleX;
+    }
+
+    public AnimatedFloat getBubbleBarBackgroundScaleY() {
+        return mBubbleBarBackgroundScaleY;
+    }
+
     public AnimatedFloat getBubbleBarTranslationY() {
         return mBubbleBarTranslationY;
     }
@@ -535,6 +547,14 @@
         mBarView.setScaleY(scale);
     }
 
+    private void updateBackgroundScaleX(float scale) {
+        mBarView.setBackgroundScaleX(scale);
+    }
+
+    private void updateBackgroundScaleY(float scale) {
+        mBarView.setBackgroundScaleY(scale);
+    }
+
     //
     // Manipulating the specific bubble views in the bar
     //
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index 99c50f2..6a955d9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -169,6 +169,8 @@
         bubbleBarView.translationY = 0f
         bubbleBarView.scaleX = 1f
         bubbleBarView.scaleY = BUBBLE_ANIMATION_INITIAL_SCALE_Y
+        bubbleBarView.setBackgroundScaleX(1f)
+        bubbleBarView.setBackgroundScaleY(1f)
         bubbleBarView.relativePivotY = 0.5f
 
         // this is the offset between the center of the bubble bar and the center of the stash
@@ -311,6 +313,7 @@
             animatingBubble = null
             if (!canceled) bubbleStashController.stashBubbleBarImmediate()
             bubbleBarView.relativePivotY = 1f
+            bubbleBarView.scaleY = 1f
             bubbleStashController.updateTaskbarTouchRegion()
         }
         animator.start()
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
index 1157305..0700ab7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
@@ -67,8 +67,8 @@
     // bubble bar properties
     private lateinit var bubbleBarAlpha: MultiPropertyFactory<View>.MultiProperty
     private lateinit var bubbleBarTranslationYAnimator: AnimatedFloat
-    private lateinit var bubbleBarScaleX: AnimatedFloat
-    private lateinit var bubbleBarScaleY: AnimatedFloat
+    private lateinit var bubbleBarBackgroundScaleX: AnimatedFloat
+    private lateinit var bubbleBarBackgroundScaleY: AnimatedFloat
     private val handleCenterFromScreenBottom =
         context.resources.getDimensionPixelSize(R.dimen.bubblebar_stashed_size) / 2f
 
@@ -149,8 +149,8 @@
         bubbleBarTranslationYAnimator = bubbleBarViewController.bubbleBarTranslationY
         // bubble bar has only alpha property, getting it at index 0
         bubbleBarAlpha = bubbleBarViewController.bubbleBarAlpha.get(/* index= */ 0)
-        bubbleBarScaleX = bubbleBarViewController.bubbleBarScaleX
-        bubbleBarScaleY = bubbleBarViewController.bubbleBarScaleY
+        bubbleBarBackgroundScaleX = bubbleBarViewController.bubbleBarBackgroundScaleX
+        bubbleBarBackgroundScaleY = bubbleBarViewController.bubbleBarBackgroundScaleY
         stashedHeight = bubbleStashedHandleViewController?.stashedHeight ?: 0
         stashHandleViewAlpha = bubbleStashedHandleViewController?.stashedHandleAlpha?.get(0)
     }
@@ -160,8 +160,8 @@
         if (isBubblesShowingOnHome || isBubblesShowingOnOverview) {
             isStashed = false
             animatorSet.playTogether(
-                bubbleBarScaleX.animateToValue(1f),
-                bubbleBarScaleY.animateToValue(1f),
+                bubbleBarBackgroundScaleX.animateToValue(1f),
+                bubbleBarBackgroundScaleY.animateToValue(1f),
                 bubbleBarTranslationYAnimator.animateToValue(bubbleBarTranslationY),
                 bubbleBarAlpha.animateToValue(1f)
             )
@@ -181,8 +181,8 @@
         stashHandleViewAlpha?.value = 0f
         this.bubbleBarTranslationYAnimator.updateValue(bubbleBarTranslationY)
         bubbleBarAlpha.setValue(1f)
-        bubbleBarScaleX.updateValue(1f)
-        bubbleBarScaleY.updateValue(1f)
+        bubbleBarBackgroundScaleX.updateValue(1f)
+        bubbleBarBackgroundScaleY.updateValue(1f)
         isStashed = false
         onIsStashedChanged()
     }
@@ -192,8 +192,8 @@
         stashHandleViewAlpha?.value = 1f
         this.bubbleBarTranslationYAnimator.updateValue(getStashTranslation())
         bubbleBarAlpha.setValue(0f)
-        bubbleBarScaleX.updateValue(getStashScaleX())
-        bubbleBarScaleY.updateValue(getStashScaleY())
+        bubbleBarBackgroundScaleX.updateValue(getStashScaleX())
+        bubbleBarBackgroundScaleY.updateValue(getStashScaleY())
         isStashed = true
         onIsStashedChanged()
     }
@@ -259,7 +259,7 @@
     override fun getHandleTranslationY(): Float? = bubbleStashedHandleViewController?.translationY
 
     private fun getStashTranslation(): Float {
-        return bubbleBarTranslationY / 2f
+        return (bubbleBarTranslationY - stashedHeight) / 2f
     }
 
     @VisibleForTesting
@@ -366,8 +366,8 @@
         val scaleXTarget = if (isStashed) getStashScaleX() else 1f
         val scaleYTarget = if (isStashed) getStashScaleY() else 1f
         return AnimatorSet().apply {
-            play(bubbleBarScaleX.animateToValue(scaleXTarget))
-            play(bubbleBarScaleY.animateToValue(scaleYTarget))
+            play(bubbleBarBackgroundScaleX.animateToValue(scaleXTarget))
+            play(bubbleBarBackgroundScaleY.animateToValue(scaleYTarget))
         }
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
index c83ac50..7739a0e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
@@ -26,23 +26,6 @@
 private constructor(
     private val taskbarActivityContext: TaskbarActivityContext,
 ) {
-
-    companion object {
-        @Volatile private lateinit var taskbarFeatureEvaluator: TaskbarFeatureEvaluator
-
-        @JvmStatic
-        fun getInstance(
-            taskbarActivityContext: TaskbarActivityContext,
-        ): TaskbarFeatureEvaluator {
-            synchronized(this) {
-                if (!::taskbarFeatureEvaluator.isInitialized) {
-                    taskbarFeatureEvaluator = TaskbarFeatureEvaluator(taskbarActivityContext)
-                }
-                return taskbarFeatureEvaluator
-            }
-        }
-    }
-
     val hasAllApps = true
     val hasAppIcons = true
     val hasBubbles = false
@@ -59,4 +42,24 @@
 
     val isLandscape: Boolean
         get() = taskbarActivityContext.deviceProfile.isLandscape
+
+    fun onDestroy() {
+        taskbarFeatureEvaluator = null
+    }
+
+    companion object {
+        @Volatile private var taskbarFeatureEvaluator: TaskbarFeatureEvaluator? = null
+
+        @JvmStatic
+        fun getInstance(
+            taskbarActivityContext: TaskbarActivityContext,
+        ): TaskbarFeatureEvaluator {
+            synchronized(this) {
+                if (taskbarFeatureEvaluator == null) {
+                    taskbarFeatureEvaluator = TaskbarFeatureEvaluator(taskbarActivityContext)
+                }
+                return taskbarFeatureEvaluator!!
+            }
+        }
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt
index 6be0828..e55cb1f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt
@@ -37,6 +37,8 @@
 
     val minimumTaskbarIconTouchSize = TaskbarIconSize(48)
 
+    val transientOrPinnedTaskbarIconPaddingSize = iconSize52dp
+
     val transientTaskbarIconSizeByGridSize =
         mapOf(
             TransientTaskbarIconSizeKey(6, 5, false) to iconSize52dp,
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
index f37b2c1..822ca64 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
@@ -31,7 +31,10 @@
     private var taskbarContainer: List<TaskbarContainer> = emptyList()
 
     val taskbarIconPadding: Int =
-        if (TaskbarIconSpecs.iconSize52dp.size > taskbarIconSize.size) {
+        if (
+            TaskbarIconSpecs.transientOrPinnedTaskbarIconPaddingSize.size > taskbarIconSize.size &&
+                !taskbarFeatureEvaluator.hasNavButtons
+        ) {
             (TaskbarIconSpecs.iconSize52dp.size - taskbarIconSize.size) / 2
         } else {
             0
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index 039c0a0..5b07926 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -34,6 +34,7 @@
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.util.ActivityOptionsWrapper;
+import com.android.launcher3.util.StableViewInfo;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 
 /** Provides a Quickstep specific animation when launching an activity from an app widget. */
@@ -69,8 +70,8 @@
                 .getActivityLaunchOptions(hostView);
         Object itemInfo = hostView.getTag();
         IBinder launchCookie = null;
-        if (itemInfo instanceof ItemInfo) {
-            launchCookie = mLauncher.getLaunchCookie((ItemInfo) itemInfo);
+        if (itemInfo instanceof ItemInfo info) {
+            launchCookie = StableViewInfo.toLaunchCookie(info);
             activityOptions.options.setLaunchCookie(launchCookie);
         }
         if (Utilities.ATLEAST_S && !pendingIntent.isActivity()) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 0b385d9..b5b8909 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -41,7 +41,6 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_HOME;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_INTERRUPTED;
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
 import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
 import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
 import static com.android.launcher3.popup.SystemShortcut.BUBBLE_SHORTCUT;
@@ -83,7 +82,6 @@
 import android.media.permission.SafeCloseable;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.SystemProperties;
 import android.os.Trace;
@@ -1232,43 +1230,6 @@
         mSplitWithKeyboardShortcutController.enterStageSplit(leftOrTop);
     }
 
-    /**
-     * Return a new launch cookie for the activity launch if supported.
-     *
-     * @param info the item info for the launch
-     */
-    public IBinder getLaunchCookie(ItemInfo info) {
-        if (info == null) {
-            return null;
-        }
-        switch (info.container) {
-            case Favorites.CONTAINER_DESKTOP:
-            case Favorites.CONTAINER_HOTSEAT:
-            case Favorites.CONTAINER_PRIVATESPACE:
-                // Fall through and continue it's on the workspace (we don't support swiping back
-                // to other containers like all apps or the hotseat predictions (which can change)
-                break;
-            default:
-                if (info.container >= 0) {
-                    // Also allow swiping to folders
-                    break;
-                }
-                // Reset any existing launch cookies associated with the cookie
-                return ObjectWrapper.wrap(NO_MATCHING_ID);
-        }
-        switch (info.itemType) {
-            case Favorites.ITEM_TYPE_APPLICATION:
-            case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
-            case Favorites.ITEM_TYPE_APPWIDGET:
-                // Fall through and continue if it's an app, shortcut, or widget
-                break;
-            default:
-                // Reset any existing launch cookies associated with the cookie
-                return ObjectWrapper.wrap(NO_MATCHING_ID);
-        }
-        return ObjectWrapper.wrap(new Integer(info.id));
-    }
-
     @Override
     public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
         super.onDisplayInfoChanged(context, info, flags);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index fa80dc2..030a7ac 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -26,7 +26,6 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.ActivityContext;
 import com.android.quickstep.util.BaseDepthController;
@@ -202,17 +201,6 @@
     }
 
     @Override
-    public float[] getOverviewScaleAndOffset(Launcher launcher) {
-        if (!FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()) {
-            return super.getOverviewScaleAndOffset(launcher);
-        }
-        // This handles the case of returning to the previous app from Overview -> All Apps gesture.
-        // This is the start scale/offset of overview that will be used for that transition.
-        // TODO (b/283336332): Translate in Y direction (ideally with overview resistance).
-        return new float[] {0.5f /* scale */, NO_OFFSET};
-    }
-
-    @Override
     public int getWorkspaceScrimColor(Launcher launcher) {
         return launcher.getDeviceProfile().isTablet
                 ? launcher.getResources().getColor(R.color.widgets_picker_scrim)
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index b5914a1..b6a0ab3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -29,7 +29,6 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.states.StateAnimationConfig;
 import com.android.launcher3.touch.AbstractStateChangeTouchController;
 import com.android.launcher3.touch.AllAppsSwipeController;
@@ -93,9 +92,7 @@
     @Override
     protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
         if (fromState == ALL_APPS && !isDragTowardPositive) {
-            return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()
-                    ? mLauncher.getStateManager().getLastState()
-                    : NORMAL;
+            return NORMAL;
         } else if (fromState == NORMAL && shouldOpenAllApps(isDragTowardPositive)) {
             return ALL_APPS;
         }
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 55489bb..978d8c4 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -45,7 +45,6 @@
 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;
@@ -265,8 +264,6 @@
             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 |
@@ -320,7 +317,6 @@
     private boolean mGestureStarted;
     private boolean mLogDirectionUpOrLeft = true;
     private boolean mIsLikelyToStartNewTask;
-    private boolean mIsInAllAppsRegion;
 
     private final long mTouchTimeMs;
     private long mLauncherFrameDrawnTime;
@@ -457,9 +453,6 @@
                 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
@@ -724,9 +717,7 @@
                 maybeUpdateRecentsAttachedState(true/* animate */, true/* moveRunningTask */);
                 Optional.ofNullable(mContainerInterface.getTaskbarController())
                         .ifPresent(TaskbarUIController::startTranslationSpring);
-                if (!mIsInAllAppsRegion) {
-                    performHapticFeedback();
-                }
+                performHapticFeedback();
             }
 
             @Override
@@ -774,9 +765,7 @@
                 .findTask(mGestureState.getTopRunningTaskId())
                 : null;
         final boolean recentsAttachedToAppWindow;
-        if (mIsInAllAppsRegion) {
-            recentsAttachedToAppWindow = false;
-        } else if (mGestureState.getEndTarget() != null) {
+        if (mGestureState.getEndTarget() != null) {
             recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
         } else if (mContinuingLastGesture
                 && mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
@@ -833,31 +822,6 @@
         }
     }
 
-    /**
-     * Update whether user is currently dragging in a region that will trigger all apps.
-     */
-    private void setIsInAllAppsRegion(boolean isInAllAppsRegion) {
-        if (mIsInAllAppsRegion == isInAllAppsRegion
-                || !mContainerInterface.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);
-
-        if (mContainer != null) {
-            mContainer.getAppsView().getSearchUiManager()
-                    .prepareToFocusEditText(mIsInAllAppsRegion);
-        }
-
-        // 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;
@@ -917,8 +881,6 @@
     @UiThread
     @Override
     public void onCurrentShiftUpdated() {
-        float threshold = DeviceConfigWrapper.get().getAllAppsOverviewThreshold() / 100f;
-        setIsInAllAppsRegion(mCurrentShift.value >= threshold);
         updateSysUiFlags(mCurrentShift.value);
         applyScrollAndTransform();
 
@@ -1203,9 +1165,6 @@
         }
 
         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
@@ -1324,9 +1283,6 @@
         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 != null
                     && mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
@@ -1342,9 +1298,7 @@
         // Fully gestural mode.
         final boolean isFlingX = Math.abs(velocity.x) > mContext.getResources()
                 .getDimension(R.dimen.quickstep_fling_threshold_speed);
-        if (mIsInAllAppsRegion) {
-            return ALL_APPS;
-        } else if (isScrollingToNewTask && isFlingX) {
+        if (isScrollingToNewTask && isFlingX) {
             // Flinging towards new task takes precedence over mIsMotionPaused (which only
             // checks y-velocity).
             return NEW_TASK;
@@ -1399,8 +1353,7 @@
                     .setUserIsNotGoingHome(endTarget != GestureState.GestureEndTarget.HOME);
         }
 
-        float endShift = endTarget == ALL_APPS ? mDragLengthFactor
-                : endTarget.isLauncher ? 1 : 0;
+        float endShift = endTarget.isLauncher ? 1 : 0;
         final float startShift;
         if (!isFling) {
             long expectedDuration = Math.abs(Math.round((endShift - currentShift)
@@ -2027,12 +1980,6 @@
         reset();
     }
 
-    @UiThread
-    private void finishCurrentTransitionToAllApps() {
-        finishCurrentTransitionToHome();
-        reset();
-    }
-
     private void reset() {
         mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
         if (mContainer != null) {
@@ -2174,7 +2121,6 @@
     private void updateThumbnail() {
         if (mGestureState.getEndTarget() == HOME
                 || mGestureState.getEndTarget() == NEW_TASK
-                || mGestureState.getEndTarget() == ALL_APPS
                 || mRecentsView == null) {
             // 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.
diff --git a/quickstep/src/com/android/quickstep/BaseContainerInterface.java b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
index 777761b..d7378ec 100644
--- a/quickstep/src/com/android/quickstep/BaseContainerInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
@@ -74,9 +74,6 @@
     public abstract boolean deferStartingActivity(RecentsAnimationDeviceState deviceState,
             MotionEvent ev);
 
-    /** @return whether to allow going to All Apps from Overview. */
-    public abstract boolean allowAllAppsFromOverview();
-
     /**
      * Returns the color of the scrim behind overview when at rest in this state.
      * Return {@link Color#TRANSPARENT} for no scrim.
diff --git a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
index e6822ff..f610014 100644
--- a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
+++ b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
@@ -142,13 +142,6 @@
             "Controls extra dp on the nav bar sides to trigger LPNH. Can be negative for a smaller touch region."
         )
 
-    val allAppsOverviewThreshold =
-        propReader.get(
-            "ALL_APPS_OVERVIEW_THRESHOLD",
-            180,
-            "Threshold to open All Apps from Overview"
-        )
-
     /** Dump config values. */
     fun dump(prefix: String, writer: PrintWriter) {
         writer.println("$prefix DeviceConfigWrapper:")
@@ -169,7 +162,6 @@
         writer.println("$prefix\tenableLpnhDeepPress=$enableLpnhDeepPress")
         writer.println("$prefix\tlpnhHapticHintDelay=$lpnhHapticHintDelay")
         writer.println("$prefix\tlpnhExtraTouchWidthDp=$lpnhExtraTouchWidthDp")
-        writer.println("$prefix\tallAppsOverviewThreshold=$allAppsOverviewThreshold")
     }
 
     companion object {
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 94a4527..df83eb2 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -133,11 +133,6 @@
     }
 
     @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
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index e9fe2f7..abd71d5 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -18,7 +18,6 @@
 import static com.android.app.animation.Interpolators.LINEAR;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.BACKGROUND_APP;
-import static com.android.launcher3.LauncherState.FLOATING_SEARCH_BAR;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -40,7 +39,6 @@
 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;
@@ -271,13 +269,6 @@
     }
 
     @Override
-    public boolean allowAllAppsFromOverview() {
-        return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()
-                // If floating search bar would not show in overview, don't allow all apps gesture.
-                && OVERVIEW.areElementsVisible(getCreatedContainer(), FLOATING_SEARCH_BAR);
-    }
-
-    @Override
     public boolean isInLiveTileMode() {
         QuickstepLauncher launcher = getCreatedContainer();
 
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index f653e60..d2dcd7b 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -20,7 +20,6 @@
 import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.Utilities.mapBoundToRange;
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
 import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
 import static com.android.launcher3.views.FloatingIconView.getFloatingIconView;
 
@@ -42,7 +41,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.states.StateAnimationConfig;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.util.ObjectWrapper;
+import com.android.launcher3.util.StableViewInfo;
 import com.android.launcher3.views.ClipIconView;
 import com.android.launcher3.views.FloatingIconView;
 import com.android.launcher3.views.FloatingView;
@@ -301,18 +300,7 @@
             return null;
         }
 
-        // Find the associated item info for the launch cookie (if available), note that predicted
-        // apps actually have an id of -1, so use another default id here
-        int launchCookieItemId = NO_MATCHING_ID;
-        for (IBinder cookie : launchCookies) {
-            Integer itemId = ObjectWrapper.unwrap(cookie);
-            if (itemId != null) {
-                launchCookieItemId = itemId;
-                break;
-            }
-        }
-
-        return mContainer.getFirstMatchForAppClose(launchCookieItemId,
+        return mContainer.getFirstMatchForAppClose(StableViewInfo.fromLaunchCookies(launchCookies),
                 sourceTaskView.getFirstTask().key.getComponent().getPackageName(),
                 UserHandle.of(sourceTaskView.getFirstTask().key.userId),
                 false /* supportsAllAppsState */);
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 49ec597..da967ab 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -329,10 +329,7 @@
         final ActivityOptions options = ActivityOptions.makeBasic();
         options.setPendingIntentBackgroundActivityStartMode(
                 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS);
-        // Use regular (non-transient) launch for all apps page to control IME.
-        if (!containerInterface.allowAllAppsFromOverview()) {
-            options.setTransientLaunch();
-        }
+        options.setTransientLaunch();
         options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
 
         // Notify taskbar that we should skip reacting to launcher visibility change to
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 4587bdd..98e7fed 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -379,6 +379,15 @@
             ));
         }
 
+        @BinderThread
+        @Override
+        public void appTransitionPending(boolean pending) {
+            MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
+                    executeForTaskbarManager(
+                            taskbarManager -> taskbarManager.appTransitionPending(pending))
+            ));
+        }
+
         /**
          * Preloads the Overview activity.
          * <p>
diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
index c7c04ed..b583a4b 100644
--- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
+++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
@@ -21,7 +21,6 @@
 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;
@@ -34,18 +33,11 @@
 
 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.quickstep.DeviceConfigWrapper;
 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
 import com.android.quickstep.views.RecentsView;
-import com.android.quickstep.views.RecentsViewContainer;
 
 /**
  * Controls an animation that can go beyond progress = 1, at which point resistance should be
@@ -57,10 +49,8 @@
 
     private enum RecentsResistanceParams {
         FROM_APP(0.75f, 0.5f, 1f, false),
-        FROM_APP_TO_ALL_APPS(1f, 0.6f, 0.8f, false),
         FROM_APP_TABLET(1f, 0.7f, 1f, true),
         FROM_APP_TABLET_GRID_ONLY(1f, 1f, 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,
@@ -157,46 +147,10 @@
         RecentsParams params = new RecentsParams(context, recentsOrientedState, dp, scaleTarget,
                 scaleProperty, translationTarget, translationProperty);
         PendingAnimation resistAnim = createRecentsResistanceAnim(params);
-
-        // Apply All Apps animation during the resistance animation.
-        if (recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()) {
-            RecentsViewContainer container =
-                    recentsOrientedState.getContainerInterface().getCreatedContainer();
-            if (container != null) {
-                RecentsView recentsView = container.getOverviewPanel();
-                StateManager<LauncherState, StatefulActivity<LauncherState>> stateManager =
-                        recentsView.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.getContainerInterface().getSwipeUpDestinationAndLength(
-                        dp, context, TEMP_RECT,
-                        recentsOrientedState.getOrientationHandler());
-        float dragLengthFactor = (float) dp.heightPx / transitionDragLength;
-        // -1s are because 0-1 is reserved for the normal transition.
-        float threshold = DeviceConfigWrapper.get().getAllAppsOverviewThreshold() / 100f;
-        return (threshold - 1) / (dragLengthFactor - 1);
-    }
-
     /**
      * Creates the resistance animation for {@link #createForRecents}, or can be used separately
      * when starting from recents, i.e. {@link #createRecentsResistanceFromOverviewAnim}.
@@ -305,17 +259,11 @@
             this.translationTarget = translationTarget;
             this.translationProperty = translationProperty;
             if (dp.isTablet) {
-                resistanceParams =
-                        recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()
-                                ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS_TABLET
-                                : enableGridOnlyOverview()
-                                        ? RecentsResistanceParams.FROM_APP_TABLET_GRID_ONLY
-                                        : RecentsResistanceParams.FROM_APP_TABLET;
+                resistanceParams = enableGridOnlyOverview()
+                        ? RecentsResistanceParams.FROM_APP_TABLET_GRID_ONLY
+                        : RecentsResistanceParams.FROM_APP_TABLET;
             } else {
-                resistanceParams =
-                        recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()
-                                ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS
-                                : RecentsResistanceParams.FROM_APP;
+                resistanceParams = RecentsResistanceParams.FROM_APP;
             }
         }
 
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
index 262d8da..a745b66 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
@@ -60,7 +60,7 @@
         const val TASK_BAR_TRANSLATION_Y = -TASKBAR_BOTTOM_SPACE
         const val HANDLE_VIEW_WIDTH = 150
         const val HANDLE_VIEW_HEIGHT = 4
-        const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -2.5f
+        const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -4.5f
     }
 
     @get:Rule val animatorTestRule: AnimatorTestRule = AnimatorTestRule(this)
@@ -302,8 +302,8 @@
 
         whenever(bubbleBarViewController.hasBubbles()).thenReturn(true)
         whenever(bubbleBarViewController.bubbleBarTranslationY).thenReturn(barTranslationY)
-        whenever(bubbleBarViewController.bubbleBarScaleX).thenReturn(barScaleX)
-        whenever(bubbleBarViewController.bubbleBarScaleY).thenReturn(barScaleY)
+        whenever(bubbleBarViewController.bubbleBarBackgroundScaleX).thenReturn(barScaleX)
+        whenever(bubbleBarViewController.bubbleBarBackgroundScaleY).thenReturn(barScaleY)
         whenever(bubbleBarViewController.bubbleBarAlpha).thenReturn(barAlpha)
         whenever(bubbleBarViewController.bubbleBarCollapsedWidth).thenReturn(BUBBLE_BAR_WIDTH)
         whenever(bubbleBarViewController.bubbleBarCollapsedHeight).thenReturn(BUBBLE_BAR_HEIGHT)
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 8ae6d73..cc5baea 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -25,7 +25,6 @@
 import static com.android.launcher3.InvariantDeviceProfile.INDEX_TWO_PANEL_PORTRAIT;
 import static com.android.launcher3.Utilities.dpiFromPx;
 import static com.android.launcher3.Utilities.pxFromSp;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH;
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
 import static com.android.launcher3.icons.GraphicsUtils.getShapePath;
 import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
@@ -503,7 +502,7 @@
         bottomSheetCloseDuration = res.getInteger(R.integer.config_bottomSheetCloseDuration);
         if (isTablet) {
             bottomSheetWorkspaceScale = workspaceContentScale;
-            if (isMultiDisplay && !ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH.get()) {
+            if (isMultiDisplay) {
                 // TODO(b/259893832): Revert to use maxWallpaperScale to calculate bottomSheetDepth
                 // when screen recorder bug is fixed.
                 if (enableScalingRevealHomeAnimation()) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 2eda54d..365e3d4 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -241,6 +241,7 @@
 import com.android.launcher3.util.ScreenOnTracker;
 import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
 import com.android.launcher3.util.SettingsCache;
+import com.android.launcher3.util.StableViewInfo;
 import com.android.launcher3.util.SystemUiController;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
@@ -2424,17 +2425,16 @@
      * Similar to {@link #getFirstMatch} but optimized to finding a suitable view for the app close
      * animation.
      *
-     * @param preferredItemId The id of the preferred item to match to if it exists,
-     *                        or ItemInfo#NO_MATCHING_ID if you want to not match by item id
+     * @param svi The StableViewInfo of the preferred item to match to if it exists or null
      * @param packageName The package name of the app to match.
      * @param user The user of the app to match.
      * @param supportsAllAppsState If true and we are in All Apps state, looks for view in All Apps.
      *                             Else we only looks on the workspace.
      */
-    public @Nullable View getFirstMatchForAppClose(int preferredItemId, String packageName,
+    public @Nullable View getFirstMatchForAppClose(
+            @Nullable StableViewInfo svi, String packageName,
             UserHandle user, boolean supportsAllAppsState) {
-        final Predicate<ItemInfo> preferredItem = info ->
-                info != null && info.id == preferredItemId;
+        final Predicate<ItemInfo> preferredItem = svi == null ? i -> false : svi::matches;
         final Predicate<ItemInfo> packageAndUserAndApp = info ->
                 info != null
                         && info.itemType == ITEM_TYPE_APPLICATION
@@ -2525,6 +2525,9 @@
         final int itemCount = container.getChildCount();
         for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
             View item = container.getChildAt(itemIdx);
+            if (item.getVisibility() != View.VISIBLE) {
+                continue;
+            }
             if (item instanceof ViewGroup viewGroup) {
                 View view = mapOverViewGroup(viewGroup, op);
                 if (view != null) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 21900c1..aa8c5a5 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -62,11 +62,6 @@
      * and set a default value for the flag. This will be the default value on Debug builds.
      * <p>
      */
-    // TODO(Block 2): Clean up flags
-    public static final BooleanFlag ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH = getDebugFlag(270395073,
-            "ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH", DISABLED,
-            "Allow bottom sheet depth to be smaller than 1 for multi-display devices.");
-
     // TODO(Block 3): Clean up flags
     public static final BooleanFlag ENABLE_DISMISS_PREDICTION_UNDO = getDebugFlag(270394476,
             "ENABLE_DISMISS_PREDICTION_UNDO", DISABLED,
@@ -85,10 +80,6 @@
                     + "data preparation for loading the home screen");
 
     // TODO(Block 4): Cleanup flags
-    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");
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 62198cb..b706d24 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -81,8 +81,6 @@
 
     public static final boolean DEBUG = false;
     public static final int NO_ID = -1;
-    // An id that doesn't match any item, including predicted apps with have an id=NO_ID
-    public static final int NO_MATCHING_ID = Integer.MIN_VALUE;
 
     /** Hidden field Settings.Secure.NAV_BAR_KIDS_MODE */
     private static final Uri NAV_BAR_KIDS_MODE = Settings.Secure.getUriFor("nav_bar_kids_mode");
@@ -545,6 +543,14 @@
         this.title = title;
     }
 
+    /**
+     * Returns a string ID that is stable for a user session, but may not be persisted
+     */
+    @Nullable
+    public Object getStableId() {
+        return getComponentKey();
+    }
+
     private int getUserType(UserIconInfo info) {
         if (info == null) {
             return SysUiStatsLog.LAUNCHER_UICHANGED__USER_TYPE__TYPE_UNKNOWN;
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index fe4a83b..9dcdf22 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -22,13 +22,9 @@
 import static com.android.app.animation.Interpolators.FINAL_FRAME;
 import static com.android.app.animation.Interpolators.INSTANT;
 import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.app.animation.Interpolators.clampToProgress;
-import static com.android.app.animation.Interpolators.mapToProgress;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
-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_ALL_APPS_KEYBOARD_FADE;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
@@ -37,15 +33,12 @@
 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.app.animation.Interpolators;
 import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.states.StateAnimationConfig;
@@ -281,36 +274,6 @@
         }
     }
 
-    /**
-     * 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.animProps |= StateAnimationConfig.USER_CONTROLLED;
-        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 {
-            // Pop the background panel, keyboard, and content in at full opacity at the threshold.
-            config.setInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE,
-                    thresholdInterpolator(threshold, INSTANT));
-            config.setInterpolator(ANIM_ALL_APPS_KEYBOARD_FADE,
-                    thresholdInterpolator(threshold, INSTANT));
-            config.setInterpolator(ANIM_ALL_APPS_FADE, thresholdInterpolator(threshold, INSTANT));
-
-            config.setInterpolator(ANIM_VERTICAL_PROGRESS,
-                    thresholdInterpolator(threshold, mapToProgress(LINEAR, threshold, 1f)));
-        }
-    }
-
     /** 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/StableViewInfo.kt b/src/com/android/launcher3/util/StableViewInfo.kt
new file mode 100644
index 0000000..29dcd59
--- /dev/null
+++ b/src/com/android/launcher3/util/StableViewInfo.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+package com.android.launcher3.util
+
+import android.os.IBinder
+import com.android.launcher3.model.data.ItemInfo
+import com.android.launcher3.model.data.ItemInfo.NO_ID
+
+/** Info parameters that can be used to identify a Launcher object */
+data class StableViewInfo(val itemId: Int, val containerId: Int, val stableId: Any) {
+
+    fun matches(info: ItemInfo?) =
+        info != null &&
+            itemId == info.id &&
+            containerId == info.container &&
+            stableId == info.stableId
+
+    companion object {
+
+        private fun ItemInfo.toStableViewInfo() =
+            stableId?.let { sId ->
+                if (id != NO_ID || container != NO_ID) StableViewInfo(id, container, sId) else null
+            }
+
+        /**
+         * Return a new launch cookie for the activity launch if supported.
+         *
+         * @param info the item info for the launch
+         */
+        @JvmStatic
+        fun toLaunchCookie(info: ItemInfo?) =
+            info?.toStableViewInfo()?.let { ObjectWrapper.wrap(it) }
+
+        /**
+         * Unwraps the binder and returns the first non-null StableViewInfo in the list or null if
+         * none can be found
+         */
+        @JvmStatic
+        fun fromLaunchCookies(launchCookies: List<IBinder>) =
+            launchCookies.firstNotNullOfOrNull { ObjectWrapper.unwrap<StableViewInfo>(it) }
+    }
+}
diff --git a/src/com/android/launcher3/views/FloatingSurfaceView.java b/src/com/android/launcher3/views/FloatingSurfaceView.java
index 7fa7517..5f8e2c0 100644
--- a/src/com/android/launcher3/views/FloatingSurfaceView.java
+++ b/src/com/android/launcher3/views/FloatingSurfaceView.java
@@ -15,7 +15,6 @@
  */
 package com.android.launcher3.views;
 
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
 import static com.android.launcher3.views.FloatingIconView.getLocationBoundsForView;
 import static com.android.launcher3.views.FloatingIconViewCompanion.setPropertiesVisible;
 
@@ -160,7 +159,7 @@
         if (mContract == null) {
             return;
         }
-        View icon = mLauncher.getFirstMatchForAppClose(NO_MATCHING_ID,
+        View icon = mLauncher.getFirstMatchForAppClose(null /* StableViewInfo */,
                 mContract.componentName.getPackageName(), mContract.user,
                 false /* supportsAllAppsState */);