[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)
This commit is contained in:
committed by
Vishnu Nair
parent
503be6e625
commit
2fe072693b
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user