Merge changes I54e39cc5,Iec62abae into sc-v2-dev am: 14a7d63c23

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/15671418

Change-Id: If86886dc25704f6fd2e864c70987bebd4d940e28
This commit is contained in:
Android Build Prod User
2021-08-25 20:46:42 +00:00
committed by Automerger Merge Worker
8 changed files with 189 additions and 71 deletions
@@ -53,7 +53,6 @@ import com.android.launcher3.statehandlers.DepthController;
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;
@@ -202,33 +201,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
recentsView.switchToScreenshot(thumbnailData, runnable);
}
/**
* 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.
*/
@@ -145,8 +145,9 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
// 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 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
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 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
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,
@@ -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 @@ public class GroupedTaskView extends TaskView {
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 @@ public class GroupedTaskView extends TaskView {
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());
}
}
@@ -575,6 +575,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
*/
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 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
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 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
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 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
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,
@@ -26,6 +26,7 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO
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.MotionEvent;
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;
@@ -381,6 +384,47 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
out2.set(0, screenHeight / 2 + splitDividerSize, screenWidth, screenHeight);
}
@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) {
@@ -19,6 +19,7 @@ package com.android.launcher3.touch;
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.view.accessibility.AccessibilityEvent;
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 @@ public interface PagedOrientationHandler {
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);
@@ -25,6 +25,7 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MA
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.MotionEvent;
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;
@@ -467,6 +470,77 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
mTmpRectF.roundOut(out2);
}
@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) {
@@ -89,12 +89,24 @@ public final class SplitConfigurationOptions {
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;
}
}