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
This commit is contained in:
Yunfan Chen
2021-12-13 18:48:57 +09:00
parent 6bd34c6b30
commit 40c0b8bdb9
4 changed files with 48 additions and 9 deletions

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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) {

View File

@@ -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);