Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96fd11c7 authored by Jorge Gil's avatar Jorge Gil
Browse files

Remove App Header as an inset source when in full immersive

The App Header visibility is transient when in full immersive mode. It
follows the status bar visibility which is controlled by the user on
swipes on the system bar area. This means the app should not see the App
Header as an inset since it doesn't need to ajust to it. This change
adds a param to skip inset updates when in full immersive mode.

Flag: com.android.window.flags.enable_fully_immersive_in_desktop
Bug: 369444183
Bug: 369444147
Bug: 369443876
Test: atest WMShellUnitTests
Change-Id: I27daf861d37c3817c3ed74e42950ab28692492a9
parent f2c815d6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -815,6 +815,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                        WindowInsets.Type.systemBars() & ~WindowInsets.Type.captionBar(),
                        false /* ignoreVisibility */);
                relayoutParams.mCaptionTopPadding = systemBarInsets.top;
                relayoutParams.mIsInsetSource = false;
            }
            // Report occluding elements as bounding rects to the insets system so that apps can
            // draw in the empty space in the center:
+3 −1
Original line number Diff line number Diff line
@@ -346,7 +346,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>

    private void updateCaptionInsets(RelayoutParams params, WindowContainerTransaction wct,
            RelayoutResult<T> outResult, Rect taskBounds) {
        if (!mIsCaptionVisible) {
        if (!mIsCaptionVisible || !params.mIsInsetSource) {
            if (mWindowDecorationInsets != null) {
                mWindowDecorationInsets.remove(wct);
                mWindowDecorationInsets = null;
@@ -724,6 +724,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        int mCaptionWidthId;
        final List<OccludingCaptionElement> mOccludingCaptionElements = new ArrayList<>();
        int mInputFeatures;
        boolean mIsInsetSource = true;
        @InsetsSource.Flags int mInsetSourceFlags;

        int mShadowRadiusId;
@@ -743,6 +744,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            mCaptionWidthId = Resources.ID_NULL;
            mOccludingCaptionElements.clear();
            mInputFeatures = 0;
            mIsInsetSource = true;
            mInsetSourceFlags = 0;

            mShadowRadiusId = Resources.ID_NULL;
+21 −0
Original line number Diff line number Diff line
@@ -613,6 +613,27 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
        assertThat(relayoutParams.mCaptionTopPadding).isEqualTo(50);
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
    public void updateRelayoutParams_header_notAnInsetsSourceInFullyImmersive() {
        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
        final RelayoutParams relayoutParams = new RelayoutParams();

        DesktopModeWindowDecoration.updateRelayoutParams(
                relayoutParams,
                mTestableContext,
                taskInfo,
                /* applyStartTransactionOnDraw= */ true,
                /* shouldSetTaskPositionAndCrop */ false,
                /* isStatusBarVisible */ true,
                /* isKeyguardVisibleAndOccluded */ false,
                /* inFullImmersiveMode */ true,
                new InsetsState());

        assertThat(relayoutParams.mIsInsetSource).isFalse();
    }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP)
    public void updateRelayoutParams_header_statusBarInvisible_captionVisible() {
+51 −0
Original line number Diff line number Diff line
@@ -649,6 +649,57 @@ public class WindowDecorationTests extends ShellTestCase {
                any(), eq(0) /* index */, eq(mandatorySystemGestures()));
    }

    @Test
    public void testRelayout_notAnInsetsSource_doesNotAddInsets() {
        final Display defaultDisplay = mock(Display.class);
        doReturn(defaultDisplay).when(mMockDisplayController)
                .getDisplay(Display.DEFAULT_DISPLAY);

        final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
                .setDisplayId(Display.DEFAULT_DISPLAY)
                .setVisible(true)
                .setBounds(new Rect(0, 0, 1000, 1000))
                .build();
        final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo);

        mRelayoutParams.mIsInsetSource = false;
        windowDecor.relayout(taskInfo);

        // Never added.
        verify(mMockWindowContainerTransaction, never()).addInsetsSource(eq(taskInfo.token), any(),
                eq(0) /* index */, eq(captionBar()), any(), any(), anyInt());
        verify(mMockWindowContainerTransaction, never()).addInsetsSource(eq(taskInfo.token), any(),
                eq(0) /* index */, eq(mandatorySystemGestures()), any(), any(), anyInt());
    }

    @Test
    public void testRelayout_notAnInsetsSource_hadInsetsBefore_removesInsets() {
        final Display defaultDisplay = mock(Display.class);
        doReturn(defaultDisplay).when(mMockDisplayController)
                .getDisplay(Display.DEFAULT_DISPLAY);

        final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
                .setDisplayId(Display.DEFAULT_DISPLAY)
                .setVisible(true)
                .setBounds(new Rect(0, 0, 1000, 1000))
                .build();
        final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo);

        mRelayoutParams.mIsCaptionVisible = true;
        mRelayoutParams.mIsInsetSource = true;
        windowDecor.relayout(taskInfo);

        mRelayoutParams.mIsCaptionVisible = true;
        mRelayoutParams.mIsInsetSource = false;
        windowDecor.relayout(taskInfo);

        // Insets should be removed.
        verify(mMockWindowContainerTransaction).removeInsetsSource(eq(taskInfo.token), any(),
                eq(0) /* index */, eq(captionBar()));
        verify(mMockWindowContainerTransaction).removeInsetsSource(eq(taskInfo.token), any(),
                eq(0) /* index */, eq(mandatorySystemGestures()));
    }

    @Test
    public void testClose_withExistingInsets_insetsRemoved() {
        final Display defaultDisplay = mock(Display.class);