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

Commit 2fe07269 authored by Yongjin Kwon's avatar Yongjin Kwon Committed by Vishnu Nair
Browse files

[wm]: Fixed layout problem in PolicyControl immersive mode

If immersive mode is enabled by policy_control Setting, immersive mode is
forcibly applied to all windows. And systemui flags for immersive mode are
added to non fullscreen window by system. If non fullscreen window requests
BOTTOM gravity layout, it is covered by input method window.

Ensure content frame according to input method window.

Test: manual - manually enable immersive mode with next command.
adb shell settings put global policy_control "immersive.full=*"
And select input field in dialog window which has BOTTOM gravity.
Test: atest WmTests:DisplayPolicyLayoutTests
Bug: 129711077

Change-Id: I22617878d2025327b8323ef4dd03d043da2da552
(cherry picked from commit d90433afee1438c5a4a1a9be92343a197fa53cd7)
parent 503be6e6
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;

import com.android.internal.annotations.VisibleForTesting;

import java.io.PrintWriter;
import java.io.StringWriter;

@@ -51,7 +53,8 @@ class PolicyControl {
    private static final String TAG = "PolicyControl";
    private static final boolean DEBUG = false;

    private static final String NAME_IMMERSIVE_FULL = "immersive.full";
    @VisibleForTesting
    static final String NAME_IMMERSIVE_FULL = "immersive.full";
    private static final String NAME_IMMERSIVE_STATUS = "immersive.status";
    private static final String NAME_IMMERSIVE_NAVIGATION = "immersive.navigation";
    private static final String NAME_IMMERSIVE_PRECONFIRMATIONS = "immersive.preconfirms";
@@ -67,15 +70,19 @@ class PolicyControl {
                : (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility);
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
            vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
                    | View.SYSTEM_UI_FLAG_FULLSCREEN;
            if (attrs.isFullscreen()) {
                vis |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
            }
            vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.STATUS_BAR_TRANSLUCENT);
        }
        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
            vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
            if (attrs.isFullscreen()) {
                vis |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
            }
            vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.NAVIGATION_BAR_TRANSLUCENT);
        }
@@ -144,7 +151,8 @@ class PolicyControl {
        }
    }

    private static void setFilters(String value) {
    @VisibleForTesting
    static void setFilters(String value) {
        if (DEBUG) Slog.d(TAG, "setFilters: " + value);
        sImmersiveStatusFilter = null;
        sImmersiveNavigationFilter = null;
+114 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@@ -56,15 +57,23 @@ import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.WindowManager;

import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;

import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.utils.WmDisplayCutout;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Tests for the {@link DisplayPolicy} class.
 *
 * Build/Install/Run:
 *  atest WmTests:DisplayPolicyLayoutTests
 */
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
@@ -93,6 +102,12 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
        attrs.format = PixelFormat.TRANSLUCENT;
    }

    @After
    public void tearDown() {
        PolicyControl.setFilters("");
        mWindow.getDisplayContent().mInputMethodTarget = null;
    }

    public void setRotation(int rotation) {
        mRotation = rotation;
        updateDisplayFrames();
@@ -393,6 +408,105 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
    }

    @FlakyTest(bugId = 129711077)
    @Test
    public void layoutWindowLw_withImmersive_SoftInputAdjustResize() {
        synchronized (mWm.mGlobalLock) {
            mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
            mWindow.mAttrs.flags = 0;
            mWindow.mAttrs.systemUiVisibility =
                    SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION;

            addWindow(mWindow);

            mWindow.getDisplayContent().mInputMethodTarget = mWindow;
            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
            mFrames.mContent.bottom = mFrames.mVoiceContent.bottom = INPUT_METHOD_WINDOW_TOP;
            mFrames.mCurrent.bottom = INPUT_METHOD_WINDOW_TOP;
            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

            int bottomInset = mFrames.mDisplayHeight - INPUT_METHOD_WINDOW_TOP;
            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
            assertInsetByTopBottom(mWindow.getContentFrameLw(), 0, 0);
            assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, bottomInset);
        }
    }

    @FlakyTest(bugId = 129711077)
    @Test
    public void layoutWindowLw_withImmersive_SoftInputAdjustNothing() {
        synchronized (mWm.mGlobalLock) {
            mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_NOTHING;
            mWindow.mAttrs.flags = 0;
            mWindow.mAttrs.systemUiVisibility =
                    SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION;

            addWindow(mWindow);

            mWindow.getDisplayContent().mInputMethodTarget = mWindow;
            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
            mFrames.mContent.bottom = mFrames.mVoiceContent.bottom = INPUT_METHOD_WINDOW_TOP;
            mFrames.mCurrent.bottom = INPUT_METHOD_WINDOW_TOP;
            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
            assertInsetByTopBottom(mWindow.getContentFrameLw(), 0, 0);
            assertInsetByTopBottom(mWindow.getVisibleFrameLw(), 0, 0);
        }
    }

    @FlakyTest(bugId = 129711077)
    @Test
    public void layoutWindowLw_withForceImmersive_fullscreen() {
        synchronized (mWm.mGlobalLock) {
            mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
            mWindow.mAttrs.flags = 0;
            mWindow.mAttrs.systemUiVisibility = 0;
            PolicyControl.setFilters(PolicyControl.NAME_IMMERSIVE_FULL + "=*");

            addWindow(mWindow);

            mWindow.getDisplayContent().mInputMethodTarget = mWindow;
            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
            mFrames.mContent.bottom = mFrames.mVoiceContent.bottom = INPUT_METHOD_WINDOW_TOP;
            mFrames.mCurrent.bottom = INPUT_METHOD_WINDOW_TOP;
            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

            int bottomInset = mFrames.mDisplayHeight - INPUT_METHOD_WINDOW_TOP;
            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
            assertInsetByTopBottom(mWindow.getContentFrameLw(), 0, 0);
            assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, bottomInset);
        }
    }

    @FlakyTest(bugId = 129711077)
    @Test
    public void layoutWindowLw_withForceImmersive_nonFullscreen() {
        synchronized (mWm.mGlobalLock) {
            mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
            mWindow.mAttrs.flags = 0;
            mWindow.mAttrs.systemUiVisibility = 0;
            mWindow.mAttrs.width = DISPLAY_WIDTH / 2;
            mWindow.mAttrs.height = DISPLAY_HEIGHT / 2;
            PolicyControl.setFilters(PolicyControl.NAME_IMMERSIVE_FULL + "=*");

            addWindow(mWindow);

            mWindow.getDisplayContent().mInputMethodTarget = mWindow;
            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
            mFrames.mContent.bottom = mFrames.mVoiceContent.bottom = INPUT_METHOD_WINDOW_TOP;
            mFrames.mCurrent.bottom = INPUT_METHOD_WINDOW_TOP;
            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

            int bottomInset = mFrames.mDisplayHeight - INPUT_METHOD_WINDOW_TOP;
            assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, bottomInset);
            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, bottomInset);
            assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, bottomInset);
        }
    }

    @Test
    public void layoutHint_appWindow() {
        // Initialize DisplayFrames
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
    static final int STATUS_BAR_HEIGHT = 10;
    static final int NAV_BAR_HEIGHT = 15;
    static final int DISPLAY_CUTOUT_HEIGHT = 8;
    static final int INPUT_METHOD_WINDOW_TOP = 585;

    DisplayPolicy mDisplayPolicy;