Merge "Fix stuck if resize split quickly" into udc-dev am: 2350a1d1a4
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21516440 Change-Id: I69ce354a76e85ed348cf22ecc0fdd1e44143e438 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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() {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user