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: I7757a737ba43aa612b62e20dfcaddb4f3fcee9b4
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user