Consolidate leaving split screen to pip mode behavior
Stop always putting another side to the bottom when a splitting task is
entering pip mode. Leave it to onStageHasChildrenChanged to handle, and
prevent expanding non-visible side to the top after dismissed the split
screen, so flows of leaving split to pip like swipe-to-home or launching
another fullscreen app won't expand another side to top unexpectedly.
When swipe-to-home from a split pair, it dismisses split screen.
However, it also performs fling divider to dismiss animation if one side
of the split is empty due to entering pip. Which might be conflicting
with each other and leaves the split layout modified with the fling
animation but not preperly reset divide position. Update to make sure it
always resets divide position and cancel running fling animation after
split screen dismissed.
Fix: 227727673
Test: atest WMShellUnitTests
Test: verify entering pip from split behavior with back-key, home-key
and launching another fullscreen app.
Video: http://recall/-/fLARJNt42LVxc3tt86SneW/gvATxkQhdJ0APek6RwRHel
http://recall/-/fLARJNt42LVxc3tt86SneW/QfHt9H0XtDNDSP3h1AA8K
http://recall/-/fLARJNt42LVxc3tt86SneW/QnbdeWo2007s8ZuMf1Syn
Change-Id: I2c53ed21e4766d06180e670ee21534cd622db081
This commit is contained in:
@@ -122,6 +122,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
private int mDensity;
|
||||
|
||||
private final boolean mDimNonImeSide;
|
||||
private ValueAnimator mDividerFlingAnimator;
|
||||
|
||||
public SplitLayout(String windowName, Context context, Configuration configuration,
|
||||
SplitLayoutHandler splitLayoutHandler,
|
||||
@@ -395,6 +396,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
mSplitWindowManager.release(t);
|
||||
mDisplayImeController.removePositionProcessor(mImePositionProcessor);
|
||||
mImePositionProcessor.reset();
|
||||
if (mDividerFlingAnimator != null) {
|
||||
mDividerFlingAnimator.cancel();
|
||||
}
|
||||
resetDividerPosition();
|
||||
}
|
||||
|
||||
public void release() {
|
||||
@@ -577,13 +582,18 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
CUJ_SPLIT_SCREEN_RESIZE);
|
||||
return;
|
||||
}
|
||||
ValueAnimator animator = ValueAnimator
|
||||
|
||||
if (mDividerFlingAnimator != null) {
|
||||
mDividerFlingAnimator.cancel();
|
||||
}
|
||||
|
||||
mDividerFlingAnimator = ValueAnimator
|
||||
.ofInt(from, to)
|
||||
.setDuration(duration);
|
||||
animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
animator.addUpdateListener(
|
||||
mDividerFlingAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
mDividerFlingAnimator.addUpdateListener(
|
||||
animation -> updateDivideBounds((int) animation.getAnimatedValue()));
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
mDividerFlingAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (flingFinishedCallback != null) {
|
||||
@@ -591,14 +601,15 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
}
|
||||
InteractionJankMonitorUtils.endTracing(
|
||||
CUJ_SPLIT_SCREEN_RESIZE);
|
||||
mDividerFlingAnimator = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
setDividePosition(to, true /* applyLayoutChange */);
|
||||
mDividerFlingAnimator = null;
|
||||
}
|
||||
});
|
||||
animator.start();
|
||||
mDividerFlingAnimator.start();
|
||||
}
|
||||
|
||||
/** Switch both surface position with animation. */
|
||||
|
||||
@@ -1035,7 +1035,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mIsDividerRemoteAnimating = false;
|
||||
|
||||
mSplitLayout.getInvisibleBounds(mTempRect1);
|
||||
if (childrenToTop == null) {
|
||||
if (childrenToTop == null || childrenToTop.getTopVisibleChildTaskId() == INVALID_TASK_ID) {
|
||||
mSideStage.removeAllTasks(wct, false /* toTop */);
|
||||
mMainStage.deactivate(wct, false /* toTop */);
|
||||
wct.reorder(mRootTaskInfo.token, false /* onTop */);
|
||||
@@ -1294,13 +1294,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
}
|
||||
|
||||
private void onStageChildTaskEnterPip() {
|
||||
// When the exit split-screen is caused by one of the task enters auto pip,
|
||||
// we want both tasks to be put to bottom instead of top, otherwise it will end up
|
||||
// a fullscreen plus a pinned task instead of pinned only at the end of the transition.
|
||||
exitSplitScreen(null, EXIT_REASON_CHILD_TASK_ENTER_PIP);
|
||||
}
|
||||
|
||||
private void updateRecentTasksSplitPair() {
|
||||
if (!mShouldUpdateRecents) {
|
||||
return;
|
||||
@@ -2063,7 +2056,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
// Update divider state after animation so that it is still around and positioned
|
||||
// properly for the animation itself.
|
||||
mSplitLayout.release();
|
||||
mSplitLayout.resetDividerPosition();
|
||||
mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
|
||||
}
|
||||
}
|
||||
@@ -2339,11 +2331,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present, visible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChildTaskEnterPip() {
|
||||
StageCoordinator.this.onStageChildTaskEnterPip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRootTaskVanished() {
|
||||
reset();
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.wm.shell.splitscreen;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
||||
|
||||
@@ -74,8 +73,6 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
|
||||
void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);
|
||||
|
||||
void onChildTaskEnterPip();
|
||||
|
||||
void onRootTaskVanished();
|
||||
|
||||
void onNoLongerSupportMultiWindow();
|
||||
@@ -257,9 +254,6 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
// Status is managed/synchronized by the transition lifecycle.
|
||||
return;
|
||||
}
|
||||
if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
|
||||
mCallbacks.onChildTaskEnterPip();
|
||||
}
|
||||
sendStatusChanged();
|
||||
} else {
|
||||
throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
|
||||
|
||||
Reference in New Issue
Block a user