From 75bd844765b4195e98ee458336373b60b6b09ea6 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Thu, 23 Dec 2021 16:50:06 +0800 Subject: [PATCH] Fix rotation bounds on devices have cut-out When rotate callback, system inset value still not updated so it should be calculated itself by DisplayLayout. Migrate this from legacy split screen. Fix: 211843962 Test: manual Test: pass existing tests Change-Id: Ibdb23d20754ac06843e0ccaa673564eb50e7c264 --- .../wm/shell/common/split/SplitLayout.java | 24 ++++++++++--------- .../shell/splitscreen/StageCoordinator.java | 16 ++++++++++++- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index a9e0c489150b6..f7c92fed55225 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -123,7 +123,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange mDividerWindowWidth = mDividerSize + 2 * mDividerInsets; mRootBounds.set(configuration.windowConfiguration.getBounds()); - mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds); + mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null); resetDividerPosition(); } @@ -201,7 +201,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange mTempRect.set(mRootBounds); mRootBounds.set(rootBounds); mRotation = rotation; - mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds); + mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null); initDividerPosition(mTempRect); if (mInitialized) { @@ -212,8 +212,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange return true; } - /** Rotate the layout to specific rotation and assume its new bounds. */ - public void rotateTo(int newRotation) { + /** Rotate the layout to specific rotation and calculate new bounds. The stable insets value + * should be calculated by display layout. */ + public void rotateTo(int newRotation, Rect stableInsets) { final int rotationDelta = (newRotation - mRotation + 4) % 4; final boolean changeOrient = (rotationDelta % 2) != 0; @@ -223,11 +224,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange tmpRect.set(mRootBounds.top, mRootBounds.left, mRootBounds.bottom, mRootBounds.right); } - final Configuration config = new Configuration(); - config.setTo(mContext.getResources().getConfiguration()); - config.orientation = mOrientation; - config.windowConfiguration.setBounds(tmpRect); - updateConfiguration(config); + // We only need new bounds here, other configuration should be update later. + mTempRect.set(mRootBounds); + mRootBounds.set(tmpRect); + mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, stableInsets); + initDividerPosition(mTempRect); } private void initDividerPosition(Rect oldBounds) { @@ -372,7 +373,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange return mDividerSnapAlgorithm.calculateSnapTarget(position, velocity, hardDismiss); } - private DividerSnapAlgorithm getSnapAlgorithm(Context context, Rect rootBounds) { + private DividerSnapAlgorithm getSnapAlgorithm(Context context, Rect rootBounds, + @Nullable Rect stableInsets) { final boolean isLandscape = isLandscape(rootBounds); return new DividerSnapAlgorithm( context.getResources(), @@ -380,7 +382,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange rootBounds.height(), mDividerSize, !isLandscape, - getDisplayInsets(context), + stableInsets != null ? stableInsets : getDisplayInsets(context), isLandscape ? DOCKED_LEFT : DOCKED_TOP /* dockSide */); } 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 2385ec90ab232..378180f9996ca 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 @@ -57,6 +57,7 @@ import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.WindowConfiguration; import android.content.Context; +import android.content.res.Configuration; import android.graphics.Rect; import android.hardware.devicestate.DeviceStateManager; import android.os.Bundle; @@ -87,6 +88,7 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.DisplayInsetsController; +import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TransactionPool; import com.android.wm.shell.common.split.SplitLayout; @@ -133,6 +135,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, private final SideStage mSideStage; private final StageListenerImpl mSideStageListener = new StageListenerImpl(); private final StageTaskUnfoldController mSideUnfoldController; + private final DisplayLayout mDisplayLayout; @SplitPosition private int mSideStagePosition = SPLIT_POSITION_BOTTOM_OR_RIGHT; @@ -234,6 +237,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions, mOnTransitionAnimationComplete); mDisplayController.addDisplayWindowListener(this); + mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId)); transitions.addHandler(this); } @@ -267,6 +271,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mLogger = logger; mRecentTasks = recentTasks; mDisplayController.addDisplayWindowListener(this); + mDisplayLayout = new DisplayLayout(); transitions.addHandler(this); } @@ -1084,6 +1089,14 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mDisplayController.addDisplayChangingController(this::onRotateDisplay); } + @Override + public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) { + if (displayId != DEFAULT_DISPLAY) { + return; + } + mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId)); + } + private void onRotateDisplay(int displayId, int fromRotation, int toRotation, WindowContainerTransaction wct) { if (!mMainStage.isActive()) return; @@ -1092,7 +1105,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, final SurfaceControl.Transaction t = mTransactionPool.acquire(); setDividerVisibility(false, t); - mSplitLayout.rotateTo(toRotation); + mDisplayLayout.rotateTo(mContext.getResources(), toRotation); + mSplitLayout.rotateTo(toRotation, mDisplayLayout.stableInsets()); updateWindowBounds(mSplitLayout, wct); updateUnfoldBounds(); t.apply();