Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b12e07b authored by Adrian Roos's avatar Adrian Roos Committed by Android (Google) Code Review
Browse files

Merge "Insets: allow controlling insets as long as the window is covering in...

Merge "Insets: allow controlling insets as long as the window is covering in the relevant direction" into rvc-dev
parents 5aacc569 8d04bcbc
Loading
Loading
Loading
Loading
+2 −12
Original line number Diff line number Diff line
@@ -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);
    }

    /**
+38 −0
Original line number Diff line number Diff line
@@ -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) {
+22 −0
Original line number Diff line number Diff line
@@ -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());