Merge "Insets: allow controlling insets as long as the window is covering in the relevant direction" into rvc-dev

This commit is contained in:
Adrian Roos
2020-06-09 08:24:57 +00:00
committed by Android (Google) Code Review
3 changed files with 62 additions and 12 deletions

View File

@@ -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);
}
/**

View File

@@ -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) {

View File

@@ -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());