Merge changes I54e39cc5,Iec62abae into sc-v2-dev

* changes:
  Set thumbnails for GroupedTaskView based on split layout bounds
  Implement swipe gesture for staged split in landscape
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index e2ef3bc..6298bb8 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -53,7 +53,6 @@
 import com.android.launcher3.statemanager.BaseState;
 import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.WindowBounds;
 import com.android.launcher3.views.ScrimView;
 import com.android.quickstep.SysUINavigationMode.Mode;
@@ -203,33 +202,6 @@
     }
 
     /**
-     * Sets the task size in {@param outRect} taking split screened windows into account.
-     * We assume combined height of both tasks will be same as one normal task, then we'll modify
-     * the task height/width based on the ratio of task screen space bounds from
-     * {@param splitInfo}
-     *
-     * @param desiredStageBounds whether task size for top/left or bottom/right needs to be computed
-     */
-    public final void calculateStagedSplitTaskSize(Context context, DeviceProfile dp, Rect outRect,
-            SplitConfigurationOptions.StagedSplitBounds splitInfo,
-            @SplitConfigurationOptions.StagePosition int desiredStageBounds) {
-        calculateTaskSize(context, dp, outRect);
-
-        // TODO(b/181705607) Change for landscape vs portrait
-        float totalHeight = splitInfo.mLeftTopBounds.height()
-                + splitInfo.mRightBottomBounds.height()
-                + splitInfo.mDividerBounds.height() / 2f;
-        float topTaskPercent = splitInfo.mLeftTopBounds.height() / totalHeight;
-        if (desiredStageBounds == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
-            float diff = outRect.height() * (1f - topTaskPercent);
-            outRect.bottom -= diff;
-        } else {
-            float diff = outRect.height() * topTaskPercent;
-            outRect.top += diff;
-        }
-    }
-
-    /**
      * Calculates the taskView size for the provided device configuration.
      */
     public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect) {
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 7b1c62e..760f665 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -145,8 +145,9 @@
             // The task rect changes according to the staged split task sizes, but recents
             // fullscreen scale and pivot remains the same since the task fits into the existing
             // sized task space bounds
-            mSizeStrategy.calculateStagedSplitTaskSize(mContext, mDp, mTaskRect, mStagedSplitBounds,
-                    mStagePosition);
+            mSizeStrategy.calculateTaskSize(mContext, mDp, mTaskRect);
+            mOrientationState.getOrientationHandler()
+                    .setSplitTaskSwipeRect(mDp, mTaskRect, mStagedSplitBounds, mStagePosition);
         } else {
             mTaskRect.set(fullTaskSize);
         }
@@ -277,13 +278,9 @@
             getFullScreenScale();
             mThumbnailData.rotation = mOrientationState.getDisplayRotation();
 
-            // TODO(b/195145340) handle non 50-50 split scenarios
             if (mStagedSplitBounds != null) {
-                if (mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
-                    // The preview set is for the bottom/right, inset by top/left task
-                    mSplitOffset.y = mStagedSplitBounds.mLeftTopBounds.height() +
-                        mStagedSplitBounds.mDividerBounds.height() / 2;
-                }
+                mOrientationState.getOrientationHandler().setLeashSplitOffset(mSplitOffset, mDp,
+                        mStagedSplitBounds, mStagePosition);
             }
 
             // mIsRecentsRtl is the inverse of TaskView RTL.
@@ -331,7 +328,7 @@
         applyWindowToHomeRotation(mMatrix);
 
         // Move lower/right split window into correct position
-        mMatrix.postTranslate(0, mSplitOffset.y);
+        mMatrix.postTranslate(mSplitOffset.x, mSplitOffset.y);
 
         // Crop rect is the inverse of thumbnail matrix
         mTempRectF.set(-insets.left, -insets.top,
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index cd20f4b..1bc7c75 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -1,13 +1,10 @@
 package com.android.quickstep.views;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
 import android.content.Context;
 import android.util.AttributeSet;
-import android.view.ViewGroup;
 
-import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
+import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.TaskThumbnailCache;
 import com.android.quickstep.util.CancellableTask;
@@ -48,13 +45,14 @@
         mSnapshotView2 = findViewById(R.id.bottomright_snapshot);
     }
 
-    public void bind(Task primary, Task secondary, RecentsOrientedState orientedState) {
+    public void bind(Task primary, Task secondary, RecentsOrientedState orientedState,
+            SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig) {
         super.bind(primary, orientedState);
         mSecondaryTask = secondary;
         mTaskIdContainer[1] = secondary.key.id;
         mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2);
         mSnapshotView2.bind(secondary);
-        adjustThumbnailBoundsForSplit();
+        adjustThumbnailBoundsForSplit(splitBoundsConfig, orientedState);
     }
 
     @Override
@@ -108,30 +106,15 @@
         mSnapshotView2.setOverlayEnabled(overlayEnabled);
     }
 
-    private void adjustThumbnailBoundsForSplit() {
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
-        ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams();
-        primaryLp.width = mSecondaryTask == null ?
-                MATCH_PARENT :
-                getWidth();
-        int spaceAboveSnapshot = deviceProfile.overviewTaskThumbnailTopMarginPx;
-        // TODO get divider height
-        int dividerBar = 20;
-        primaryLp.height = mSecondaryTask == null ?
-                MATCH_PARENT :
-                (getHeight() - spaceAboveSnapshot - dividerBar) / 2;
-        mSnapshotView.setLayoutParams(primaryLp);
-
-        if (mSecondaryTask == null) {
-            mSnapshotView2.setVisibility(GONE);
+    private void adjustThumbnailBoundsForSplit(
+            SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig,
+            RecentsOrientedState orientedState) {
+        if (splitBoundsConfig == null) {
             return;
         }
 
-        mSnapshotView2.setVisibility(VISIBLE);
-        ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
-        secondaryLp.width = getWidth();
-        secondaryLp.height = primaryLp.height;
-        mSnapshotView2.setLayoutParams(secondaryLp);
-        mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
+        orientedState.getOrientationHandler().setGroupedTaskViewThumbnailBounds(
+                mSnapshotView, mSnapshotView2, this, splitBoundsConfig,
+                mActivity.getDeviceProfile());
     }
 }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 2a19ca2..ad41321 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -575,6 +575,7 @@
      */
     private TaskView mSplitHiddenTaskView;
     private TaskView mSecondSplitHiddenTaskView;
+    private SplitConfigurationOptions.StagedSplitBounds mSplitBoundsConfig;
 
     /**
      * Keeps track of the index of the TaskView that split screen was initialized with so we know
@@ -1314,7 +1315,8 @@
                     taskDataIndex--;
                     leftTop = tasks.get(taskDataIndex);
                 }
-                ((GroupedTaskView) taskView).bind(leftTop, rightBottom, mOrientationState);
+                ((GroupedTaskView) taskView).bind(leftTop, rightBottom, mOrientationState,
+                        mSplitBoundsConfig);
             } else {
                 taskView.bind(task, mOrientationState);
             }
@@ -2087,8 +2089,11 @@
                         Task.from(new TaskKey(secondaryTaskInfo), secondaryTaskInfo, false)
                 };
                 addView(taskView, mTaskViewStartIndex);
+                // When we create a placeholder task view mSplitBoundsConfig will be null, but with
+                // the actual app running we won't need to show the thumbnail until all the tasks
+                // load later anyways
                 ((GroupedTaskView)taskView).bind(mTmpRunningTasks[0], mTmpRunningTasks[1],
-                        mOrientationState);
+                        mOrientationState, mSplitBoundsConfig);
             } else {
                 taskView = getTaskViewFromPool(false);
                 addView(taskView, mTaskViewStartIndex);
@@ -4038,12 +4043,13 @@
             mRemoteTargetHandles[1] = new RemoteTargetHandle(secondaryTvs, new TransformParams());
             RemoteAnimationTargetCompat primaryTaskTarget = recentsAnimationTargets.apps[0];
             RemoteAnimationTargetCompat secondaryTaskTarget = recentsAnimationTargets.apps[1];
-            SplitConfigurationOptions.StagedSplitBounds
-                    info = new SplitConfigurationOptions.StagedSplitBounds(
+            mSplitBoundsConfig = new SplitConfigurationOptions.StagedSplitBounds(
                     primaryTaskTarget.screenSpaceBounds,
                     secondaryTaskTarget.screenSpaceBounds, dividerTarget.screenSpaceBounds);
-            mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget, info);
-            mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget, info);
+            mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget,
+                    mSplitBoundsConfig);
+            mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget,
+                    mSplitBoundsConfig);
             RemoteAnimationTargets rats = new RemoteAnimationTargets(
                     new RemoteAnimationTargetCompat[]{primaryTaskTarget},
                     recentsAnimationTargets.wallpapers, recentsAnimationTargets.nonApps,
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 816e5dc..0304a4e 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -26,6 +26,7 @@
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
 
 import android.content.res.Resources;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -35,12 +36,14 @@
 import android.view.Surface;
 import android.view.VelocityTracker;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.LinearLayout;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
 import com.android.launcher3.views.BaseDragLayer;
 
@@ -382,6 +385,47 @@
     }
 
     @Override
+    public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+        float diff;
+        if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
+            diff = outRect.height() * (1f - splitInfo.mLeftTaskPercent);
+            outRect.bottom -= diff;
+        } else {
+            diff = outRect.height() * splitInfo.mLeftTaskPercent;
+            outRect.top += diff;
+        }
+    }
+
+    @Override
+    public void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+        if (desiredStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+            // The preview set is for the bottom/right, inset by top/left task
+            splitOffset.x = splitInfo.mLeftTopBounds.width() + splitInfo.mDividerBounds.width() / 2;
+        }
+    }
+
+    @Override
+    public void setGroupedTaskViewThumbnailBounds(View mSnapshotView, View mSnapshotView2,
+            View taskParent, SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig,
+            DeviceProfile dp) {
+        int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+        int totalThumbnailHeight = taskParent.getHeight() - spaceAboveSnapshot;
+        int totalThumbnailWidth = taskParent.getWidth();
+        int dividerBar = splitBoundsConfig.mDividerBounds.width() / 2;
+        ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams();
+        ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
+
+        primaryLp.width = totalThumbnailWidth;
+        primaryLp.height = (int)(totalThumbnailHeight * splitBoundsConfig.mLeftTaskPercent);
+
+        secondaryLp.width = totalThumbnailWidth;
+        secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar;
+        mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
+    }
+
+    @Override
     public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
             DeviceProfile deviceProfile) {
         return primary;
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index dae2dde..5ef6950 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -19,6 +19,7 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -31,6 +32,7 @@
 import android.widget.LinearLayout;
 
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
 import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
 
@@ -133,6 +135,34 @@
     void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
             SplitPositionOption initialSplitOption, Rect out1, Rect out2);
 
+    /**
+     * @param outRect This is expected to be the rect that has the dimensions for a non-split,
+     *                fullscreen task in overview. This will directly be modified.
+     * @param desiredStagePosition Which stage position (topLeft/rightBottom) we want to resize
+     *                           outRect for
+     */
+    void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo,
+            @SplitConfigurationOptions.StagePosition int desiredStagePosition);
+
+    /**
+     * It's important to note that {@link #setSplitTaskSwipeRect(DeviceProfile, Rect,
+     * SplitConfigurationOptions.StagedSplitBounds, int)} above operates on the outRect based on
+     * launcher's coordinate system, meaning it will treat the outRect as portrait if home rotation
+     * is not allowed.
+     *
+     * However, here the splitOffset is from perspective of TaskViewSimulator, which is in display
+     * orientation coordinates. So, for example, for the fake landscape scenario, even though
+     * launcher is portrait, we inset the bottom/right task by an X coordinate instead of the
+     * usual Y
+     */
+    void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo,
+            @SplitConfigurationOptions.StagePosition int desiredStagePosition);
+
+    void setGroupedTaskViewThumbnailBounds(View mSnapshot1, View mSnapshot2, View taskParent,
+            SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig, DeviceProfile dp);
+
     // Overview TaskMenuView methods
     float getTaskMenuX(float x, View thumbnailView, int overScroll);
     float getTaskMenuY(float y, View thumbnailView, int overScroll);
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 1253589..bc3c0bf 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -25,6 +25,7 @@
 
 import android.content.res.Resources;
 import android.graphics.Matrix;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -34,12 +35,14 @@
 import android.view.Surface;
 import android.view.VelocityTracker;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.LinearLayout;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
 import com.android.launcher3.views.BaseDragLayer;
 
@@ -468,6 +471,77 @@
     }
 
     @Override
+    public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+        boolean isLandscape = dp.isLandscape;
+        float diff;
+        if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
+            if (isLandscape) {
+                diff = outRect.width() * (1f - splitInfo.mLeftTaskPercent);
+                outRect.right -= diff;
+            } else {
+                diff = outRect.height() * (1f - splitInfo.mTopTaskPercent);
+                outRect.bottom -= diff;
+            }
+        } else {
+            if (isLandscape) {
+                diff = outRect.width() * splitInfo.mLeftTaskPercent;
+                outRect.left += diff;
+            } else {
+                diff = outRect.height() * splitInfo.mTopTaskPercent;
+                outRect.top += diff;
+            }
+        }
+    }
+
+    @Override
+    public void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+        if (desiredStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+            if (dp.isLandscape) {
+                splitOffset.x = splitInfo.mLeftTopBounds.width() +
+                        splitInfo.mDividerBounds.width() / 2;
+            } else {
+                splitOffset.y = splitInfo.mLeftTopBounds.height() +
+                        splitInfo.mDividerBounds.height() / 2;
+            }
+        }
+    }
+
+    @Override
+    public void setGroupedTaskViewThumbnailBounds(View mSnapshotView, View mSnapshotView2,
+            View taskParent, SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig,
+            DeviceProfile dp) {
+        int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+        int totalThumbnailHeight = taskParent.getHeight() - spaceAboveSnapshot;
+        int totalThumbnailWidth = taskParent.getWidth();
+        int dividerBar = (dp.isLandscape ?
+                splitBoundsConfig.mDividerBounds.width() :
+                splitBoundsConfig.mDividerBounds.height())
+                / 2;
+        ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams();
+        ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
+
+        if (dp.isLandscape) {
+            primaryLp.height = totalThumbnailHeight;
+            primaryLp.width = (int)(totalThumbnailWidth * splitBoundsConfig.mLeftTaskPercent);
+
+            secondaryLp.height = totalThumbnailHeight;
+            secondaryLp.width = totalThumbnailWidth - primaryLp.width - dividerBar;
+            mSnapshotView2.setTranslationX(primaryLp.width + dividerBar);
+            mSnapshotView2.setTranslationY(spaceAboveSnapshot);
+        } else {
+            primaryLp.width = totalThumbnailWidth;
+            primaryLp.height = (int)(totalThumbnailHeight * splitBoundsConfig.mTopTaskPercent);
+
+            secondaryLp.width = totalThumbnailWidth;
+            secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar;
+            mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
+            mSnapshotView2.setTranslationX(0);
+        }
+    }
+
+    @Override
     public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
             DeviceProfile dp) {
         if (dp.isLandscape) { // or seascape
diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java
index 1f1db9d..b07c21f 100644
--- a/src/com/android/launcher3/util/SplitConfigurationOptions.java
+++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java
@@ -89,12 +89,24 @@
         public final Rect mLeftTopBounds;
         public final Rect mRightBottomBounds;
         public final Rect mDividerBounds;
+        // This class is orientation-agnostic, so we compute both for later use
+        public final float mTopTaskPercent;
+        public final float mLeftTaskPercent;
 
 
         public StagedSplitBounds(Rect leftTopBounds, Rect rightBottomBounds, Rect dividerBounds) {
             mLeftTopBounds = leftTopBounds;
             mRightBottomBounds = rightBottomBounds;
             mDividerBounds = dividerBounds;
+            float totalHeight = mLeftTopBounds.height()
+                    + mRightBottomBounds.height()
+                    + mDividerBounds.height();
+            float totalWidth = mLeftTopBounds.width()
+                    + mRightBottomBounds.width()
+                    + mDividerBounds.width();
+
+            mLeftTaskPercent = mLeftTopBounds.width() / totalWidth;
+            mTopTaskPercent = mLeftTopBounds.height() / totalHeight;
         }
     }