diff options
| author | 2022-04-13 18:13:52 +0800 | |
|---|---|---|
| committer | 2022-04-13 18:13:52 +0800 | |
| commit | e467b6e722316e54be6053e0798a635d0207c4e6 (patch) | |
| tree | 9e1c07674b4a1add74607b77a7829522303e5aba | |
| parent | eb1eb03859559e48fcd2cbefb8b100523ac08d6c (diff) | |
Fix InsetsState#calculateVisibleInsets
Before the new insets system, a window wouldn't receive visible insets
if it:
- has FLAG_LAYOUT_NO_LIMITS,
- is not TYPE_WALLPAPER or TYPE_SYSTEM_ERROR, and
- is not in multi-window mode.
This CL makes the visible insets compatible with the legacy insets
system.
Fix: 223536648
Test: atest InsetsStateTest
Change-Id: Ia73142cfae701d0532a9a397366c50aeef82abb2
9 files changed, 55 insertions, 36 deletions
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 7b6a0d64f980..cce3e8c84451 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 b1b630ed7353..eb746080de15 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 a3d0bf79416b..35b2d5893246 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2570,7 +2570,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 1c6d93da092c..c846175699f2 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 2f7c0152207f..1db4bbba9ad5 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 bf8bb76891d7..be9da11057a2 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,11 +432,28 @@ 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)); mState.getSource(ITYPE_STATUS_BAR).setVisible(true); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index a46544d6c902..dde89ba2e35f 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -2780,9 +2780,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 4d262efd03d0..a2e0bf063617 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 e7d4877ce514..238f96ffd1e1 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<WindowState> 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); } |