diff options
| author | 2020-06-09 08:35:45 +0000 | |
|---|---|---|
| committer | 2020-06-09 08:35:45 +0000 | |
| commit | 30e24e93fdf0a9b3b0b61f07a419083670ab47af (patch) | |
| tree | 9ad7730ceb17c7c0a989e0f408a5f9249d58efb5 | |
| parent | 84a06dbe0b743955be824769ad6fa1409331cc7c (diff) | |
| parent | 5b12e07b9c8837442a1dc041805e9a919d3cb7b2 (diff) | |
Merge "Insets: allow controlling insets as long as the window is covering in the relevant direction" into rvc-dev am: 5b12e07b9c
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11632046
Change-Id: I4c93f16807003209a8b99cee0aa35081e6b76062
| -rw-r--r-- | core/java/android/view/InsetsController.java | 14 | ||||
| -rw-r--r-- | core/java/android/view/InsetsState.java | 38 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/view/InsetsStateTest.java | 22 |
3 files changed, 62 insertions, 12 deletions
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index ef9edc6c0741..e4d53c64a063 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -791,7 +791,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation WindowInsetsAnimationControlListener listener, boolean fromIme, long durationMs, @Nullable Interpolator interpolator, @AnimationType int animationType) { - if (!checkDisplayFramesForControlling()) { + if ((mState.calculateUncontrollableInsetsFromFrame(mFrame) & types) != 0) { listener.onCancelled(null); return; } @@ -801,13 +801,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation false /* useInsetsAnimationThread */); } - private boolean checkDisplayFramesForControlling() { - - // If the frame of our window doesn't span the entire display, the control API makes very - // little sense, as we don't deal with negative insets. So just cancel immediately. - return mState.getDisplayFrame().equals(mFrame); - } - private void controlAnimationUnchecked(@InsetsType int types, @Nullable CancellationSignal cancellationSignal, WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme, @@ -1285,9 +1278,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } private @InsetsType int calculateControllableTypes() { - if (!checkDisplayFramesForControlling()) { - return 0; - } @InsetsType int result = 0; for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i); @@ -1295,7 +1285,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation result |= toPublicType(consumer.mType); } } - return result; + return result & ~mState.calculateUncontrollableInsetsFromFrame(mFrame); } /** diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 3822ee59b4aa..f0bca260be38 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -245,6 +245,44 @@ public class InsetsState implements Parcelable { return insets.toRect(); } + /** + * Calculate which insets *cannot* be controlled, because the frame does not cover the + * respective side of the inset. + * + * If the frame of our window doesn't cover the entire inset, the control API makes very + * little sense, as we don't deal with negative insets. + */ + @InsetsType + public int calculateUncontrollableInsetsFromFrame(Rect frame) { + int blocked = 0; + for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) { + InsetsSource source = mSources.get(type); + if (source == null) { + continue; + } + if (!canControlSide(frame, getInsetSide( + source.calculateInsets(frame, true /* ignoreVisibility */)))) { + blocked |= toPublicType(type); + } + } + return blocked; + } + + private boolean canControlSide(Rect frame, int side) { + switch (side) { + case ISIDE_LEFT: + case ISIDE_RIGHT: + return frame.left == mDisplayFrame.left && frame.right == mDisplayFrame.right; + case ISIDE_TOP: + case ISIDE_BOTTOM: + return frame.top == mDisplayFrame.top && frame.bottom == mDisplayFrame.bottom; + case ISIDE_FLOATING: + return true; + default: + return false; + } + } + private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility, Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray typeSideMap, @Nullable boolean[] typeVisibilityMap) { diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java index daaf31a6bb65..cd93eeb857f1 100644 --- a/core/tests/coretests/src/android/view/InsetsStateTest.java +++ b/core/tests/coretests/src/android/view/InsetsStateTest.java @@ -27,6 +27,8 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE; import static android.view.WindowInsets.Type.ime; +import static android.view.WindowInsets.Type.navigationBars; +import static android.view.WindowInsets.Type.statusBars; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; @@ -341,6 +343,26 @@ public class InsetsStateTest { } } + @Test + public void testCalculateUncontrollableInsets() throws Exception { + try (InsetsModeSession session = new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_FULL)) { + mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 200, 100)); + mState.getSource(ITYPE_STATUS_BAR).setVisible(true); + mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 200, 300)); + mState.getSource(ITYPE_IME).setVisible(true); + mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(100, 0, 200, 300)); + mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true); + + mState.setDisplayFrame(new Rect(0, 0, 200, 300)); + assertEquals(0, + mState.calculateUncontrollableInsetsFromFrame(new Rect(0, 0, 200, 300))); + assertEquals(statusBars() | ime(), + mState.calculateUncontrollableInsetsFromFrame(new Rect(0, 50, 200, 250))); + assertEquals(navigationBars(), + mState.calculateUncontrollableInsetsFromFrame(new Rect(50, 0, 150, 300))); + } + } + private void assertEqualsAndHashCode() { assertEquals(mState, mState2); assertEquals(mState.hashCode(), mState2.hashCode()); |