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

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

API update for insets

- Rename WindowInsetsAnimationListener to
WindowInsetsAnimationCallback
- Make onAnimation WindowInsetsAnimationCallback.onStarted
hierarchical by giving the client a chance to consume
AnimationBounds, which then will be dispatched to its children.
- Clarify that WindowInsetsAnimationController insets are always
relative to the window.
- Introduce progress variable for inset animations. Since
DecorView will be consuming insets, apps still need a way to
calculate the full progress. Instead of also dispatching the root
insets, we offer a animation progress instead.

Bug: 111084606
Test: CTS will be added in the future
Change-Id: I7df27581d01c1db0118eef469ec089249012ba5f
parent 3082d6f9
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
@@ -51068,6 +51068,9 @@ package android.view {
    method public boolean dispatchUnhandledMove(android.view.View, int);
    method protected void dispatchVisibilityChanged(@NonNull android.view.View, int);
    method public void dispatchWindowFocusChanged(boolean);
    method public void dispatchWindowInsetsAnimationFinished(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation);
    method @NonNull public android.view.WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull android.view.WindowInsets);
    method @NonNull public android.view.WindowInsetsAnimationCallback.AnimationBounds dispatchWindowInsetsAnimationStarted(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation, @NonNull android.view.WindowInsetsAnimationCallback.AnimationBounds);
    method public void dispatchWindowSystemUiVisiblityChanged(int);
    method public void dispatchWindowVisibilityChanged(int);
    method @CallSuper public void draw(android.graphics.Canvas);
@@ -51248,6 +51251,7 @@ package android.view {
    method @android.view.ViewDebug.ExportedProperty(category="layout") public final int getWidth();
    method protected int getWindowAttachCount();
    method public android.view.WindowId getWindowId();
    method @Nullable public android.view.WindowInsetsController getWindowInsetsController();
    method public int getWindowSystemUiVisibility();
    method public android.os.IBinder getWindowToken();
    method public int getWindowVisibility();
@@ -51586,6 +51590,7 @@ package android.view {
    method public void setVisibility(int);
    method @Deprecated public void setWillNotCacheDrawing(boolean);
    method public void setWillNotDraw(boolean);
    method public void setWindowInsetsAnimationCallback(@Nullable android.view.WindowInsetsAnimationCallback);
    method public void setX(float);
    method public void setY(float);
    method public void setZ(float);
@@ -52472,6 +52477,7 @@ package android.view {
    method public android.transition.Transition getExitTransition();
    method protected final int getFeatures();
    method protected final int getForcedWindowFlags();
    method @Nullable public android.view.WindowInsetsController getInsetsController();
    method @NonNull public abstract android.view.LayoutInflater getLayoutInflater();
    method protected final int getLocalFeatures();
    method public android.media.session.MediaController getMediaController();
@@ -52688,7 +52694,9 @@ package android.view {
    method @NonNull public android.view.WindowInsets consumeStableInsets();
    method @NonNull public android.view.WindowInsets consumeSystemWindowInsets();
    method @Nullable public android.view.DisplayCutout getDisplayCutout();
    method @NonNull public android.graphics.Insets getInsets(int);
    method @NonNull public android.graphics.Insets getMandatorySystemGestureInsets();
    method @NonNull public android.graphics.Insets getMaxInsets(int) throws java.lang.IllegalArgumentException;
    method public int getStableInsetBottom();
    method public int getStableInsetLeft();
    method public int getStableInsetRight();
@@ -52707,6 +52715,7 @@ package android.view {
    method @NonNull public android.view.WindowInsets inset(@IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
    method public boolean isConsumed();
    method public boolean isRound();
    method public boolean isVisible(int);
    method @Deprecated @NonNull public android.view.WindowInsets replaceSystemWindowInsets(int, int, int, int);
    method @Deprecated @NonNull public android.view.WindowInsets replaceSystemWindowInsets(android.graphics.Rect);
  }
@@ -52716,11 +52725,76 @@ package android.view {
    ctor public WindowInsets.Builder(@NonNull android.view.WindowInsets);
    method @NonNull public android.view.WindowInsets build();
    method @NonNull public android.view.WindowInsets.Builder setDisplayCutout(@Nullable android.view.DisplayCutout);
    method @NonNull public android.view.WindowInsets.Builder setInsets(int, @NonNull android.graphics.Insets);
    method @NonNull public android.view.WindowInsets.Builder setMandatorySystemGestureInsets(@NonNull android.graphics.Insets);
    method @NonNull public android.view.WindowInsets.Builder setMaxInsets(int, @NonNull android.graphics.Insets) throws java.lang.IllegalArgumentException;
    method @NonNull public android.view.WindowInsets.Builder setStableInsets(@NonNull android.graphics.Insets);
    method @NonNull public android.view.WindowInsets.Builder setSystemGestureInsets(@NonNull android.graphics.Insets);
    method @NonNull public android.view.WindowInsets.Builder setSystemWindowInsets(@NonNull android.graphics.Insets);
    method @NonNull public android.view.WindowInsets.Builder setTappableElementInsets(@NonNull android.graphics.Insets);
    method @NonNull public android.view.WindowInsets.Builder setVisible(int, boolean);
  }
  public static final class WindowInsets.Type {
    method public static int all();
    method public static int captionBar();
    method public static int ime();
    method public static int mandatorySystemGestures();
    method public static int navigationBars();
    method public static int statusBars();
    method public static int systemBars();
    method public static int systemGestures();
    method public static int tappableElement();
    method public static int windowDecor();
  }
  public interface WindowInsetsAnimationCallback {
    method public default void onFinished(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation);
    method @NonNull public android.view.WindowInsets onProgress(@NonNull android.view.WindowInsets);
    method @NonNull public default android.view.WindowInsetsAnimationCallback.AnimationBounds onStarted(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation, @NonNull android.view.WindowInsetsAnimationCallback.AnimationBounds);
  }
  public static final class WindowInsetsAnimationCallback.AnimationBounds {
    ctor public WindowInsetsAnimationCallback.AnimationBounds(@NonNull android.graphics.Insets, @NonNull android.graphics.Insets);
    method @NonNull public android.graphics.Insets getLowerBound();
    method @NonNull public android.graphics.Insets getUpperBound();
    method @NonNull public android.view.WindowInsetsAnimationCallback.AnimationBounds inset(@NonNull android.graphics.Insets);
  }
  public static final class WindowInsetsAnimationCallback.InsetsAnimation {
    ctor public WindowInsetsAnimationCallback.InsetsAnimation(int, @Nullable android.view.animation.Interpolator, long);
    method public long getDurationMillis();
    method @FloatRange(from=0.0f, to=1.0f) public float getFraction();
    method public float getInterpolatedFraction();
    method @Nullable public android.view.animation.Interpolator getInterpolator();
    method public int getTypeMask();
    method public void setDuration(long);
    method public void setFraction(@FloatRange(from=0.0f, to=1.0f) float);
  }
  public interface WindowInsetsAnimationControlListener {
    method public void onCancelled();
    method public void onReady(@NonNull android.view.WindowInsetsAnimationController, int);
  }
  public interface WindowInsetsAnimationController {
    method public void finish(boolean);
    method @FloatRange(from=0.0f, to=1.0f) public float getCurrentFraction();
    method @NonNull public android.graphics.Insets getCurrentInsets();
    method @NonNull public android.graphics.Insets getHiddenStateInsets();
    method @NonNull public android.graphics.Insets getShownStateInsets();
    method public int getTypes();
    method public void setInsetsAndAlpha(@Nullable android.graphics.Insets, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
  }
  public interface WindowInsetsController {
    method public default void controlInputMethodAnimation(long, @NonNull android.view.WindowInsetsAnimationControlListener);
    method public default void hideInputMethod();
    method public void setSystemBarsAppearance(int);
    method public void setSystemBarsBehavior(int);
    method public default void showInputMethod();
    field public static final int APPEARANCE_LIGHT_NAVIGATION_BARS = 16; // 0x10
    field public static final int APPEARANCE_LIGHT_STATUS_BARS = 8; // 0x8
  }
  public interface WindowManager extends android.view.ViewManager {
+5 −4
Original line number Diff line number Diff line
@@ -16,13 +16,13 @@

package android.view;

import static android.view.DisplayEventReceiver.CONFIG_CHANGED_EVENT_SUPPRESS;
import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP;
import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER;

import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.graphics.FrameInfo;
import android.graphics.Insets;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Build;
import android.os.Handler;
@@ -219,9 +219,10 @@ public final class Choreographer {
    /**
     * Callback type: Animation callback to handle inset updates. This is separate from
     * {@link #CALLBACK_ANIMATION} as we need to "gather" all inset animation updates via
     * {@link WindowInsetsAnimationController#changeInsets} for multiple ongoing animations but then
     * update the whole view system with a single callback to {@link View#dispatchWindowInsetsAnimationProgress}
     * that contains all the combined updated insets.
     * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)} for multiple
     * ongoing animations but then update the whole view system with a single callback to
     * {@link View#dispatchWindowInsetsAnimationProgress} that contains all the combined updated
     * insets.
     * <p>
     * Both input and animation may change insets, so we need to run this after these callbacks, but
     * before traversals.
+34 −15
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ 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.toPublicType;

import android.annotation.Nullable;
import android.graphics.Insets;
@@ -34,7 +33,8 @@ import android.util.SparseSetArray;
import android.view.InsetsState.InternalInsetsSide;
import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimationListener.InsetsAnimation;
import android.view.WindowInsetsAnimationCallback.AnimationBounds;
import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
import android.view.WindowManager.LayoutParams;

import com.android.internal.annotations.VisibleForTesting;
@@ -66,20 +66,21 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
    private final @InsetsType int mTypes;
    private final Supplier<SyncRtSurfaceTransactionApplier> mTransactionApplierSupplier;
    private final InsetsController mController;
    private final WindowInsetsAnimationListener.InsetsAnimation mAnimation;
    private final WindowInsetsAnimationCallback.InsetsAnimation mAnimation;
    private final Rect mFrame;
    private Insets mCurrentInsets;
    private Insets mPendingInsets;
    private float mPendingFraction;
    private boolean mFinished;
    private boolean mCancelled;
    private int mFinishedShownTypes;
    private boolean mShownOnFinish;

    @VisibleForTesting
    public InsetsAnimationControlImpl(SparseArray<InsetsSourceConsumer> consumers, Rect frame,
            InsetsState state, WindowInsetsAnimationControlListener listener,
            @InsetsType int types,
            Supplier<SyncRtSurfaceTransactionApplier> transactionApplierSupplier,
            InsetsController controller) {
            InsetsController controller, long durationMs) {
        mConsumers = consumers;
        mListener = listener;
        mTypes = types;
@@ -97,9 +98,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
        // TODO: Check for controllability first and wait for IME if needed.
        listener.onReady(this, types);

        mAnimation = new WindowInsetsAnimationListener.InsetsAnimation(mTypes, mHiddenInsets,
                mShownInsets);
        mController.dispatchAnimationStarted(mAnimation);
        mAnimation = new WindowInsetsAnimationCallback.InsetsAnimation(mTypes,
                InsetsController.INTERPOLATOR, durationMs);
        mController.dispatchAnimationStarted(mAnimation,
                new AnimationBounds(mHiddenInsets, mShownInsets));
    }

    @Override
@@ -123,7 +125,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
    }

    @Override
    public void changeInsets(Insets insets) {
    public void setInsetsAndAlpha(Insets insets, float alpha, float fraction) {
        if (mFinished) {
            throw new IllegalStateException(
                    "Can't change insets on an animation that is finished.");
@@ -132,6 +134,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
            throw new IllegalStateException(
                    "Can't change insets on an animation that is cancelled.");
        }
        mPendingFraction = sanitize(fraction);
        mPendingInsets = sanitize(insets);
        mController.scheduleApplyChangeInsets();
    }
@@ -155,30 +158,35 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
        SyncRtSurfaceTransactionApplier applier = mTransactionApplierSupplier.get();
        applier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
        mCurrentInsets = mPendingInsets;
        mAnimation.setFraction(mPendingFraction);
        if (mFinished) {
            mController.notifyFinished(this, mFinishedShownTypes);
            mController.notifyFinished(this, mShownOnFinish);
        }
        return mFinished;
    }

    @Override
    public void finish(int shownTypes) {
    public void finish(boolean shown) {
        if (mCancelled) {
            return;
        }
        InsetsState state = new InsetsState(mController.getState());
        for (int i = mConsumers.size() - 1; i >= 0; i--) {
            InsetsSourceConsumer consumer = mConsumers.valueAt(i);
            boolean visible = (shownTypes & toPublicType(consumer.getType())) != 0;
            state.getSource(consumer.getType()).setVisible(visible);
            state.getSource(consumer.getType()).setVisible(shown);
        }
        Insets insets = getInsetsFromState(state, mFrame, null /* typeSideMap */);
        changeInsets(insets);
        setInsetsAndAlpha(insets, 1f /* alpha */, shown ? 1f : 0f /* fraction */);
        mFinished = true;
        mFinishedShownTypes = shownTypes;
        mShownOnFinish = shown;
    }

    @Override
    @VisibleForTesting
    public float getCurrentFraction() {
        return mAnimation.getFraction();
    }

    public void onCancelled() {
        if (mFinished) {
            return;
@@ -191,6 +199,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
        return mAnimation;
    }

    WindowInsetsAnimationControlListener getListener() {
        return mListener;
    }

    private Insets calculateInsets(InsetsState state, Rect frame,
            SparseArray<InsetsSourceConsumer> consumers, boolean shown,
            @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
@@ -210,9 +222,16 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
    }

    private Insets sanitize(Insets insets) {
        if (insets == null) {
            insets = getCurrentInsets();
        }
        return Insets.max(Insets.min(insets, mShownInsets), mHiddenInsets);
    }

    private static float sanitize(float alpha) {
        return alpha >= 1 ? 1 : (alpha <= 0 ? 0 : alpha);
    }

    private void updateLeashesForSide(@InternalInsetsSide int side, int offset, int inset,
            ArrayList<SurfaceParams> surfaceParams, InsetsState state) {
        ArraySet<InsetsSourceConsumer> items = mSideSourceMap.get(side);
+92 −65
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ import android.view.InsetsState.InternalInsetsType;
import android.view.SurfaceControl.Transaction;
import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimationCallback.AnimationBounds;
import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;

@@ -55,11 +57,12 @@ public class InsetsController implements WindowInsetsController {

    private static final int ANIMATION_DURATION_SHOW_MS = 275;
    private static final int ANIMATION_DURATION_HIDE_MS = 340;
    private static final Interpolator INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
    private static final int DIRECTION_NONE = 0;
    private static final int DIRECTION_SHOW = 1;
    private static final int DIRECTION_HIDE = 2;

    static final Interpolator INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f);

    @IntDef ({DIRECTION_NONE, DIRECTION_SHOW, DIRECTION_HIDE})
    private @interface AnimationDirection{}

@@ -85,8 +88,75 @@ public class InsetsController implements WindowInsetsController {
            return object.getCurrentInsets();
        }
        @Override
        public void set(WindowInsetsAnimationController object, Insets value) {
            object.changeInsets(value);
        public void set(WindowInsetsAnimationController controller, Insets value) {
            controller.setInsetsAndAlpha(
                    value, 1f /* alpha */, (((DefaultAnimationControlListener)
                            ((InsetsAnimationControlImpl) controller).getListener())
                                    .getRawProgress()));
        }
    }

    private class DefaultAnimationControlListener implements WindowInsetsAnimationControlListener {

        private WindowInsetsAnimationController mController;
        private ObjectAnimator mAnimator;
        private boolean mShow;

        DefaultAnimationControlListener(boolean show) {
            mShow = show;
        }

        @Override
        public void onReady(WindowInsetsAnimationController controller, int types) {
            mController = controller;
            if (mShow) {
                showDirectly(types);
            } else {
                hideDirectly(types);
            }
            mAnimationDirection = mShow ? DIRECTION_SHOW : DIRECTION_HIDE;
            mAnimator = ObjectAnimator.ofObject(
                    controller,
                    new InsetsProperty(),
                    sEvaluator,
                    mShow ? controller.getHiddenStateInsets() : controller.getShownStateInsets(),
                    mShow ? controller.getShownStateInsets() : controller.getHiddenStateInsets()
            );
            mAnimator.setDuration(getDurationMs());
            mAnimator.setInterpolator(INTERPOLATOR);
            mAnimator.addListener(new AnimatorListenerAdapter() {

                @Override
                public void onAnimationEnd(Animator animation) {
                    onAnimationFinish();
                }
            });
            mAnimator.start();
        }

        @Override
        public void onCancelled() {
            // Animator can be null when it is cancelled before onReady() completes.
            if (mAnimator != null) {
                mAnimator.cancel();
            }
        }

        private void onAnimationFinish() {
            mAnimationDirection = DIRECTION_NONE;
            mController.finish(mShow);
        }

        private float getRawProgress() {
            float fraction = (float) mAnimator.getCurrentPlayTime() / mAnimator.getDuration();
            return mShow ? fraction : 1 - fraction;
        }

        private long getDurationMs() {
            if (mAnimator != null) {
                return mAnimator.getDuration();
            }
            return mShow ? ANIMATION_DURATION_SHOW_MS : ANIMATION_DURATION_HIDE_MS;
        }
    }

@@ -273,24 +343,25 @@ public class InsetsController implements WindowInsetsController {
    }

    @Override
    public void controlWindowInsetsAnimation(@InsetsType int types,
    public void controlWindowInsetsAnimation(@InsetsType int types, long durationMs,
            WindowInsetsAnimationControlListener listener) {
        controlWindowInsetsAnimation(types, listener, false /* fromIme */);
        controlWindowInsetsAnimation(types, listener, false /* fromIme */, durationMs);
    }

    private void controlWindowInsetsAnimation(@InsetsType int types,
            WindowInsetsAnimationControlListener listener, boolean fromIme) {
            WindowInsetsAnimationControlListener listener, boolean fromIme, long durationMs) {
        // If the frame of our window doesn't span the entire display, the control API makes very
        // little sense, as we don't deal with negative insets. So just cancel immediately.
        if (!mState.getDisplayFrame().equals(mFrame)) {
            listener.onCancelled();
            return;
        }
        controlAnimationUnchecked(types, listener, mFrame, fromIme);
        controlAnimationUnchecked(types, listener, mFrame, fromIme, durationMs);
    }

    private void controlAnimationUnchecked(@InsetsType int types,
            WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme) {
            WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme,
            long durationMs) {
        if (types == 0) {
            // nothing to animate.
            return;
@@ -321,7 +392,7 @@ public class InsetsController implements WindowInsetsController {

        final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(consumers,
                frame, mState, listener, typesReady,
                () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView), this);
                () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView), this, durationMs);
        mAnimationControls.add(controller);
    }

@@ -392,10 +463,13 @@ public class InsetsController implements WindowInsetsController {
    }

    @VisibleForTesting
    public void notifyFinished(InsetsAnimationControlImpl controller, int shownTypes) {
    public void notifyFinished(InsetsAnimationControlImpl controller, boolean shown) {
        mAnimationControls.remove(controller);
        hideDirectly(controller.getTypes() & ~shownTypes);
        showDirectly(controller.getTypes() & shownTypes);
        if (shown) {
            showDirectly(controller.getTypes());
        } else {
            hideDirectly(controller.getTypes());
        }
    }

    void notifyControlRevoked(InsetsSourceConsumer consumer) {
@@ -505,58 +579,11 @@ public class InsetsController implements WindowInsetsController {
            return;
        }

        WindowInsetsAnimationControlListener listener = new WindowInsetsAnimationControlListener() {

            private WindowInsetsAnimationController mController;
            private ObjectAnimator mAnimator;

            @Override
            public void onReady(WindowInsetsAnimationController controller, int types) {
                mController = controller;
                if (show) {
                    showDirectly(types);
                } else {
                    hideDirectly(types);
                }
                mAnimationDirection = show ? DIRECTION_SHOW : DIRECTION_HIDE;
                mAnimator = ObjectAnimator.ofObject(
                        controller,
                        new InsetsProperty(),
                        sEvaluator,
                        show ? controller.getHiddenStateInsets() : controller.getShownStateInsets(),
                        show ? controller.getShownStateInsets() : controller.getHiddenStateInsets()
                );
                mAnimator.setDuration(show
                        ? ANIMATION_DURATION_SHOW_MS
                        : ANIMATION_DURATION_HIDE_MS);
                mAnimator.setInterpolator(INTERPOLATOR);
                mAnimator.addListener(new AnimatorListenerAdapter() {

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        onAnimationFinish();
                    }
                });
                mAnimator.start();
            }

            @Override
            public void onCancelled() {
                // Animator can be null when it is cancelled before onReady() completes.
                if (mAnimator != null) {
                    mAnimator.cancel();
                }
            }

            private void onAnimationFinish() {
                mAnimationDirection = DIRECTION_NONE;
                mController.finish(show ? types : 0);
            }
        };

        final DefaultAnimationControlListener listener = new DefaultAnimationControlListener(show);
        // Show/hide animations always need to be relative to the display frame, in order that shown
        // and hidden state insets are correct.
        controlAnimationUnchecked(types, listener, mState.getDisplayFrame(), fromIme);
        controlAnimationUnchecked(
                types, listener, mState.getDisplayFrame(), fromIme, listener.getDurationMs());
    }

    private void hideDirectly(@InsetsType int types) {
@@ -587,12 +614,12 @@ public class InsetsController implements WindowInsetsController {
    }

    @VisibleForTesting
    public void dispatchAnimationStarted(WindowInsetsAnimationListener.InsetsAnimation animation) {
        mViewRoot.mView.dispatchWindowInsetsAnimationStarted(animation);
    public void dispatchAnimationStarted(InsetsAnimation animation, AnimationBounds bounds) {
        mViewRoot.mView.dispatchWindowInsetsAnimationStarted(animation, bounds);
    }

    @VisibleForTesting
    public void dispatchAnimationFinished(WindowInsetsAnimationListener.InsetsAnimation animation) {
    public void dispatchAnimationFinished(InsetsAnimation animation) {
        mViewRoot.mView.dispatchWindowInsetsAnimationFinished(animation);
    }

+38 −16

File changed.

Preview size limit exceeded, changes collapsed.

Loading