Make display frame compatible
The display frame is used to limit the windows boundary. The frame is the same as the parent frame in most cases if the window is not attched. However, if a window doesn't have any layout related window/sysui flags and the soft input mode is not ADJUST_RESIZE, the display frame doesn't need to be inset by IME (but the parent frame does). Fix: 163435784 Test: atest ViewRootImplTest DisplayPolicyLayoutTests Merged-In: Ia61933120027642d1f0e0a490546071ca2b6c853 Change-Id: Ia61933120027642d1f0e0a490546071ca2b6c853
This commit is contained in:
@@ -53,6 +53,9 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CO
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
|
||||
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
|
||||
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
|
||||
@@ -1449,11 +1452,10 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
// Don't lose the mode we last auto-computed.
|
||||
if ((attrs.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
|
||||
if ((attrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
|
||||
== WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
|
||||
mWindowAttributes.softInputMode = (mWindowAttributes.softInputMode
|
||||
& ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
|
||||
| (oldSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);
|
||||
& ~SOFT_INPUT_MASK_ADJUST) | (oldSoftInputMode & SOFT_INPUT_MASK_ADJUST);
|
||||
}
|
||||
|
||||
if (mWindowAttributes.softInputMode != oldSoftInputMode) {
|
||||
@@ -2073,6 +2075,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
final int sysUiVis = inOutParams.systemUiVisibility | inOutParams.subtreeSystemUiVisibility;
|
||||
final int flags = inOutParams.flags;
|
||||
final int type = inOutParams.type;
|
||||
final int adjust = inOutParams.softInputMode & SOFT_INPUT_MASK_ADJUST;
|
||||
|
||||
if ((inOutParams.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) {
|
||||
inOutParams.insetsFlags.appearance = 0;
|
||||
@@ -2098,12 +2101,13 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
inOutParams.privateFlags &= ~PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
|
||||
|
||||
if ((inOutParams.privateFlags & PRIVATE_FLAG_FIT_INSETS_CONTROLLED) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int types = inOutParams.getFitInsetsTypes();
|
||||
int sides = inOutParams.getFitInsetsSides();
|
||||
boolean ignoreVis = inOutParams.isFitInsetsIgnoringVisibility();
|
||||
|
||||
if (((sysUiVis & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0
|
||||
@@ -2118,10 +2122,13 @@ public final class ViewRootImpl implements ViewParent,
|
||||
if (type == TYPE_TOAST || type == TYPE_SYSTEM_ALERT) {
|
||||
ignoreVis = true;
|
||||
} else if ((types & Type.systemBars()) == Type.systemBars()) {
|
||||
types |= Type.ime();
|
||||
if (adjust == SOFT_INPUT_ADJUST_RESIZE) {
|
||||
types |= Type.ime();
|
||||
} else {
|
||||
inOutParams.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
|
||||
}
|
||||
}
|
||||
inOutParams.setFitInsetsTypes(types);
|
||||
inOutParams.setFitInsetsSides(sides);
|
||||
inOutParams.setFitInsetsIgnoringVisibility(ignoreVis);
|
||||
|
||||
// The fitting of insets are not really controlled by the clients, so we remove the flag.
|
||||
@@ -2491,8 +2498,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
|
||||
if (mFirst || mAttachInfo.mViewVisibilityChanged) {
|
||||
mAttachInfo.mViewVisibilityChanged = false;
|
||||
int resizeMode = mSoftInputMode &
|
||||
WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
|
||||
int resizeMode = mSoftInputMode & SOFT_INPUT_MASK_ADJUST;
|
||||
// If we are in auto resize mode, then we need to determine
|
||||
// what mode to use now.
|
||||
if (resizeMode == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
|
||||
@@ -2505,11 +2511,8 @@ public final class ViewRootImpl implements ViewParent,
|
||||
if (resizeMode == 0) {
|
||||
resizeMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
|
||||
}
|
||||
if ((lp.softInputMode &
|
||||
WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) != resizeMode) {
|
||||
lp.softInputMode = (lp.softInputMode &
|
||||
~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) |
|
||||
resizeMode;
|
||||
if ((lp.softInputMode & SOFT_INPUT_MASK_ADJUST) != resizeMode) {
|
||||
lp.softInputMode = (lp.softInputMode & ~SOFT_INPUT_MASK_ADJUST) | resizeMode;
|
||||
params = lp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2032,6 +2032,12 @@ public interface WindowManager extends ViewManager {
|
||||
*/
|
||||
public static final int PRIVATE_FLAG_FIT_INSETS_CONTROLLED = 0x10000000;
|
||||
|
||||
/**
|
||||
* Flag to indicate that the parent frame of a window should be inset by IME.
|
||||
* @hide
|
||||
*/
|
||||
public static final int PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME = 0x40000000;
|
||||
|
||||
/**
|
||||
* An internal annotation for flags that can be specified to {@link #softInputMode}.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,7 @@ import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
|
||||
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
|
||||
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
|
||||
@@ -117,7 +118,15 @@ public class ViewRootImplTest {
|
||||
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
|
||||
ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
|
||||
|
||||
// A window which fits system bars must fit IME, unless its type is toast or system alert.
|
||||
assertEquals(Type.systemBars(), attrs.getFitInsetsTypes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void adjustLayoutParamsForCompatibility_fitSystemBarsAndIme() {
|
||||
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
|
||||
attrs.softInputMode |= SOFT_INPUT_ADJUST_RESIZE;
|
||||
ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
|
||||
|
||||
assertEquals(Type.systemBars() | Type.ime(), attrs.getFitInsetsTypes());
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT;
|
||||
import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
|
||||
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
|
||||
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_IME;
|
||||
import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT;
|
||||
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
|
||||
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
||||
@@ -71,6 +72,7 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M
|
||||
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
|
||||
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
|
||||
@@ -2191,6 +2193,13 @@ public class DisplayPolicy {
|
||||
df.set(left, top, dfu.right - right, dfu.bottom - bottom);
|
||||
if (attached == null) {
|
||||
pf.set(df);
|
||||
if ((pfl & PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME) != 0) {
|
||||
final InsetsSource source = mDisplayContent.getInsetsPolicy()
|
||||
.getInsetsForDispatch(win).peekSource(ITYPE_IME);
|
||||
if (source != null) {
|
||||
pf.inset(source.calculateInsets(pf, false /* ignoreVisibility */));
|
||||
}
|
||||
}
|
||||
vf.set(adjust != SOFT_INPUT_ADJUST_NOTHING
|
||||
? displayFrames.mCurrent : displayFrames.mDock);
|
||||
} else {
|
||||
|
||||
@@ -36,6 +36,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
|
||||
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
|
||||
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
|
||||
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
@@ -348,6 +349,24 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
|
||||
assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layoutWindowLw_insetParentFrameByIme() {
|
||||
final InsetsState state =
|
||||
mDisplayContent.getInsetsStateController().getRawInsetsState();
|
||||
state.getSource(InsetsState.ITYPE_IME).setVisible(true);
|
||||
state.getSource(InsetsState.ITYPE_IME).setFrame(
|
||||
0, DISPLAY_HEIGHT - IME_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT);
|
||||
mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
|
||||
mWindow.mBehindIme = true;
|
||||
addWindow(mWindow);
|
||||
|
||||
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
|
||||
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
|
||||
|
||||
assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
|
||||
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, IME_HEIGHT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layoutWindowLw_fitDisplayCutout() {
|
||||
addDisplayCutout();
|
||||
|
||||
@@ -62,7 +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;
|
||||
static final int IME_HEIGHT = 415;
|
||||
|
||||
DisplayPolicy mDisplayPolicy;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user