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

Commit afe40385 authored by Johannes Gallmann's avatar Johannes Gallmann
Browse files

Fix flicker in predictive IME back animation

This CL fixes a flicker that appears sometimes when clicking an InputTextField while the IME is still animating away (initiated by predictive back anim). In that case the IME would flicker to fully shown for one frame before animating in from the bottom. This CL fixes that flicker.

Bug: 322836622
Flag: ACONFIG android.view.inputmethod.predictive_back_ime DISABLED
Test: atest FrameworksCoreTests:InsetsControllerTest
Test: atest FrameworksCoreTests:ImeBackAnimationControllerTest
Test: Manual, i.e. starting (predictive) IME hide animation and immediately click InputField again to show IME again -> Verify no flicker
Change-Id: I1bb8a9e42a372efb6c49aa437adbecb7d165596b
parent 73415720
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
    private final Matrix mTmpMatrix = new Matrix();
    private final InsetsState mInitialInsetsState;
    private final @AnimationType int mAnimationType;
    private final @LayoutInsetsDuringAnimation int mLayoutInsetsDuringAnimation;
    private @LayoutInsetsDuringAnimation int mLayoutInsetsDuringAnimation;
    private final @InsetsType int mTypes;
    private @InsetsType int mControllingTypes;
    private final InsetsAnimationControlCallbacks mController;
@@ -376,6 +376,12 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
        return mAnimation;
    }

    @Override
    public void updateLayoutInsetsDuringAnimation(
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
        mLayoutInsetsDuringAnimation = layoutInsetsDuringAnimation;
    }

    @Override
    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
        final long token = proto.start(fieldId);
+9 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsController.AnimationType;
import android.view.InsetsController.LayoutInsetsDuringAnimation;
import android.view.WindowInsets.Type.InsetsType;
import android.view.inputmethod.ImeTracker;

@@ -81,6 +82,14 @@ public interface InsetsAnimationControlRunner {
    @Nullable
    ImeTracker.Token getStatsToken();

    /**
     * Updates the desired layout insets during the animation.
     *
     * @param layoutInsetsDuringAnimation Whether the insets should be shown or hidden
     */
    void updateLayoutInsetsDuringAnimation(
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation);

    /**
     *
     * Export the state of classes that implement this interface into a protocol buffer
+7 −0
Original line number Diff line number Diff line
@@ -186,4 +186,11 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
    public int getAnimationType() {
        return mControl.getAnimationType();
    }

    @Override
    public void updateLayoutInsetsDuringAnimation(
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
        InsetsAnimationThread.getHandler().post(
                () -> mControl.updateLayoutInsetsDuringAnimation(layoutInsetsDuringAnimation));
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -1031,6 +1031,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    @VisibleForTesting(visibility = PACKAGE)
    public void setPredictiveBackImeHideAnimInProgress(boolean isInProgress) {
        mIsPredictiveBackImeHideAnimInProgress = isInProgress;
        if (isInProgress) {
            // The InsetsAnimationControlRunner has layoutInsetsDuringAnimation set to SHOWN during
            // predictive back. Let's set it to HIDDEN once the predictive back animation enters the
            // post-commit phase.
            // That prevents flickers in case the animation is cancelled by an incoming show request
            // during the hide animation.
            for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
                final InsetsAnimationControlRunner runner = mRunningAnimations.get(i).runner;
                if ((runner.getTypes() & ime()) != 0) {
                    runner.updateLayoutInsetsDuringAnimation(LAYOUT_INSETS_DURING_ANIMATION_HIDDEN);
                    break;
                }
            }
        }
    }

    boolean isPredictiveBackImeHideAnimInProgress() {
+6 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.graphics.Insets;
import android.graphics.Rect;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsController.LayoutInsetsDuringAnimation;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimation.Bounds;
import android.view.animation.Interpolator;
@@ -242,4 +243,9 @@ public class InsetsResizeAnimationRunner implements InsetsAnimationControlRunner
    @Override
    public void onCancelled(WindowInsetsAnimationController controller) {
    }

    @Override
    public void updateLayoutInsetsDuringAnimation(
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
    }
}