From 40c0b8bdb97d872ce9278db9a2ac4ee9ac14bb8f Mon Sep 17 00:00:00 2001 From: Yunfan Chen Date: Mon, 13 Dec 2021 18:48:57 +0900 Subject: [PATCH] Introduce a flag to enable shell caption A new interface in WindowManagerProxy was introduced to let the shell be able to set insets with a given frame. The interface won't work for caption as we applied special logic to assemble the caption frame with the attached task frame. To make it work with caption insets, we need to disable all the special logics to make use of the shell interface. A flag CAPTION_ON_SHELL is introduced to disable the calling path and enable the above client owned logic. Turn the flag to true when the caption is moved to shell. Test: InsetsControllerTest, WindowContainerInsetsSourceProviderTest Bug: 189998209 Change-Id: I989b319001a118d1f1ff8e34761b39ee18fde335 --- core/java/android/view/InsetsController.java | 31 ++++++++++++++----- core/java/android/view/ViewRootImpl.java | 9 ++++++ .../android/internal/policy/DecorView.java | 5 ++- .../android/view/InsetsControllerTest.java | 12 +++++++ 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 71c1b7c47a9f4..a4841f6f0d952 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -23,6 +23,7 @@ import static android.view.InsetsState.ITYPE_CAPTION_BAR; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.toInternalType; import static android.view.InsetsState.toPublicType; +import static android.view.ViewRootImpl.CAPTION_ON_SHELL; import static android.view.WindowInsets.Type.all; import static android.view.WindowInsets.Type.ime; @@ -682,9 +683,15 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @VisibleForTesting public boolean onStateChanged(InsetsState state) { - boolean stateChanged = !mState.equals(state, true /* excludingCaptionInsets */, - false /* excludeInvisibleIme */) - || !captionInsetsUnchanged(); + boolean stateChanged = false; + if (!CAPTION_ON_SHELL) { + stateChanged = !mState.equals(state, true /* excludingCaptionInsets */, + false /* excludeInvisibleIme */) + || captionInsetsUnchanged(); + } else { + stateChanged = !mState.equals(state, false /* excludingCaptionInsets */, + false /* excludeInvisibleIme */); + } if (!stateChanged && mLastDispatchedState.equals(state)) { return false; } @@ -758,16 +765,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } private boolean captionInsetsUnchanged() { + if (CAPTION_ON_SHELL) { + return false; + } if (mState.peekSource(ITYPE_CAPTION_BAR) == null && mCaptionInsetsHeight == 0) { - return true; + return false; } if (mState.peekSource(ITYPE_CAPTION_BAR) != null && mCaptionInsetsHeight == mState.peekSource(ITYPE_CAPTION_BAR).getFrame().height()) { - return true; + return false; } - return false; + + return true; } private void startResizingAnimationIfNeeded(InsetsState fromState) { @@ -1582,11 +1593,15 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @Override public void setCaptionInsetsHeight(int height) { + // This method is to be removed once the caption is moved to the shell. + if (CAPTION_ON_SHELL) { + return; + } if (mCaptionInsetsHeight != height) { mCaptionInsetsHeight = height; if (mCaptionInsetsHeight != 0) { - mState.getSource(ITYPE_CAPTION_BAR).setFrame(new Rect(mFrame.left, mFrame.top, - mFrame.right, mFrame.top + mCaptionInsetsHeight)); + mState.getSource(ITYPE_CAPTION_BAR).setFrame(mFrame.left, mFrame.top, + mFrame.right, mFrame.top + mCaptionInsetsHeight); } else { mState.removeSource(ITYPE_CAPTION_BAR); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index bde761e59620b..18e65c9f3a378 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -276,6 +276,12 @@ public final class ViewRootImpl implements ViewParent, */ private static final boolean ENABLE_INPUT_LATENCY_TRACKING = true; + /** + * Whether the caption is drawn by the shell. + * @hide + */ + public static final boolean CAPTION_ON_SHELL = false; + /** * Set this system property to true to force the view hierarchy to render * at 60 Hz. This can be used to measure the potential framerate. @@ -2561,6 +2567,9 @@ public final class ViewRootImpl implements ViewParent, } private boolean updateCaptionInsets() { + if (CAPTION_ON_SHELL) { + return false; + } if (!(mView instanceof DecorView)) return false; final int captionInsetsHeight = ((DecorView) mView).getCaptionInsetsHeight(); final Rect captionFrame = new Rect(); diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 40e40856b0002..89ac722553063 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -30,6 +30,7 @@ import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.getMode; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; +import static android.view.ViewRootImpl.CAPTION_ON_SHELL; import static android.view.Window.DECOR_CAPTION_SHADE_DARK; import static android.view.Window.DECOR_CAPTION_SHADE_LIGHT; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; @@ -2120,7 +2121,9 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind * corresponding insets change to the InsetsController. */ public void notifyCaptionHeightChanged() { - getWindowInsetsController().setCaptionInsetsHeight(getCaptionInsetsHeight()); + if (!CAPTION_ON_SHELL) { + getWindowInsetsController().setCaptionInsetsHeight(getCaptionInsetsHeight()); + } } void setWindow(PhoneWindow phoneWindow) { diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index 227a86576113b..c504f0cf2d943 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -30,6 +30,7 @@ import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.LAST_TYPE; +import static android.view.ViewRootImpl.CAPTION_ON_SHELL; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.navigationBars; import static android.view.WindowInsets.Type.statusBars; @@ -758,6 +759,11 @@ public class InsetsControllerTest { @Test public void testCaptionInsetsStateAssemble() { + if (CAPTION_ON_SHELL) { + // For this case, the test is covered by WindowContainerInsetsSourceProviderTest, This + // test can be removed after the caption is moved to shell completely. + return; + } InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { mController.onFrameChanged(new Rect(0, 0, 100, 300)); final InsetsState state = new InsetsState(mController.getState(), true); @@ -769,6 +775,7 @@ public class InsetsControllerTest { assertEquals(captionFrame, currentState.peekSource(ITYPE_CAPTION_BAR).getFrame()); assertTrue(currentState.equals(state, true /* excludingCaptionInsets*/, true /* excludeInvisibleIme */)); + // Test update to remove the caption bar mController.setCaptionInsetsHeight(0); mController.onStateChanged(state); // The caption bar source should not be there at all, because we don't add empty @@ -779,6 +786,11 @@ public class InsetsControllerTest { @Test public void testNotifyCaptionInsetsOnlyChange() { + if (CAPTION_ON_SHELL) { + // For this case, the test is covered by WindowContainerInsetsSourceProviderTest, This + // test can be removed after the caption is moved to shell completely. + return; + } InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { final InsetsState state = new InsetsState(mController.getState(), true); reset(mTestHost);