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

Commit 89f87931 authored by Felix Stern's avatar Felix Stern Committed by Android (Google) Code Review
Browse files

Merge "Revert^2 "Adding hasZeroInsetsIme check in case animationCallbacks are set"" into main

parents 2e399b63 ac36f6ee
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -35,8 +35,8 @@ import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_SHOWN
import static android.view.InsetsController.LayoutInsetsDuringAnimation;
import static android.view.InsetsSource.ID_IME;
import static android.view.InsetsSource.SIDE_BOTTOM;
import static android.view.InsetsSource.SIDE_NONE;
import static android.view.InsetsSource.SIDE_LEFT;
import static android.view.InsetsSource.SIDE_NONE;
import static android.view.InsetsSource.SIDE_RIGHT;
import static android.view.InsetsSource.SIDE_TOP;
import static android.view.WindowInsets.Type.ime;
@@ -100,6 +100,8 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
    private @InsetsType int mControllingTypes;
    private final InsetsAnimationControlCallbacks mController;
    private final WindowInsetsAnimation mAnimation;
    private final long mDurationMs;
    private final Interpolator mInterpolator;
    /** @see WindowInsetsAnimationController#hasZeroInsetsIme */
    private final boolean mHasZeroInsetsIme;
    private final CompatibilityInfo.Translator mTranslator;
@@ -120,8 +122,8 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
    @VisibleForTesting
    public InsetsAnimationControlImpl(SparseArray<InsetsSourceControl> controls,
            @Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener,
            @InsetsType int types, InsetsAnimationControlCallbacks controller, long durationMs,
            Interpolator interpolator, @AnimationType int animationType,
            @InsetsType int types, InsetsAnimationControlCallbacks controller,
            InsetsAnimationSpec insetsAnimationSpec, @AnimationType int animationType,
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
            CompatibilityInfo.Translator translator, @Nullable ImeTracker.Token statsToken) {
        mControls = controls;
@@ -155,8 +157,10 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
        }
        mPendingInsets = mCurrentInsets;

        mAnimation = new WindowInsetsAnimation(mTypes, interpolator,
                durationMs);
        mDurationMs = insetsAnimationSpec.getDurationMs(mHasZeroInsetsIme);
        mInterpolator = insetsAnimationSpec.getInsetsInterpolator(mHasZeroInsetsIme);

        mAnimation = new WindowInsetsAnimation(mTypes, mInterpolator, mDurationMs);
        mAnimation.setAlpha(getCurrentAlpha());
        mAnimationType = animationType;
        mLayoutInsetsDuringAnimation = layoutInsetsDuringAnimation;
@@ -185,6 +189,16 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
        return mHasZeroInsetsIme;
    }

    @Override
    public long getDurationMs() {
        return mDurationMs;
    }

    @Override
    public Interpolator getInsetsInterpolator() {
        return mInterpolator;
    }

    @Override
    public void setReadyDispatched(boolean dispatched) {
        mReadyDispatched = dispatched;
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

import android.view.animation.Interpolator;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Used by {@link InsetsAnimationControlImpl}
 * @hide
 */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public interface InsetsAnimationSpec {
    /**
     * @param hasZeroInsetsIme whether IME has no insets (floating, fullscreen or non-overlapping).
     * @return Duration of animation in {@link java.util.concurrent.TimeUnit#MILLISECONDS}
     */
    long getDurationMs(boolean hasZeroInsetsIme);
    /**
     * @param hasZeroInsetsIme whether IME has no insets (floating, fullscreen or non-overlapping).
     * @return The interpolator used for the animation
     */
    Interpolator getInsetsInterpolator(boolean hasZeroInsetsIme);
}
+3 −4
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import android.view.InsetsController.LayoutInsetsDuringAnimation;
import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimation.Bounds;
import android.view.animation.Interpolator;
import android.view.inputmethod.ImeTracker;

/**
@@ -110,15 +109,15 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
    @UiThread
    public InsetsAnimationThreadControlRunner(SparseArray<InsetsSourceControl> controls,
            @Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener,
            @InsetsType int types, InsetsAnimationControlCallbacks controller, long durationMs,
            Interpolator interpolator, @AnimationType int animationType,
            @InsetsType int types, InsetsAnimationControlCallbacks controller,
            InsetsAnimationSpec insetsAnimationSpec, @AnimationType int animationType,
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
            CompatibilityInfo.Translator translator, Handler mainThreadHandler,
            @Nullable ImeTracker.Token statsToken) {
        mMainThreadHandler = mainThreadHandler;
        mOuterCallbacks = controller;
        mControl = new InsetsAnimationControlImpl(controls, frame, state, listener, types,
                mCallbacks, durationMs, interpolator, animationType, layoutInsetsDuringAnimation,
                mCallbacks, insetsAnimationSpec, animationType, layoutInsetsDuringAnimation,
                translator, statsToken);
        InsetsAnimationThread.getHandler().post(() -> {
            if (mControl.isCancelled()) {
+45 −50
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
     * animate insets.
     */
    public static class InternalAnimationControlListener
            implements WindowInsetsAnimationControlListener {
            implements WindowInsetsAnimationControlListener, InsetsAnimationSpec {

        private WindowInsetsAnimationController mController;
        private ValueAnimator mAnimator;
@@ -374,7 +374,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        private final boolean mHasAnimationCallbacks;
        private final @InsetsType int mRequestedTypes;
        private final @Behavior int mBehavior;
        private final long mDurationMs;
        private final boolean mDisable;
        private final int mFloatingImeBottomInset;
        private final WindowInsetsAnimationControlListener mLoggingListener;
@@ -388,7 +387,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            mHasAnimationCallbacks = hasAnimationCallbacks;
            mRequestedTypes = requestedTypes;
            mBehavior = behavior;
            mDurationMs = calculateDurationMs();
            mDisable = disable;
            mFloatingImeBottomInset = floatingImeBottomInset;
            mLoggingListener = loggingListener;
@@ -407,13 +405,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                onAnimationFinish();
                return;
            }
            final boolean hasZeroInsetsIme = controller.hasZeroInsetsIme();
            mAnimator = ValueAnimator.ofFloat(0f, 1f);
            mAnimator.setDuration(mDurationMs);
            mAnimator.setDuration(controller.getDurationMs());
            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()
            hiddenInsets = hasZeroInsetsIme
                    ? Insets.of(hiddenInsets.left, hiddenInsets.top, hiddenInsets.right,
                            mFloatingImeBottomInset)
                    : hiddenInsets;
@@ -423,7 +422,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            Insets end = mShow
                    ? controller.getShownStateInsets()
                    : hiddenInsets;
            Interpolator insetsInterpolator = getInsetsInterpolator();
            Interpolator insetsInterpolator = controller.getInsetsInterpolator();
            Interpolator alphaInterpolator = getAlphaInterpolator();
            mAnimator.addUpdateListener(animation -> {
                float rawFraction = animation.getAnimatedFraction();
@@ -486,9 +485,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            }
        }

        protected Interpolator getInsetsInterpolator() {
        @Override
        public Interpolator getInsetsInterpolator(boolean hasZeroInsetsIme) {
            if ((mRequestedTypes & ime()) != 0) {
                if (mHasAnimationCallbacks) {
                if (mHasAnimationCallbacks && hasZeroInsetsIme) {
                    return SYNC_IME_INTERPOLATOR;
                } else if (mShow) {
                    return LINEAR_OUT_SLOW_IN_INTERPOLATOR;
@@ -507,10 +507,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

        Interpolator getAlphaInterpolator() {
            if ((mRequestedTypes & ime()) != 0) {
                if (mHasAnimationCallbacks) {
                if (mHasAnimationCallbacks && !mController.hasZeroInsetsIme()) {
                    return input -> 1f;
                } else if (mShow) {

                    // Alpha animation takes half the time with linear interpolation;
                    return input -> Math.min(1f, 2 * input);
                } else {
@@ -534,16 +533,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            if (DEBUG) Log.d(TAG, "onAnimationFinish showOnFinish: " + mShow);
        }

        /**
         * To get the animation duration in MS.
         */
        public long getDurationMs() {
            return mDurationMs;
        }

        private long calculateDurationMs() {
        @Override
        public long getDurationMs(boolean hasZeroInsetsIme) {
            if ((mRequestedTypes & ime()) != 0) {
                if (mHasAnimationCallbacks) {
                if (mHasAnimationCallbacks && hasZeroInsetsIme) {
                    return ANIMATION_DURATION_SYNC_IME_MS;
                } else {
                    return ANIMATION_DURATION_UNSYNC_IME_MS;
@@ -593,13 +586,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    private static class PendingControlRequest {

        PendingControlRequest(@InsetsType int types, WindowInsetsAnimationControlListener listener,
                long durationMs, Interpolator interpolator, @AnimationType int animationType,
                InsetsAnimationSpec insetsAnimationSpec,
                @AnimationType int animationType,
                @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
                CancellationSignal cancellationSignal, boolean useInsetsAnimationThread) {
            this.types = types;
            this.listener = listener;
            this.durationMs = durationMs;
            this.interpolator = interpolator;
            this.mInsetsAnimationSpec = insetsAnimationSpec;
            this.animationType = animationType;
            this.layoutInsetsDuringAnimation = layoutInsetsDuringAnimation;
            this.cancellationSignal = cancellationSignal;
@@ -608,8 +601,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

        @InsetsType int types;
        final WindowInsetsAnimationControlListener listener;
        final long durationMs;
        final Interpolator interpolator;
        final InsetsAnimationSpec mInsetsAnimationSpec;
        final @AnimationType int animationType;
        final @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation;
        final CancellationSignal cancellationSignal;
@@ -1201,12 +1193,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

        // We are about to playing the default animation. Passing a null frame indicates the
        // controlled types should be animated regardless of the frame.
        controlAnimationUnchecked(
                pendingRequest.types, pendingRequest.cancellationSignal,
                pendingRequest.listener, null /* frame */,
                true /* fromIme */, pendingRequest.durationMs, pendingRequest.interpolator,
                pendingRequest.animationType,
                pendingRequest.layoutInsetsDuringAnimation,
        controlAnimationUnchecked(pendingRequest.types, pendingRequest.cancellationSignal,
                pendingRequest.listener, null /* frame */, true /* fromIme */,
                pendingRequest.mInsetsAnimationSpec,
                pendingRequest.animationType, pendingRequest.layoutInsetsDuringAnimation,
                pendingRequest.useInsetsAnimationThread, statsToken);
    }

@@ -1327,18 +1317,26 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                    mHost.getInputMethodManager(), null /* icProto */);
        }

        InsetsAnimationSpec spec = new InsetsAnimationSpec() {
            @Override
            public long getDurationMs(boolean hasZeroInsetsIme) {
                return durationMs;
            }
            @Override
            public Interpolator getInsetsInterpolator(boolean hasZeroInsetsIme) {
                return interpolator;
            }
        };
        // TODO(b/342111149): Create statsToken here once ImeTracker#onStart becomes async.
        controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, durationMs,
                interpolator, animationType,
                getLayoutInsetsDuringAnimationMode(types, fromPredictiveBack),
        controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, spec,
                animationType, getLayoutInsetsDuringAnimationMode(types, fromPredictiveBack),
                false /* useInsetsAnimationThread */, null);
    }

    private void controlAnimationUnchecked(@InsetsType int types,
            @Nullable CancellationSignal cancellationSignal,
            WindowInsetsAnimationControlListener listener, @Nullable Rect frame, boolean fromIme,
            long durationMs, Interpolator interpolator,
            @AnimationType int animationType,
            InsetsAnimationSpec insetsAnimationSpec, @AnimationType int animationType,
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
            boolean useInsetsAnimationThread, @Nullable ImeTracker.Token statsToken) {
        final boolean visible = layoutInsetsDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN;
@@ -1349,7 +1347,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        // However, we might reject the request in some cases, such as delaying showing IME or
        // rejecting showing IME.
        controlAnimationUncheckedInner(types, cancellationSignal, listener, frame, fromIme,
                durationMs, interpolator, animationType, layoutInsetsDuringAnimation,
                insetsAnimationSpec, animationType, layoutInsetsDuringAnimation,
                useInsetsAnimationThread, statsToken);

        // We are finishing setting the requested visible types. Report them to the server
@@ -1360,8 +1358,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    private void controlAnimationUncheckedInner(@InsetsType int types,
            @Nullable CancellationSignal cancellationSignal,
            WindowInsetsAnimationControlListener listener, @Nullable Rect frame, boolean fromIme,
            long durationMs, Interpolator interpolator,
            @AnimationType int animationType,
            InsetsAnimationSpec insetsAnimationSpec, @AnimationType int animationType,
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
            boolean useInsetsAnimationThread, @Nullable ImeTracker.Token statsToken) {
        if ((types & mTypesBeingCancelled) != 0) {
@@ -1418,8 +1415,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                    // TODO (b/323319146) remove layoutInsetsDuringAnimation from
                    //  PendingControlRequest, as it is now only used for showing
                    final PendingControlRequest request = new PendingControlRequest(types,
                            listener, durationMs,
                            interpolator, animationType, LAYOUT_INSETS_DURING_ANIMATION_SHOWN,
                            listener, insetsAnimationSpec, animationType,
                            LAYOUT_INSETS_DURING_ANIMATION_SHOWN,
                            cancellationSignal, false /* useInsetsAnimationThread */);
                    mPendingImeControlRequest = request;
                    // only add a timeout when the control is not currently showing
@@ -1460,11 +1457,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            if (!imeReady) {
                // IME isn't ready, all requested types will be animated once IME is ready
                abortPendingImeControlRequest();
                final PendingControlRequest request = new PendingControlRequest(types,
                        listener, durationMs,
                        interpolator, animationType, layoutInsetsDuringAnimation,
                        cancellationSignal,
                        useInsetsAnimationThread);
                final PendingControlRequest request = new PendingControlRequest(types, listener,
                        insetsAnimationSpec, animationType, layoutInsetsDuringAnimation,
                        cancellationSignal, useInsetsAnimationThread);
                mPendingImeControlRequest = request;
                mHandler.postDelayed(mPendingControlTimeout, PENDING_CONTROL_TIMEOUT_MS);
                if (DEBUG) Log.d(TAG, "Ime not ready. Create pending request");
@@ -1520,11 +1515,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

        final InsetsAnimationControlRunner runner = useInsetsAnimationThread
                ? new InsetsAnimationThreadControlRunner(controls,
                        frame, mState, listener, typesReady, this, durationMs, interpolator,
                        animationType, layoutInsetsDuringAnimation, mHost.getTranslator(),
                        mHost.getHandler(), statsToken)
                        frame, mState, listener, typesReady, this,
                        insetsAnimationSpec, animationType, layoutInsetsDuringAnimation,
                        mHost.getTranslator(), mHost.getHandler(), statsToken)
                : new InsetsAnimationControlImpl(controls,
                        frame, mState, listener, typesReady, this, durationMs, interpolator,
                        frame, mState, listener, typesReady, this, insetsAnimationSpec,
                        animationType, layoutInsetsDuringAnimation, mHost.getTranslator(),
                        statsToken);
        if ((typesReady & WindowInsets.Type.ime()) != 0) {
@@ -2023,7 +2018,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        // the controlled types should be animated regardless of the frame.
        controlAnimationUnchecked(
                types, null /* cancellationSignal */, listener, null /* frame */, fromIme,
                listener.getDurationMs(), listener.getInsetsInterpolator(),
                listener /* insetsAnimationSpec */,
                show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
                show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN,
                !hasAnimationCallbacks /* useInsetsAnimationThread */, statsToken);
+10 −0
Original line number Diff line number Diff line
@@ -232,6 +232,16 @@ public class InsetsResizeAnimationRunner implements InsetsAnimationControlRunner
        return false;
    }

    @Override
    public long getDurationMs() {
        return 0;
    }

    @Override
    public Interpolator getInsetsInterpolator() {
        return null;
    }

    @Override
    public void setReadyDispatched(boolean dispatched) {
    }
Loading