Merge "Add flag to enable SettingsBackupAgent to collect B&R agent metrics." into main
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0268b5b..a4d8a5c 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6767,19 +6767,6 @@
         }
 
         /**
-         * Construct a RemoteViews for the ambient version of the notification.
-         *
-         * @hide
-         */
-        public RemoteViews makeAmbientNotification() {
-            RemoteViews headsUpContentView = createHeadsUpContentView(false /* increasedHeight */);
-            if (headsUpContentView != null) {
-                return headsUpContentView;
-            }
-            return createContentView();
-        }
-
-        /**
          * Adapt the Notification header if this view is used as an expanded view.
          *
          * @hide
diff --git a/core/java/android/view/LetterboxScrollProcessor.java b/core/java/android/view/LetterboxScrollProcessor.java
index 1364a82..8c1b0f8 100644
--- a/core/java/android/view/LetterboxScrollProcessor.java
+++ b/core/java/android/view/LetterboxScrollProcessor.java
@@ -78,6 +78,11 @@
     @Nullable
     @VisibleForTesting(visibility = PACKAGE)
     public List<MotionEvent> processMotionEvent(@NonNull MotionEvent motionEvent) {
+        if (!motionEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
+            // This is a non-pointer event that doesn't correspond to any location on the screen.
+            // Ignore it.
+            return null;
+        }
         mProcessedEvents.clear();
         final Rect appBounds = getAppBounds();
 
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index f690bd3..92f9e60 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -20,9 +20,13 @@
 
 import android.annotation.Nullable;
 import android.app.AlertDialog;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.pm.PackageManager;
 import android.content.res.TypedArray;
 import android.database.Cursor;
 import android.graphics.drawable.Drawable;
@@ -58,6 +62,7 @@
 import android.widget.ScrollView;
 import android.widget.SimpleCursorAdapter;
 import android.widget.TextView;
+import android.widget.flags.Flags;
 
 import com.android.internal.R;
 
@@ -66,6 +71,12 @@
 public class AlertController {
     public static final int MICRO = 1;
 
+    private static boolean sUseWearMaterial3Style;
+
+    @ChangeId
+    @EnabledSince(targetSdkVersion = 36)
+    private static final long WEAR_MATERIAL3_ALERTDIALOG = 379365266L;
+
     private final Context mContext;
     private final DialogInterface mDialogInterface;
     protected final Window mWindow;
@@ -210,7 +221,8 @@
         mHandler = new ButtonHandler(di);
 
         final TypedArray a = context.obtainStyledAttributes(null,
-                R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);
+                R.styleable.AlertDialog, getAlertDialogDefStyleAttr(context),
+                getAlertDialogDefStyleRes());
 
         mAlertDialogLayout = a.getResourceId(
                 R.styleable.AlertDialog_layout, R.layout.alert_dialog);
@@ -236,6 +248,28 @@
         window.requestFeature(Window.FEATURE_NO_TITLE);
     }
 
+    private int getAlertDialogDefStyleAttr(Context context) {
+        sUseWearMaterial3Style = useWearMaterial3Style(context);
+        if (sUseWearMaterial3Style) {
+            return 0;
+        }
+        return R.attr.alertDialogStyle;
+    }
+
+    private int getAlertDialogDefStyleRes() {
+        if (sUseWearMaterial3Style) {
+            return com.android.internal.R.style.AlertDialog_DeviceDefault_WearMaterial3;
+        }
+        return 0;
+    }
+
+    private static boolean useWearMaterial3Style(Context context) {
+        return Flags.useWearMaterial3Ui()
+                && CompatChanges.isChangeEnabled(WEAR_MATERIAL3_ALERTDIALOG)
+                && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
+                && context.getThemeResId() == com.android.internal.R.style.Theme_DeviceDefault;
+    }
+
     static boolean canTextInput(View v) {
         if (v.onCheckIsTextEditor()) {
             return true;
diff --git a/core/res/res/layout-watch-v36/alert_dialog_material.xml b/core/res/res/layout-watch-v36/alert_dialog_wear_material3.xml
similarity index 100%
rename from core/res/res/layout-watch-v36/alert_dialog_material.xml
rename to core/res/res/layout-watch-v36/alert_dialog_wear_material3.xml
diff --git a/core/res/res/values-watch-v36/styles_material.xml b/core/res/res/values-watch-v36/styles_material.xml
index 20f4095..fc9f669 100644
--- a/core/res/res/values-watch-v36/styles_material.xml
+++ b/core/res/res/values-watch-v36/styles_material.xml
@@ -57,6 +57,10 @@
     </style>
 
     <!--  AlertDialog Styles  -->
+    <style name="AlertDialog.DeviceDefault.WearMaterial3">
+        <item name="layout">@layout/alert_dialog_wear_material3</item>
+    </style>
+
     <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3" parent="Widget.DeviceDefault.Button">
         <item name="android:textSize">0sp</item>
         <item name="android:gravity">center</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 748f4b3..380b297 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -5824,5 +5824,8 @@
   <!-- Style for Wear Material3 Button. Will only be used for sdk 36 or above. -->
   <java-symbol type="style" name="Widget.DeviceDefault.Button.WearMaterial3" />
 
+  <!-- Style for Wear Material3 AlertDialog. Will only be used for sdk 36 or above. -->
+  <java-symbol type="style" name="AlertDialog.DeviceDefault.WearMaterial3" />
+
   <java-symbol type="bool" name="config_allowNormalBrightnessForDozePolicy" />
 </resources>
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index 8f9730a..6fdd73a 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -50,6 +50,7 @@
             android:name="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
             android:label="@string/action_bar_label"
             android:exported="true"
+            android:enableOnBackInvokedCallback="false"
             android:permission="android.permission.MODIFY_PHONE_STATE"
             android:theme="@style/AppTheme"
             android:configChanges="keyboardHidden|orientation|screenSize">
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index 68443a7..e029f3a 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -81,10 +81,12 @@
             android:exported="false" />
 
         <activity android:name=".PackageInstallerActivity"
-                android:exported="false" />
+                android:exported="false"
+                android:enableOnBackInvokedCallback="false" />
 
         <activity android:name=".InstallInstalling"
-                android:exported="false" />
+                android:exported="false"
+                android:enableOnBackInvokedCallback="false" />
 
         <receiver android:name=".common.InstallEventReceiver"
                 android:permission="android.permission.INSTALL_PACKAGES"
@@ -138,6 +140,7 @@
 
         <activity android:name=".UninstallUninstalling"
             android:excludeFromRecents="true"
+            android:enableOnBackInvokedCallback="false"
             android:exported="false" />
 
         <receiver android:name=".UninstallFinish"
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
index a3709c1..366d54b 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
@@ -136,6 +136,13 @@
     /** Returns the preference widget object associated with given key. */
     abstract fun <T> findPreference(key: String): T?
 
+    /**
+     * Returns the preference widget object associated with given key.
+     *
+     * @throws NullPointerException if preference is not found
+     */
+    abstract fun <T : Any> requirePreference(key: String): T
+
     /** Notifies that preference state of given key is changed and updates preference widget UI. */
     abstract fun notifyPreferenceChange(key: String)
 
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
index 7cec59c..153089e 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
@@ -60,6 +60,8 @@
             override fun <T> findPreference(key: String) =
                 preferenceScreen.findPreference(key) as T?
 
+            override fun <T : Any> requirePreference(key: String) = findPreference<T>(key)!!
+
             override fun notifyPreferenceChange(key: String) =
                 notifyChange(key, CHANGE_REASON_STATE)
 
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 0d654d9..e6d9dc1 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -156,13 +156,6 @@
 }
 
 flag {
-    name: "notifications_improved_hun_animation"
-    namespace: "systemui"
-    description: "Adds a translateY animation, and other improvements to match the motion specs of the HUN Intro + Outro animations."
-    bug: "243302608"
-}
-
-flag {
     name: "notification_content_alpha_optimization"
     namespace: "systemui"
     description: "Only reset alpha values of needed content views"
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index cf0ba51..7a8d20a 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:Suppress("NOTHING_TO_INLINE")
-
 package com.android.compose.animation.scene
 
 import androidx.compose.foundation.gestures.Orientation
@@ -97,68 +95,11 @@
     internal val positionalThreshold
         get() = with(layoutImpl.density) { 56.dp.toPx() }
 
-    /**
-     * Whether we should immediately intercept a gesture.
-     *
-     * Note: if this returns true, then [onDragStarted] will be called with overSlop equal to 0f,
-     * indicating that the transition should be intercepted.
-     */
-    internal fun shouldImmediatelyIntercept(pointersDown: PointersInfo.PointersDown?): Boolean {
-        // We don't intercept the touch if we are not currently driving the transition.
-        val dragController = dragController
-        if (dragController?.isDrivingTransition != true) {
-            return false
-        }
-
-        val swipeAnimation = dragController.swipeAnimation
-
-        // Only intercept the current transition if one of the 2 swipes results is also a transition
-        // between the same pair of contents.
-        val swipes = computeSwipes(pointersDown)
-        val fromContent = layoutImpl.content(swipeAnimation.currentContent)
-        val (upOrLeft, downOrRight) = swipes.computeSwipesResults(fromContent)
-        val currentScene = layoutImpl.state.currentScene
-        val contentTransition = swipeAnimation.contentTransition
-        return (upOrLeft != null &&
-            contentTransition.isTransitioningBetween(
-                fromContent.key,
-                upOrLeft.toContent(currentScene),
-            )) ||
-            (downOrRight != null &&
-                contentTransition.isTransitioningBetween(
-                    fromContent.key,
-                    downOrRight.toContent(currentScene),
-                ))
-    }
-
     override fun onDragStarted(
         pointersDown: PointersInfo.PointersDown?,
         overSlop: Float,
     ): DragController {
-        if (overSlop == 0f) {
-            val oldDragController = dragController
-            check(oldDragController != null && oldDragController.isDrivingTransition) {
-                val isActive = oldDragController?.isDrivingTransition
-                "onDragStarted(overSlop=0f) requires an active dragController, but was $isActive"
-            }
-
-            // This [transition] was already driving the animation: simply take over it.
-            // Stop animating and start from the current offset.
-            val oldSwipeAnimation = oldDragController.swipeAnimation
-
-            // We need to recompute the swipe results since this is a new gesture, and the
-            // fromScene.userActions may have changed.
-            val swipes = oldDragController.swipes
-            swipes.updateSwipesResults(
-                fromContent = layoutImpl.content(oldSwipeAnimation.fromContent)
-            )
-
-            // A new gesture should always create a new SwipeAnimation. This way there cannot be
-            // different gestures controlling the same transition.
-            val swipeAnimation = createSwipeAnimation(oldSwipeAnimation)
-            return updateDragController(swipes, swipeAnimation)
-        }
-
+        check(overSlop != 0f)
         val swipes = computeSwipes(pointersDown)
         val fromContent = layoutImpl.contentForUserActions()
 
@@ -196,7 +137,7 @@
         return createSwipeAnimation(layoutImpl, result, isUpOrLeft, orientation)
     }
 
-    internal fun resolveSwipeSource(startedPosition: Offset): SwipeSource.Resolved? {
+    private fun resolveSwipeSource(startedPosition: Offset): SwipeSource.Resolved? {
         return layoutImpl.swipeSourceDetector.source(
             layoutSize = layoutImpl.lastSize,
             position = startedPosition.round(),
@@ -291,71 +232,25 @@
             return 0f
         }
 
-        val toContent = swipeAnimation.toContent
         val distance = swipeAnimation.distance()
         val previousOffset = swipeAnimation.dragOffset
         val desiredOffset = previousOffset + delta
+        val desiredProgress = swipeAnimation.computeProgress(desiredOffset)
 
-        fun hasReachedToSceneUpOrLeft() =
-            distance < 0 &&
-                desiredOffset <= distance &&
-                swipes.upOrLeftResult?.toContent(layoutState.currentScene) == toContent
+        // Note: the distance could be negative if fromContent is above or to the left of
+        // toContent.
+        val newOffset =
+            when {
+                distance == DistanceUnspecified ||
+                    swipeAnimation.contentTransition.isWithinProgressRange(desiredProgress) ->
+                    desiredOffset
+                distance > 0f -> desiredOffset.fastCoerceIn(0f, distance)
+                else -> desiredOffset.fastCoerceIn(distance, 0f)
+            }
 
-        fun hasReachedToSceneDownOrRight() =
-            distance > 0 &&
-                desiredOffset >= distance &&
-                swipes.downOrRightResult?.toContent(layoutState.currentScene) == toContent
+        val consumedDelta = newOffset - previousOffset
 
-        // Considering accelerated swipe: Change fromContent in the case where the user quickly
-        // swiped multiple times in the same direction to accelerate the transition from A => B then
-        // B => C.
-        //
-        // TODO(b/290184746): the second drag needs to pass B to work. Add support for flinging
-        //  twice before B has been reached
-        val hasReachedToContent =
-            swipeAnimation.currentContent == toContent &&
-                (hasReachedToSceneUpOrLeft() || hasReachedToSceneDownOrRight())
-
-        val fromContent: ContentKey
-        val currentTransitionOffset: Float
-        val newOffset: Float
-        val consumedDelta: Float
-        if (hasReachedToContent) {
-            // The new transition will start from the current toContent.
-            fromContent = toContent
-
-            // The current transition is completed (we have reached the full swipe distance).
-            currentTransitionOffset = distance
-
-            // The next transition will start with the remaining offset.
-            newOffset = desiredOffset - distance
-            consumedDelta = delta
-        } else {
-            fromContent = swipeAnimation.fromContent
-            val desiredProgress = swipeAnimation.computeProgress(desiredOffset)
-
-            // Note: the distance could be negative if fromContent is above or to the left of
-            // toContent.
-            currentTransitionOffset =
-                when {
-                    distance == DistanceUnspecified ||
-                        swipeAnimation.contentTransition.isWithinProgressRange(desiredProgress) ->
-                        desiredOffset
-
-                    distance > 0f -> desiredOffset.fastCoerceIn(0f, distance)
-                    else -> desiredOffset.fastCoerceIn(distance, 0f)
-                }
-
-            // If there is a new transition, we will use the same offset
-            newOffset = currentTransitionOffset
-            consumedDelta = newOffset - previousOffset
-        }
-
-        swipeAnimation.dragOffset = currentTransitionOffset
-
-        if (hasReachedToContent) {
-            swipes.updateSwipesResults(draggableHandler.layoutImpl.content(fromContent))
-        }
+        swipeAnimation.dragOffset = newOffset
         val result = swipes.findUserActionResult(directionOffset = newOffset)
 
         if (result == null) {
@@ -372,13 +267,12 @@
 
         val needNewTransition =
             !currentTransitionIrreversible &&
-                (hasReachedToContent ||
-                    result.toContent(layoutState.currentScene) != swipeAnimation.toContent ||
+                (result.toContent(layoutState.currentScene) != swipeAnimation.toContent ||
                     result.transitionKey != swipeAnimation.contentTransition.key)
 
         if (needNewTransition) {
             // Make sure the current transition will finish to the right current scene.
-            swipeAnimation.currentContent = fromContent
+            swipeAnimation.currentContent = swipeAnimation.fromContent
 
             val newSwipeAnimation = draggableHandler.createSwipeAnimation(swipes, result)
             newSwipeAnimation.dragOffset = newOffset
@@ -499,7 +393,9 @@
     var upOrLeftResult: UserActionResult? = null
     var downOrRightResult: UserActionResult? = null
 
-    fun computeSwipesResults(fromContent: Content): Pair<UserActionResult?, UserActionResult?> {
+    private fun computeSwipesResults(
+        fromContent: Content
+    ): Pair<UserActionResult?, UserActionResult?> {
         val upOrLeftResult = fromContent.findActionResultBestMatch(swipe = upOrLeft)
         val downOrRightResult = fromContent.findActionResultBestMatch(swipe = downOrRight)
         return upOrLeftResult to downOrRightResult
@@ -564,48 +460,9 @@
                 .shouldEnableSwipes(draggableHandler.orientation)
         }
 
-        var isIntercepting = false
-
         return PriorityNestedScrollConnection(
             orientation = draggableHandler.orientation,
-            canStartPreScroll = { offsetAvailable, offsetBeforeStart, _ ->
-                val pointersDown: PointersInfo.PointersDown? =
-                    when (val info = pointersInfoOwner.pointersInfo()) {
-                        PointersInfo.MouseWheel -> {
-                            // Do not support mouse wheel interactions
-                            return@PriorityNestedScrollConnection false
-                        }
-
-                        is PointersInfo.PointersDown -> info
-                        null -> null
-                    }
-
-                canChangeScene =
-                    if (isExternalOverscrollGesture()) false else offsetBeforeStart == 0f
-
-                val canInterceptSwipeTransition =
-                    canChangeScene &&
-                        offsetAvailable != 0f &&
-                        draggableHandler.shouldImmediatelyIntercept(pointersDown)
-                if (!canInterceptSwipeTransition) return@PriorityNestedScrollConnection false
-
-                val layoutImpl = draggableHandler.layoutImpl
-                val threshold = layoutImpl.transitionInterceptionThreshold
-                val hasSnappedToIdle = layoutImpl.state.snapToIdleIfClose(threshold)
-                if (hasSnappedToIdle) {
-                    // If the current swipe transition is closed to 0f or 1f, then we want to
-                    // interrupt the transition (snapping it to Idle) and scroll the list.
-                    return@PriorityNestedScrollConnection false
-                }
-
-                lastPointersDown = pointersDown
-
-                // If the current swipe transition is *not* closed to 0f or 1f, then we want the
-                // scroll events to intercept the current transition to continue the scene
-                // transition.
-                isIntercepting = true
-                true
-            },
+            canStartPreScroll = { _, _, _ -> false },
             canStartPostScroll = { offsetAvailable, offsetBeforeStart, _ ->
                 val behavior: NestedScrollBehavior =
                     when {
@@ -629,29 +486,22 @@
                     }
                 lastPointersDown = pointersDown
 
-                val canStart =
-                    when (behavior) {
-                        NestedScrollBehavior.EdgeNoPreview -> {
-                            canChangeScene = isZeroOffset
-                            isZeroOffset && shouldEnableSwipes()
-                        }
-
-                        NestedScrollBehavior.EdgeWithPreview -> {
-                            canChangeScene = isZeroOffset
-                            shouldEnableSwipes()
-                        }
-
-                        NestedScrollBehavior.EdgeAlways -> {
-                            canChangeScene = true
-                            shouldEnableSwipes()
-                        }
+                when (behavior) {
+                    NestedScrollBehavior.EdgeNoPreview -> {
+                        canChangeScene = isZeroOffset
+                        isZeroOffset && shouldEnableSwipes()
                     }
 
-                if (canStart) {
-                    isIntercepting = false
-                }
+                    NestedScrollBehavior.EdgeWithPreview -> {
+                        canChangeScene = isZeroOffset
+                        shouldEnableSwipes()
+                    }
 
-                canStart
+                    NestedScrollBehavior.EdgeAlways -> {
+                        canChangeScene = true
+                        shouldEnableSwipes()
+                    }
+                }
             },
             canStartPostFling = { velocityAvailable ->
                 val behavior: NestedScrollBehavior =
@@ -676,19 +526,14 @@
                     }
                 lastPointersDown = pointersDown
 
-                val canStart = behavior.canStartOnPostFling && shouldEnableSwipes()
-                if (canStart) {
-                    isIntercepting = false
-                }
-
-                canStart
+                behavior.canStartOnPostFling && shouldEnableSwipes()
             },
             onStart = { firstScroll ->
                 scrollController(
                     dragController =
                         draggableHandler.onDragStarted(
                             pointersDown = lastPointersDown,
-                            overSlop = if (isIntercepting) 0f else firstScroll,
+                            overSlop = firstScroll,
                         ),
                     canChangeScene = canChangeScene,
                     pointersInfoOwner = pointersInfoOwner,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
index 501fbb0..f5f01d4 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
@@ -80,7 +80,6 @@
 @Stable
 internal fun Modifier.multiPointerDraggable(
     orientation: Orientation,
-    startDragImmediately: (pointersDown: PointersInfo.PointersDown) -> Boolean,
     onDragStarted: (pointersDown: PointersInfo.PointersDown, overSlop: Float) -> DragController,
     onFirstPointerDown: () -> Unit = {},
     swipeDetector: SwipeDetector = DefaultSwipeDetector,
@@ -89,7 +88,6 @@
     this.then(
         MultiPointerDraggableElement(
             orientation,
-            startDragImmediately,
             onDragStarted,
             onFirstPointerDown,
             swipeDetector,
@@ -99,7 +97,6 @@
 
 private data class MultiPointerDraggableElement(
     private val orientation: Orientation,
-    private val startDragImmediately: (pointersDown: PointersInfo.PointersDown) -> Boolean,
     private val onDragStarted:
         (pointersDown: PointersInfo.PointersDown, overSlop: Float) -> DragController,
     private val onFirstPointerDown: () -> Unit,
@@ -109,7 +106,6 @@
     override fun create(): MultiPointerDraggableNode =
         MultiPointerDraggableNode(
             orientation = orientation,
-            startDragImmediately = startDragImmediately,
             onDragStarted = onDragStarted,
             onFirstPointerDown = onFirstPointerDown,
             swipeDetector = swipeDetector,
@@ -118,7 +114,6 @@
 
     override fun update(node: MultiPointerDraggableNode) {
         node.orientation = orientation
-        node.startDragImmediately = startDragImmediately
         node.onDragStarted = onDragStarted
         node.onFirstPointerDown = onFirstPointerDown
         node.swipeDetector = swipeDetector
@@ -127,7 +122,6 @@
 
 internal class MultiPointerDraggableNode(
     orientation: Orientation,
-    var startDragImmediately: (pointersDown: PointersInfo.PointersDown) -> Boolean,
     var onDragStarted: (pointersDown: PointersInfo.PointersDown, overSlop: Float) -> DragController,
     var onFirstPointerDown: () -> Unit,
     swipeDetector: SwipeDetector = DefaultSwipeDetector,
@@ -293,7 +287,6 @@
                 try {
                     detectDragGestures(
                         orientation = orientation,
-                        startDragImmediately = startDragImmediately,
                         onDragStart = { pointersDown, overSlop ->
                             onDragStarted(pointersDown, overSlop)
                         },
@@ -434,13 +427,11 @@
      * Detect drag gestures in the given [orientation].
      *
      * This function is a mix of [androidx.compose.foundation.gestures.awaitDownAndSlop] and
-     * [androidx.compose.foundation.gestures.detectVerticalDragGestures] to add support for:
-     * 1) starting the gesture immediately without requiring a drag >= touch slope;
-     * 2) passing the number of pointers down to [onDragStart].
+     * [androidx.compose.foundation.gestures.detectVerticalDragGestures] to add support for passing
+     * the number of pointers down to [onDragStart].
      */
     private suspend fun AwaitPointerEventScope.detectDragGestures(
         orientation: Orientation,
-        startDragImmediately: (pointersDown: PointersInfo.PointersDown) -> Boolean,
         onDragStart: (pointersDown: PointersInfo.PointersDown, overSlop: Float) -> DragController,
         onDrag: (controller: DragController, dragAmount: Float) -> Unit,
         onDragEnd: (controller: DragController) -> Unit,
@@ -466,71 +457,49 @@
                 .first()
 
         var overSlop = 0f
-        var lastPointersDown: PointersInfo.PointersDown =
+        val onSlopReached = { change: PointerInputChange, over: Float ->
+            if (swipeDetector.detectSwipe(change)) {
+                change.consume()
+                overSlop = over
+            }
+        }
+
+        // TODO(b/291055080): Replace by await[Orientation]PointerSlopOrCancellation once it
+        // is public.
+        val drag =
+            when (orientation) {
+                Orientation.Horizontal ->
+                    awaitHorizontalTouchSlopOrCancellation(consumablePointer.id, onSlopReached)
+                Orientation.Vertical ->
+                    awaitVerticalTouchSlopOrCancellation(consumablePointer.id, onSlopReached)
+            } ?: return
+
+        val lastPointersDown =
             checkNotNull(pointersInfo()) {
                 "We should have pointers down, last event: $currentEvent"
             }
                 as PointersInfo.PointersDown
-
-        val drag =
-            if (startDragImmediately(lastPointersDown)) {
-                consumablePointer.consume()
-                consumablePointer
-            } else {
-                val onSlopReached = { change: PointerInputChange, over: Float ->
-                    if (swipeDetector.detectSwipe(change)) {
-                        change.consume()
-                        overSlop = over
-                    }
+        // Make sure that overSlop is not 0f. This can happen when the user drags by exactly
+        // the touch slop. However, the overSlop we pass to onDragStarted() is used to
+        // compute the direction we are dragging in, so overSlop should never be 0f.
+        if (overSlop == 0f) {
+            // If the user drags in the opposite direction, the delta becomes zero because
+            // we return to the original point. Therefore, we should use the previous event
+            // to calculate the direction.
+            val delta = (drag.position - drag.previousPosition).toFloat()
+            check(delta != 0f) {
+                buildString {
+                    append("delta is equal to 0 ")
+                    append("touchSlop ${currentValueOf(LocalViewConfiguration).touchSlop} ")
+                    append("consumablePointer.position ${consumablePointer.position} ")
+                    append("drag.position ${drag.position} ")
+                    append("drag.previousPosition ${drag.previousPosition}")
                 }
-
-                // TODO(b/291055080): Replace by await[Orientation]PointerSlopOrCancellation once it
-                // is public.
-                val drag =
-                    when (orientation) {
-                        Orientation.Horizontal ->
-                            awaitHorizontalTouchSlopOrCancellation(
-                                consumablePointer.id,
-                                onSlopReached,
-                            )
-                        Orientation.Vertical ->
-                            awaitVerticalTouchSlopOrCancellation(
-                                consumablePointer.id,
-                                onSlopReached,
-                            )
-                    } ?: return
-
-                lastPointersDown =
-                    checkNotNull(pointersInfo()) {
-                        "We should have pointers down, last event: $currentEvent"
-                    }
-                        as PointersInfo.PointersDown
-                // Make sure that overSlop is not 0f. This can happen when the user drags by exactly
-                // the touch slop. However, the overSlop we pass to onDragStarted() is used to
-                // compute the direction we are dragging in, so overSlop should never be 0f unless
-                // we intercept an ongoing swipe transition (i.e. startDragImmediately() returned
-                // true).
-                if (overSlop == 0f) {
-                    // If the user drags in the opposite direction, the delta becomes zero because
-                    // we return to the original point. Therefore, we should use the previous event
-                    // to calculate the direction.
-                    val delta = (drag.position - drag.previousPosition).toFloat()
-                    check(delta != 0f) {
-                        buildString {
-                            append("delta is equal to 0 ")
-                            append("touchSlop ${currentValueOf(LocalViewConfiguration).touchSlop} ")
-                            append("consumablePointer.position ${consumablePointer.position} ")
-                            append("drag.position ${drag.position} ")
-                            append("drag.previousPosition ${drag.previousPosition}")
-                        }
-                    }
-                    overSlop = delta.sign
-                }
-                drag
             }
+            overSlop = delta.sign
+        }
 
         val controller = onDragStart(lastPointersDown, overSlop)
-
         val successful: Boolean
         try {
             onDrag(controller, overSlop)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
index 5ab306a..6ef8b86 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
@@ -149,7 +149,6 @@
         delegate(
             MultiPointerDraggableNode(
                 orientation = draggableHandler.orientation,
-                startDragImmediately = ::startDragImmediately,
                 onDragStarted = draggableHandler::onDragStarted,
                 onFirstPointerDown = ::onFirstPointerDown,
                 swipeDetector = swipeDetector,
@@ -198,21 +197,6 @@
     ) = multiPointerDraggableNode.onPointerEvent(pointerEvent, pass, bounds)
 
     override fun onCancelPointerInput() = multiPointerDraggableNode.onCancelPointerInput()
-
-    private fun startDragImmediately(pointersDown: PointersInfo.PointersDown): Boolean {
-        // Immediately start the drag if the user can't swipe in the other direction and the gesture
-        // handler can intercept it.
-        return !canOppositeSwipe() && draggableHandler.shouldImmediatelyIntercept(pointersDown)
-    }
-
-    private fun canOppositeSwipe(): Boolean {
-        val oppositeOrientation =
-            when (draggableHandler.orientation) {
-                Orientation.Vertical -> Orientation.Horizontal
-                Orientation.Horizontal -> Orientation.Vertical
-            }
-        return draggableHandler.contentForSwipes().shouldEnableSwipes(oppositeOrientation)
-    }
 }
 
 /** Find the [ScrollBehaviorOwner] for the current orientation. */
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index a1077cf..394568d 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -234,12 +234,6 @@
             )
         }
 
-        fun onDragStartedImmediately(
-            pointersInfo: PointersInfo.PointersDown = pointersDown()
-        ): DragController {
-            return onDragStarted(draggableHandler, pointersInfo, overSlop = 0f)
-        }
-
         fun onDragStarted(
             draggableHandler: DraggableHandler,
             pointersInfo: PointersInfo.PointersDown = pointersDown(),
@@ -602,82 +596,6 @@
     }
 
     @Test
-    fun onAcceleratedScroll_scrollToThirdScene() = runGestureTest {
-        // Drag A -> B with progress 0.2
-        val dragController1 = onDragStarted(overSlop = up(fractionOfScreen = 0.2f))
-        assertTransition(
-            currentScene = SceneA,
-            fromScene = SceneA,
-            toScene = SceneB,
-            progress = 0.2f,
-        )
-
-        // Start animation A -> B with progress 0.2 -> 1.0
-        dragController1.onDragStoppedAnimateLater(velocity = -velocityThreshold)
-        assertTransition(currentScene = SceneB, fromScene = SceneA, toScene = SceneB)
-
-        // While at A -> B do a 100% screen drag (progress 1.2). This should go past B and change
-        // the transition to B -> C with progress 0.2
-        val dragController2 = onDragStartedImmediately()
-        dragController2.onDragDelta(pixels = up(fractionOfScreen = 1f))
-        assertTransition(
-            currentScene = SceneB,
-            fromScene = SceneB,
-            toScene = SceneC,
-            progress = 0.2f,
-        )
-
-        // After the drag stopped scene C should be committed
-        dragController2.onDragStoppedAnimateNow(
-            velocity = -velocityThreshold,
-            onAnimationStart = {
-                assertTransition(currentScene = SceneC, fromScene = SceneB, toScene = SceneC)
-            },
-            expectedConsumedVelocity = -velocityThreshold,
-        )
-        assertIdle(currentScene = SceneC)
-    }
-
-    @Test
-    fun onAcceleratedScrollBothTargetsBecomeNull_settlesToIdle() = runGestureTest {
-        val dragController1 = onDragStarted(overSlop = up(fractionOfScreen = 0.2f))
-        dragController1.onDragDelta(pixels = up(fractionOfScreen = 0.2f))
-        dragController1.onDragStoppedAnimateLater(velocity = -velocityThreshold)
-        assertTransition(currentScene = SceneB, fromScene = SceneA, toScene = SceneB)
-
-        mutableUserActionsA = emptyMap()
-        mutableUserActionsB = emptyMap()
-
-        // start acceleratedScroll and scroll over to B -> null
-        val dragController2 = onDragStartedImmediately()
-        dragController2.onDragDelta(pixels = up(fractionOfScreen = 0.5f), expectedConsumed = 0f)
-        dragController2.onDragDelta(pixels = up(fractionOfScreen = 0.5f), expectedConsumed = 0f)
-
-        // here onDragStopped is already triggered, but subsequent onDelta/onDragStopped calls may
-        // still be called. Make sure that they don't crash or change the scene
-        dragController2.onDragDelta(pixels = up(fractionOfScreen = 0.5f), expectedConsumed = 0f)
-        dragController2.onDragStoppedAnimateNow(
-            velocity = 0f,
-            onAnimationStart = {
-                assertTransition(currentScene = SceneB, fromScene = SceneA, toScene = SceneB)
-            },
-            expectedConsumedVelocity = 0f,
-        )
-
-        advanceUntilIdle()
-        assertIdle(SceneB)
-
-        // These events can still come in after the animation has settled
-        dragController2.onDragDelta(pixels = up(fractionOfScreen = 0.5f), expectedConsumed = 0f)
-        dragController2.onDragStoppedAnimateNow(
-            velocity = 0f,
-            onAnimationStart = { assertIdle(SceneB) },
-            expectedConsumedVelocity = 0f,
-        )
-        assertIdle(SceneB)
-    }
-
-    @Test
     fun onDragTargetsChanged_targetStaysTheSame() = runGestureTest {
         val dragController1 = onDragStarted(overSlop = up(fractionOfScreen = 0.1f))
         assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.1f)
@@ -711,9 +629,8 @@
         dragController1.onDragStoppedAnimateLater(velocity = down(fractionOfScreen = 0.1f))
 
         // now target changed to C for new drag that started before previous drag settled to Idle
-        val dragController2 = onDragStartedImmediately()
-        dragController2.onDragDelta(pixels = up(fractionOfScreen = 0.1f))
-        assertTransition(fromScene = SceneA, toScene = SceneC, progress = 0.3f)
+        onDragStarted(overSlop = up(fractionOfScreen = 0.1f))
+        assertTransition(fromScene = SceneA, toScene = SceneC, progress = 0.1f)
     }
 
     @Test
@@ -728,7 +645,7 @@
         assertThat(isUserInputOngoing).isFalse()
 
         // Start a new gesture while the offset is animating
-        onDragStartedImmediately()
+        onDragStarted(overSlop = up(fractionOfScreen = 0.1f))
         assertThat(isUserInputOngoing).isTrue()
     }
 
@@ -812,36 +729,6 @@
     }
 
     @Test
-    fun scrollAndFling_scrollLessThanInterceptable_goToIdleOnCurrentScene() = runGestureTest {
-        val firstScroll = (transitionInterceptionThreshold - 0.0001f) * SCREEN_SIZE
-        val secondScroll = 1f
-
-        preScrollAfterSceneTransition(firstScroll = firstScroll, secondScroll = secondScroll)
-
-        assertIdle(SceneA)
-    }
-
-    @Test
-    fun scrollAndFling_scrollMinInterceptable_interceptPreScrollEvents() = runGestureTest {
-        val firstScroll = (transitionInterceptionThreshold + 0.0001f) * SCREEN_SIZE
-        val secondScroll = 1f
-
-        preScrollAfterSceneTransition(firstScroll = firstScroll, secondScroll = secondScroll)
-
-        assertTransition(progress = (firstScroll + secondScroll) / SCREEN_SIZE)
-    }
-
-    @Test
-    fun scrollAndFling_scrollMaxInterceptable_interceptPreScrollEvents() = runGestureTest {
-        val firstScroll = -(1f - transitionInterceptionThreshold - 0.0001f) * SCREEN_SIZE
-        val secondScroll = -1f
-
-        preScrollAfterSceneTransition(firstScroll = firstScroll, secondScroll = secondScroll)
-
-        assertTransition(progress = -(firstScroll + secondScroll) / SCREEN_SIZE)
-    }
-
-    @Test
     fun scrollAndFling_scrollMoreThanInterceptable_goToIdleOnNextScene() = runGestureTest {
         val firstScroll = -(1f - transitionInterceptionThreshold + 0.0001f) * SCREEN_SIZE
         val secondScroll = -0.01f
@@ -1025,7 +912,7 @@
 
         // now we can intercept the scroll events
         nestedScroll.scroll(available = -offsetY10)
-        assertThat(progress).isEqualTo(0.2f)
+        assertThat(progress).isEqualTo(0.1f)
 
         // this should be ignored, we are scrolling now!
         dragController.onDragStoppedAnimateNow(
@@ -1036,10 +923,10 @@
         assertTransition(currentScene = SceneA)
 
         nestedScroll.scroll(available = -offsetY10)
-        assertThat(progress).isEqualTo(0.3f)
+        assertThat(progress).isEqualTo(0.2f)
 
         nestedScroll.scroll(available = -offsetY10)
-        assertThat(progress).isEqualTo(0.4f)
+        assertThat(progress).isEqualTo(0.3f)
 
         nestedScroll.preFling(available = Velocity(0f, -velocityThreshold))
         assertTransition(currentScene = SceneB)
@@ -1050,57 +937,6 @@
     }
 
     @Test
-    fun interceptTransition() = runGestureTest {
-        // Start at scene C.
-        navigateToSceneC()
-
-        // Swipe up from the middle to transition to scene B.
-        val middle = pointersDown(startedPosition = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f))
-        onDragStarted(pointersInfo = middle, overSlop = up(0.1f))
-        assertTransition(
-            currentScene = SceneC,
-            fromScene = SceneC,
-            toScene = SceneB,
-            progress = 0.1f,
-            isUserInputOngoing = true,
-        )
-
-        val firstTransition = transitionState
-
-        // During the current gesture, start a new gesture, still in the middle of the screen. We
-        // should intercept it. Because it is intercepted, the overSlop passed to onDragStarted()
-        // should be 0f.
-        assertThat(draggableHandler.shouldImmediatelyIntercept(middle)).isTrue()
-        onDragStartedImmediately(pointersInfo = middle)
-
-        // We should have intercepted the transition, so the transition should be the same object.
-        assertTransition(
-            currentScene = SceneC,
-            fromScene = SceneC,
-            toScene = SceneB,
-            progress = 0.1f,
-            isUserInputOngoing = true,
-        )
-        // We should have a new transition
-        assertThat(transitionState).isNotSameInstanceAs(firstTransition)
-
-        // Start a new gesture from the bottom of the screen. Because swiping up from the bottom of
-        // C leads to scene A (and not B), the previous transitions is *not* intercepted and we
-        // instead animate from C to A.
-        val bottom = pointersDown(startedPosition = Offset(SCREEN_SIZE / 2, SCREEN_SIZE))
-        assertThat(draggableHandler.shouldImmediatelyIntercept(bottom)).isFalse()
-        onDragStarted(pointersInfo = bottom, overSlop = up(0.1f))
-
-        assertTransition(
-            currentScene = SceneC,
-            fromScene = SceneC,
-            toScene = SceneA,
-            isUserInputOngoing = true,
-        )
-        assertThat(transitionState).isNotSameInstanceAs(firstTransition)
-    }
-
-    @Test
     fun freezeAndAnimateToCurrentState() = runGestureTest {
         // Start at scene C.
         navigateToSceneC()
@@ -1110,9 +946,6 @@
         onDragStarted(pointersInfo = middle, overSlop = up(0.1f))
         assertTransition(fromScene = SceneC, toScene = SceneB, isUserInputOngoing = true)
 
-        // The current transition can be intercepted.
-        assertThat(draggableHandler.shouldImmediatelyIntercept(middle)).isTrue()
-
         // Freeze the transition.
         val transition = transitionState as Transition
         transition.freezeAndAnimateToCurrentState()
@@ -1123,19 +956,6 @@
     }
 
     @Test
-    fun interruptedTransitionCanNotBeImmediatelyIntercepted() = runGestureTest {
-        assertThat(draggableHandler.shouldImmediatelyIntercept(pointersDown = null)).isFalse()
-        onDragStarted(overSlop = up(0.1f))
-        assertThat(draggableHandler.shouldImmediatelyIntercept(pointersDown = null)).isTrue()
-
-        layoutState.startTransitionImmediately(
-            animationScope = testScope.backgroundScope,
-            transition(SceneA, SceneB),
-        )
-        assertThat(draggableHandler.shouldImmediatelyIntercept(pointersDown = null)).isFalse()
-    }
-
-    @Test
     fun blockTransition() = runGestureTest {
         assertIdle(SceneA)
 
@@ -1154,30 +974,6 @@
     }
 
     @Test
-    fun blockInterceptedTransition() = runGestureTest {
-        assertIdle(SceneA)
-
-        // Swipe up to B.
-        val dragController1 = onDragStarted(overSlop = up(0.1f))
-        assertTransition(currentScene = SceneA, fromScene = SceneA, toScene = SceneB)
-        dragController1.onDragStoppedAnimateLater(velocity = -velocityThreshold)
-        assertTransition(currentScene = SceneB, fromScene = SceneA, toScene = SceneB)
-
-        // Intercept the transition and swipe down back to scene A.
-        assertThat(draggableHandler.shouldImmediatelyIntercept(pointersDown = null)).isTrue()
-        val dragController2 = onDragStartedImmediately()
-
-        // Block the transition when the user release their finger.
-        canChangeScene = { false }
-        dragController2.onDragStoppedAnimateNow(
-            velocity = velocityThreshold,
-            onAnimationStart = { assertTransition(fromScene = SceneA, toScene = SceneB) },
-            expectedConsumedVelocity = velocityThreshold,
-        )
-        assertIdle(SceneB)
-    }
-
-    @Test
     fun scrollFromIdleWithNoTargetScene_shouldUseOverscrollSpecIfAvailable() = runGestureTest {
         layoutState.transitions = transitions {
             overscroll(SceneC, Orientation.Vertical) { fade(TestElements.Foo) }
@@ -1531,25 +1327,6 @@
     }
 
     @Test
-    fun interceptingTransitionKeepsDistance() = runGestureTest {
-        var swipeDistance = 75f
-        layoutState.transitions = transitions {
-            from(SceneA, to = SceneB) { distance = UserActionDistance { _, _, _ -> swipeDistance } }
-        }
-
-        // Start transition.
-        val controller = onDragStarted(overSlop = -50f)
-        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 50f / 75f)
-
-        // Intercept the transition and change the swipe distance. The original distance and
-        // progress should be the same.
-        swipeDistance = 50f
-        controller.onDragStoppedAnimateLater(0f)
-        onDragStartedImmediately()
-        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 50f / 75f)
-    }
-
-    @Test
     fun requireFullDistanceSwipe() = runGestureTest {
         mutableUserActionsA +=
             Swipe.Up to UserActionResult(SceneB, requiresFullDistanceSwipe = true)
@@ -1579,19 +1356,6 @@
     }
 
     @Test
-    fun interceptingTransitionReplacesCurrentTransition() = runGestureTest {
-        val controller = onDragStarted(overSlop = up(fractionOfScreen = 0.5f))
-        val transition = assertThat(layoutState.transitionState).isSceneTransition()
-        controller.onDragStoppedAnimateLater(velocity = 0f)
-
-        // Intercept the transition.
-        onDragStartedImmediately()
-        val newTransition = assertThat(layoutState.transitionState).isSceneTransition()
-        assertThat(newTransition).isNotSameInstanceAs(transition)
-        assertThat(newTransition.replacedTransition).isSameInstanceAs(transition)
-    }
-
-    @Test
     fun showOverlay() = runGestureTest {
         mutableUserActionsA = mapOf(Swipe.Down to UserActionResult.ShowOverlay(OverlayA))
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
index cb3e433..4153350 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
@@ -101,7 +101,6 @@
                     .thenIf(enabled) {
                         Modifier.multiPointerDraggable(
                             orientation = Orientation.Vertical,
-                            startDragImmediately = { false },
                             onDragStarted = { _, _ ->
                                 started = true
                                 SimpleDragController(
@@ -169,8 +168,6 @@
                     .nestedScrollDispatcher()
                     .multiPointerDraggable(
                         orientation = Orientation.Vertical,
-                        // We want to start a drag gesture immediately
-                        startDragImmediately = { true },
                         onDragStarted = { _, _ ->
                             started = true
                             SimpleDragController(
@@ -242,7 +239,6 @@
                     .nestedScrollDispatcher()
                     .multiPointerDraggable(
                         orientation = Orientation.Vertical,
-                        startDragImmediately = { false },
                         onDragStarted = { _, _ ->
                             started = true
                             SimpleDragController(
@@ -361,7 +357,6 @@
                     .nestedScrollDispatcher()
                     .multiPointerDraggable(
                         orientation = Orientation.Vertical,
-                        startDragImmediately = { false },
                         onDragStarted = { _, _ ->
                             started = true
                             SimpleDragController(
@@ -466,7 +461,6 @@
                     .nestedScrollDispatcher()
                     .multiPointerDraggable(
                         orientation = Orientation.Vertical,
-                        startDragImmediately = { false },
                         onDragStarted = { _, _ ->
                             verticalStarted = true
                             SimpleDragController(
@@ -478,7 +472,6 @@
                     )
                     .multiPointerDraggable(
                         orientation = Orientation.Horizontal,
-                        startDragImmediately = { false },
                         onDragStarted = { _, _ ->
                             horizontalStarted = true
                             SimpleDragController(
@@ -570,7 +563,6 @@
                     .nestedScrollDispatcher()
                     .multiPointerDraggable(
                         orientation = Orientation.Vertical,
-                        startDragImmediately = { false },
                         swipeDetector =
                             object : SwipeDetector {
                                 override fun detectSwipe(change: PointerInputChange): Boolean {
@@ -636,7 +628,6 @@
                     .nestedScrollDispatcher()
                     .multiPointerDraggable(
                         orientation = Orientation.Vertical,
-                        startDragImmediately = { false },
                         swipeDetector =
                             object : SwipeDetector {
                                 override fun detectSwipe(change: PointerInputChange): Boolean {
@@ -738,7 +729,6 @@
                     .nestedScrollDispatcher()
                     .multiPointerDraggable(
                         orientation = Orientation.Vertical,
-                        startDragImmediately = { false },
                         onDragStarted = { _, _ ->
                             SimpleDragController(
                                 onDrag = { consumedOnDrag = it },
@@ -809,7 +799,6 @@
                     .nestedScrollDispatcher()
                     .multiPointerDraggable(
                         orientation = Orientation.Vertical,
-                        startDragImmediately = { false },
                         onDragStarted = { _, _ ->
                             SimpleDragController(
                                 onDrag = { /* do nothing */ },
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 2b7e950..dcac294 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -3,7 +3,6 @@
 import android.annotation.DimenRes
 import android.content.pm.PackageManager
 import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
 import android.platform.test.flag.junit.FlagsParameterization
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
@@ -30,7 +29,6 @@
 import com.android.systemui.statusbar.notification.headsup.AvalancheController
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
-import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
 import com.google.common.truth.Expect
 import com.google.common.truth.Truth.assertThat
@@ -154,22 +152,6 @@
 
     @Test
     @DisableSceneContainer
-    fun resetViewStates_defaultHun_yTranslationIsInset() {
-        whenever(notificationRow.isPinned).thenReturn(true)
-        whenever(notificationRow.isHeadsUp).thenReturn(true)
-        resetViewStates_hunYTranslationIs(stackScrollAlgorithm.mHeadsUpInset)
-    }
-
-    @Test
-    @DisableSceneContainer
-    fun resetViewStates_defaultHunWithStackMargin_changesHunYTranslation() {
-        whenever(notificationRow.isPinned).thenReturn(true)
-        whenever(notificationRow.isHeadsUp).thenReturn(true)
-        resetViewStates_stackMargin_changesHunYTranslation()
-    }
-
-    @Test
-    @DisableSceneContainer
     fun resetViewStates_defaultHunWhenShadeIsOpening_yTranslationIsInset() {
         whenever(notificationRow.isPinned).thenReturn(true)
         whenever(notificationRow.isHeadsUp).thenReturn(true)
@@ -183,24 +165,7 @@
 
     @Test
     @DisableSceneContainer
-    @DisableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
-    fun resetViewStates_hunAnimatingAway_yTranslationIsInset() {
-        whenever(notificationRow.isHeadsUpAnimatingAway).thenReturn(true)
-        resetViewStates_hunYTranslationIs(stackScrollAlgorithm.mHeadsUpInset)
-    }
-
-    @Test
-    @DisableSceneContainer
-    @DisableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
-    fun resetViewStates_hunAnimatingAway_StackMarginChangesHunYTranslation() {
-        whenever(notificationRow.isHeadsUpAnimatingAway).thenReturn(true)
-        resetViewStates_stackMargin_changesHunYTranslation()
-    }
-
-    @Test
-    @DisableSceneContainer
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
-    fun resetViewStates_defaultHun_newHeadsUpAnim_yTranslationIsInset() {
+    fun resetViewStates_defaultHun_yTranslationIsInset() {
         whenever(notificationRow.isPinned).thenReturn(true)
         whenever(notificationRow.isHeadsUp).thenReturn(true)
         resetViewStates_hunYTranslationIs(stackScrollAlgorithm.mHeadsUpInset)
@@ -208,8 +173,7 @@
 
     @Test
     @DisableSceneContainer
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
-    fun resetViewStates_defaultHunWithStackMargin_newHeadsUpAnim_changesHunYTranslation() {
+    fun resetViewStates_defaultHunWithStackMargin_changesHunYTranslation() {
         whenever(notificationRow.isPinned).thenReturn(true)
         whenever(notificationRow.isHeadsUp).thenReturn(true)
         resetViewStates_stackMargin_changesHunYTranslation()
@@ -399,8 +363,7 @@
 
     @Test
     @DisableSceneContainer
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
-    fun resetViewStates_defaultHun_showingQS_newHeadsUpAnim_hunTranslatedToMax() {
+    fun resetViewStates_defaultHun_showingQS_hunTranslatedToMax() {
         // Given: the shade is open and scrolled to the bottom to show the QuickSettings
         val maxHunTranslation = 2000f
         ambientState.maxHeadsUpTranslation = maxHunTranslation
@@ -416,8 +379,7 @@
 
     @Test
     @DisableSceneContainer
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
-    fun resetViewStates_hunAnimatingAway_showingQS_newHeadsUpAnim_hunTranslatedToBottomOfScreen() {
+    fun resetViewStates_hunAnimatingAway_showingQS_hunTranslatedToBottomOfScreen() {
         // Given: the shade is open and scrolled to the bottom to show the QuickSettings
         val bottomOfScreen = 2600f
         val maxHunTranslation = 2000f
@@ -437,8 +399,7 @@
     }
 
     @Test
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
-    fun resetViewStates_hunAnimatingAway_newHeadsUpAnim_hunTranslatedToTopOfScreen() {
+    fun resetViewStates_hunAnimatingAway_hunTranslatedToTopOfScreen() {
         val topMargin = 100f
         ambientState.maxHeadsUpTranslation = 2000f
         ambientState.stackTopMargin = topMargin.toInt()
@@ -461,7 +422,6 @@
 
     @Test
     @DisableSceneContainer
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun resetViewStates_hunAnimatingAwayWhileDozing_yTranslationIsInset() {
         whenever(notificationRow.isHeadsUpAnimatingAway).thenReturn(true)
 
@@ -472,7 +432,6 @@
 
     @Test
     @DisableSceneContainer
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun resetViewStates_hunAnimatingAwayWhileDozing_hasStackMargin_changesHunYTranslation() {
         whenever(notificationRow.isHeadsUpAnimatingAway).thenReturn(true)
 
@@ -494,18 +453,6 @@
     }
 
     @Test
-    @DisableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
-    fun resetViewStates_hunsOverlappingAndBottomHunAnimatingAway_bottomHunClipped() {
-        val topHun = mockExpandableNotificationRow()
-        val bottomHun = mockExpandableNotificationRow()
-        whenever(topHun.isHeadsUp).thenReturn(true)
-        whenever(topHun.isPinned).thenReturn(true)
-        whenever(bottomHun.isHeadsUpAnimatingAway).thenReturn(true)
-
-        resetViewStates_hunsOverlapping_bottomHunClipped(topHun, bottomHun)
-    }
-
-    @Test
     @EnableSceneContainer
     fun resetViewStates_emptyShadeView_isCenteredVertically_withSceneContainer() {
         stackScrollAlgorithm.initView(context)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
index 798465e..e4dd29a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.notification.stack
 
-import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -24,7 +23,6 @@
 import com.android.systemui.animation.AnimatorTestRule
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.notification.row.ExpandableView
-import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_HEADS_UP_APPEAR
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_HEADS_UP_DISAPPEAR
@@ -60,11 +58,12 @@
     private val viewState: ExpandableViewState =
         ExpandableViewState().apply { height = VIEW_HEIGHT }
     private val runnableCaptor: ArgumentCaptor<Runnable> = argumentCaptor()
+
     @Before
     fun setUp() {
         overrideResource(
             R.dimen.go_to_full_shade_appearing_translation,
-            FULL_SHADE_APPEAR_TRANSLATION
+            FULL_SHADE_APPEAR_TRANSLATION,
         )
         overrideResource(R.dimen.heads_up_appear_y_above_screen, HEADS_UP_ABOVE_SCREEN)
 
@@ -74,7 +73,6 @@
     }
 
     @Test
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun startAnimationForEvents_headsUpFromTop_startsHeadsUpAppearAnim() {
         val topMargin = 50f
         val expectedStartY = -topMargin - stackStateAnimator.mHeadsUpAppearStartAboveScreen
@@ -90,12 +88,11 @@
                 /* delay= */ 0L,
                 /* duration= */ ANIMATION_DURATION_HEADS_UP_APPEAR.toLong(),
                 /* isHeadsUpAppear= */ true,
-                /* onEndRunnable= */ null
+                /* onEndRunnable= */ null,
             )
     }
 
     @Test
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun startAnimationForEvents_headsUpFromBottom_startsHeadsUpAppearAnim() {
         val screenHeight = 2000f
         val expectedStartY = screenHeight + stackStateAnimator.mHeadsUpAppearStartAboveScreen
@@ -114,12 +111,11 @@
                 /* delay= */ 0L,
                 /* duration= */ ANIMATION_DURATION_HEADS_UP_APPEAR.toLong(),
                 /* isHeadsUpAppear= */ true,
-                /* onEndRunnable= */ null
+                /* onEndRunnable= */ null,
             )
     }
 
     @Test
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun startAnimationForEvents_startsHeadsUpDisappearAnim() {
         val disappearDuration = ANIMATION_DURATION_HEADS_UP_DISAPPEAR.toLong()
         val event = AnimationEvent(view, AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
index 9f5a311..f91c5dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarOrchestrator.kt
@@ -242,10 +242,10 @@
 
     private fun updateBubblesVisibility(statusBarVisible: Boolean) {
         if (displayId != Display.DEFAULT_DISPLAY) {
+            // Bubbles are currently only supported on the default display.
             return
         }
         bubblesOptional.ifPresent { bubbles: Bubbles ->
-            // TODO(b/373311537): per display implementation of Bubbles
             bubbles.onStatusBarVisibilityChanged(statusBarVisible)
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
index 3b48b39..d0d2258 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/Roundable.kt
@@ -4,7 +4,6 @@
 import android.view.View
 import androidx.annotation.FloatRange
 import com.android.systemui.res.R
-import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation
 import com.android.systemui.statusbar.notification.stack.AnimationProperties
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator
 import kotlin.math.abs
@@ -39,15 +38,11 @@
 
     /** Current top corner in pixel, based on [topRoundness] and [maxRadius] */
     val topCornerRadius: Float
-        get() =
-            if (NotificationsImprovedHunAnimation.isEnabled) roundableState.topCornerRadius
-            else topRoundness * maxRadius
+        get() = roundableState.topCornerRadius
 
     /** Current bottom corner in pixel, based on [bottomRoundness] and [maxRadius] */
     val bottomCornerRadius: Float
-        get() =
-            if (NotificationsImprovedHunAnimation.isEnabled) roundableState.bottomCornerRadius
-            else bottomRoundness * maxRadius
+        get() = roundableState.bottomCornerRadius
 
     /** Get and update the current radii */
     val updatedRadii: FloatArray
@@ -123,7 +118,7 @@
         return requestTopRoundness(
             value = value,
             sourceType = sourceType,
-            animate = roundableState.targetView.isShown
+            animate = roundableState.targetView.isShown,
         )
     }
 
@@ -190,7 +185,7 @@
         return requestBottomRoundness(
             value = value,
             sourceType = sourceType,
-            animate = roundableState.targetView.isShown
+            animate = roundableState.targetView.isShown,
         )
     }
 
@@ -289,11 +284,7 @@
      *
      * This method reuses the previous [radii] for performance reasons.
      */
-    fun updateRadii(
-        topCornerRadius: Float,
-        bottomCornerRadius: Float,
-        radii: FloatArray,
-    ) {
+    fun updateRadii(topCornerRadius: Float, bottomCornerRadius: Float, radii: FloatArray) {
         if (radii.size != 8) error("Unexpected radiiBuffer size ${radii.size}")
 
         if (radii[0] != topCornerRadius || radii[4] != bottomCornerRadius) {
@@ -312,11 +303,7 @@
  */
 class RoundableState
 @JvmOverloads
-constructor(
-    internal val targetView: View,
-    private val roundable: Roundable,
-    maxRadius: Float,
-) {
+constructor(internal val targetView: View, private val roundable: Roundable, maxRadius: Float) {
     internal var maxRadius = maxRadius
         private set
 
@@ -387,18 +374,12 @@
     internal fun isBottomAnimating() = PropertyAnimator.isAnimating(targetView, bottomAnimatable)
 
     /** Set the current top roundness */
-    internal fun setTopRoundness(
-        value: Float,
-        animated: Boolean,
-    ) {
+    internal fun setTopRoundness(value: Float, animated: Boolean) {
         PropertyAnimator.setProperty(targetView, topAnimatable, value, DURATION, animated)
     }
 
     /** Set the current bottom roundness */
-    internal fun setBottomRoundness(
-        value: Float,
-        animated: Boolean,
-    ) {
+    internal fun setBottomRoundness(value: Float, animated: Boolean) {
         PropertyAnimator.setProperty(targetView, bottomAnimatable, value, DURATION, animated)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index d538f52..5c51ada 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -46,7 +46,6 @@
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.shared.NotificationHeadsUpCycling;
-import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.util.DumpUtilsKt;
@@ -407,12 +406,7 @@
 
         mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction,
                 targetValue);
-        if (NotificationsImprovedHunAnimation.isEnabled()
-                || NotificationHeadsUpCycling.isEnabled()) {
-            mAppearAnimator.setInterpolator(mCurrentAppearInterpolator);
-        } else {
-            mAppearAnimator.setInterpolator(Interpolators.LINEAR);
-        }
+        mAppearAnimator.setInterpolator(mCurrentAppearInterpolator);
         mAppearAnimator.setDuration(
                 (long) (duration * Math.abs(mAppearAnimationFraction - targetValue)));
         mAppearAnimator.addUpdateListener(animation -> {
@@ -531,10 +525,7 @@
      * @param clipSide Which side if view we want to clip from
      */
     private void updateAppearRect(ClipSide clipSide) {
-        float interpolatedFraction =
-                NotificationsImprovedHunAnimation.isEnabled()
-                        || NotificationHeadsUpCycling.isEnabled() ? mAppearAnimationFraction
-                        : mCurrentAppearInterpolator.getInterpolation(mAppearAnimationFraction);
+        float interpolatedFraction = mAppearAnimationFraction;
         mAppearAnimationTranslation = (1.0f - interpolatedFraction) * mAnimationTranslationY;
         final int fullHeight = getActualHeight();
         float height = fullHeight * interpolatedFraction;
@@ -566,14 +557,6 @@
         updateAppearRect(ClipSide.BOTTOM);
     }
 
-    private float getInterpolatedAppearAnimationFraction() {
-
-        if (mAppearAnimationFraction >= 0) {
-            return mCurrentAppearInterpolator.getInterpolation(mAppearAnimationFraction);
-        }
-        return 1.0f;
-    }
-
     private void updateAppearAnimationAlpha() {
         updateAppearAnimationContentAlpha(
                 mAppearAnimationFraction,
@@ -643,26 +626,6 @@
         super.applyRoundnessAndInvalidate();
     }
 
-    @Override
-    public float getTopCornerRadius() {
-        if (NotificationsImprovedHunAnimation.isEnabled()) {
-            return super.getTopCornerRadius();
-        }
-
-        float fraction = getInterpolatedAppearAnimationFraction();
-        return MathUtils.lerp(0, super.getTopCornerRadius(), fraction);
-    }
-
-    @Override
-    public float getBottomCornerRadius() {
-        if (NotificationsImprovedHunAnimation.isEnabled()) {
-            return super.getBottomCornerRadius();
-        }
-
-        float fraction = getInterpolatedAppearAnimationFraction();
-        return MathUtils.lerp(0, super.getBottomCornerRadius(), fraction);
-    }
-
     private void applyBackgroundRoundness(float topRadius, float bottomRadius) {
         mBackgroundNormal.setRadius(topRadius, bottomRadius);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index a323c26..80cf818 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -30,7 +30,6 @@
 
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.RoundableState;
-import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
 import com.android.systemui.util.DumpUtilsKt;
 
@@ -123,15 +122,6 @@
             return EMPTY_PATH;
         }
         float bottomRadius = mAlwaysRoundBothCorners ? getMaxRadius() : getBottomCornerRadius();
-        if (!NotificationsImprovedHunAnimation.isEnabled() && (topRadius + bottomRadius > height)) {
-            float overShoot = topRadius + bottomRadius - height;
-            float currentTopRoundness = getTopRoundness();
-            float currentBottomRoundness = getBottomRoundness();
-            topRadius -= overShoot * currentTopRoundness
-                    / (currentTopRoundness + currentBottomRoundness);
-            bottomRadius -= overShoot * currentBottomRoundness
-                    / (currentTopRoundness + currentBottomRoundness);
-        }
         getRoundedRectPath(left, top, right, bottom, topRadius, bottomRadius, mTmpPath);
         return mTmpPath;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationsImprovedHunAnimation.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationsImprovedHunAnimation.kt
deleted file mode 100644
index 16d35fe..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationsImprovedHunAnimation.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.systemui.statusbar.notification.shared
-
-import com.android.systemui.Flags
-import com.android.systemui.flags.FlagToken
-import com.android.systemui.flags.RefactorFlagUtils
-
-/** Helper for reading or using the notifications improved hun animation flag state. */
-@Suppress("NOTHING_TO_INLINE")
-object NotificationsImprovedHunAnimation {
-    /** The aconfig flag name */
-    const val FLAG_NAME = Flags.FLAG_NOTIFICATIONS_IMPROVED_HUN_ANIMATION
-
-    /** A token used for dependency declaration */
-    val token: FlagToken
-        get() = FlagToken(FLAG_NAME, isEnabled)
-
-    /** Is the refactor enabled */
-    @JvmStatic
-    inline val isEnabled
-        get() = Flags.notificationsImprovedHunAnimation()
-
-    /**
-     * Called to ensure code is only run when the flag is enabled. This protects users from the
-     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
-     * build to ensure that the refactor author catches issues in testing.
-     */
-    @JvmStatic
-    inline fun isUnexpectedlyInLegacyMode() =
-        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
-
-    /**
-     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
-     * the flag is enabled to ensure that the refactor author catches issues in testing.
-     */
-    @JvmStatic
-    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 223475e..c7b3fd7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -118,7 +118,6 @@
 import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
 import com.android.systemui.statusbar.notification.shared.NotificationHeadsUpCycling;
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun;
-import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation;
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor;
 import com.android.systemui.statusbar.notification.stack.shared.model.AccessibilityScrollEvent;
 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds;
@@ -3459,11 +3458,8 @@
             }
             AnimationEvent event = new AnimationEvent(row, type);
             event.headsUpFromBottom = onBottom;
-            if (NotificationsImprovedHunAnimation.isEnabled()) {
-                // TODO(b/283084712) remove this with the flag and update the HUN filters at
-                //  creation
-                event.filter.animateHeight = false;
-            }
+            // TODO(b/283084712) remove this and update the HUN filters at creation
+            event.filter.animateHeight = false;
             mAnimationEvents.add(event);
             if (SPEW) {
                 Log.v(TAG, "Generating HUN animation event: "
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index b251b07..1653029 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -41,7 +41,6 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.shared.NotificationHeadsUpCycling;
-import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -1065,8 +1064,7 @@
                             headsUpTranslation);
                     childState.setYTranslation(inSpaceTranslation + extraTranslation);
                     cyclingInHunHeight = -1;
-                } else
-                if (NotificationsImprovedHunAnimation.isEnabled() && !ambientState.isDozing()) {
+                } else if (!ambientState.isDozing()) {
                     if (shouldHunAppearFromBottom(ambientState, childState)) {
                         // move to the bottom of the screen
                         childState.setYTranslation(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index 058233f..4686bef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -37,8 +37,6 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
-import com.android.systemui.statusbar.notification.shared.NotificationHeadsUpCycling;
-import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -179,10 +177,7 @@
         mHeadsUpDisappearChildren.clear();
         mNewEvents.clear();
         mNewAddChildren.clear();
-        if (NotificationsImprovedHunAnimation.isEnabled()
-                || NotificationHeadsUpCycling.isEnabled()) {
-            mAnimationProperties.resetCustomInterpolators();
-        }
+        mAnimationProperties.resetCustomInterpolators();
     }
 
     private void initAnimationProperties(ExpandableView child,
@@ -498,8 +493,7 @@
                 }
                 changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_CYCLING,
                         /* isHeadsUpAppear= */ true, onAnimationEnd);
-            } else if (NotificationsImprovedHunAnimation.isEnabled()
-                    && (event.animationType == ANIMATION_TYPE_HEADS_UP_APPEAR)) {
+            } else if (event.animationType == ANIMATION_TYPE_HEADS_UP_APPEAR) {
                 mHeadsUpAppearChildren.add(changingView);
 
                 mTmpState.copyFrom(changingView.getViewState());
@@ -602,30 +596,6 @@
                     endRunnable.run();
                 }
                 needsCustomAnimation |= needsAnimation;
-            } else if (event.animationType == ANIMATION_TYPE_HEADS_UP_APPEAR) {
-                NotificationsImprovedHunAnimation.assertInLegacyMode();
-                // This item is added, initialize its properties.
-                ExpandableViewState viewState = changingView.getViewState();
-                mTmpState.copyFrom(viewState);
-                if (event.headsUpFromBottom) {
-                    mTmpState.setYTranslation(mHeadsUpAppearHeightBottom);
-                } else {
-                    Runnable onAnimationEnd = null;
-                    if (loggable) {
-                        String finalKey = key;
-                        onAnimationEnd = () -> mLogger.appearAnimationEnded(finalKey);
-                    }
-                    changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_APPEAR,
-                            true /* isHeadsUpAppear */, onAnimationEnd);
-                }
-                mHeadsUpAppearChildren.add(changingView);
-                // this only captures HEADS_UP_APPEAR animations, but HUNs can appear with normal
-                // ADD animations, which would not be logged here.
-                if (loggable) {
-                    mLogger.logHUNViewAppearing(key);
-                }
-
-                mTmpState.applyToView(changingView);
             } else if (event.animationType == ANIMATION_TYPE_HEADS_UP_DISAPPEAR
                     || event.animationType == ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
                 mHeadsUpDisappearChildren.add(changingView);
@@ -636,14 +606,10 @@
                     // transiently
                     mHostLayout.addTransientView(changingView, 0);
                     changingView.setTransientContainer(mHostLayout);
-                    if (NotificationsImprovedHunAnimation.isEnabled()) {
-                        // StackScrollAlgorithm cannot find this view because it has been removed
-                        // from the NSSL. To correctly translate the view to the top or bottom of
-                        // the screen (where it animated from), we need to update its translation.
-                        mTmpState.setYTranslation(
-                                getHeadsUpYTranslationStart(event.headsUpFromBottom)
-                        );
-                    }
+                    // StackScrollAlgorithm cannot find this view because it has been removed
+                    // from the NSSL. To correctly translate the view to the top or bottom of
+                    // the screen (where it animated from), we need to update its translation.
+                    mTmpState.setYTranslation(getHeadsUpYTranslationStart(event.headsUpFromBottom));
                     endRunnable = changingView::removeFromTransientContainer;
                 }
 
@@ -697,14 +663,12 @@
                             startAnimation, postAnimation,
                             getGlobalAnimationFinishedListener(), ExpandableView.ClipSide.BOTTOM);
                     mAnimationProperties.delay += removeAnimationDelay;
-                    if (NotificationsImprovedHunAnimation.isEnabled()) {
-                        mAnimationProperties.duration = ANIMATION_DURATION_HEADS_UP_DISAPPEAR;
-                        mAnimationProperties.setCustomInterpolator(View.TRANSLATION_Y,
-                                Interpolators.FAST_OUT_SLOW_IN_REVERSE);
-                        mAnimationProperties.getAnimationFilter().animateY = true;
-                        mTmpState.animateTo(changingView, mAnimationProperties);
-                        mAnimationProperties.resetCustomInterpolators();
-                    }
+                    mAnimationProperties.duration = ANIMATION_DURATION_HEADS_UP_DISAPPEAR;
+                    mAnimationProperties.setCustomInterpolator(View.TRANSLATION_Y,
+                            Interpolators.FAST_OUT_SLOW_IN_REVERSE);
+                    mAnimationProperties.getAnimationFilter().animateY = true;
+                    mTmpState.animateTo(changingView, mAnimationProperties);
+                    mAnimationProperties.resetCustomInterpolators();
                 } else if (endRunnable != null) {
                     endRunnable.run();
                 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/RoundableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/RoundableTest.kt
index 382b307..2371ccc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/RoundableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/RoundableTest.kt
@@ -1,11 +1,9 @@
 package com.android.systemui.statusbar.notification
 
-import android.platform.test.annotations.EnableFlags
 import android.view.View
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import org.junit.Assert.assertEquals
@@ -148,7 +146,6 @@
     }
 
     @Test
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun getCornerRadii_radius_maxed_to_height() {
         whenever(targetView.height).thenReturn(10)
         roundable.requestRoundness(1f, 1f, SOURCE1)
@@ -157,7 +154,6 @@
     }
 
     @Test
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun getCornerRadii_topRadius_maxed_to_height() {
         whenever(targetView.height).thenReturn(5)
         roundable.requestRoundness(1f, 0f, SOURCE1)
@@ -166,7 +162,6 @@
     }
 
     @Test
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun getCornerRadii_bottomRadius_maxed_to_height() {
         whenever(targetView.height).thenReturn(5)
         roundable.requestRoundness(0f, 1f, SOURCE1)
@@ -175,7 +170,6 @@
     }
 
     @Test
-    @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun getCornerRadii_radii_kept() {
         whenever(targetView.height).thenReturn(100)
         roundable.requestRoundness(1f, 1f, SOURCE1)
@@ -188,16 +182,9 @@
         assertEquals("bottomCornerRadius", bottom, roundable.bottomCornerRadius)
     }
 
-    class FakeRoundable(
-        targetView: View,
-        radius: Float = MAX_RADIUS,
-    ) : Roundable {
+    class FakeRoundable(targetView: View, radius: Float = MAX_RADIUS) : Roundable {
         override val roundableState =
-            RoundableState(
-                targetView = targetView,
-                roundable = this,
-                maxRadius = radius,
-            )
+            RoundableState(targetView = targetView, roundable = this, maxRadius = radius)
 
         override val clipHeight: Int
             get() = roundableState.targetView.height
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index ca4b5d4..6ccfaf3 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -41,6 +41,7 @@
         <activity android:name=".PlatformVpnConfirmDialog"
                   android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight"
                   android:noHistory="true"
+                  android:enableOnBackInvokedCallback="false"
                   android:excludeFromRecents="true"
                   android:exported="true">
         </activity>
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index f86474f..70febcd 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -22,6 +22,7 @@
 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_END;
 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_RESTRICTION_CHANGE;
 import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
+import static android.content.pm.Flags.appCompatOption16kb;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
@@ -2025,6 +2026,16 @@
                 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
             }
 
+            if (appCompatOption16kb()) {
+                boolean is16KbDevice = Os.sysconf(OsConstants._SC_PAGESIZE) == 16384;
+                if (is16KbDevice
+                        && mService.mContext
+                        .getPackageManager()
+                        .isPageSizeCompatEnabled(app.info.packageName)) {
+                    runtimeFlags |= Zygote.ENABLE_PAGE_SIZE_APP_COMPAT;
+                }
+            }
+
             String invokeWith = null;
             if (debuggableFlag) {
                 // Debuggable apps may include a wrapper script with their library directory.
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 776bf53..9956d85 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4613,6 +4613,17 @@
             } else if (fromOrientation != requestedOrientation) {
                 return false;
             }
+
+            // If another activity above the activity which has starting window, allows to steal the
+            // starting window if the above activity isn't drawn.
+            if (task.getChildCount() >= 3
+                    && fromActivity.mStartingData.mAssociatedTask == null) {
+                final ActivityRecord aboveFrom = task.getActivityAbove(fromActivity);
+                if (aboveFrom != null && aboveFrom != this && !aboveFrom.mReportedDrawn) {
+                    return false;
+                }
+            }
+
             // In this case, the starting icon has already been displayed, so start
             // letting windows get shown immediately without any more transitions.
             if (fromActivity.mVisible) {
@@ -4636,6 +4647,16 @@
                 tStartingWindow.mToken = this;
                 tStartingWindow.mActivityRecord = this;
 
+                if (mStartingData.mRemoveAfterTransaction == AFTER_TRANSACTION_REMOVE_DIRECTLY) {
+                    // The removal of starting window should wait for window drawn of current
+                    // activity.
+                    final WindowState mainWin = findMainWindow(false /* includeStartingApp */);
+                    if (mainWin == null || !mainWin.isDrawn()) {
+                        mStartingData.mRemoveAfterTransaction = AFTER_TRANSACTION_IDLE;
+                        mStartingData.mPrepareRemoveAnimation = false;
+                    }
+                }
+
                 ProtoLog.v(WM_DEBUG_ADD_REMOVE,
                         "Removing starting %s from %s", tStartingWindow, fromActivity);
                 mTransitionController.collect(tStartingWindow);