Merge "Adds LAUNCHER_FOLDER_LABEL_CHANGED event." into ub-launcher3-rvc-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index 7520688..6761148 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -46,6 +46,7 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.touch.ItemClickHandler;
 import com.android.launcher3.touch.ItemLongClickListener;
+import com.android.launcher3.util.SafeCloseable;
 import com.android.launcher3.views.DoubleShadowBubbleTextView;
 
 /**
@@ -65,6 +66,7 @@
     private final int mNormalizedIconRadius;
     private final BlurMaskFilter mShadowFilter;
     private int mPlateColor;
+    boolean mDrawForDrag = false;
 
 
     public PredictedAppIcon(Context context) {
@@ -188,6 +190,10 @@
     }
 
     private void drawEffect(Canvas canvas, boolean isBadged) {
+        // Don't draw ring effect if item is about to be dragged.
+        if (mDrawForDrag) {
+            return;
+        }
         mRingPath.reset();
         getShape().addToPath(mRingPath, getOutlineOffsetX(), getOutlineOffsetY(),
                 mNormalizedIconRadius);
@@ -208,6 +214,26 @@
         canvas.drawPath(mRingPath, mIconRingPaint);
     }
 
+    @Override
+    public void getSourceVisualDragBounds(Rect bounds) {
+        super.getSourceVisualDragBounds(bounds);
+        if (!mIsPinned) {
+            int internalSize = (int) (bounds.width() * RING_EFFECT_RATIO);
+            bounds.inset(internalSize, internalSize);
+        }
+    }
+
+    @Override
+    public SafeCloseable prepareDrawDragView() {
+        mDrawForDrag = true;
+        invalidate();
+        SafeCloseable r = super.prepareDrawDragView();
+        return () -> {
+            r.close();
+            mDrawForDrag = false;
+        };
+    }
+
     /**
      * Creates and returns a new instance of PredictedAppIcon from WorkspaceItemInfo
      */
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index 1f3b82c..0ee5d04 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -58,6 +58,7 @@
     private final SingleAxisSwipeDetector mDetector;
     private final RecentsView mRecentsView;
     private final int[] mTempCords = new int[2];
+    private final boolean mIsRtl;
 
     private PendingAnimation mPendingAnimation;
     private AnimatorPlaybackController mCurrentAnimation;
@@ -75,6 +76,7 @@
     public TaskViewTouchController(T activity) {
         mActivity = activity;
         mRecentsView = activity.getOverviewPanel();
+        mIsRtl = Utilities.isRtl(activity.getResources());
         SingleAxisSwipeDetector.Direction dir =
             mRecentsView.getPagedOrientationHandler().getOppositeSwipeDirection();
         mDetector = new SingleAxisSwipeDetector(activity, this, dir);
@@ -201,8 +203,8 @@
         mCurrentAnimationIsGoingUp = goingUp;
         BaseDragLayer dl = mActivity.getDragLayer();
         final int secondaryLayerDimension = orientationHandler.getSecondaryDimension(dl);
-        long maxDuration = (long) (2 * secondaryLayerDimension);
-        int verticalFactor = -orientationHandler.getTaskDismissDirectionFactor();
+        long maxDuration = 2 * secondaryLayerDimension;
+        int verticalFactor = orientationHandler.getTaskDragDisplacementFactor(mIsRtl);
         int secondaryTaskDimension = orientationHandler.getSecondaryDimension(mTaskBeingDragged);
         if (goingUp) {
             mPendingAnimation = mRecentsView.createTaskDismissAnimation(mTaskBeingDragged,
@@ -236,7 +238,7 @@
     public void onDragStart(boolean start, float startDisplacement) {
         PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler();
         if (mCurrentAnimation == null) {
-            reInitAnimationController(orientationHandler.isGoingUp(startDisplacement));
+            reInitAnimationController(orientationHandler.isGoingUp(startDisplacement, mIsRtl));
             mDisplacementShift = 0;
         } else {
             mDisplacementShift = mCurrentAnimation.getProgressFraction() / mProgressMultiplier;
@@ -250,7 +252,7 @@
         PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler();
         float totalDisplacement = displacement + mDisplacementShift;
         boolean isGoingUp = totalDisplacement == 0 ? mCurrentAnimationIsGoingUp :
-                orientationHandler.isGoingUp(totalDisplacement);
+                orientationHandler.isGoingUp(totalDisplacement, mIsRtl);
         if (isGoingUp != mCurrentAnimationIsGoingUp) {
             reInitAnimationController(isGoingUp);
             mFlingBlockCheck.blockFling();
@@ -282,7 +284,7 @@
         float interpolatedProgress = mCurrentAnimation.getInterpolatedProgress();
         if (fling) {
             logAction = Touch.FLING;
-            boolean goingUp = orientationHandler.isGoingUp(velocity);
+            boolean goingUp = orientationHandler.isGoingUp(velocity, mIsRtl);
             goingToEnd = goingUp == mCurrentAnimationIsGoingUp;
         } else {
             logAction = Touch.SWIPE;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/ClearAllButton.java
index 1018211..2c85618 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/ClearAllButton.java
@@ -64,7 +64,13 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mParent = (RecentsView) getParent();
-        mIsRtl = !mParent.getPagedOrientationHandler().getRecentsRtlSetting(getResources());
+        mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+    }
+
+    @Override
+    public void onRtlPropertiesChanged(int layoutDirection) {
+        super.onRtlPropertiesChanged(layoutDirection);
+        mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
     }
 
     @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index bf9119e..54ed40f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -1608,7 +1608,12 @@
         if (mOrientationState.update(touchRotation, displayRotation)) {
             mOrientationHandler = mOrientationState.getOrientationHandler();
             mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
-            setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
+            setLayoutDirection(mIsRtl
+                    ? View.LAYOUT_DIRECTION_RTL
+                    : View.LAYOUT_DIRECTION_LTR);
+            mClearAllButton.setLayoutDirection(mIsRtl
+                    ? View.LAYOUT_DIRECTION_LTR
+                    : View.LAYOUT_DIRECTION_RTL);
             mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
             mActivity.getDragLayer().recreateControllers();
             mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index da9468e..6b759ba 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -449,13 +449,13 @@
 
     public void setOrientationState(RecentsOrientedState orientationState) {
         PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
-        boolean isRtl = orientationHandler.getRecentsRtlSetting(getResources());
+        boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
         LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
         int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
         LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
         switch (orientationHandler.getRotation()) {
             case Surface.ROTATION_90:
-                iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
+                iconParams.gravity = (isRtl ? START : END) | CENTER_VERTICAL;
                 iconParams.rightMargin = -thumbnailPadding;
                 iconParams.leftMargin = 0;
                 iconParams.topMargin = snapshotParams.topMargin / 2;
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index a98aad1..8889560 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -64,24 +64,46 @@
     }
 
     /**
-     * Logs an event and accompanying {@link ItemInfo}
+     * Logs a {@link LauncherEvent}.
      */
+    @Override
+    public void log(LauncherEvent event) {
+        log(event, DEFAULT_INSTANCE_ID, LauncherAtom.ItemInfo.getDefaultInstance());
+    }
+
+    /**
+     * Logs an event and accompanying {@link InstanceId}.
+     */
+    @Override
+    public void log(LauncherEvent event, InstanceId instanceId) {
+        log(event, instanceId, LauncherAtom.ItemInfo.getDefaultInstance());
+    }
+
+    /**
+     * Logs an event and accompanying {@link ItemInfo}.
+     */
+    @Override
     public void log(LauncherEvent event, LauncherAtom.ItemInfo itemInfo) {
         log(event, DEFAULT_INSTANCE_ID, itemInfo);
     }
 
     /**
-     * Logs an event and accompanying {@link LauncherAtom.ItemInfo}
+     * Logs an event and accompanying {@link InstanceId} and {@link LauncherAtom.ItemInfo}.
      */
     @Override
     public void log(LauncherEvent event, InstanceId instanceId, LauncherAtom.ItemInfo itemInfo) {
         if (IS_VERBOSE) {
-            Log.d(TAG, String.format("\n%s\n%s", event.name(), itemInfo));
+            Log.d(TAG, instanceId == DEFAULT_INSTANCE_ID
+                    ? String.format("\n%s\n%s", event.name(), itemInfo)
+                    : String.format("%s(InstanceId:%s)\n%s", event.name(), instanceId, itemInfo));
         }
+
         if (!Utilities.ATLEAST_R) {
             return;
         }
-        SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_EVENT,
+
+        SysUiStatsLog.write(
+                SysUiStatsLog.LAUNCHER_EVENT,
                 SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
                 SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__HOME /* TODO */,
                 SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__BACKGROUND /* TODO */,
@@ -118,6 +140,7 @@
     }
 
     private class SnapshotWorker extends BaseModelUpdateTask {
+
         @Override
         public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
             IntSparseArrayMap<FolderInfo> folders = dataModel.folders.clone();
@@ -140,6 +163,7 @@
             }
         }
     }
+
     private static void writeSnapshot(LauncherAtom.ItemInfo itemInfo) {
         if (IS_VERBOSE) {
             Log.d(TAG, "\nwriteSnapshot:" + itemInfo);
diff --git a/quickstep/src/com/android/quickstep/util/WindowSizeStrategy.java b/quickstep/src/com/android/quickstep/util/WindowSizeStrategy.java
index dce6f67..b088ba8 100644
--- a/quickstep/src/com/android/quickstep/util/WindowSizeStrategy.java
+++ b/quickstep/src/com/android/quickstep/util/WindowSizeStrategy.java
@@ -56,35 +56,41 @@
 
     private void calculateTaskSize(
             Context context, DeviceProfile dp, float extraVerticalSpace, Rect outRect) {
-        float taskWidth, taskHeight, paddingHorz;
         Resources res = context.getResources();
-        Rect insets = dp.getInsets();
         final boolean showLargeTaskSize = showOverviewActions(context);
 
+        final int paddingResId;
+        if (dp.isMultiWindowMode) {
+            paddingResId = R.dimen.multi_window_task_card_horz_space;
+        } else if (dp.isVerticalBarLayout()) {
+            paddingResId = R.dimen.landscape_task_card_horz_space;
+        } else if (showLargeTaskSize) {
+            paddingResId = R.dimen.portrait_task_card_horz_space_big_overview;
+        } else {
+            paddingResId = R.dimen.portrait_task_card_horz_space;
+        }
+        float paddingHorz = res.getDimension(paddingResId);
+        float paddingVert = showLargeTaskSize
+                ? 0 : res.getDimension(R.dimen.task_card_vert_space);
+
+        calculateTaskSizeInternal(context, dp, extraVerticalSpace, paddingHorz, paddingVert,
+                res.getDimension(R.dimen.task_thumbnail_top_margin), outRect);
+    }
+
+    private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
+            float extraVerticalSpace, float paddingHorz, float paddingVert, float topIconMargin,
+            Rect outRect) {
+        float taskWidth, taskHeight;
+        Rect insets = dp.getInsets();
         if (dp.isMultiWindowMode) {
             WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
             taskWidth = bounds.availableSize.x;
             taskHeight = bounds.availableSize.y;
-            paddingHorz = res.getDimension(R.dimen.multi_window_task_card_horz_space);
         } else {
             taskWidth = dp.availableWidthPx;
             taskHeight = dp.availableHeightPx;
-
-            final int paddingResId;
-            if (dp.isVerticalBarLayout()) {
-                paddingResId = R.dimen.landscape_task_card_horz_space;
-            } else if (showLargeTaskSize) {
-                paddingResId = R.dimen.portrait_task_card_horz_space_big_overview;
-            } else {
-                paddingResId = R.dimen.portrait_task_card_horz_space;
-            }
-            paddingHorz = res.getDimension(paddingResId);
         }
 
-        float topIconMargin = res.getDimension(R.dimen.task_thumbnail_top_margin);
-        float paddingVert = showLargeTaskSize
-                ? 0 : res.getDimension(R.dimen.task_card_vert_space);
-
         // Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless
         // we override the insets ourselves.
         int launcherVisibleWidth = dp.widthPx - insets.left - insets.right;
@@ -110,47 +116,16 @@
      * Calculates the modal taskView size for the provided device configuration
      */
     public void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect) {
-        float taskWidth, taskHeight, paddingHorz;
-        Resources res = context.getResources();
-        Rect insets = dp.getInsets();
-
-        if (dp.isMultiWindowMode) {
-            getMultiWindowSize(context, dp, mTempPoint);
-            taskWidth = mTempPoint.x;
-            taskHeight = mTempPoint.y;
-            paddingHorz = res.getDimension(R.dimen.multi_window_task_card_horz_space);
-        } else {
-            taskWidth = dp.availableWidthPx;
-            taskHeight = dp.availableHeightPx;
-
-            final int paddingResId;
-            if (dp.isVerticalBarLayout()) {
-                paddingResId = R.dimen.landscape_task_card_horz_space;
-            } else {
-                paddingResId = R.dimen.portrait_modal_task_card_horz_space;
-            }
-            paddingHorz = res.getDimension(paddingResId);
-        }
-
-        // Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless
-        // we override the insets ourselves.
-        int launcherVisibleWidth = dp.widthPx - insets.left - insets.right;
-        int launcherVisibleHeight = dp.heightPx - insets.top - insets.bottom;
-
-        // Calculate for the overview height.
-        float overviewActionsHeight = getOverviewActionsHeight(context);
-        float availableHeight = launcherVisibleHeight - overviewActionsHeight;
-        float availableWidth = launcherVisibleWidth - paddingHorz;
-
-        float scale = Math.min(availableWidth / taskWidth, availableHeight / taskHeight);
-        float outWidth = scale * taskWidth;
-        float outHeight = scale * taskHeight;
-
-        // Center in the visible space
-        float x = insets.left + (launcherVisibleWidth - outWidth) / 2;
-        float y = insets.top + (launcherVisibleHeight - overviewActionsHeight - outHeight) / 2;
-        outRect.set(Math.round(x), Math.round(y),
-                Math.round(x) + Math.round(outWidth), Math.round(y) + Math.round(outHeight));
+        float paddingHorz = context.getResources().getDimension(dp.isMultiWindowMode
+                ? R.dimen.multi_window_task_card_horz_space
+                : dp.isVerticalBarLayout()
+                        ? R.dimen.landscape_task_card_horz_space
+                        : R.dimen.portrait_modal_task_card_horz_space);
+        float extraVerticalSpace = getOverviewActionsHeight(context);
+        float paddingVert = 0;
+        float topIconMargin = 0;
+        calculateTaskSizeInternal(context, dp, extraVerticalSpace, paddingHorz, paddingVert,
+                topIconMargin, outRect);
     }
 
     /** Gets the space that the overview actions will take, including margins. */
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 79ed2b8..60b6da6 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -60,6 +60,7 @@
 import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.model.data.PromiseAppInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.util.SafeCloseable;
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.IconLabelDotView;
 
@@ -744,11 +745,12 @@
     }
 
     @Override
-    public void prepareDrawDragView() {
+    public SafeCloseable prepareDrawDragView() {
         if (getIcon() instanceof FastBitmapDrawable) {
             FastBitmapDrawable icon = (FastBitmapDrawable) getIcon();
             icon.setScale(1f);
         }
         setForceHideDot(true);
+        return () -> { };
     }
 }
diff --git a/src/com/android/launcher3/dragndrop/DraggableView.java b/src/com/android/launcher3/dragndrop/DraggableView.java
index 287c781..f7dcf6b 100644
--- a/src/com/android/launcher3/dragndrop/DraggableView.java
+++ b/src/com/android/launcher3/dragndrop/DraggableView.java
@@ -18,6 +18,10 @@
 
 import android.graphics.Rect;
 
+import androidx.annotation.NonNull;
+
+import com.android.launcher3.util.SafeCloseable;
+
 /**
  * Interface defining methods required for drawing and previewing DragViews, drag previews, and
  * related animations
@@ -42,9 +46,12 @@
     int getViewType();
 
     /**
-     * Before rendering as a DragView bitmap, some views need a preparation step.
+     * Before rendering as a DragView bitmap, some views need a preparation step. Returns a
+     * callback to clear any preparation work
      */
-    default void prepareDrawDragView() { }
+    @NonNull default SafeCloseable prepareDrawDragView() {
+        return () -> { };
+    }
 
     /**
      * If an actual View subclass, this method returns the rectangle (within the View's coordinates)
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index 634d07e..21822a3 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -35,6 +35,7 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dragndrop.DraggableView;
 import com.android.launcher3.icons.BitmapRenderer;
+import com.android.launcher3.util.SafeCloseable;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 
 import java.nio.ByteBuffer;
@@ -76,11 +77,12 @@
 
         if (mView instanceof DraggableView) {
             DraggableView dv = (DraggableView) mView;
-            dv.prepareDrawDragView();
-            dv.getSourceVisualDragBounds(mTempRect);
-            destCanvas.translate(blurSizeOutline / 2 - mTempRect.left,
-                    blurSizeOutline / 2 - mTempRect.top);
-            mView.draw(destCanvas);
+            try (SafeCloseable t = dv.prepareDrawDragView()) {
+                dv.getSourceVisualDragBounds(mTempRect);
+                destCanvas.translate(blurSizeOutline / 2 - mTempRect.left,
+                        blurSizeOutline / 2 - mTempRect.top);
+                mView.draw(destCanvas);
+            }
         }
         destCanvas.restoreToCount(saveCount);
     }
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index c62f308..350f221 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -81,10 +81,12 @@
             binderDied();
         }
 
+        SurfaceControlViewHost.SurfacePackage surfacePackage;
         try {
             mSurfaceControlViewHost = MAIN_EXECUTOR
                     .submit(() -> new SurfaceControlViewHost(mContext, mDisplay, mHostToken))
                     .get(5, TimeUnit.SECONDS);
+            surfacePackage = mSurfaceControlViewHost.getSurfacePackage();
             mHostToken.linkToDeath(this, 0);
         } catch (Exception e) {
             e.printStackTrace();
@@ -92,6 +94,14 @@
         }
 
         MAIN_EXECUTOR.execute(() -> {
+            // If mSurfaceControlViewHost is null due to any reason (e.g. binder died,
+            // happening when user leaves the preview screen before preview rendering finishes),
+            // we should return here.
+            SurfaceControlViewHost host = mSurfaceControlViewHost;
+            if (host == null) {
+                return;
+            }
+
             View view = new LauncherPreviewRenderer(mContext, mIdp).getRenderedView();
             // This aspect scales the view to fit in the surface and centers it
             final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(),
@@ -107,14 +117,14 @@
                     .setInterpolator(new AccelerateDecelerateInterpolator())
                     .setDuration(FADE_IN_ANIMATION_DURATION)
                     .start();
-            mSurfaceControlViewHost.setView(view, view.getMeasuredWidth(),
+            host.setView(view, view.getMeasuredWidth(),
                     view.getMeasuredHeight());
         });
 
         Bundle result = new Bundle();
-        result.putParcelable(KEY_SURFACE_PACKAGE, mSurfaceControlViewHost.getSurfacePackage());
+        result.putParcelable(KEY_SURFACE_PACKAGE, surfacePackage);
 
-        Handler handler = new Handler(Looper.getMainLooper(), Loopermessage -> {
+        Handler handler = new Handler(Looper.getMainLooper(), message -> {
             binderDied();
             return true;
         });
@@ -128,8 +138,10 @@
     @Override
     public void binderDied() {
         if (mSurfaceControlViewHost != null) {
-            mSurfaceControlViewHost.release();
-            mSurfaceControlViewHost = null;
+            MAIN_EXECUTOR.execute(() -> {
+                mSurfaceControlViewHost.release();
+                mSurfaceControlViewHost = null;
+            });
         }
         mHostToken.unlinkToDeath(this, 0);
     }
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 309263d..ee9322b 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -16,10 +16,8 @@
 package com.android.launcher3.logging;
 
 import android.content.Context;
-import android.util.Log;
 
 import com.android.launcher3.R;
-import com.android.launcher3.logger.LauncherAtom;
 import com.android.launcher3.logger.LauncherAtom.ItemInfo;
 import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
 import com.android.launcher3.util.ResourceBasedOverride;
@@ -32,8 +30,6 @@
  */
 public class StatsLogManager implements ResourceBasedOverride {
 
-    private static final String TAG = "StatsLogManager";
-
     interface EventEnum {
         int getId();
     }
@@ -88,9 +84,11 @@
         // ADD MORE
 
         private final int mId;
+
         LauncherEvent(int id) {
             mId = id;
         }
+
         public int getId() {
             return mId;
         }
@@ -113,22 +111,32 @@
     }
 
     /**
-     * Logs an event and accompanying {@link ItemInfo}
+     * Logs a {@link LauncherEvent}.
      */
-    public void log(LauncherEvent event, InstanceId instanceId) {
-        Log.d(TAG, String.format("%s(InstanceId:%s)", event.name(), instanceId));
-        // Call StatsLog method
+    public void log(LauncherEvent event) {
     }
 
     /**
-     * Logs an event and accompanying {@link LauncherAtom.ItemInfo}
+     * Logs an event and accompanying {@link InstanceId}.
      */
-    public void log(LauncherEvent event, InstanceId instanceId, LauncherAtom.ItemInfo itemInfo) { }
-    public void log(LauncherEvent event, LauncherAtom.ItemInfo itemInfo) { }
+    public void log(LauncherEvent event, InstanceId instanceId) {
+    }
 
+    /**
+     * Logs an event and accompanying {@link ItemInfo}.
+     */
+    public void log(LauncherEvent event, ItemInfo itemInfo) {
+    }
+
+    /**
+     * Logs an event and accompanying {@link InstanceId} and {@link ItemInfo}.
+     */
+    public void log(LauncherEvent event, InstanceId instanceId, ItemInfo itemInfo) {
+    }
 
     /**
      * Logs snapshot, or impression of the current workspace.
      */
-    public void logSnapshot() { }
+    public void logSnapshot() {
+    }
 }
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index da081a0..7818ff5 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -145,7 +145,9 @@
         LauncherEvent event = newLauncherEvent(action,  targets);
         ItemInfo info = v == null ? null : (ItemInfo) v.getTag();
         if (info != null && Utilities.IS_DEBUG_DEVICE && FeatureFlags.ENABLE_HYBRID_HOTSEAT.get()) {
-            FileLog.d(TAG, "appLaunch: packageName:" + info.getTargetComponent().getPackageName()
+            final String pkg = info.getTargetComponent() != null
+                    ? info.getTargetComponent().getPackageName() : "unknown";
+            FileLog.d(TAG, "appLaunch: packageName:" + pkg
                     + ",isWorkApp:" + (info.user != null && !Process.myUserHandle().equals(
                     userHandle)) + ",launchLocation:" + info.container);
         }
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 5007ca0..d02c731 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -33,7 +33,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.LinearLayout;
 
-import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.PagedView;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.OverScroller;
@@ -74,8 +73,8 @@
     }
 
     @Override
-    public boolean isGoingUp(float displacement) {
-        return displacement > 0;
+    public boolean isGoingUp(float displacement, boolean isRtl) {
+        return isRtl ? displacement < 0 : displacement > 0;
     }
 
     @Override
@@ -226,13 +225,13 @@
     }
 
     @Override
-    public int getShortEdgeLength(DeviceProfile dp) {
-        return dp.heightPx;
+    public int getTaskDismissDirectionFactor() {
+        return 1;
     }
 
     @Override
-    public int getTaskDismissDirectionFactor() {
-        return 1;
+    public int getTaskDragDisplacementFactor(boolean isRtl) {
+        return isRtl ? 1 : -1;
     }
 
     @Override
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index cdfe6d5..2e0268d 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -75,8 +75,8 @@
     int getScrollOffsetStart(View view, Rect insets);
     int getScrollOffsetEnd(View view, Rect insets);
     SingleAxisSwipeDetector.Direction getOppositeSwipeDirection();
-    int getShortEdgeLength(DeviceProfile dp);
     int getTaskDismissDirectionFactor();
+    int getTaskDragDisplacementFactor(boolean isRtl);
     ChildBounds getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild);
     void setMaxScroll(AccessibilityEvent event, int maxScroll);
     boolean getRecentsRtlSetting(Resources resources);
@@ -91,7 +91,7 @@
     void delegateScrollBy(PagedView pagedView, int unboundedScroll, int x, int y);
     void scrollerStartScroll(OverScroller scroller, int newPosition);
     void getCurveProperties(PagedView view, Rect insets, CurveProperties out);
-    boolean isGoingUp(float displacement);
+    boolean isGoingUp(float displacement, boolean isRtl);
     boolean isLayoutNaturalToLauncher();
     float getTaskMenuX(float x, View thumbnailView);
     float getTaskMenuY(float y, View thumbnailView);
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 25dc1f6..2fc7a9f 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -32,7 +32,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.LinearLayout;
 
-import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.PagedView;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.OverScroller;
@@ -73,7 +72,8 @@
     }
 
     @Override
-    public boolean isGoingUp(float displacement) {
+    public boolean isGoingUp(float displacement, boolean isRtl) {
+        // Ignore rtl since it only affects X value displacement, Y displacement doesn't change
         return displacement < 0;
     }
 
@@ -223,13 +223,14 @@
     }
 
     @Override
-    public int getShortEdgeLength(DeviceProfile dp) {
-        return dp.widthPx;
+    public int getTaskDismissDirectionFactor() {
+        return -1;
     }
 
     @Override
-    public int getTaskDismissDirectionFactor() {
-        return -1;
+    public int getTaskDragDisplacementFactor(boolean isRtl) {
+        // Ignore rtl since it only affects X value displacement, Y displacement doesn't change
+        return 1;
     }
 
     @Override
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index dde2829..4c1700e 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -32,6 +32,11 @@
     }
 
     @Override
+    public int getTaskDragDisplacementFactor(boolean isRtl) {
+        return isRtl ? -1 : 1;
+    }
+
+    @Override
     public boolean getRecentsRtlSetting(Resources resources) {
         return Utilities.isRtl(resources);
     }
@@ -60,8 +65,8 @@
     }
 
     @Override
-    public boolean isGoingUp(float displacement) {
-        return displacement < 0;
+    public boolean isGoingUp(float displacement, boolean isRtl) {
+        return isRtl ? displacement > 0 : displacement < 0;
     }
 
     @Override
@@ -82,13 +87,8 @@
     }
 
     @Override
-    public int getClearAllScrollOffset(View view, boolean isRtl) {
-        return (isRtl ? view.getPaddingTop() : - view.getPaddingBottom()) / 2;
-    }
-
-    @Override
     public void setPrimaryAndResetSecondaryTranslate(View view, float translation) {
         view.setTranslationX(0);
-        view.setTranslationY(-translation);
+        view.setTranslationY(translation);
     }
 }
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 6e9c5a0..14212be 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -436,6 +436,13 @@
                 sEventChecker.finishNoWait();
             }
         }
+        // b/156287114
+        try {
+            log("Input: " + mDevice.executeShellCommand("dumpsys input"));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
         log("Hierarchy dump for: " + message);
         dumpViewHierarchy();
 
diff --git a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
index ac90b1b..79d20ac 100644
--- a/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
+++ b/tests/tapl/com/android/launcher3/tapl/LogEventChecker.java
@@ -207,7 +207,9 @@
 
     // Workaround for b/154157191
     private static boolean ignoreMistatch(boolean successfulGesture, String sequence) {
-        return TestProtocol.SEQUENCE_TIS.equals(sequence) && successfulGesture;
+        // b/156287114
+        return false;
+//        return TestProtocol.SEQUENCE_TIS.equals(sequence) && successfulGesture;
     }
 
     // If the list of actual events matches the list of expected events, returns -1, otherwise