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

Commit aebdc015 authored by Jerry Chang's avatar Jerry Chang
Browse files

Adjust split layout with IME animation in split (5/N)

Adjust split bounds to match the IME animation.

Fix: 179262787
Test: atest WMShellUnitTests
Test: observed split bounds been offset properly when rotating devices
or changing focus while IME showing.

Change-Id: I70d8cdf5a019f77873a75bc0881b1c100b372664
parent 64049c4e
Loading
Loading
Loading
Loading
+39 −10
Original line number Diff line number Diff line
@@ -119,17 +119,17 @@ public final class SplitLayout {

    /** Gets bounds of the primary split. */
    public Rect getBounds1() {
        return mBounds1;
        return new Rect(mBounds1);
    }

    /** Gets bounds of the secondary split. */
    public Rect getBounds2() {
        return mBounds2;
        return new Rect(mBounds2);
    }

    /** Gets bounds of divider window. */
    public Rect getDividerBounds() {
        return mDividerBounds;
        return new Rect(mDividerBounds);
    }

    /** Returns leash of the current divider bar. */
@@ -308,18 +308,21 @@ public final class SplitLayout {
    /** Apply recorded surface layout to the {@link SurfaceControl.Transaction}. */
    public void applySurfaceChanges(SurfaceControl.Transaction t, SurfaceControl leash1,
            SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2) {
        final Rect dividerBounds = mImePositionProcessor.adjustForIme(mDividerBounds);
        final Rect bounds1 = mImePositionProcessor.adjustForIme(mBounds1);
        final Rect bounds2 = mImePositionProcessor.adjustForIme(mBounds2);
        final SurfaceControl dividerLeash = getDividerLeash();
        if (dividerLeash != null) {
            t.setPosition(dividerLeash, mDividerBounds.left, mDividerBounds.top)
            t.setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
                    // Resets layer of divider bar to make sure it is always on top.
                    .setLayer(dividerLeash, Integer.MAX_VALUE);
        }

        t.setPosition(leash1, mBounds1.left, mBounds1.top)
                .setWindowCrop(leash1, mBounds1.width(), mBounds1.height());
        t.setPosition(leash1, bounds1.left, bounds1.top)
                .setWindowCrop(leash1, bounds1.width(), bounds1.height());

        t.setPosition(leash2, mBounds2.left, mBounds2.top)
                .setWindowCrop(leash2, mBounds2.width(), mBounds2.height());
        t.setPosition(leash2, bounds2.left, bounds2.top)
                .setWindowCrop(leash2, bounds2.width(), bounds2.height());

        mImePositionProcessor.applySurfaceDimValues(t, dimLayer1, dimLayer2);
    }
@@ -327,8 +330,8 @@ public final class SplitLayout {
    /** Apply recorded task layout to the {@link WindowContainerTransaction}. */
    public void applyTaskChanges(WindowContainerTransaction wct,
            ActivityManager.RunningTaskInfo task1, ActivityManager.RunningTaskInfo task2) {
        wct.setBounds(task1.token, mBounds1)
                .setBounds(task2.token, mBounds2);
        wct.setBounds(task1.token, mImePositionProcessor.adjustForIme(mBounds1))
                .setBounds(task2.token, mImePositionProcessor.adjustForIme(mBounds2));
    }

    /** Handles layout change event. */
@@ -363,12 +366,15 @@ public final class SplitLayout {

        private final int mDisplayId;

        private int mYOffsetForIme;
        private float mDimValue1;
        private float mDimValue2;

        private int mStartImeTop;
        private int mEndImeTop;

        private int mTargetYOffset;
        private int mLastYOffset;
        private float mTargetDim1;
        private float mTargetDim2;
        private float mLastDim1;
@@ -395,6 +401,12 @@ public final class SplitLayout {
            mTargetDim2 = imeTargetPosition == SPLIT_POSITION_TOP_OR_LEFT && showing
                    ? ADJUSTED_NONFOCUS_DIM : 0.0f;

            // Calculate target bounds offset for IME
            mLastYOffset = mYOffsetForIme;
            final boolean needOffset = imeTargetPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
                    && !isFloating && !isLandscape(mRootBounds) && showing;
            mTargetYOffset = needOffset ? getTargetYOffset() : 0;

            // Make {@link DividerView} non-interactive while IME showing in split mode. Listen to
            // ImePositionProcessor#onImeVisibilityChanged directly in DividerView is not enough
            // because DividerView won't receive onImeVisibilityChanged callback after it being
@@ -420,6 +432,13 @@ public final class SplitLayout {
            mSplitLayoutHandler.onBoundsChanging(SplitLayout.this);
        }

        private int getTargetYOffset() {
            final int desireOffset = Math.abs(mEndImeTop - mStartImeTop);
            // Make sure to keep at least 30% visible for the top split.
            final int maxOffset = (int) (mBounds1.height() * ADJUSTED_SPLIT_FRACTION_MAX);
            return -Math.min(desireOffset, maxOffset);
        }

        @SplitPosition
        private int getImeTargetPosition() {
            final WindowContainerToken token = mTaskOrganizer.getImeTarget(mDisplayId);
@@ -433,6 +452,8 @@ public final class SplitLayout {
        private void onProgress(float progress) {
            mDimValue1 = getProgressValue(mLastDim1, mTargetDim1, progress);
            mDimValue2 = getProgressValue(mLastDim2, mTargetDim2, progress);
            mYOffsetForIme =
                    (int) getProgressValue((float) mLastYOffset, (float) mTargetYOffset, progress);
        }

        private float getProgressValue(float start, float end, float progress) {
@@ -440,9 +461,17 @@ public final class SplitLayout {
        }

        private void reset() {
            mYOffsetForIme = 0;
            mDimValue1 = mDimValue2 = 0.0f;
        }

        /* Adjust bounds with IME offset. */
        private Rect adjustForIme(Rect bounds) {
            final Rect temp = new Rect(bounds);
            if (mYOffsetForIme != 0) temp.offset(0, mYOffsetForIme);
            return temp;
        }

        private void applySurfaceDimValues(SurfaceControl.Transaction t, SurfaceControl dimLayer1,
                SurfaceControl dimLayer2) {
            t.setAlpha(dimLayer1, mDimValue1).setVisibility(dimLayer1, mDimValue1 > 0.001f);