Merge "Add passive callback for system-run insets animation" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
7f9f126df7
@@ -314,6 +314,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
|||||||
(int) (startValue.right + fraction * (endValue.right - startValue.right)),
|
(int) (startValue.right + fraction * (endValue.right - startValue.right)),
|
||||||
(int) (startValue.bottom + fraction * (endValue.bottom - startValue.bottom)));
|
(int) (startValue.bottom + fraction * (endValue.bottom - startValue.bottom)));
|
||||||
|
|
||||||
|
/** Logging listener. */
|
||||||
|
private WindowInsetsAnimationControlListener mLoggingListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default implementation of listener, to be used by InsetsController and InsetsPolicy to
|
* The default implementation of listener, to be used by InsetsController and InsetsPolicy to
|
||||||
* animate insets.
|
* animate insets.
|
||||||
@@ -330,6 +333,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
|||||||
private final long mDurationMs;
|
private final long mDurationMs;
|
||||||
private final boolean mDisable;
|
private final boolean mDisable;
|
||||||
private final int mFloatingImeBottomInset;
|
private final int mFloatingImeBottomInset;
|
||||||
|
private final WindowInsetsAnimationControlListener mLoggingListener;
|
||||||
|
|
||||||
private final ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
|
private final ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
|
||||||
new ThreadLocal<AnimationHandler>() {
|
new ThreadLocal<AnimationHandler>() {
|
||||||
@@ -343,7 +347,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
|||||||
|
|
||||||
public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks,
|
public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks,
|
||||||
@InsetsType int requestedTypes, @Behavior int behavior, boolean disable,
|
@InsetsType int requestedTypes, @Behavior int behavior, boolean disable,
|
||||||
int floatingImeBottomInset) {
|
int floatingImeBottomInset, WindowInsetsAnimationControlListener loggingListener) {
|
||||||
mShow = show;
|
mShow = show;
|
||||||
mHasAnimationCallbacks = hasAnimationCallbacks;
|
mHasAnimationCallbacks = hasAnimationCallbacks;
|
||||||
mRequestedTypes = requestedTypes;
|
mRequestedTypes = requestedTypes;
|
||||||
@@ -351,12 +355,16 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
|||||||
mDurationMs = calculateDurationMs();
|
mDurationMs = calculateDurationMs();
|
||||||
mDisable = disable;
|
mDisable = disable;
|
||||||
mFloatingImeBottomInset = floatingImeBottomInset;
|
mFloatingImeBottomInset = floatingImeBottomInset;
|
||||||
|
mLoggingListener = loggingListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReady(WindowInsetsAnimationController controller, int types) {
|
public void onReady(WindowInsetsAnimationController controller, int types) {
|
||||||
mController = controller;
|
mController = controller;
|
||||||
if (DEBUG) Log.d(TAG, "default animation onReady types: " + types);
|
if (DEBUG) Log.d(TAG, "default animation onReady types: " + types);
|
||||||
|
if (mLoggingListener != null) {
|
||||||
|
mLoggingListener.onReady(controller, types);
|
||||||
|
}
|
||||||
|
|
||||||
if (mDisable) {
|
if (mDisable) {
|
||||||
onAnimationFinish();
|
onAnimationFinish();
|
||||||
@@ -410,6 +418,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
|||||||
public void onFinished(WindowInsetsAnimationController controller) {
|
public void onFinished(WindowInsetsAnimationController controller) {
|
||||||
if (DEBUG) Log.d(TAG, "InternalAnimationControlListener onFinished types:"
|
if (DEBUG) Log.d(TAG, "InternalAnimationControlListener onFinished types:"
|
||||||
+ Type.toString(mRequestedTypes));
|
+ Type.toString(mRequestedTypes));
|
||||||
|
if (mLoggingListener != null) {
|
||||||
|
mLoggingListener.onFinished(controller);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -420,6 +431,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
|||||||
}
|
}
|
||||||
if (DEBUG) Log.d(TAG, "InternalAnimationControlListener onCancelled types:"
|
if (DEBUG) Log.d(TAG, "InternalAnimationControlListener onCancelled types:"
|
||||||
+ mRequestedTypes);
|
+ mRequestedTypes);
|
||||||
|
if (mLoggingListener != null) {
|
||||||
|
mLoggingListener.onCancelled(controller);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Interpolator getInsetsInterpolator() {
|
protected Interpolator getInsetsInterpolator() {
|
||||||
@@ -1147,6 +1161,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
|||||||
updateRequestedVisibilities();
|
updateRequestedVisibilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(b/242962223): Make this setter restrictive.
|
||||||
|
@Override
|
||||||
|
public void setSystemDrivenInsetsAnimationLoggingListener(
|
||||||
|
@Nullable WindowInsetsAnimationControlListener listener) {
|
||||||
|
mLoggingListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Pair of (types ready to animate, IME ready to animate).
|
* @return Pair of (types ready to animate, IME ready to animate).
|
||||||
*/
|
*/
|
||||||
@@ -1460,7 +1481,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
|||||||
boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks();
|
boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks();
|
||||||
final InternalAnimationControlListener listener = new InternalAnimationControlListener(
|
final InternalAnimationControlListener listener = new InternalAnimationControlListener(
|
||||||
show, hasAnimationCallbacks, types, mHost.getSystemBarsBehavior(),
|
show, hasAnimationCallbacks, types, mHost.getSystemBarsBehavior(),
|
||||||
skipAnim || mAnimationsDisabled, mHost.dipToPx(FLOATING_IME_BOTTOM_INSET_DP));
|
skipAnim || mAnimationsDisabled, mHost.dipToPx(FLOATING_IME_BOTTOM_INSET_DP),
|
||||||
|
mLoggingListener);
|
||||||
|
|
||||||
// We are about to playing the default animation (show/hide). Passing a null frame indicates
|
// We are about to playing the default animation (show/hide). Passing a null frame indicates
|
||||||
// the controlled types should be animated regardless of the frame.
|
// the controlled types should be animated regardless of the frame.
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public class PendingInsetsController implements WindowInsetsController {
|
|||||||
private ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners
|
private ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners
|
||||||
= new ArrayList<>();
|
= new ArrayList<>();
|
||||||
private int mCaptionInsetsHeight = 0;
|
private int mCaptionInsetsHeight = 0;
|
||||||
|
private WindowInsetsAnimationControlListener mLoggingListener;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void show(int types) {
|
public void show(int types) {
|
||||||
@@ -176,6 +177,9 @@ public class PendingInsetsController implements WindowInsetsController {
|
|||||||
controller.addOnControllableInsetsChangedListener(
|
controller.addOnControllableInsetsChangedListener(
|
||||||
mControllableInsetsChangedListeners.get(i));
|
mControllableInsetsChangedListeners.get(i));
|
||||||
}
|
}
|
||||||
|
if (mLoggingListener != null) {
|
||||||
|
controller.setSystemDrivenInsetsAnimationLoggingListener(mLoggingListener);
|
||||||
|
}
|
||||||
|
|
||||||
// Reset all state so it doesn't get applied twice just in case
|
// Reset all state so it doesn't get applied twice just in case
|
||||||
mRequests.clear();
|
mRequests.clear();
|
||||||
@@ -184,7 +188,7 @@ public class PendingInsetsController implements WindowInsetsController {
|
|||||||
mAppearance = 0;
|
mAppearance = 0;
|
||||||
mAppearanceMask = 0;
|
mAppearanceMask = 0;
|
||||||
mAnimationsDisabled = false;
|
mAnimationsDisabled = false;
|
||||||
|
mLoggingListener = null;
|
||||||
// After replaying, we forward everything directly to the replayed instance.
|
// After replaying, we forward everything directly to the replayed instance.
|
||||||
mReplayedInsetsController = controller;
|
mReplayedInsetsController = controller;
|
||||||
}
|
}
|
||||||
@@ -197,6 +201,16 @@ public class PendingInsetsController implements WindowInsetsController {
|
|||||||
mReplayedInsetsController = null;
|
mReplayedInsetsController = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSystemDrivenInsetsAnimationLoggingListener(
|
||||||
|
@Nullable WindowInsetsAnimationControlListener listener) {
|
||||||
|
if (mReplayedInsetsController != null) {
|
||||||
|
mReplayedInsetsController.setSystemDrivenInsetsAnimationLoggingListener(listener);
|
||||||
|
} else {
|
||||||
|
mLoggingListener = listener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void controlWindowInsetsAnimation(@InsetsType int types, long durationMillis,
|
public void controlWindowInsetsAnimation(@InsetsType int types, long durationMillis,
|
||||||
@Nullable Interpolator interpolator,
|
@Nullable Interpolator interpolator,
|
||||||
|
|||||||
@@ -200,6 +200,21 @@ public interface WindowInsetsController {
|
|||||||
@Nullable CancellationSignal cancellationSignal,
|
@Nullable CancellationSignal cancellationSignal,
|
||||||
@NonNull WindowInsetsAnimationControlListener listener);
|
@NonNull WindowInsetsAnimationControlListener listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lets the application add non-controllable listener object that can be called back
|
||||||
|
* when animation is invoked by the system by host calling methods such as {@link #show} or
|
||||||
|
* {@link #hide}.
|
||||||
|
*
|
||||||
|
* The listener is supposed to be used for logging only, using the control or
|
||||||
|
* relying on the timing of the callback in any other way is not supported.
|
||||||
|
*
|
||||||
|
* @param listener The {@link WindowInsetsAnimationControlListener} that gets called when
|
||||||
|
* the animation is driven by the system and not the host
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
void setSystemDrivenInsetsAnimationLoggingListener(
|
||||||
|
@Nullable WindowInsetsAnimationControlListener listener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the appearance of system bars.
|
* Controls the appearance of system bars.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -235,6 +235,21 @@ public class InsetsControllerTest {
|
|||||||
verify(controlListener, never()).onReady(any(), anyInt());
|
verify(controlListener, never()).onReady(any(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSystemDrivenInsetsAnimationLoggingListener_onReady() {
|
||||||
|
prepareControls();
|
||||||
|
// only the original thread that created view hierarchy can touch its views
|
||||||
|
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
||||||
|
WindowInsetsAnimationControlListener loggingListener =
|
||||||
|
mock(WindowInsetsAnimationControlListener.class);
|
||||||
|
mController.setSystemDrivenInsetsAnimationLoggingListener(loggingListener);
|
||||||
|
mController.getSourceConsumer(ITYPE_IME).onWindowFocusGained(true);
|
||||||
|
// since there is no focused view, forcefully make IME visible.
|
||||||
|
mController.show(Type.ime(), true /* fromIme */);
|
||||||
|
verify(loggingListener).onReady(notNull(), anyInt());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAnimationEndState() {
|
public void testAnimationEndState() {
|
||||||
InsetsSourceControl[] controls = prepareControls();
|
InsetsSourceControl[] controls = prepareControls();
|
||||||
|
|||||||
@@ -212,6 +212,25 @@ public class PendingInsetsControllerTest {
|
|||||||
verifyZeroInteractions(secondController);
|
verifyZeroInteractions(secondController);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSystemDrivenInsetsAnimationLoggingListener() {
|
||||||
|
WindowInsetsAnimationControlListener listener =
|
||||||
|
mock(WindowInsetsAnimationControlListener.class);
|
||||||
|
mPendingInsetsController.setSystemDrivenInsetsAnimationLoggingListener(listener);
|
||||||
|
mPendingInsetsController.replayAndAttach(mReplayedController);
|
||||||
|
verify(mReplayedController).setSystemDrivenInsetsAnimationLoggingListener(eq(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSystemDrivenInsetsAnimationLoggingListener_direct() {
|
||||||
|
mPendingInsetsController.replayAndAttach(mReplayedController);
|
||||||
|
WindowInsetsAnimationControlListener listener =
|
||||||
|
mock(WindowInsetsAnimationControlListener.class);
|
||||||
|
mPendingInsetsController.setSystemDrivenInsetsAnimationLoggingListener(listener);
|
||||||
|
verify(mReplayedController).setSystemDrivenInsetsAnimationLoggingListener(
|
||||||
|
eq(listener));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDetachReattach() {
|
public void testDetachReattach() {
|
||||||
mPendingInsetsController.show(systemBars());
|
mPendingInsetsController.show(systemBars());
|
||||||
|
|||||||
@@ -759,7 +759,7 @@ class InsetsPolicy {
|
|||||||
|
|
||||||
InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback, int types) {
|
InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback, int types) {
|
||||||
super(show, false /* hasCallbacks */, types, BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE,
|
super(show, false /* hasCallbacks */, types, BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE,
|
||||||
false /* disable */, 0 /* floatingImeBottomInsets */);
|
false /* disable */, 0 /* floatingImeBottomInsets */, null);
|
||||||
mFinishCallback = finishCallback;
|
mFinishCallback = finishCallback;
|
||||||
mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this);
|
mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user