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

Commit cc498f3e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Animate IME with zero insets" into rvc-dev

parents 3ed037cb 42914101
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -16,13 +16,14 @@

package android.view;

import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
import static android.view.InsetsController.AnimationType;
import static android.view.InsetsController.DEBUG;
import static android.view.InsetsState.ISIDE_BOTTOM;
import static android.view.InsetsState.ISIDE_FLOATING;
import static android.view.InsetsState.ISIDE_LEFT;
import static android.view.InsetsState.ISIDE_RIGHT;
import static android.view.InsetsState.ISIDE_TOP;
import static android.view.InsetsState.ITYPE_IME;

import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;

@@ -74,6 +75,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
    private final @InsetsType int mTypes;
    private final InsetsAnimationControlCallbacks mController;
    private final WindowInsetsAnimation mAnimation;
    /** @see WindowInsetsAnimationController#hasZeroInsetsIme */
    private final boolean mHasZeroInsetsIme;
    private Insets mCurrentInsets;
    private Insets mPendingInsets;
    private float mPendingFraction;
@@ -102,6 +105,12 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
                null /* typeSideMap */);
        mShownInsets = calculateInsets(mInitialInsetsState, frame, controls, true /* shown */,
                mTypeSideMap);
        mHasZeroInsetsIme = mShownInsets.bottom == 0 && controlsInternalType(ITYPE_IME);
        if (mHasZeroInsetsIme) {
            // IME has shownInsets of ZERO, and can't map to a side by default.
            // Map zero insets IME to bottom, making it a special case of bottom insets.
            mTypeSideMap.put(ITYPE_IME, ISIDE_BOTTOM);
        }
        buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls);

        mAnimation = new WindowInsetsAnimation(mTypes, interpolator,
@@ -112,6 +121,11 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
                new Bounds(mHiddenInsets, mShownInsets));
    }

    @Override
    public boolean hasZeroInsetsIme() {
        return mHasZeroInsetsIme;
    }

    @Override
    public Insets getHiddenStateInsets() {
        return mHiddenInsets;
@@ -182,8 +196,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
                params, state, mPendingAlpha);
        updateLeashesForSide(ISIDE_BOTTOM, offset.bottom, mShownInsets.bottom,
                mPendingInsets.bottom, params, state, mPendingAlpha);
        updateLeashesForSide(ISIDE_FLOATING, 0 /* offset */, 0 /* inset */, 0 /* maxInset */,
                params, state, mPendingAlpha);

        mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()]));
        mCurrentInsets = mPendingInsets;
@@ -290,6 +302,9 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
        if (insets == null) {
            insets = getCurrentInsets();
        }
        if (hasZeroInsetsIme()) {
            return insets;
        }
        return Insets.max(Insets.min(insets, mShownInsets), mHiddenInsets);
    }

@@ -313,17 +328,19 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
            mTmpFrame.set(source.getFrame());
            addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);

            state.getSource(source.getType()).setVisible(side == ISIDE_FLOATING || inset != 0);
            final boolean visible = mHasZeroInsetsIme && side == ISIDE_BOTTOM
                    ? (mAnimationType == ANIMATION_TYPE_SHOW ? true : !mFinished)
                    : inset != 0;

            state.getSource(source.getType()).setVisible(visible);
            state.getSource(source.getType()).setFrame(mTmpFrame);

            // If the system is controlling the insets source, the leash can be null.
            if (leash != null) {
                SurfaceParams params = new SurfaceParams.Builder(leash)
                        .withAlpha(side == ISIDE_FLOATING ? 1 : alpha)
                        .withAlpha(alpha)
                        .withMatrix(mTmpMatrix)
                        .withVisibility(side == ISIDE_FLOATING
                                ? mShownOnFinish
                                : inset != 0 /* visible */)
                        .withVisibility(visible)
                        .build();
                surfaceParams.add(params);
            }
+20 −4
Original line number Diff line number Diff line
@@ -162,6 +162,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
         */
        @Nullable
        String getRootViewTitle();

        /** @see ViewRootImpl#dipToPx */
        int dipToPx(int dips);
    }

    private static final String TAG = "InsetsController";
@@ -254,6 +257,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    public static class InternalAnimationControlListener
            implements WindowInsetsAnimationControlListener {

        /** The amount IME will move up/down when animating in floating mode. */
        protected static final int FLOATING_IME_BOTTOM_INSET = -80;

        private WindowInsetsAnimationController mController;
        private ValueAnimator mAnimator;
        private final boolean mShow;
@@ -261,6 +267,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        private final @InsetsType int mRequestedTypes;
        private final long mDurationMs;
        private final boolean mDisable;
        private final int mFloatingImeBottomInset;

        private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
                new ThreadLocal<AnimationHandler>() {
@@ -273,12 +280,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        };

        public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks,
                int requestedTypes, boolean disable) {
                int requestedTypes, boolean disable, int floatingImeBottomInset) {
            mShow = show;
            mHasAnimationCallbacks = hasAnimationCallbacks;
            mRequestedTypes = requestedTypes;
            mDurationMs = calculateDurationMs();
            mDisable = disable;
            mFloatingImeBottomInset = floatingImeBottomInset;
        }

        @Override
@@ -293,12 +301,19 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            mAnimator = ValueAnimator.ofFloat(0f, 1f);
            mAnimator.setDuration(mDurationMs);
            mAnimator.setInterpolator(new LinearInterpolator());
            Insets hiddenInsets = controller.getHiddenStateInsets();
            // IME with zero insets is a special case: it will animate-in from offscreen and end
            // with final insets of zero and vice-versa.
            hiddenInsets = controller.hasZeroInsetsIme()
                    ? Insets.of(hiddenInsets.left, hiddenInsets.top, hiddenInsets.right,
                            mFloatingImeBottomInset)
                    : hiddenInsets;
            Insets start = mShow
                    ? controller.getHiddenStateInsets()
                    ? hiddenInsets
                    : controller.getShownStateInsets();
            Insets end = mShow
                    ? controller.getShownStateInsets()
                    : controller.getHiddenStateInsets();
                    : hiddenInsets;
            Interpolator insetsInterpolator = getInterpolator();
            Interpolator alphaInterpolator = getAlphaInterpolator();
            mAnimator.addUpdateListener(animation -> {
@@ -1173,7 +1188,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

        boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks();
        final InternalAnimationControlListener listener = new InternalAnimationControlListener(
                show, hasAnimationCallbacks, types, mAnimationsDisabled);
                show, hasAnimationCallbacks, types, mAnimationsDisabled,
                mHost.dipToPx(InternalAnimationControlListener.FLOATING_IME_BOTTOM_INSET));

        // Show/hide animations always need to be relative to the display frame, in order that shown
        // and hidden state insets are correct.
+1 −1
Original line number Diff line number Diff line
@@ -2315,7 +2315,7 @@ public final class ViewRootImpl implements ViewParent,
                || lp.type == TYPE_VOLUME_OVERLAY;
    }

    private int dipToPx(int dip) {
    int dipToPx(int dip) {
        final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
        return (int) (displayMetrics.density * dip + 0.5f);
    }
+8 −0
Original line number Diff line number Diff line
@@ -228,4 +228,12 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
        }
        return mViewRoot.getTitle().toString();
    }

    @Override
    public int dipToPx(int dips) {
        if (mViewRoot != null) {
            return mViewRoot.dipToPx(dips);
        }
        return 0;
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -181,4 +181,11 @@ public interface WindowInsetsAnimationController {
     * @return {@code true} if the instance is cancelled, {@code false} otherwise.
     */
    boolean isCancelled();

    /**
     * @hide
     * @return {@code true} when controller controls IME and IME has no insets (floating,
     *  fullscreen or non-overlapping).
     */
    boolean hasZeroInsetsIme();
}
Loading