Merge "Fix stuck if resize split quickly" into udc-dev

This commit is contained in:
Tony Huang
2023-03-01 06:43:52 +00:00
committed by Android (Google) Code Review
6 changed files with 58 additions and 12 deletions

View File

@@ -371,7 +371,14 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
mViewHost.relayout(lp); mViewHost.relayout(lp);
} }
void setInteractive(boolean interactive, String from) { /**
* Set divider should interactive to user or not.
*
* @param interactive divider interactive.
* @param hideHandle divider handle hidden or not, only work when interactive is false.
* @param from caller from where.
*/
void setInteractive(boolean interactive, boolean hideHandle, String from) {
if (interactive == mInteractive) return; if (interactive == mInteractive) return;
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
"Set divider bar %s from %s", interactive ? "interactive" : "non-interactive", "Set divider bar %s from %s", interactive ? "interactive" : "non-interactive",
@@ -387,7 +394,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
mMoving = false; mMoving = false;
} }
releaseTouching(); releaseTouching();
mHandle.setVisibility(mInteractive ? View.VISIBLE : View.INVISIBLE); mHandle.setVisibility(!mInteractive && hideHandle ? View.INVISIBLE : View.VISIBLE);
} }
private boolean isLandscape() { private boolean isLandscape() {

View File

@@ -485,6 +485,17 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mWinBounds2.setEmpty(); mWinBounds2.setEmpty();
} }
/**
* Set divider should interactive to user or not.
*
* @param interactive divider interactive.
* @param hideHandle divider handle hidden or not, only work when interactive is false.
* @param from caller from where.
*/
public void setDividerInteractive(boolean interactive, boolean hideHandle, String from) {
mSplitWindowManager.setInteractive(interactive, hideHandle, from);
}
/** /**
* Sets new divide position and updates bounds correspondingly. Notifies listener if the new * Sets new divide position and updates bounds correspondingly. Notifies listener if the new
* target indicates dismissing split. * target indicates dismissing split.
@@ -735,21 +746,28 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
} }
} }
/** Apply recorded task layout to the {@link WindowContainerTransaction}. */ /** Apply recorded task layout to the {@link WindowContainerTransaction}.
public void applyTaskChanges(WindowContainerTransaction wct, *
* @return true if stage bounds actually update.
*/
public boolean applyTaskChanges(WindowContainerTransaction wct,
ActivityManager.RunningTaskInfo task1, ActivityManager.RunningTaskInfo task2) { ActivityManager.RunningTaskInfo task1, ActivityManager.RunningTaskInfo task2) {
boolean boundsChanged = false;
if (!mBounds1.equals(mWinBounds1) || !task1.token.equals(mWinToken1)) { if (!mBounds1.equals(mWinBounds1) || !task1.token.equals(mWinToken1)) {
wct.setBounds(task1.token, mBounds1); wct.setBounds(task1.token, mBounds1);
wct.setSmallestScreenWidthDp(task1.token, getSmallestWidthDp(mBounds1)); wct.setSmallestScreenWidthDp(task1.token, getSmallestWidthDp(mBounds1));
mWinBounds1.set(mBounds1); mWinBounds1.set(mBounds1);
mWinToken1 = task1.token; mWinToken1 = task1.token;
boundsChanged = true;
} }
if (!mBounds2.equals(mWinBounds2) || !task2.token.equals(mWinToken2)) { if (!mBounds2.equals(mWinBounds2) || !task2.token.equals(mWinToken2)) {
wct.setBounds(task2.token, mBounds2); wct.setBounds(task2.token, mBounds2);
wct.setSmallestScreenWidthDp(task2.token, getSmallestWidthDp(mBounds2)); wct.setSmallestScreenWidthDp(task2.token, getSmallestWidthDp(mBounds2));
mWinBounds2.set(mBounds2); mWinBounds2.set(mBounds2);
mWinToken2 = task2.token; mWinToken2 = task2.token;
boundsChanged = true;
} }
return boundsChanged;
} }
private int getSmallestWidthDp(Rect bounds) { private int getSmallestWidthDp(Rect bounds) {
@@ -1091,7 +1109,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
// ImePositionProcessor#onImeVisibilityChanged directly in DividerView is not enough // ImePositionProcessor#onImeVisibilityChanged directly in DividerView is not enough
// because DividerView won't receive onImeVisibilityChanged callback after it being // because DividerView won't receive onImeVisibilityChanged callback after it being
// re-inflated. // re-inflated.
mSplitWindowManager.setInteractive(!mImeShown || !mHasImeFocus || isFloating, setDividerInteractive(!mImeShown || !mHasImeFocus || isFloating, true,
"onImeStartPositioning"); "onImeStartPositioning");
return needOffset ? IME_ANIMATION_NO_ALPHA : 0; return needOffset ? IME_ANIMATION_NO_ALPHA : 0;
@@ -1118,7 +1136,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
// Restore the split layout when wm-shell is not controlling IME insets anymore. // Restore the split layout when wm-shell is not controlling IME insets anymore.
if (!controlling && mImeShown) { if (!controlling && mImeShown) {
reset(); reset();
mSplitWindowManager.setInteractive(true, "onImeControlTargetChanged"); setDividerInteractive(true, true, "onImeControlTargetChanged");
mSplitLayoutHandler.setLayoutOffsetTarget(0, 0, SplitLayout.this); mSplitLayoutHandler.setLayoutOffsetTarget(0, 0, SplitLayout.this);
mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this); mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this);
} }

View File

@@ -168,9 +168,16 @@ public final class SplitWindowManager extends WindowlessWindowManager {
} }
} }
void setInteractive(boolean interactive, String from) { /**
* Set divider should interactive to user or not.
*
* @param interactive divider interactive.
* @param hideHandle divider handle hidden or not, only work when interactive is false.
* @param from caller from where.
*/
void setInteractive(boolean interactive, boolean hideHandle, String from) {
if (mDividerView == null) return; if (mDividerView == null) return;
mDividerView.setInteractive(interactive, from); mDividerView.setInteractive(interactive, hideHandle, from);
} }
View getDividerView() { View getDividerView() {

View File

@@ -340,6 +340,12 @@ class SplitScreenTransitions {
IBinder startResizeTransition(WindowContainerTransaction wct, IBinder startResizeTransition(WindowContainerTransaction wct,
Transitions.TransitionHandler handler, Transitions.TransitionHandler handler,
@Nullable TransitionFinishedCallback finishCallback) { @Nullable TransitionFinishedCallback finishCallback) {
if (mPendingResize != null) {
mPendingResize.cancel(null);
mAnimations.clear();
onFinish(null /* wct */, null /* wctCB */);
}
IBinder transition = mTransitions.startTransition(TRANSIT_CHANGE, wct, handler); IBinder transition = mTransitions.startTransition(TRANSIT_CHANGE, wct, handler);
setResizeTransition(transition, finishCallback); setResizeTransition(transition, finishCallback);
return transition; return transition;

View File

@@ -1925,10 +1925,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
} }
final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction();
updateWindowBounds(layout, wct); boolean sizeChanged = updateWindowBounds(layout, wct);
if (!sizeChanged) return;
sendOnBoundsChanged(); sendOnBoundsChanged();
if (ENABLE_SHELL_TRANSITIONS) { if (ENABLE_SHELL_TRANSITIONS) {
mSplitTransitions.startResizeTransition(wct, this, null /* callback */); mSplitLayout.setDividerInteractive(false, false, "onSplitResizeStart");
mSplitTransitions.startResizeTransition(wct, this, (finishWct, t) ->
mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish"));
} else { } else {
mSyncQueue.queue(wct); mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> { mSyncQueue.runInSync(t -> {
@@ -1947,13 +1951,16 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
/** /**
* Populates `wct` with operations that match the split windows to the current layout. * Populates `wct` with operations that match the split windows to the current layout.
* To match relevant surfaces, make sure to call updateSurfaceBounds after `wct` is applied * To match relevant surfaces, make sure to call updateSurfaceBounds after `wct` is applied
*
* @return true if stage bounds actually .
*/ */
private void updateWindowBounds(SplitLayout layout, WindowContainerTransaction wct) { private boolean updateWindowBounds(SplitLayout layout, WindowContainerTransaction wct) {
final StageTaskListener topLeftStage = final StageTaskListener topLeftStage =
mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage; mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
final StageTaskListener bottomRightStage = final StageTaskListener bottomRightStage =
mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage; mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
layout.applyTaskChanges(wct, topLeftStage.mRootTaskInfo, bottomRightStage.mRootTaskInfo); return layout.applyTaskChanges(wct, topLeftStage.mRootTaskInfo,
bottomRightStage.mRootTaskInfo);
} }
void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t, void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t,

View File

@@ -134,6 +134,7 @@ public class StageCoordinatorTests extends ShellTestCase {
when(mSplitLayout.getBounds2()).thenReturn(mBounds2); when(mSplitLayout.getBounds2()).thenReturn(mBounds2);
when(mSplitLayout.getRootBounds()).thenReturn(mRootBounds); when(mSplitLayout.getRootBounds()).thenReturn(mRootBounds);
when(mSplitLayout.isLandscape()).thenReturn(false); when(mSplitLayout.isLandscape()).thenReturn(false);
when(mSplitLayout.applyTaskChanges(any(), any(), any())).thenReturn(true);
mRootTask = new TestRunningTaskInfoBuilder().build(); mRootTask = new TestRunningTaskInfoBuilder().build();
mRootLeash = new SurfaceControl.Builder(mSurfaceSession).setName("test").build(); mRootLeash = new SurfaceControl.Builder(mSurfaceSession).setName("test").build();