Merge changes I88f7f7e5,If6c1153d
* changes:
Expand docs for animation listener
A brave new world for window insets (11/n)
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 96ef8ba..ccd0fc1 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -22,6 +22,7 @@
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;
@@ -199,7 +200,7 @@
* @hide
*/
private static final String[] CALLBACK_TRACE_TITLES = {
- "input", "animation", "traversal", "commit"
+ "input", "animation", "insets_animation", "traversal", "commit"
};
/**
@@ -209,18 +210,33 @@
public static final int CALLBACK_INPUT = 0;
/**
- * Callback type: Animation callback. Runs before traversals.
+ * Callback type: Animation callback. Runs before {@link #CALLBACK_INSETS_ANIMATION}.
* @hide
*/
@TestApi
public static final int CALLBACK_ANIMATION = 1;
/**
+ * 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.
+ * <p>
+ * Both input and animation may change insets, so we need to run this after these callbacks, but
+ * before traversals.
+ * <p>
+ * Runs before traversals.
+ * @hide
+ */
+ public static final int CALLBACK_INSETS_ANIMATION = 2;
+
+ /**
* Callback type: Traversal callback. Handles layout and draw. Runs
* after all other asynchronous messages have been handled.
* @hide
*/
- public static final int CALLBACK_TRAVERSAL = 2;
+ public static final int CALLBACK_TRAVERSAL = 3;
/**
* Callback type: Commit callback. Handles post-draw operations for the frame.
@@ -232,7 +248,7 @@
* to the view hierarchy state) actually took effect.
* @hide
*/
- public static final int CALLBACK_COMMIT = 3;
+ public static final int CALLBACK_COMMIT = 4;
private static final int CALLBACK_LAST = CALLBACK_COMMIT;
@@ -704,6 +720,7 @@
mFrameInfo.markAnimationsStart();
doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
+ doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameTimeNanos);
mFrameInfo.markPerformTraversalsStart();
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 7b9f78e..ce71b07 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -45,7 +45,9 @@
* @hide
*/
@VisibleForTesting
-public class InsetsAnimationControlImpl implements WindowInsetsAnimationController {
+public class InsetsAnimationControlImpl implements WindowInsetsAnimationController {
+
+ private final Rect mTmpFrame = new Rect();
private final WindowInsetsAnimationControlListener mListener;
private final SparseArray<InsetsSourceConsumer> mConsumers;
@@ -61,19 +63,23 @@
private final InsetsState mInitialInsetsState;
private final @InsetType int mTypes;
private final Supplier<SyncRtSurfaceTransactionApplier> mTransactionApplierSupplier;
-
+ private final InsetsController mController;
+ private final WindowInsetsAnimationListener.InsetsAnimation mAnimation;
private Insets mCurrentInsets;
+ private Insets mPendingInsets;
@VisibleForTesting
public InsetsAnimationControlImpl(SparseArray<InsetsSourceConsumer> consumers, Rect frame,
InsetsState state, WindowInsetsAnimationControlListener listener,
@InsetType int types,
- Supplier<SyncRtSurfaceTransactionApplier> transactionApplierSupplier) {
+ Supplier<SyncRtSurfaceTransactionApplier> transactionApplierSupplier,
+ InsetsController controller) {
mConsumers = consumers;
mListener = listener;
mTypes = types;
mTransactionApplierSupplier = transactionApplierSupplier;
- mInitialInsetsState = new InsetsState(state);
+ mController = controller;
+ mInitialInsetsState = new InsetsState(state, true /* copySources */);
mCurrentInsets = getInsetsFromState(mInitialInsetsState, frame, null /* typeSideMap */);
mHiddenInsets = calculateInsets(mInitialInsetsState, frame, consumers, false /* shown */,
null /* typeSideMap */);
@@ -83,6 +89,10 @@
// 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);
}
@Override
@@ -108,29 +118,35 @@
@Override
public void changeInsets(Insets insets) {
- insets = sanitize(insets);
- final Insets offset = Insets.subtract(mShownInsets, insets);
+ mPendingInsets = sanitize(insets);
+ mController.scheduleApplyChangeInsets();
+ }
+
+ void applyChangeInsets(InsetsState state) {
+ final Insets offset = Insets.subtract(mShownInsets, mPendingInsets);
ArrayList<SurfaceParams> params = new ArrayList<>();
if (offset.left != 0) {
- updateLeashesForSide(INSET_SIDE_LEFT, offset.left, params);
+ updateLeashesForSide(INSET_SIDE_LEFT, offset.left, params, state);
}
if (offset.top != 0) {
- updateLeashesForSide(INSET_SIDE_TOP, offset.top, params);
+ updateLeashesForSide(INSET_SIDE_TOP, offset.top, params, state);
}
if (offset.right != 0) {
- updateLeashesForSide(INSET_SIDE_RIGHT, offset.right, params);
+ updateLeashesForSide(INSET_SIDE_RIGHT, offset.right, params, state);
}
if (offset.bottom != 0) {
- updateLeashesForSide(INSET_SIDE_BOTTOM, offset.bottom, params);
+ updateLeashesForSide(INSET_SIDE_BOTTOM, offset.bottom, params, state);
}
SyncRtSurfaceTransactionApplier applier = mTransactionApplierSupplier.get();
applier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
- mCurrentInsets = insets;
+ mCurrentInsets = mPendingInsets;
}
@Override
public void finish(int shownTypes) {
// TODO
+
+ mController.dispatchAnimationFinished(mAnimation);
}
private Insets calculateInsets(InsetsState state, Rect frame,
@@ -146,7 +162,7 @@
@Nullable @InsetSide SparseIntArray typeSideMap) {
return state.calculateInsets(frame, false /* isScreenRound */,
false /* alwaysConsumerNavBar */, null /* displayCutout */, typeSideMap)
- .getSystemWindowInsets();
+ .getInsets(mTypes);
}
private Insets sanitize(Insets insets) {
@@ -154,7 +170,7 @@
}
private void updateLeashesForSide(@InsetSide int side, int inset,
- ArrayList<SurfaceParams> surfaceParams) {
+ ArrayList<SurfaceParams> surfaceParams, InsetsState state) {
ArraySet<InsetsSourceConsumer> items = mSideSourceMap.get(side);
// TODO: Implement behavior when inset spans over multiple types
for (int i = items.size() - 1; i >= 0; i--) {
@@ -162,24 +178,32 @@
final InsetsSource source = mInitialInsetsState.getSource(consumer.getType());
final SurfaceControl leash = consumer.getControl().getLeash();
mTmpMatrix.setTranslate(source.getFrame().left, source.getFrame().top);
- addTranslationToMatrix(side, inset, mTmpMatrix);
+
+ mTmpFrame.set(source.getFrame());
+ addTranslationToMatrix(side, inset, mTmpMatrix, mTmpFrame);
+
+ state.getSource(source.getType()).setFrame(mTmpFrame);
surfaceParams.add(new SurfaceParams(leash, 1f, mTmpMatrix, null, 0, 0f));
}
}
- private void addTranslationToMatrix(@InsetSide int side, int inset, Matrix m) {
+ private void addTranslationToMatrix(@InsetSide int side, int inset, Matrix m, Rect frame) {
switch (side) {
case INSET_SIDE_LEFT:
m.postTranslate(-inset, 0);
+ frame.offset(-inset, 0);
break;
case INSET_SIDE_TOP:
m.postTranslate(0, -inset);
+ frame.offset(0, -inset);
break;
case INSET_SIDE_RIGHT:
m.postTranslate(inset, 0);
+ frame.offset(inset, 0);
break;
case INSET_SIDE_BOTTOM:
m.postTranslate(0, inset);
+ frame.offset(0, inset);
break;
}
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 01af37e..c2ade76 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.Insets;
import android.graphics.Rect;
import android.os.RemoteException;
import android.util.ArraySet;
@@ -49,9 +50,29 @@
private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>();
private final ArrayList<InsetsAnimationControlImpl> mAnimationControls = new ArrayList<>();
+ private WindowInsets mLastInsets;
+
+ private boolean mAnimCallbackScheduled;
+
+ private final Runnable mAnimCallback;
public InsetsController(ViewRootImpl viewRoot) {
mViewRoot = viewRoot;
+ mAnimCallback = () -> {
+ mAnimCallbackScheduled = false;
+ if (mAnimationControls.isEmpty()) {
+ return;
+ }
+
+ InsetsState state = new InsetsState(mState, true /* copySources */);
+ for (int i = mAnimationControls.size() - 1; i >= 0; i--) {
+ mAnimationControls.get(i).applyChangeInsets(state);
+ }
+ WindowInsets insets = state.calculateInsets(mFrame, mLastInsets.isRound(),
+ mLastInsets.shouldAlwaysConsumeNavBar(), mLastInsets.getDisplayCutout(),
+ null /* typeSideMap */);
+ mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets);
+ };
}
void onFrameChanged(Rect frame) {
@@ -82,8 +103,9 @@
@VisibleForTesting
public WindowInsets calculateInsets(boolean isScreenRound,
boolean alwaysConsumeNavBar, DisplayCutout cutout) {
- return mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeNavBar, cutout,
+ mLastInsets = mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeNavBar, cutout,
null /* typeSideMap */);
+ return mLastInsets;
}
/**
@@ -148,7 +170,7 @@
}
final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(consumers,
mFrame, mState, listener, types,
- () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView));
+ () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView), this);
mAnimationControls.add(controller);
}
@@ -200,4 +222,20 @@
pw.println(prefix); pw.println("InsetsController:");
mState.dump(prefix + " ", pw);
}
+
+ void dispatchAnimationStarted(WindowInsetsAnimationListener.InsetsAnimation animation) {
+ mViewRoot.mView.dispatchWindowInsetsAnimationStarted(animation);
+ }
+
+ void dispatchAnimationFinished(WindowInsetsAnimationListener.InsetsAnimation animation) {
+ mViewRoot.mView.dispatchWindowInsetsAnimationFinished(animation);
+ }
+
+ void scheduleApplyChangeInsets() {
+ if (!mAnimCallbackScheduled) {
+ mViewRoot.mChoreographer.postCallback(Choreographer.CALLBACK_INSETS_ANIMATION,
+ mAnimCallback, null /* token*/);
+ mAnimCallbackScheduled = true;
+ }
+ }
}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 0931914..cf8c0707 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -107,6 +107,10 @@
set(copy);
}
+ public InsetsState(InsetsState copy, boolean copySources) {
+ set(copy, copySources);
+ }
+
/**
* Calculates {@link WindowInsets} based on the current source configuration.
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index cd0e579..abefd55 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -96,6 +96,7 @@
import android.view.AccessibilityIterators.TextSegmentIterator;
import android.view.AccessibilityIterators.WordTextSegmentIterator;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.WindowInsetsAnimationListener.InsetsAnimation;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEventSource;
import android.view.accessibility.AccessibilityManager;
@@ -4547,6 +4548,8 @@
OnCapturedPointerListener mOnCapturedPointerListener;
private ArrayList<OnUnhandledKeyEventListener> mUnhandledKeyListeners;
+
+ private WindowInsetsAnimationListener mWindowInsetsAnimationListener;
}
@UnsupportedAppUsage
@@ -10488,6 +10491,37 @@
}
/**
+ * Sets a {@link WindowInsetsAnimationListener} to be notified about animations of windows that
+ * cause insets.
+ *
+ * @param listener The listener to set.
+ * @hide pending unhide
+ */
+ public void setWindowInsetsAnimationListener(WindowInsetsAnimationListener listener) {
+ getListenerInfo().mWindowInsetsAnimationListener = listener;
+ }
+
+ void dispatchWindowInsetsAnimationStarted(InsetsAnimation animation) {
+ if (mListenerInfo != null && mListenerInfo.mWindowInsetsAnimationListener != null) {
+ mListenerInfo.mWindowInsetsAnimationListener.onStarted(animation);
+ }
+ }
+
+ WindowInsets dispatchWindowInsetsAnimationProgress(WindowInsets insets) {
+ if (mListenerInfo != null && mListenerInfo.mWindowInsetsAnimationListener != null) {
+ return mListenerInfo.mWindowInsetsAnimationListener.onProgress(insets);
+ } else {
+ return insets;
+ }
+ }
+
+ void dispatchWindowInsetsAnimationFinished(InsetsAnimation animation) {
+ if (mListenerInfo != null && mListenerInfo.mOnApplyWindowInsetsListener != null) {
+ mListenerInfo.mWindowInsetsAnimationListener.onFinished(animation);
+ }
+ }
+
+ /**
* Compute the view's coordinate within the surface.
*
* <p>Computes the coordinates of this view in its surface. The argument
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9d11397..0986cfa 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -51,6 +51,7 @@
import android.util.Pools.SynchronizedPool;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import android.view.WindowInsetsAnimationListener.InsetsAnimation;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -7139,6 +7140,34 @@
return insets;
}
+ @Override
+ void dispatchWindowInsetsAnimationStarted(InsetsAnimation animation) {
+ super.dispatchWindowInsetsAnimationStarted(animation);
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ getChildAt(i).dispatchWindowInsetsAnimationStarted(animation);
+ }
+ }
+
+ @Override
+ WindowInsets dispatchWindowInsetsAnimationProgress(WindowInsets insets) {
+ insets = super.dispatchWindowInsetsAnimationProgress(insets);
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ getChildAt(i).dispatchWindowInsetsAnimationProgress(insets);
+ }
+ return insets;
+ }
+
+ @Override
+ void dispatchWindowInsetsAnimationFinished(InsetsAnimation animation) {
+ super.dispatchWindowInsetsAnimationFinished(animation);
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ getChildAt(i).dispatchWindowInsetsAnimationFinished(animation);
+ }
+ }
+
/**
* Returns the animation listener to which layout animation events are
* sent.
diff --git a/core/java/android/view/WindowInsetsAnimationController.java b/core/java/android/view/WindowInsetsAnimationController.java
index 9de517d..cf4415d 100644
--- a/core/java/android/view/WindowInsetsAnimationController.java
+++ b/core/java/android/view/WindowInsetsAnimationController.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.graphics.Insets;
import android.view.WindowInsets.Type.InsetType;
+import android.view.WindowInsetsAnimationListener.InsetsAnimation;
/**
* Interface to control a window inset animation frame-by-frame.
@@ -28,8 +29,13 @@
/**
* Retrieves the {@link Insets} when the windows this animation is controlling are fully hidden.
+ * <p>
+ * If there are any animation listeners registered, this value is the same as
+ * {@link InsetsAnimation#getLowerBound()} that will be passed into the callbacks.
*
* @return Insets when the windows this animation is controlling are fully hidden.
+ *
+ * @see InsetsAnimation#getLowerBound()
*/
@NonNull Insets getHiddenStateInsets();
@@ -38,8 +44,13 @@
* <p>
* In case the size of a window causing insets is changing in the middle of the animation, we
* execute that height change after this animation has finished.
+ * <p>
+ * If there are any animation listeners registered, this value is the same as
+ * {@link InsetsAnimation#getUpperBound()} that will be passed into the callbacks.
*
* @return Insets when the windows this animation is controlling are fully shown.
+ *
+ * @see InsetsAnimation#getUpperBound()
*/
@NonNull Insets getShownStateInsets();
@@ -59,8 +70,11 @@
* <p>
* Note that this will <b>not</b> inform the view system of a full inset change via
* {@link View#dispatchApplyWindowInsets} in order to avoid a full layout pass during the
- * animation. If you'd like to animate views during a window inset animation, use
- * TODO add link to animation listeners.
+ * animation. If you'd like to animate views during a window inset animation, register a
+ * {@link WindowInsetsAnimationListener} by calling
+ * {@link View#setWindowInsetsAnimationListener(WindowInsetsAnimationListener)} that will be
+ * notified about any insets change via {@link WindowInsetsAnimationListener#onProgress} during
+ * the animation.
* <p>
* {@link View#dispatchApplyWindowInsets} will instead be called once the animation has
* finished, i.e. once {@link #finish} has been called.
@@ -70,6 +84,9 @@
* the resulting insets of that configuration will match the passed in parameter.
* Note that these insets are being clamped to the range from
* {@link #getHiddenStateInsets} to {@link #getShownStateInsets}
+ *
+ * @see WindowInsetsAnimationListener
+ * @see View#setWindowInsetsAnimationListener(WindowInsetsAnimationListener)
*/
void changeInsets(@NonNull Insets insets);
diff --git a/core/java/android/view/WindowInsetsAnimationListener.java b/core/java/android/view/WindowInsetsAnimationListener.java
new file mode 100644
index 0000000..682ab5b
--- /dev/null
+++ b/core/java/android/view/WindowInsetsAnimationListener.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2018 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.graphics.Insets;
+
+/**
+ * Interface that allows the application to listen to animation events for windows that cause
+ * insets.
+ * @hide pending unhide
+ */
+public interface WindowInsetsAnimationListener {
+
+ /**
+ * Called when an inset animation gets started.
+ *
+ * @param animation The animation that is about to start.
+ */
+ void onStarted(InsetsAnimation animation);
+
+ /**
+ * Called when the insets change as part of running an animation. Note that even if multiple
+ * animations for different types are running, there will only be one progress callback per
+ * frame. The {@code insets} passed as an argument represents the overall state and will include
+ * all types, regardless of whether they are animating or not.
+ * <p>
+ * Note that insets dispatch is hierarchical: It will start at the root of the view hierarchy,
+ * and then traverse it and invoke the callback of the specific {@link View} being traversed.
+ * The callback may return a modified instance by calling {@link WindowInsets#inset(int, int, int, int)}
+ * to indicate that a part of the insets have been used to offset or clip its children, and the
+ * children shouldn't worry about that part anymore.
+ *
+ * @param insets The current insets.
+ * @return The insets to dispatch to the subtree of the hierarchy.
+ */
+ WindowInsets onProgress(WindowInsets insets);
+
+ /**
+ * Called when an inset animation has finished.
+ *
+ * @param animation The animation that has finished running.
+ */
+ void onFinished(InsetsAnimation animation);
+
+ /**
+ * Class representing an animation of a set of windows that cause insets.
+ */
+ class InsetsAnimation {
+
+ private final @WindowInsets.Type.InsetType int mTypeMask;
+ private final Insets mLowerBound;
+ private final Insets mUpperBound;
+
+ /**
+ * @hide
+ */
+ InsetsAnimation(int typeMask, Insets lowerBound, Insets upperBound) {
+ mTypeMask = typeMask;
+ mLowerBound = lowerBound;
+ mUpperBound = upperBound;
+ }
+
+ /**
+ * @return The bitmask of {@link WindowInsets.Type.InsetType}s that are animating.
+ */
+ public @WindowInsets.Type.InsetType int getTypeMask() {
+ return mTypeMask;
+ }
+
+ /**
+ * Queries the lower inset bound of the animation. If the animation is about showing or
+ * hiding a window that cause insets, the lower bound is {@link Insets#NONE} and the upper
+ * bound is the same as {@link WindowInsets#getInsets(int)} for the fully shown state. This
+ * is the same as {@link WindowInsetsAnimationController#getHiddenStateInsets} and
+ * {@link WindowInsetsAnimationController#getShownStateInsets} in case the listener gets
+ * invoked because of an animation that originates from
+ * {@link WindowInsetsAnimationController}.
+ * <p>
+ * However, if the size of a window that causes insets is changing, these are the
+ * lower/upper bounds of that size animation.
+ * <p>
+ * There are no overlapping animations for a specific type, but there may be two animations
+ * running at the same time for different inset types.
+ *
+ * @see #getUpperBound()
+ * @see WindowInsetsAnimationController#getHiddenStateInsets
+ * TODO: It's a bit weird that these are global per window but onProgress is hierarchical.
+ * TODO: If multiple types are animating, querying the bound per type isn't possible. Should
+ * we:
+ * 1. Offer bounds by type here?
+ * 2. Restrict one animation to one single type only?
+ * Returning WindowInsets here isn't feasible in case of overlapping animations: We can't
+ * fill in the insets for the types from the other animation into the WindowInsets object
+ * as it's changing as well.
+ */
+ public Insets getLowerBound() {
+ return mLowerBound;
+ }
+
+ /**
+ * @see #getLowerBound()
+ * @see WindowInsetsAnimationController#getShownStateInsets
+ */
+ public Insets getUpperBound() {
+ return mUpperBound;
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index d520f15..81ca910 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -19,6 +19,7 @@
import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
import static android.view.InsetsState.TYPE_TOP_BAR;
import static junit.framework.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.graphics.Insets;
@@ -83,7 +84,7 @@
consumers.put(TYPE_NAVIGATION_BAR, navConsumer);
mController = new InsetsAnimationControlImpl(consumers,
new Rect(0, 0, 500, 500), state, mMockListener, WindowInsets.Type.systemBars(),
- () -> mMockTransactionApplier);
+ () -> mMockTransactionApplier, mock(InsetsController.class));
}
@Test