From a948d9fc754f02d2c57d1748f40245b726efeadb Mon Sep 17 00:00:00 2001 From: Nicolo' Mazzucato Date: Mon, 6 Dec 2021 18:17:29 +0100 Subject: [PATCH] Do not animate some split screen sides on fold animation Sides adjacent to the divider or the taskbar are not animated anymore Bug: 202396814 Test: atest com.android.wm.shell.splitscreen.StageCoordinatorTests Test: Manual testing Change-Id: I13c5dc6872f457cd303f6f6868be81d349de7f50 --- .../shell/splitscreen/StageCoordinator.java | 10 ++- .../StageTaskUnfoldController.java | 68 ++++++++++++++++--- .../splitscreen/StageCoordinatorTests.java | 12 ++-- 3 files changed, 76 insertions(+), 14 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index e30e6c537c93a..d1feee4803c19 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -965,11 +965,17 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void updateUnfoldBounds() { if (mMainUnfoldController != null && mSideUnfoldController != null) { - mMainUnfoldController.onLayoutChanged(getMainStageBounds()); - mSideUnfoldController.onLayoutChanged(getSideStageBounds()); + mMainUnfoldController.onLayoutChanged(getMainStageBounds(), getMainStagePosition(), + isLandscape()); + mSideUnfoldController.onLayoutChanged(getSideStageBounds(), getSideStagePosition(), + isLandscape()); } } + private boolean isLandscape() { + return mSplitLayout.isLandscape(); + } + /** * 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 diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskUnfoldController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskUnfoldController.java index e904f6a9e22c5..0683a25ecd417 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskUnfoldController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskUnfoldController.java @@ -18,11 +18,15 @@ package com.android.wm.shell.splitscreen; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; +import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; + import android.animation.RectEvaluator; import android.animation.TypeEvaluator; import android.annotation.NonNull; import android.app.ActivityManager; import android.content.Context; +import android.graphics.Insets; import android.graphics.Rect; import android.util.SparseArray; import android.view.InsetsSource; @@ -33,6 +37,7 @@ import com.android.internal.policy.ScreenDecorationsUtils; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener; import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.unfold.ShellUnfoldProgressProvider; import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener; import com.android.wm.shell.unfold.UnfoldBackgroundController; @@ -161,12 +166,13 @@ public class StageTaskUnfoldController implements UnfoldListener, OnInsetsChange * Called when split screen stage bounds changed * @param bounds new bounds for this stage */ - public void onLayoutChanged(Rect bounds) { + public void onLayoutChanged(Rect bounds, @SplitPosition int splitPosition, + boolean isLandscape) { mStageBounds.set(bounds); for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) { final AnimationContext context = mAnimationContextByTaskId.valueAt(i); - context.update(); + context.update(splitPosition, isLandscape); } } @@ -195,20 +201,27 @@ public class StageTaskUnfoldController implements UnfoldListener, OnInsetsChange final Rect mEndCropRect = new Rect(); final Rect mCurrentCropRect = new Rect(); + private @SplitPosition int mSplitPosition = SPLIT_POSITION_UNDEFINED; + private boolean mIsLandscape = false; + private AnimationContext(SurfaceControl leash) { this.mLeash = leash; update(); } + private void update(@SplitPosition int splitPosition, boolean isLandscape) { + this.mSplitPosition = splitPosition; + this.mIsLandscape = isLandscape; + update(); + } + private void update() { mStartCropRect.set(mStageBounds); - if (mTaskbarInsetsSource != null) { + boolean taskbarExpanded = isTaskbarExpanded(); + if (taskbarExpanded) { // Only insets the cropping window with taskbar when taskbar is expanded - if (mTaskbarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) { - mStartCropRect.inset(mTaskbarInsetsSource - .calculateVisibleInsets(mStartCropRect)); - } + mStartCropRect.inset(mTaskbarInsetsSource.calculateVisibleInsets(mStartCropRect)); } // Offset to surface coordinates as layout bounds are in screen coordinates @@ -218,7 +231,46 @@ public class StageTaskUnfoldController implements UnfoldListener, OnInsetsChange int maxSize = Math.max(mEndCropRect.width(), mEndCropRect.height()); int margin = (int) (maxSize * CROPPING_START_MARGIN_FRACTION); - mStartCropRect.inset(margin, margin, margin, margin); + + // Sides adjacent to split bar or task bar are not be animated. + Insets margins; + if (mIsLandscape) { // Left and right splits. + margins = getLandscapeMargins(margin, taskbarExpanded); + } else { // Top and bottom splits. + margins = getPortraitMargins(margin, taskbarExpanded); + } + mStartCropRect.inset(margins); + } + + private Insets getLandscapeMargins(int margin, boolean taskbarExpanded) { + int left = margin; + int right = margin; + int bottom = taskbarExpanded ? 0 : margin; // Taskbar margin. + if (mSplitPosition == SPLIT_POSITION_TOP_OR_LEFT) { + right = 0; // Divider margin. + } else { + left = 0; // Divider margin. + } + return Insets.of(left, /* top= */ margin, right, bottom); + } + + private Insets getPortraitMargins(int margin, boolean taskbarExpanded) { + int bottom = margin; + int top = margin; + if (mSplitPosition == SPLIT_POSITION_TOP_OR_LEFT) { + bottom = 0; // Divider margin. + } else { // Bottom split. + top = 0; // Divider margin. + if (taskbarExpanded) { + bottom = 0; // Taskbar margin. + } + } + return Insets.of(/* left= */ margin, top, /* right= */ margin, bottom); + } + + private boolean isTaskbarExpanded() { + return mTaskbarInsetsSource != null + && mTaskbarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight; } } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java index 85f6789c3435f..fb6300c8a4bfd 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java @@ -114,6 +114,7 @@ public class StageCoordinatorTests extends ShellTestCase { when(mSplitLayout.getBounds1()).thenReturn(mBounds1); when(mSplitLayout.getBounds2()).thenReturn(mBounds2); + when(mSplitLayout.isLandscape()).thenReturn(false); } @Test @@ -168,8 +169,9 @@ public class StageCoordinatorTests extends ShellTestCase { mStageCoordinator.onLayoutSizeChanged(mSplitLayout); - verify(mMainUnfoldController).onLayoutChanged(mBounds2); - verify(mSideUnfoldController).onLayoutChanged(mBounds1); + verify(mMainUnfoldController).onLayoutChanged(mBounds2, SPLIT_POSITION_BOTTOM_OR_RIGHT, + false); + verify(mSideUnfoldController).onLayoutChanged(mBounds1, SPLIT_POSITION_TOP_OR_LEFT, false); } @Test @@ -180,8 +182,10 @@ public class StageCoordinatorTests extends ShellTestCase { mStageCoordinator.onLayoutSizeChanged(mSplitLayout); - verify(mMainUnfoldController).onLayoutChanged(mBounds1); - verify(mSideUnfoldController).onLayoutChanged(mBounds2); + verify(mMainUnfoldController).onLayoutChanged(mBounds1, SPLIT_POSITION_TOP_OR_LEFT, + false); + verify(mSideUnfoldController).onLayoutChanged(mBounds2, SPLIT_POSITION_BOTTOM_OR_RIGHT, + false); } @Test