From 31838fb8dd9402e719eec129a185637e05c0f88c Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Wed, 23 Mar 2022 18:36:16 +0000 Subject: [PATCH] Consolidate split screen rotation in shell transition 1. Prevent updating split layout twice during rotation with configuration changed. If the only difference is orientation, it means we've handled bounds changes for rotation before, the only thing thing left is to make sure divider bar will be rendered with proper resources that matching with the new orientation. 2. When handling child task changes, make sure to also update crop if it's not sharing the same bounds with its parent. 3. Also exclude adjusting bounds of tasks created-by-organizer while display changed, since the organizer created them should handle that instead. This is needed to prevent their bounds being rotated twice in organizer and wm-core. Bug: 207185041 Bug: 206487881 Test: atest WMShellUnitTests Test: enable shell-transition, enter split screen, check the rotation behavior of split screen. Change-Id: I63e4a8566bdc4f3fcad7d4bae59fa23ad03929ac --- .../wm/shell/common/split/SplitLayout.java | 20 +++++++++---------- .../shell/splitscreen/StageCoordinator.java | 8 ++++---- .../transition/DefaultTransitionHandler.java | 10 +++++++++- .../shell/common/split/SplitLayoutTests.java | 5 ----- .../core/java/com/android/server/wm/Task.java | 2 +- 5 files changed, 24 insertions(+), 21 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 065da3119a954..116d3524e711d 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 @@ -201,24 +201,24 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange /** Applies new configuration, returns {@code false} if there's no effect to the layout. */ public boolean updateConfiguration(Configuration configuration) { + // Always update configuration after orientation changed to make sure to render divider bar + // with proper resources that matching screen orientation. + final int orientation = configuration.orientation; + if (mOrientation != orientation) { + mContext = mContext.createConfigurationContext(configuration); + mSplitWindowManager.setConfiguration(configuration); + mOrientation = orientation; + } + // Update the split bounds when necessary. Besides root bounds changed, split bounds need to // be updated when the rotation changed to cover the case that users rotated the screen 180 // degrees. - // Make sure to render the divider bar with proper resources that matching the screen - // orientation. final int rotation = configuration.windowConfiguration.getRotation(); final Rect rootBounds = configuration.windowConfiguration.getBounds(); - final int orientation = configuration.orientation; - - if (mOrientation == orientation - && rotation == mRotation - && mRootBounds.equals(rootBounds)) { + if (mRotation == rotation && mRootBounds.equals(rootBounds)) { return false; } - mContext = mContext.createConfigurationContext(configuration); - mSplitWindowManager.setConfiguration(configuration); - mOrientation = orientation; mTempRect.set(mRootBounds); mRootBounds.set(rootBounds); mRotation = rotation; 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 2304ef8b82105..1378a1ad39df9 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 @@ -1228,13 +1228,10 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Only do this when shell transition if (!ENABLE_SHELL_TRANSITIONS) return; - final SurfaceControl.Transaction t = mTransactionPool.acquire(); mDisplayLayout.rotateTo(mContext.getResources(), toRotation); mSplitLayout.rotateTo(toRotation, mDisplayLayout.stableInsets()); updateWindowBounds(mSplitLayout, wct); updateUnfoldBounds(); - t.apply(); - mTransactionPool.release(t); } private void onFoldedStateChanged(boolean folded) { @@ -1286,7 +1283,10 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask(); if (triggerTask == null) { if (mMainStage.isActive()) { - if (request.getType() == TRANSIT_CHANGE && request.getDisplayChange() != null) { + final TransitionRequestInfo.DisplayChange displayChange = + request.getDisplayChange(); + if (request.getType() == TRANSIT_CHANGE && displayChange != null + && displayChange.getStartRotation() != displayChange.getEndRotation()) { mSplitLayout.setFreezeDividerWindow(true); } // Still want to monitor everything while in split-screen, so return non-null. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index b0e44a15b0dab..542ddeea769c0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -369,12 +369,20 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } if (change.getMode() == TRANSIT_CHANGE) { - // If task is child task, only set position in parent. + // If task is child task, only set position in parent and update crop when needed. if (isTask && change.getParent() != null && info.getChange(change.getParent()).getTaskInfo() != null) { final Point positionInParent = change.getTaskInfo().positionInParent; startTransaction.setPosition(change.getLeash(), positionInParent.x, positionInParent.y); + + if (!change.getEndAbsBounds().equals( + info.getChange(change.getParent()).getEndAbsBounds())) { + startTransaction.setWindowCrop(change.getLeash(), + change.getEndAbsBounds().width(), + change.getEndAbsBounds().height()); + } + continue; } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java index daec336fc71ee..8b4e1f8bfdb74 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java @@ -16,7 +16,6 @@ package com.android.wm.shell.common.split; -import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static com.google.common.truth.Truth.assertThat; @@ -85,10 +84,6 @@ public class SplitLayoutTests extends ShellTestCase { // Verify it returns true if new config won't affect split layout. assertThat(mSplitLayout.updateConfiguration(config)).isFalse(); - // Verify updateConfiguration returns true if the orientation changed. - config.orientation = ORIENTATION_LANDSCAPE; - assertThat(mSplitLayout.updateConfiguration(config)).isTrue(); - // Verify updateConfiguration returns true if it rotated. config.windowConfiguration.setRotation(1); assertThat(mSplitLayout.updateConfiguration(config)).isTrue(); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 72b7e7939669b..0542c0be57901 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -2701,7 +2701,7 @@ class Task extends TaskFragment { @Override void onDisplayChanged(DisplayContent dc) { final boolean isRootTask = isRootTask(); - if (!isRootTask) { + if (!isRootTask && !mCreatedByOrganizer) { adjustBoundsForDisplayChangeIfNeeded(dc); } super.onDisplayChanged(dc);