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

Commit b9538cdf authored by Tarandeep Singh's avatar Tarandeep Singh Committed by Taran Singh
Browse files

Fix controlWindowInsets for IME

If IME is already visible, requestShow() is immediate.
If animation is finishing and IME is hiding, notify IME process of the
visibility.

Bug: 111084606
Test: Use test app [1] and verify that swiping up and down multiple
      times opens and closes the IME respectively.

      [1] I4320871bdc8184fac38921616e1a1322f8dbc804

Change-Id: Icf202b56c0bc3833e86ee70c43fedd418e27b140
parent 73b1d16d
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.view;

import static android.view.InsetsController.ANIMATION_TYPE_USER;
import static android.view.InsetsController.AnimationType;
import static android.view.InsetsState.ITYPE_IME;

import android.annotation.Nullable;
@@ -99,9 +101,15 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
    }

    @Override
    void hide(boolean animationFinished) {
    void hide(boolean animationFinished, @AnimationType int animationType) {
        super.hide();
        if (animationFinished) {

        if (!animationFinished) {
            if (animationType == ANIMATION_TYPE_USER) {
                // if controlWindowInsetsAnimation is hiding keyboard.
                notifyHidden();
            }
        } else {
            // remove IME surface as IME has finished hide animation.
            removeSurface();
        }
@@ -118,7 +126,8 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {

        // If we had a request before to show from IME (tracked with mImeRequestedShow), reaching
        // this code here means that we now got control, so we can start the animation immediately.
        if (fromIme || mImeRequestedShow) {
        // If client window is trying to control IME and IME is already visible, it is immediate.
        if (fromIme || mImeRequestedShow || mState.getSource(getType()).isVisible()) {
            mImeRequestedShow = false;
            return ShowResult.SHOW_IMMEDIATELY;
        }
+9 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view;

import static android.view.InsetsController.AnimationType;
import static android.view.InsetsState.ISIDE_BOTTOM;
import static android.view.InsetsState.ISIDE_FLOATING;
import static android.view.InsetsState.ISIDE_LEFT;
@@ -64,10 +65,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
    private final Insets mShownInsets;
    private final Matrix mTmpMatrix = new Matrix();
    private final InsetsState mInitialInsetsState;
    private final @AnimationType int mAnimationType;
    private final @InsetsType int mTypes;
    private final InsetsAnimationControlCallbacks mController;
    private final WindowInsetsAnimation mAnimation;
    private final Rect mFrame;
    private final boolean mFade;
    private Insets mCurrentInsets;
    private Insets mPendingInsets;
@@ -83,7 +84,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
            InsetsState state, WindowInsetsAnimationControlListener listener,
            @InsetsType int types,
            InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator,
            boolean fade, @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
            boolean fade, @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
            @AnimationType int animationType) {
        mControls = controls;
        mListener = listener;
        mTypes = types;
@@ -96,12 +98,12 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
                null /* typeSideMap */);
        mShownInsets = calculateInsets(mInitialInsetsState, frame, controls, true /* shown */,
                mTypeSideMap);
        mFrame = new Rect(frame);
        buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls);

        mAnimation = new WindowInsetsAnimation(mTypes, interpolator,
                durationMs);
        mAnimation.setAlpha(getCurrentAlpha());
        mAnimationType = animationType;
        mController.startAnimation(this, listener, types, mAnimation,
                new Bounds(mHiddenInsets, mShownInsets), layoutInsetsDuringAnimation);
    }
@@ -135,6 +137,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
        return InsetsState.toInternalType(mTypes).contains(type);
    }

    @AnimationType int getAnimationType() {
        return mAnimationType;
    }

    @Override
    public void setInsetsAndAlpha(Insets insets, float alpha, float fraction) {
        if (mFinished) {
+9 −6
Original line number Diff line number Diff line
@@ -582,7 +582,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

        final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(controls,
                frame, mState, listener, typesReady, this, durationMs, interpolator, fade,
                layoutInsetsDuringAnimation);
                layoutInsetsDuringAnimation, animationType);
        mRunningAnimations.add(new RunningAnimation(controller, animationType));
        mRunningInsetsAnimations.add(controller.getAnimation());
        cancellationSignal.setOnCancelListener(controller::onCancelled);
@@ -598,7 +598,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        int typesReady = 0;
        boolean imeReady = true;
        for (int i = internalTypes.size() - 1; i >= 0; i--) {
            InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
            final InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
            boolean show = animationType == ANIMATION_TYPE_SHOW
                    || animationType == ANIMATION_TYPE_USER;
            boolean canRun = false;
@@ -694,7 +694,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if (shown) {
            showDirectly(controller.getTypes());
        } else {
            hideDirectly(controller.getTypes(), true /* animationFinished */);
            hideDirectly(controller.getTypes(), true /* animationFinished */,
                    controller.getAnimationType());
        }
    }

@@ -852,10 +853,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                        : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN);
    }

    private void hideDirectly(@InsetsType int types, boolean animationFinished) {
    private void hideDirectly(
            @InsetsType int types, boolean animationFinished, @AnimationType int animationType) {
        final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
        for (int i = internalTypes.size() - 1; i >= 0; i--) {
            getSourceConsumer(internalTypes.valueAt(i)).hide(animationFinished);
            getSourceConsumer(internalTypes.valueAt(i)).hide(animationFinished, animationType);
        }
    }

@@ -887,8 +889,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if (layoutDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN) {
            showDirectly(types);
        } else {
            hideDirectly(types, false /* animationFinished */);
            hideDirectly(types, false /* animationFinished */, controller.getAnimationType());
        }

        if (mViewRoot.mView == null) {
            return;
        }
+5 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view;

import static android.view.InsetsController.AnimationType;
import static android.view.InsetsState.toPublicType;

import android.annotation.IntDef;
@@ -57,9 +58,10 @@ public class InsetsSourceConsumer {

    protected final InsetsController mController;
    protected boolean mRequestedVisible;
    protected final InsetsState mState;
    protected final @InternalInsetsType int mType;

    private final Supplier<Transaction> mTransactionSupplier;
    private final @InternalInsetsType int mType;
    private final InsetsState mState;
    private @Nullable InsetsSourceControl mSourceControl;
    private boolean mHasWindowFocus;

@@ -135,7 +137,7 @@ public class InsetsSourceConsumer {
        setRequestedVisible(false);
    }

    void hide(boolean animationFinished) {
    void hide(boolean animationFinished, @AnimationType int animationType) {
        hide();
    }

+1 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ public class InsetsAnimationControlImplTest {
        mController = new InsetsAnimationControlImpl(controls,
                new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(),
                mMockController, 10 /* durationMs */, new LinearInterpolator(),
                false /* fade */, LAYOUT_INSETS_DURING_ANIMATION_SHOWN);
                false /* fade */, LAYOUT_INSETS_DURING_ANIMATION_SHOWN, 0 /* animationType */);
    }

    @Test
Loading