diff --git a/services/core/java/com/android/server/wm/PolicyControl.java b/services/core/java/com/android/server/wm/PolicyControl.java index 4c8ce9ebb72cc..0f92bc83a6666 100644 --- a/services/core/java/com/android/server/wm/PolicyControl.java +++ b/services/core/java/com/android/server/wm/PolicyControl.java @@ -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; diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index 2a3731a2e4835..67b7a66b4794e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -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 diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java index 2933b4a460d82..d4558dc29fda0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java @@ -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;