diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 7b6a0d64f9804..cce3e8c84451d 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -833,10 +833,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } /** - * @see InsetsState#calculateVisibleInsets(Rect, int) + * @see InsetsState#calculateVisibleInsets(Rect, int, int, int, int) */ - public Insets calculateVisibleInsets(@SoftInputModeFlags int softInputMode) { - return mState.calculateVisibleInsets(mFrame, softInputMode); + public Insets calculateVisibleInsets(int windowType, int windowingMode, + @SoftInputModeFlags int softInputMode, int windowFlags) { + return mState.calculateVisibleInsets(mFrame, windowType, windowingMode, softInputMode, + windowFlags); } /** diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index b1b630ed73531..eb746080de15c 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -23,11 +23,11 @@ import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE; import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.indexOf; -import static android.view.WindowInsets.Type.isVisibleInsetsType; import static android.view.WindowInsets.Type.statusBars; import static android.view.WindowInsets.Type.systemBars; import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; 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_SYSTEM_ERROR; @@ -257,7 +257,7 @@ public class InsetsState implements Parcelable { if ((legacyWindowFlags & FLAG_FULLSCREEN) != 0) { compatInsetsTypes &= ~statusBars(); } - if (clearCompatInsets(windowType, legacyWindowFlags, windowingMode)) { + if (clearsCompatInsets(windowType, legacyWindowFlags, windowingMode)) { compatInsetsTypes = 0; } @@ -358,17 +358,23 @@ public class InsetsState implements Parcelable { return insets; } - public Insets calculateVisibleInsets(Rect frame, @SoftInputModeFlags int softInputMode) { + public Insets calculateVisibleInsets(Rect frame, int windowType, int windowingMode, + @SoftInputModeFlags int softInputMode, int windowFlags) { + if (clearsCompatInsets(windowType, windowFlags, windowingMode)) { + return Insets.NONE; + } + final int softInputAdjustMode = softInputMode & SOFT_INPUT_MASK_ADJUST; + final int visibleInsetsTypes = softInputAdjustMode != SOFT_INPUT_ADJUST_NOTHING + ? systemBars() | ime() + : systemBars(); Insets insets = Insets.NONE; for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) { InsetsSource source = mSources[type]; if (source == null) { continue; } - - // Ignore everything that's not a system bar or IME. - int publicType = InsetsState.toPublicType(type); - if (!isVisibleInsetsType(publicType, softInputMode)) { + final int publicType = InsetsState.toPublicType(type); + if ((publicType & visibleInsetsTypes) == 0) { continue; } insets = Insets.max(source.calculateVisibleInsets(frame), insets); @@ -676,7 +682,7 @@ public class InsetsState implements Parcelable { mSources[source.getType()] = source; } - public static boolean clearCompatInsets(int windowType, int windowFlags, int windowingMode) { + public static boolean clearsCompatInsets(int windowType, int windowFlags, int windowingMode) { return (windowFlags & FLAG_LAYOUT_NO_LIMITS) != 0 && windowType != TYPE_WALLPAPER && windowType != TYPE_SYSTEM_ERROR && !WindowConfiguration.inMultiWindowMode(windowingMode); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index f310e7f7b185a..70ba5426fd076 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2572,7 +2572,8 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mContentInsets.set(mLastWindowInsets.getSystemWindowInsets().toRect()); mAttachInfo.mStableInsets.set(mLastWindowInsets.getStableInsets().toRect()); mAttachInfo.mVisibleInsets.set(mInsetsController.calculateVisibleInsets( - mWindowAttributes.softInputMode).toRect()); + mWindowAttributes.type, config.windowConfiguration.getWindowingMode(), + mWindowAttributes.softInputMode, mWindowAttributes.flags).toRect()); } return mLastWindowInsets; } diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index 1c6d93da092cb..c846175699f2a 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -32,8 +32,6 @@ import static android.view.WindowInsets.Type.all; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.indexOf; import static android.view.WindowInsets.Type.systemBars; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import android.annotation.IntDef; import android.annotation.IntRange; @@ -46,7 +44,6 @@ import android.graphics.Rect; import android.util.SparseArray; import android.view.View.OnApplyWindowInsetsListener; import android.view.WindowInsets.Type.InsetsType; -import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethod; @@ -1600,17 +1597,6 @@ public final class WindowInsets { public static @InsetsType int all() { return 0xFFFFFFFF; } - - /** - * Checks whether the specified type is considered to be part of visible insets. - * @hide - */ - public static boolean isVisibleInsetsType(int type, - @SoftInputModeFlags int softInputModeFlags) { - int softInputMode = softInputModeFlags & SOFT_INPUT_MASK_ADJUST; - return (type & Type.systemBars()) != 0 - || (softInputMode != SOFT_INPUT_ADJUST_NOTHING && (type & Type.ime()) != 0); - } } /** diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 2f7c0152207fb..1db4bbba9ad5a 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -22,7 +22,7 @@ import static android.os.Build.VERSION_CODES.M; import static android.os.Build.VERSION_CODES.N; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; -import static android.view.InsetsState.clearCompatInsets; +import static android.view.InsetsState.clearsCompatInsets; import static android.view.View.MeasureSpec.AT_MOST; import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.getMode; @@ -1120,11 +1120,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind : controller.getSystemBarsAppearance(); if (insets != null) { - final boolean clearCompatInsets = clearCompatInsets(attrs.type, attrs.flags, + final boolean clearsCompatInsets = clearsCompatInsets(attrs.type, attrs.flags, getResources().getConfiguration().windowConfiguration.getWindowingMode()); final Insets stableBarInsets = insets.getInsetsIgnoringVisibility( WindowInsets.Type.systemBars()); - final Insets systemInsets = clearCompatInsets + final Insets systemInsets = clearsCompatInsets ? Insets.NONE : Insets.min(insets.getInsets(WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout()), stableBarInsets); diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java index bf8bb76891d78..be9da11057a2a 100644 --- a/core/tests/coretests/src/android/view/InsetsStateTest.java +++ b/core/tests/coretests/src/android/view/InsetsStateTest.java @@ -217,7 +217,8 @@ public class InsetsStateTest { mState.getSource(ITYPE_CAPTION_BAR).setVisible(true); Insets visibleInsets = mState.calculateVisibleInsets( - new Rect(0, 0, 100, 400), SOFT_INPUT_ADJUST_NOTHING); + new Rect(0, 0, 100, 400), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */); assertEquals(Insets.of(0, 300, 0, 0), visibleInsets); } @@ -227,7 +228,8 @@ public class InsetsStateTest { mState.getSource(ITYPE_CAPTION_BAR).setVisible(true); Insets visibleInsets = mState.calculateVisibleInsets( - new Rect(0, 0, 150, 400), SOFT_INPUT_ADJUST_NOTHING); + new Rect(0, 0, 150, 400), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */); assertEquals(Insets.of(0, 300, 0, 0), visibleInsets); } @@ -414,7 +416,8 @@ public class InsetsStateTest { mState.getSource(ITYPE_BOTTOM_GESTURES).setFrame(new Rect(0, 100, 100, 300)); mState.getSource(ITYPE_BOTTOM_GESTURES).setVisible(true); Insets visibleInsets = mState.calculateVisibleInsets( - new Rect(0, 0, 100, 300), SOFT_INPUT_ADJUST_PAN); + new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + SOFT_INPUT_ADJUST_PAN, 0 /* windowFlags */); assertEquals(Insets.of(0, 100, 0, 100), visibleInsets); } @@ -429,10 +432,27 @@ public class InsetsStateTest { mState.getSource(ITYPE_BOTTOM_GESTURES).setFrame(new Rect(0, 100, 100, 300)); mState.getSource(ITYPE_BOTTOM_GESTURES).setVisible(true); Insets visibleInsets = mState.calculateVisibleInsets( - new Rect(0, 0, 100, 300), SOFT_INPUT_ADJUST_NOTHING); + new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */); assertEquals(Insets.of(0, 100, 0, 0), visibleInsets); } + @Test + public void testCalculateVisibleInsets_layoutNoLimits() { + mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100)); + mState.getSource(ITYPE_STATUS_BAR).setVisible(true); + mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300)); + mState.getSource(ITYPE_IME).setVisible(true); + + // Make sure bottom gestures are ignored + mState.getSource(ITYPE_BOTTOM_GESTURES).setFrame(new Rect(0, 100, 100, 300)); + mState.getSource(ITYPE_BOTTOM_GESTURES).setVisible(true); + Insets visibleInsets = mState.calculateVisibleInsets( + new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + SOFT_INPUT_ADJUST_PAN, FLAG_LAYOUT_NO_LIMITS); + assertEquals(Insets.NONE, visibleInsets); + } + @Test public void testCalculateUncontrollableInsets() { mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 200, 100)); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index ac048434c0605..0e20b26560043 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -2788,9 +2788,11 @@ class Task extends TaskFragment { } final Rect visibleFrame = sTmpBounds; + final WindowManager.LayoutParams attrs = win.mAttrs; visibleFrame.set(win.getFrame()); visibleFrame.inset(win.getInsetsStateWithVisibilityOverride().calculateVisibleInsets( - visibleFrame, win.mAttrs.softInputMode)); + visibleFrame, attrs.type, win.getWindowingMode(), attrs.softInputMode, + attrs.flags)); out.union(visibleFrame); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 4d262efd03d06..a2e0bf0636173 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1976,8 +1976,10 @@ public class WindowManagerService extends IWindowManager.Stub // We use the visible frame, because we want the animation to morph the window from what // was visible to the user to the final destination of the new window. final Rect frame = new Rect(replacedWindow.getFrame()); + final WindowManager.LayoutParams attrs = replacedWindow.mAttrs; frame.inset(replacedWindow.getInsetsStateWithVisibilityOverride().calculateVisibleInsets( - frame, replacedWindow.mAttrs.softInputMode)); + frame, attrs.type, replacedWindow.getWindowingMode(), attrs.softInputMode, + attrs.flags)); // We treat this as if this activity was opening, so we can trigger the app transition // animation and piggy-back on existing transition animation infrastructure. final DisplayContent dc = activity.getDisplayContent(); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e7d4877ce5142..238f96ffd1e16 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1851,7 +1851,7 @@ class WindowState extends WindowContainer implements WindowManagerP bounds.set(mWindowFrames.mFrame); bounds.inset(getInsetsStateWithVisibilityOverride().calculateVisibleInsets( - bounds, mAttrs.softInputMode)); + bounds, mAttrs.type, getWindowingMode(), mAttrs.softInputMode, mAttrs.flags)); if (intersectWithRootTaskBounds) { bounds.intersect(mTmpRect); }