Merging ub-launcher3-master, build 5434161

Test: Manual

Bug:127840207 [logging] quickswitch usage
Bug:127848641 [logging] (left|right) back gesture / home gesture usage
Bug:128711026 [Gesture Nav] widgets and icons are clipped
Bug:129337684 Swipe up from home falses to Overview
Bug:129711952 Overview stays in view hierarchy while in all apps
Bug:129723135 Broken tests: swipe from killed launcher doesn't open overview
Bug:129867977 [gestural nav] Add assistant gesture logging

Change-Id: I5a47424b0eb6cadbb8e3ced037fe5913302e6afa
diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
index fe92890..c579c8a 100644
--- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -30,7 +30,6 @@
 
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
-import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
 
 /**
  * Service connected by system-UI for handling touch interaction.
@@ -38,8 +37,6 @@
 @TargetApi(Build.VERSION_CODES.O)
 public class TouchInteractionService extends Service {
 
-    public static final int EDGE_NAV_BAR = 1 << 8;
-
     private static final String TAG = "TouchInteractionService";
 
     private final IBinder mMyBinder = new IOverviewProxy.Stub() {
diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto
index ce965bf..4974dcb 100644
--- a/protos/launcher_log.proto
+++ b/protos/launcher_log.proto
@@ -143,6 +143,7 @@
     SWIPE = 3;
     FLING = 4;
     PINCH = 5;
+    SWIPE_NOOP = 6;
   }
 
   enum Direction {
@@ -151,6 +152,8 @@
     DOWN = 2;
     LEFT = 3;
     RIGHT = 4;
+    UPRIGHT = 5;
+    UPLEFT = 6;
   }
   enum Command {
     HOME_INTENT = 0;
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
index 0757e85..6dd5e21 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
@@ -27,6 +27,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
@@ -96,9 +97,9 @@
     }
 
     @Override
-    public boolean onDrag(float displacement) {
-        mMotionPauseDetector.addPosition(displacement, 0);
-        return super.onDrag(displacement);
+    public boolean onDrag(float displacement, MotionEvent event) {
+        mMotionPauseDetector.addPosition(displacement, 0, event.getEventTime());
+        return super.onDrag(displacement, event);
     }
 
     @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
index c00b4dc..7c0791e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AssistantTouchConsumer.java
@@ -21,6 +21,11 @@
 import static android.view.MotionEvent.ACTION_MOVE;
 import static android.view.MotionEvent.ACTION_POINTER_UP;
 import static android.view.MotionEvent.ACTION_UP;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.SWIPE;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.SWIPE_NOOP;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction.UPLEFT;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction.UPRIGHT;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.NAVBAR;
 
 import android.animation.ValueAnimator;
 import android.content.Context;
@@ -32,6 +37,7 @@
 import android.util.Log;
 import android.view.MotionEvent;
 import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.quickstep.util.MotionPauseDetector;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.launcher3.R;
@@ -66,6 +72,7 @@
     private long mDragTime;
     private float mLastProgress;
     private int mState;
+    private int mDirection;
 
     private final float mDistThreshold;
     private final long mTimeThreshold;
@@ -74,10 +81,12 @@
     private final MotionPauseDetector mMotionPauseDetector;
     private final ISystemUiProxy mSysUiProxy;
     private final InputConsumer mConsumerDelegate;
+    private final Context mContext;
 
     public AssistantTouchConsumer(Context context, ISystemUiProxy systemUiProxy,
             InputConsumer delegate) {
         final Resources res = context.getResources();
+        mContext = context;
         mSysUiProxy = systemUiProxy;
         mConsumerDelegate = delegate;
         mMotionPauseDetector = new MotionPauseDetector(context);
@@ -151,6 +160,7 @@
                         // Determine if angle is larger than threshold for assistant detection
                         float angle = (float) Math.toDegrees(
                                 Math.atan2(mDownPos.y - mLastPos.y, mDownPos.x - mLastPos.x));
+                        mDirection = angle > 90 ? UPLEFT : UPRIGHT;
                         angle = angle > 90 ? 180 - angle : angle;
                         if (angle > mAngleThreshold) {
                             mState = STATE_ASSISTANT_ACTIVE;
@@ -170,7 +180,7 @@
                     // Movement
                     mDistance = (float) Math.hypot(mLastPos.x - mStartDragPos.x,
                             mLastPos.y - mStartDragPos.y);
-                    mMotionPauseDetector.addPosition(mDistance, 0);
+                    mMotionPauseDetector.addPosition(mDistance, 0, ev.getEventTime());
                     if (mDistance >= 0) {
                         final long diff = SystemClock.uptimeMillis() - mDragTime;
                         mTimeFraction = Math.min(diff * 1f / mTimeThreshold, 1);
@@ -184,9 +194,12 @@
                 if (mState != STATE_DELEGATE_ACTIVE && !mLaunchedAssistant) {
                     ValueAnimator animator = ValueAnimator.ofFloat(mLastProgress, 0)
                             .setDuration(RETRACT_ANIMATION_DURATION_MS);
+                    UserEventDispatcher.newInstance(mContext).logActionOnContainer(
+                            SWIPE_NOOP, mDirection, NAVBAR);
                     animator.addUpdateListener(valueAnimator -> {
                             float progress = (float) valueAnimator.getAnimatedValue();
                             try {
+
                                 mSysUiProxy.onAssistantProgress(progress);
                             } catch (RemoteException e) {
                                 Log.w(TAG, "Failed to send SysUI start/send assistant progress: "
@@ -211,8 +224,9 @@
             mLastProgress = progress;
             try {
                 mSysUiProxy.onAssistantProgress(progress);
-
                 if (mDistance >= mDistThreshold && mTimeFraction >= 1) {
+                    UserEventDispatcher.newInstance(mContext).logActionOnContainer(
+                            SWIPE, mDirection, NAVBAR);
                     mSysUiProxy.startAssistant(new Bundle());
                     mLaunchedAssistant = true;
                 }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
index fb73f9e..aada84f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
@@ -255,7 +255,8 @@
                         float orthogonalDisplacement = !isLandscape
                                 ? ev.getX() - mDownPos.x
                                 : ev.getY() - mDownPos.y;
-                        mMotionPauseDetector.addPosition(displacement, orthogonalDisplacement);
+                        mMotionPauseDetector.addPosition(displacement, orthogonalDisplacement,
+                                ev.getEventTime());
                     }
                 }
                 break;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 0065cb5..b1db780 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -203,6 +203,11 @@
 
     private static final long SHELF_ANIM_DURATION = 120;
 
+    /**
+     * Used as the page index for logging when we return to the last task at the end of the gesture.
+     */
+    private static final int LOG_NO_OP_PAGE_INDEX = -1;
+
     private final ClipAnimationHelper mClipAnimationHelper;
     private final ClipAnimationHelper.TransformParams mTransformParams;
 
@@ -245,6 +250,7 @@
     private boolean mPassedOverviewThreshold;
     private boolean mGestureStarted;
     private int mLogAction = Touch.SWIPE;
+    private int mLogDirection = Direction.UP;
 
     private final RecentsAnimationWrapper mRecentsAnimationWrapper;
 
@@ -692,6 +698,12 @@
         setStateOnUiThread(STATE_GESTURE_COMPLETED);
 
         mLogAction = isFling ? Touch.FLING : Touch.SWIPE;
+        boolean isVelocityVertical = Math.abs(velocity.y) > Math.abs(velocity.x);
+        if (isVelocityVertical) {
+            mLogDirection = velocity.y < 0 ? Direction.UP : Direction.DOWN;
+        } else {
+            mLogDirection = velocity.x < 0 ? Direction.LEFT : Direction.RIGHT;
+        }
         handleNormalGestureEnd(endVelocity, isFling, velocity);
     }
 
@@ -824,19 +836,15 @@
             // We probably never received an animation controller, skip logging.
             return;
         }
-        boolean toLauncher = endTarget.isLauncher;
-        final int direction;
-        if (dp.isVerticalBarLayout()) {
-            direction = (dp.isSeascape() ^ toLauncher) ? Direction.LEFT : Direction.RIGHT;
-        } else {
-            direction = toLauncher ? Direction.UP : Direction.DOWN;
-        }
 
+        int pageIndex = endTarget == LAST_TASK
+                ? LOG_NO_OP_PAGE_INDEX
+                : mRecentsView.getNextPage();
         UserEventDispatcher.newInstance(mContext).logStateChangeAction(
-                mLogAction, direction,
+                mLogAction, mLogDirection,
                 ContainerType.NAVBAR, ContainerType.APP,
                 endTarget.containerType,
-                0);
+                pageIndex);
     }
 
     /** Animates to the given progress, where 0 is the current app and 1 is overview. */
@@ -931,7 +939,7 @@
             HomeAnimationFactory homeAnimationFactory) {
         final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
         final RectF startRect = new RectF(mClipAnimationHelper.applyTransform(targetSet,
-                mTransformParams.setProgress(startProgress)));
+                mTransformParams.setProgress(startProgress), false /* launcherOnTop */));
         final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
 
         final View floatingView = homeAnimationFactory.getFloatingView();
@@ -956,7 +964,8 @@
                     windowAlphaThreshold, 0f, 1f, Interpolators.LINEAR);
             mTransformParams.setCurrentRectAndTargetAlpha(currentRect, 1f - iconAlpha)
                     .setSyncTransactionApplier(mSyncTransactionApplier);
-            mClipAnimationHelper.applyTransform(targetSet, mTransformParams);
+            mClipAnimationHelper.applyTransform(targetSet, mTransformParams,
+                    false /* launcherOnTop */);
 
             if (isFloatingIconView) {
                 ((FloatingIconView) floatingView).update(currentRect, iconAlpha, progress,
@@ -968,6 +977,7 @@
             @Override
             public void onAnimationStart(Animator animation) {
                 homeAnim.dispatchOnStart();
+                mActivity.getRootView().getOverlay().remove(mLiveTileOverlay);
             }
 
             @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
index 6b3f028..777e592 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
@@ -17,12 +17,18 @@
 
 import android.annotation.TargetApi;
 import android.content.Context;
+import android.graphics.Insets;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.ViewDebug;
+import android.view.WindowInsets;
 
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.views.BaseDragLayer;
@@ -33,6 +39,9 @@
     private static final int MIN_SIZE = 10;
     private final RecentsActivity mActivity;
 
+    @ViewDebug.ExportedProperty(category = "launcher")
+    private final RectF mTouchExcludeRegion = new RectF();
+
     private final Point mLastKnownSize = new Point(MIN_SIZE, MIN_SIZE);
 
     public RecentsRootView(Context context, AttributeSet attrs) {
@@ -88,4 +97,29 @@
         mActivity.getDeviceProfile().updateInsets(mInsets);
         super.setInsets(mInsets);
     }
+
+    @Override
+    public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
+        if (Utilities.ATLEAST_Q) {
+            Insets gestureInsets = insets.getMandatorySystemGestureInsets();
+            mTouchExcludeRegion.set(gestureInsets.left, gestureInsets.top,
+                    gestureInsets.right, gestureInsets.bottom);
+        }
+        return super.dispatchApplyWindowInsets(insets);
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            float x = ev.getX();
+            float y = ev.getY();
+            if (y < mTouchExcludeRegion.top
+                    || x < mTouchExcludeRegion.left
+                    || x > (getWidth() - mTouchExcludeRegion.right)
+                    || y > (getHeight() - mTouchExcludeRegion.bottom)) {
+                return false;
+            }
+        }
+        return super.dispatchTouchEvent(ev);
+    }
 }
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
index fe5a675..e1a39c6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -149,6 +149,11 @@
     }
 
     public RectF applyTransform(RemoteAnimationTargetSet targetSet, TransformParams params) {
+        return applyTransform(targetSet, params, true /* launcherOnTop */);
+    }
+
+    public RectF applyTransform(RemoteAnimationTargetSet targetSet, TransformParams params,
+            boolean launcherOnTop) {
         if (params.currentRect == null) {
             RectF currentRect;
             mTmpRectF.set(mTargetRect);
@@ -189,7 +194,7 @@
                     }
                 }
                 alpha = mTaskAlphaCallback.apply(app, params.targetAlpha);
-            } else if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) {
                 crop = null;
                 layer = Integer.MAX_VALUE;
             }
diff --git a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
index 4392851..6dff187 100644
--- a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
+++ b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
@@ -34,7 +34,6 @@
  * quickstep interactions.
  */
 @SuppressWarnings("unused")
-@Deprecated
 public class UserEventDispatcherExtension extends UserEventDispatcher {
 
     private static final String TAG = "UserEventDispatcher";
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index 96620bd..ae5f390 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -17,7 +17,6 @@
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.os.SystemClock;
 import android.view.MotionEvent;
 
 import com.android.launcher3.Alarm;
@@ -80,7 +79,7 @@
      *
      * TODO: Use historical positions as well, e.g. {@link MotionEvent#getHistoricalY(int, int)}.
      */
-    public void addPosition(float position, float orthogonalPosition) {
+    public void addPosition(float position, float orthogonalPosition, long time) {
         if (mFirstPosition == null) {
             mFirstPosition = position;
         }
@@ -88,7 +87,6 @@
             mFirstOrthogonalPosition = orthogonalPosition;
         }
         mForcePauseTimeout.setAlarm(FORCE_PAUSE_TIMEOUT);
-        long time = SystemClock.uptimeMillis();
         if (mPreviousTime != null && mPreviousPosition != null) {
             long changeInTime = Math.max(1, time - mPreviousTime);
             float changeInPosition = position - mPreviousPosition;
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 554aef4..dc83e87 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -96,6 +96,7 @@
     }
 
     @Test
+    @Ignore // b/129723135
     @NavigationModeSwitch
     public void testStressSwipeToOverview() {
         for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 6623861..4112ccf 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -60,7 +60,7 @@
     }
 
     private void startTestApps() throws Exception {
-        startAppFast(resolveSystemApp(Intent.CATEGORY_APP_MESSAGING));
+        startAppFast(resolveSystemApp(Intent.CATEGORY_APP_MARKET));
         startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
         startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CONTACTS));
 
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 8e2ffe9..f9a8d1b 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -24,6 +24,9 @@
 import com.android.launcher3.util.FocusLogic;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class AppWidgetResizeFrame extends AbstractFloatingView implements View.OnKeyListener {
     private static final int SNAP_DURATION = 150;
     private static final float DIMMED_HANDLE_ALPHA = 0f;
@@ -45,6 +48,7 @@
     private final FirstFrameAnimatorHelper mFirstFrameAnimatorHelper;
 
     private final View[] mDragHandles = new View[HANDLE_COUNT];
+    private final List<Rect> mSystemGestureExclusionRects = new ArrayList<>(HANDLE_COUNT);
 
     private LauncherAppWidgetHostView mWidgetView;
     private CellLayout mCellLayout;
@@ -106,6 +110,10 @@
                 .getDimensionPixelSize(R.dimen.resize_frame_background_padding);
         mTouchTargetWidth = 2 * mBackgroundPadding;
         mFirstFrameAnimatorHelper = new FirstFrameAnimatorHelper(this);
+
+        for (int i = 0; i < HANDLE_COUNT; i++) {
+            mSystemGestureExclusionRects.add(new Rect());
+        }
     }
 
     @Override
@@ -118,6 +126,19 @@
         }
     }
 
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        if (Utilities.ATLEAST_Q) {
+            for (int i = 0; i < HANDLE_COUNT; i++) {
+                View dragHandle = mDragHandles[i];
+                mSystemGestureExclusionRects.get(i).set(dragHandle.getLeft(), dragHandle.getTop(),
+                        dragHandle.getRight(), dragHandle.getBottom());
+            }
+            setSystemGestureExclusionRects(mSystemGestureExclusionRects);
+        }
+    }
+
     public static void showForWidget(LauncherAppWidgetHostView widget, CellLayout cellLayout) {
         Launcher launcher = Launcher.getLauncher(cellLayout.getContext());
         AbstractFloatingView.closeAllOpenViews(launcher);
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index 9f6e5cd..e738eb7 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -8,11 +8,15 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Insets;
 import android.graphics.Paint;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewDebug;
+import android.view.WindowInsets;
 
 public class LauncherRootView extends InsettableFrameLayout {
 
@@ -23,6 +27,9 @@
     @ViewDebug.ExportedProperty(category = "launcher")
     private final Rect mConsumedInsets = new Rect();
 
+    @ViewDebug.ExportedProperty(category = "launcher")
+    private final RectF mTouchExcludeRegion = new RectF();
+
     private View mAlignedView;
     private WindowStateListener mWindowStateListener;
 
@@ -145,6 +152,31 @@
         }
     }
 
+    @Override
+    public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
+        if (Utilities.ATLEAST_Q) {
+            Insets gestureInsets = insets.getMandatorySystemGestureInsets();
+            mTouchExcludeRegion.set(gestureInsets.left, gestureInsets.top,
+                    gestureInsets.right, gestureInsets.bottom);
+        }
+        return super.dispatchApplyWindowInsets(insets);
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            float x = ev.getX();
+            float y = ev.getY();
+            if (y < mTouchExcludeRegion.top
+                    || x < mTouchExcludeRegion.left
+                    || x > (getWidth() - mTouchExcludeRegion.right)
+                    || y > (getHeight() - mTouchExcludeRegion.bottom)) {
+                return false;
+            }
+        }
+        return super.dispatchTouchEvent(ev);
+    }
+
     public interface WindowStateListener {
 
         void onWindowFocusChanged(boolean hasFocus);
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 5f7538b..5b654d8 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -17,6 +17,7 @@
 package com.android.launcher3;
 
 import static android.view.View.VISIBLE;
+
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
@@ -29,7 +30,6 @@
 import static com.android.launcher3.anim.Interpolators.DEACCEL;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
 import static com.android.launcher3.anim.Interpolators.INSTANT;
-import static com.android.launcher3.anim.Interpolators.NEVER;
 import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
 import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
 import static com.android.launcher3.anim.Interpolators.clampToProgress;
@@ -41,6 +41,8 @@
 import android.os.Handler;
 import android.os.Looper;
 
+import androidx.annotation.IntDef;
+
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.AnimatorSetBuilder;
@@ -52,8 +54,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 
-import androidx.annotation.IntDef;
-
 /**
  * TODO: figure out what kind of tests we can write for this
  *
@@ -326,7 +326,8 @@
         } else if (fromState == NORMAL && toState == OVERVIEW_PEEK) {
             builder.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
         } else if (fromState == OVERVIEW_PEEK && toState == NORMAL) {
-            builder.setInterpolator(ANIM_OVERVIEW_FADE, NEVER);
+            // Keep fully visible until the very end (when overview is offscreen) to make invisible.
+            builder.setInterpolator(ANIM_OVERVIEW_FADE, t -> t < 1 ? 0 : 1);
         }
     }
 
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 217b6db..b169cb8 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -58,7 +58,6 @@
     public static final Interpolator EXAGGERATED_EASE;
 
     public static final Interpolator INSTANT = t -> 1;
-    public static final Interpolator NEVER = t -> 0;
 
     private static final int MIN_SETTLE_DURATION = 200;
     private static final float OVERSHOOT_FACTOR = 0.9f;
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 4ef8626..d208077 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -15,7 +15,8 @@
  */
 package com.android.launcher3.logging;
 
-import android.content.Context;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.NAVBAR;
+
 import android.util.ArrayMap;
 import android.util.SparseArray;
 import android.view.View;
@@ -97,7 +98,8 @@
             case Target.Type.CONTAINER:
                 str = getFieldName(t.containerType, ContainerType.class);
                 if (t.containerType == ContainerType.WORKSPACE ||
-                        t.containerType == ContainerType.HOTSEAT) {
+                        t.containerType == ContainerType.HOTSEAT ||
+                        t.containerType == NAVBAR) {
                     str += " id=" + t.pageIndex;
                 } else if (t.containerType == ContainerType.FOLDER) {
                     str += " grid(" + t.gridX + "," + t.gridY+ ")";
diff --git a/src/com/android/launcher3/touch/SwipeDetector.java b/src/com/android/launcher3/touch/SwipeDetector.java
index e558fc7..d758a29 100644
--- a/src/com/android/launcher3/touch/SwipeDetector.java
+++ b/src/com/android/launcher3/touch/SwipeDetector.java
@@ -219,6 +219,10 @@
 
         boolean onDrag(float displacement);
 
+        default boolean onDrag(float displacement, MotionEvent event) {
+            return onDrag(displacement);
+        }
+
         void onDragEnd(float velocity, boolean fling);
     }
 
@@ -307,7 +311,7 @@
                     setState(ScrollState.DRAGGING);
                 }
                 if (mState == ScrollState.DRAGGING) {
-                    reportDragging();
+                    reportDragging(ev);
                 }
                 mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
                 break;
@@ -359,14 +363,14 @@
         return mDir.isPositive(mSubtractDisplacement);
     }
 
-    private boolean reportDragging() {
+    private boolean reportDragging(MotionEvent event) {
         if (mDisplacement != mLastDisplacement) {
             if (DBG) {
                 Log.d(TAG, String.format("onDrag disp=%.1f", mDisplacement));
             }
 
             mLastDisplacement = mDisplacement;
-            return mListener.onDrag(mDisplacement - mSubtractDisplacement);
+            return mListener.onDrag(mDisplacement - mSubtractDisplacement, event);
         }
         return true;
     }
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 91ebd9b..d29d29c 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -207,8 +207,8 @@
         // Test that ensureWorkspaceIsScrollable adds a page by dragging an icon there.
         executeOnLauncher(launcher -> assertFalse("Initial workspace state is scrollable",
                 isWorkspaceScrollable(launcher)));
-        assertNull("Messages app was found on empty workspace",
-                workspace.tryGetWorkspaceAppIcon("Messages"));
+        assertNull("Play Store app was found on empty workspace",
+                workspace.tryGetWorkspaceAppIcon("Play Store"));
 
         workspace.ensureWorkspaceIsScrollable();
 
@@ -218,8 +218,8 @@
         executeOnLauncher(
                 launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
                         isWorkspaceScrollable(launcher)));
-        assertNotNull("ensureScrollable didn't add Messages app",
-                workspace.tryGetWorkspaceAppIcon("Messages"));
+        assertNotNull("ensureScrollable didn't add Play Store app",
+                workspace.tryGetWorkspaceAppIcon("Play Store"));
 
         // Test flinging workspace.
         workspace.flingBackward();
@@ -235,10 +235,10 @@
         assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
 
         // Test starting a workspace app.
-        final AppIcon app = workspace.tryGetWorkspaceAppIcon("Messages");
-        assertNotNull("No Messages app in workspace", app);
+        final AppIcon app = workspace.tryGetWorkspaceAppIcon("Play Store");
+        assertNotNull("No Play Store app in workspace", app);
         assertNotNull("AppIcon.launch returned null",
-                app.launch(resolveSystemApp(Intent.CATEGORY_APP_MESSAGING)));
+                app.launch(resolveSystemApp(Intent.CATEGORY_APP_MARKET)));
         executeOnLauncher(launcher -> assertTrue(
                 "Launcher activity is the top activity; expecting another activity to be the top "
                         + "one",
diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java
index 41932c8..b88da3a 100644
--- a/tests/tapl/com/android/launcher3/tapl/Overview.java
+++ b/tests/tapl/com/android/launcher3/tapl/Overview.java
@@ -18,8 +18,6 @@
 
 import static com.android.launcher3.TestProtocol.ALL_APPS_STATE_ORDINAL;
 
-import android.graphics.Point;
-
 import androidx.annotation.NonNull;
 import androidx.test.uiautomator.UiObject2;
 
@@ -53,9 +51,9 @@
 
             // Swipe from navbar to the top.
             final UiObject2 navBar = mLauncher.waitForSystemUiObject("navigation_bar_frame");
-            final Point start = navBar.getVisibleCenter();
             LauncherInstrumentation.log("Overview.switchToAllApps before swipe");
-            mLauncher.swipe(start.x, start.y, start.x, 0, ALL_APPS_STATE_ORDINAL);
+            final int x = navBar.getVisibleCenter().x;
+            mLauncher.swipe(x, navBar.getVisibleBounds().top - 1, x, 0, ALL_APPS_STATE_ORDINAL);
 
             try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
                     "swiped all way up from overview")) {
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 22b5564..91443d0 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -50,8 +50,8 @@
      */
     @NonNull
     public AllApps switchToAllApps() {
-        try(LauncherInstrumentation.Closable c =
-                    mLauncher.addContextLayer("want to switch from workspace to all apps")) {
+        try (LauncherInstrumentation.Closable c =
+                     mLauncher.addContextLayer("want to switch from workspace to all apps")) {
             verifyActiveContainer();
             final UiObject2 hotseat = mHotseat;
             final Point start = hotseat.getVisibleCenter();
@@ -114,7 +114,7 @@
         if (!isWorkspaceScrollable(workspace)) {
             dragIconToWorkspace(
                     mLauncher,
-                    getHotseatAppIcon("Messages"),
+                    getHotseatAppIcon("Play Store"),
                     new Point(mLauncher.getDevice().getDisplayWidth(),
                             workspace.getVisibleBounds().centerY()),
                     (int) (ICON_DRAG_SPEED * mLauncher.getDisplayDensity()));