diff options
| author | 2019-05-28 17:00:16 -0400 | |
|---|---|---|
| committer | 2019-05-29 15:22:31 -0400 | |
| commit | c36ee6f4ff07154b302f16efc9e842f01fb90dfd (patch) | |
| tree | 3330cc8a69fb0f93889b59ad7531d14beab68ed2 | |
| parent | 0fa7a54e3026937528c03456287d8cb23598631d (diff) | |
Stability and logic fixes to PhysicsAnimationLayout to address bugs that leave Bubbles in a bad state.
- Ignore attempts to start animations from controllers that aren't the active controller.
- Use -Float.MAX_VALUE for the start velocity default, not 0, so negative velocities aren't discarded.
- Update the SpringForce's final position directly rather than using animateToFinalPosition (the latter is susceptible to race conditions if animateToFinalPosition is called again before the next animation frame, a bug in DynamicAnimation).
Test: atest SystemUITests
Fixes: 131625234
Change-Id: Ie48da88db6c241896bba17bb800a2f91ab61651e
8 files changed, 188 insertions, 88 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 6de0fb581e90..29a69fb15ba6 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -332,7 +332,7 @@ public class BubbleStackView extends FrameLayout { mBubbleContainer = new PhysicsAnimationLayout(context); mBubbleContainer.setMaxRenderedChildren( getResources().getInteger(R.integer.bubbles_max_rendered)); - mBubbleContainer.setController(mStackAnimationController); + mBubbleContainer.setActiveController(mStackAnimationController); mBubbleContainer.setElevation(elevation); mBubbleContainer.setClipChildren(false); addView(mBubbleContainer, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)); @@ -909,7 +909,7 @@ public class BubbleStackView extends FrameLayout { }; if (shouldExpand) { - mBubbleContainer.setController(mExpandedAnimationController); + mBubbleContainer.setActiveController(mExpandedAnimationController); mExpandedAnimationController.expandFromStack( mStackAnimationController.getStackPositionAlongNearestHorizontalEdge() /* collapseTo */, @@ -921,7 +921,7 @@ public class BubbleStackView extends FrameLayout { mBubbleContainer.cancelAllAnimations(); mExpandedAnimationController.collapseBackToStack( () -> { - mBubbleContainer.setController(mStackAnimationController); + mBubbleContainer.setActiveController(mStackAnimationController); updateAfter.run(); }); } @@ -1014,7 +1014,7 @@ public class BubbleStackView extends FrameLayout { } mStackAnimationController.cancelStackPositionAnimations(); - mBubbleContainer.setController(mStackAnimationController); + mBubbleContainer.setActiveController(mStackAnimationController); hideFlyoutImmediate(); mDraggingInDismissTarget = false; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java index 24337a3c3312..b52280a12a64 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java @@ -103,20 +103,6 @@ public class ExpandedAnimationController private float mBubbleDraggingOutVelX; private float mBubbleDraggingOutVelY; - @Override - protected void setLayout(PhysicsAnimationLayout layout) { - super.setLayout(layout); - - final Resources res = layout.getResources(); - mStackOffsetPx = res.getDimensionPixelSize(R.dimen.bubble_stack_offset); - mBubblePaddingPx = res.getDimensionPixelSize(R.dimen.bubble_padding); - mBubbleSizePx = res.getDimensionPixelSize(R.dimen.individual_bubble_size); - mStatusBarHeight = - res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); - mPipDismissHeight = res.getDimensionPixelSize(R.dimen.pip_dismiss_gradient_height); - mBubblesMaxRendered = res.getInteger(R.integer.bubbles_max_rendered); - } - /** * Animates expanding the bubbles into a row along the top of the screen. */ @@ -297,6 +283,24 @@ public class ExpandedAnimationController } @Override + void onActiveControllerForLayout(PhysicsAnimationLayout layout) { + final Resources res = layout.getResources(); + mStackOffsetPx = res.getDimensionPixelSize(R.dimen.bubble_stack_offset); + mBubblePaddingPx = res.getDimensionPixelSize(R.dimen.bubble_padding); + mBubbleSizePx = res.getDimensionPixelSize(R.dimen.individual_bubble_size); + mStatusBarHeight = + res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); + mPipDismissHeight = res.getDimensionPixelSize(R.dimen.pip_dismiss_gradient_height); + mBubblesMaxRendered = res.getInteger(R.integer.bubbles_max_rendered); + + // Ensure that all child views are at 1x scale, and visible, in case they were animating + // in. + mLayout.setVisibility(View.VISIBLE); + animationsForChildrenFromIndex(0 /* startIndex */, (index, animation) -> + animation.scaleX(1f).scaleY(1f).alpha(1f)).startAll(); + } + + @Override Set<DynamicAnimation.ViewProperty> getAnimatedProperties() { return Sets.newHashSet( DynamicAnimation.TRANSLATION_X, diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java index 997d2c4627d8..6390f844c64c 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java @@ -17,10 +17,12 @@ package com.android.systemui.bubbles.animation; import android.content.Context; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import androidx.annotation.Nullable; import androidx.dynamicanimation.animation.DynamicAnimation; import androidx.dynamicanimation.animation.SpringAnimation; import androidx.dynamicanimation.animation.SpringForce; @@ -137,12 +139,30 @@ public class PhysicsAnimationLayout extends FrameLayout { */ abstract void onChildRemoved(View child, int index, Runnable finishRemoval); + /** + * Called when the controller is set as the active animation controller for the given + * layout. Once active, the controller can start animations using the animator instances + * returned by {@link #animationForChild}. + * + * While all animations started by the previous controller will be cancelled, the new + * controller should not make any assumptions about the state of the layout or its children. + * Their translation, alpha, scale, etc. values may have been changed by the previous + * controller and should be reset here if relevant. + */ + abstract void onActiveControllerForLayout(PhysicsAnimationLayout layout); + protected PhysicsAnimationLayout mLayout; PhysicsAnimationController() { } + /** Whether this controller is the currently active controller for its associated layout. */ + protected boolean isActiveController() { + return this == mLayout.mController; + } + protected void setLayout(PhysicsAnimationLayout layout) { this.mLayout = layout; + onActiveControllerForLayout(layout); } protected PhysicsAnimationLayout getLayout() { @@ -170,6 +190,9 @@ public class PhysicsAnimationLayout extends FrameLayout { child.setTag(R.id.physics_animator_tag, animator); } + animator.clearAnimator(); + animator.setAssociatedController(this); + return animator; } @@ -235,7 +258,7 @@ public class PhysicsAnimationLayout extends FrameLayout { new HashMap<>(); /** The currently active animation controller. */ - private PhysicsAnimationController mController; + @Nullable protected PhysicsAnimationController mController; /** * The maximum number of children to render and animate at a time. See @@ -260,7 +283,7 @@ public class PhysicsAnimationLayout extends FrameLayout { * Sets the animation controller and constructs or reconfigures the layout's physics animations * to meet the controller's specifications. */ - public void setController(PhysicsAnimationController controller) { + public void setActiveController(PhysicsAnimationController controller) { cancelAllAnimations(); mEndActionForProperty.clear(); @@ -315,7 +338,7 @@ public class PhysicsAnimationLayout extends FrameLayout { super.addView(child, index, params); // Set up animations for the new view, if the controller is set. If it isn't set, we'll be - // setting up animations for all children when setController is called. + // setting up animations for all children when setActiveController is called. if (mController != null) { for (DynamicAnimation.ViewProperty property : mController.getAnimatedProperties()) { setUpAnimationForChild(property, child, index); @@ -427,6 +450,10 @@ public class PhysicsAnimationLayout extends FrameLayout { } } + protected boolean isActiveController(PhysicsAnimationController controller) { + return mController == controller; + } + /** Whether the first child would be left of center if translated to the given x value. */ protected boolean isFirstChildXLeftOfCenter(float x) { if (getChildCount() > 0) { @@ -592,7 +619,7 @@ public class PhysicsAnimationLayout extends FrameLayout { private View mView; /** Start velocity to use for all property animations. */ - private float mDefaultStartVelocity = 0f; + private float mDefaultStartVelocity = -Float.MAX_VALUE; /** Start delay to use when start is called. */ private long mStartDelay = 0; @@ -625,6 +652,15 @@ public class PhysicsAnimationLayout extends FrameLayout { */ private Map<DynamicAnimation.ViewProperty, Float> mAnimatedProperties = new HashMap<>(); + /** + * All of the initial property values that have been set. These values will be instantly set + * when {@link #start} is called, just before the animation begins. + */ + private Map<DynamicAnimation.ViewProperty, Float> mInitialPropertyValues = new HashMap<>(); + + /** The animation controller that last retrieved this animator instance. */ + private PhysicsAnimationController mAssociatedController; + protected PhysicsPropertyAnimator(View view) { this.mView = view; } @@ -644,7 +680,7 @@ public class PhysicsAnimationLayout extends FrameLayout { /** Set the view's alpha value to 'from', then animate it to the given value. */ public PhysicsPropertyAnimator alpha(float from, float to, Runnable... endActions) { - mView.setAlpha(from); + mInitialPropertyValues.put(DynamicAnimation.ALPHA, from); return alpha(to, endActions); } @@ -656,7 +692,7 @@ public class PhysicsAnimationLayout extends FrameLayout { /** Set the view's translationX value to 'from', then animate it to the given value. */ public PhysicsPropertyAnimator translationX( float from, float to, Runnable... endActions) { - mView.setTranslationX(from); + mInitialPropertyValues.put(DynamicAnimation.TRANSLATION_X, from); return translationX(to, endActions); } @@ -668,7 +704,7 @@ public class PhysicsAnimationLayout extends FrameLayout { /** Set the view's translationY value to 'from', then animate it to the given value. */ public PhysicsPropertyAnimator translationY( float from, float to, Runnable... endActions) { - mView.setTranslationY(from); + mInitialPropertyValues.put(DynamicAnimation.TRANSLATION_Y, from); return translationY(to, endActions); } @@ -690,7 +726,7 @@ public class PhysicsAnimationLayout extends FrameLayout { /** Set the view's scaleX value to 'from', then animate it to the given value. */ public PhysicsPropertyAnimator scaleX(float from, float to, Runnable... endActions) { - mView.setScaleX(from); + mInitialPropertyValues.put(DynamicAnimation.SCALE_X, from); return scaleX(to, endActions); } @@ -701,7 +737,7 @@ public class PhysicsAnimationLayout extends FrameLayout { /** Set the view's scaleY value to 'from', then animate it to the given value. */ public PhysicsPropertyAnimator scaleY(float from, float to, Runnable... endActions) { - mView.setScaleY(from); + mInitialPropertyValues.put(DynamicAnimation.SCALE_Y, from); return scaleY(to, endActions); } @@ -750,6 +786,13 @@ public class PhysicsAnimationLayout extends FrameLayout { * animated property on every child (including chained animations) have ended. */ public void start(Runnable... after) { + if (!isActiveController(mAssociatedController)) { + Log.w(TAG, "Only the active animation controller is allowed to start animations. " + + "Use PhysicsAnimationLayout#setActiveController to set the active " + + "animation controller."); + return; + } + final Set<DynamicAnimation.ViewProperty> properties = getAnimatedProperties(); // If there are end actions, set an end listener on the layout for all the properties @@ -791,6 +834,10 @@ public class PhysicsAnimationLayout extends FrameLayout { // Actually start the animations. for (DynamicAnimation.ViewProperty property : properties) { + if (mInitialPropertyValues.containsKey(property)) { + property.setValue(mView, mInitialPropertyValues.get(property)); + } + final SpringForce defaultSpringForce = mController.getSpringForce(property, mView); animateValueForChild( property, @@ -803,14 +850,7 @@ public class PhysicsAnimationLayout extends FrameLayout { mEndActionsForProperty.get(property)); } - // Clear out the animator. - mAnimatedProperties.clear(); - mPositionStartVelocities.clear(); - mDefaultStartVelocity = 0; - mStartDelay = 0; - mStiffness = -1; - mDampingRatio = -1; - mEndActionsForProperty.clear(); + clearAnimator(); } /** Returns the set of properties that will animate once {@link #start} is called. */ @@ -847,20 +887,50 @@ public class PhysicsAnimationLayout extends FrameLayout { }); } - animation.getSpring().setStiffness(stiffness); - animation.getSpring().setDampingRatio(dampingRatio); + final SpringForce animationSpring = animation.getSpring(); - if (startVel > 0) { - animation.setStartVelocity(startVel); + if (animationSpring == null) { + return; } + final Runnable configureAndStartAnimation = () -> { + animationSpring.setStiffness(stiffness); + animationSpring.setDampingRatio(dampingRatio); + + if (startVel > -Float.MAX_VALUE) { + animation.setStartVelocity(startVel); + } + + animationSpring.setFinalPosition(value); + animation.start(); + }; + if (startDelay > 0) { - postDelayed(() -> animation.animateToFinalPosition(value), startDelay); + postDelayed(configureAndStartAnimation, startDelay); } else { - animation.animateToFinalPosition(value); + configureAndStartAnimation.run(); } } } + + private void clearAnimator() { + mInitialPropertyValues.clear(); + mAnimatedProperties.clear(); + mPositionStartVelocities.clear(); + mDefaultStartVelocity = -Float.MAX_VALUE; + mStartDelay = 0; + mStiffness = -1; + mDampingRatio = -1; + mEndActionsForProperty.clear(); + } + + /** + * Sets the controller that last retrieved this animator instance, so that we can prevent + * {@link #start} from actually starting animations if called by a non-active controller. + */ + private void setAssociatedController(PhysicsAnimationController controller) { + mAssociatedController = controller; + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java index b9cdc844eef9..cfc14f83ec8f 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java @@ -154,21 +154,6 @@ public class StackAnimationController extends /** Height of the status bar. */ private float mStatusBarHeight; - @Override - protected void setLayout(PhysicsAnimationLayout layout) { - super.setLayout(layout); - - Resources res = layout.getResources(); - mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset); - mIndividualBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size); - mBubblePadding = res.getDimensionPixelSize(R.dimen.bubble_padding); - mBubbleOffscreen = res.getDimensionPixelSize(R.dimen.bubble_stack_offscreen); - mStackStartingVerticalOffset = - res.getDimensionPixelSize(R.dimen.bubble_stack_starting_offset_y); - mStatusBarHeight = - res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); - } - /** * Instantly move the first bubble to the given point, and animate the rest of the stack behind * it with the 'following' effect. @@ -656,19 +641,35 @@ public class StackAnimationController extends if (mLayout.getChildCount() > 0) { animationForChildAtIndex(0).translationX(mStackPosition.x).start(); + } else { + // Set the start position back to the default since we're out of bubbles. New bubbles + // will then animate in from the start position. + mStackPosition = getDefaultStartPosition(); } } + @Override + void onActiveControllerForLayout(PhysicsAnimationLayout layout) { + Resources res = layout.getResources(); + mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset); + mIndividualBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size); + mBubblePadding = res.getDimensionPixelSize(R.dimen.bubble_padding); + mBubbleOffscreen = res.getDimensionPixelSize(R.dimen.bubble_stack_offscreen); + mStackStartingVerticalOffset = + res.getDimensionPixelSize(R.dimen.bubble_stack_starting_offset_y); + mStatusBarHeight = + res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); + } + /** Moves the stack, without any animation, to the starting position. */ private void moveStackToStartPosition() { // Post to ensure that the layout's width and height have been calculated. mLayout.setVisibility(View.INVISIBLE); mLayout.post(() -> { + setStackPosition(mRestingStackPosition == null + ? getDefaultStartPosition() + : mRestingStackPosition); mStackMovedToStartPosition = true; - setStackPosition( - mRestingStackPosition == null - ? getDefaultStartPosition() - : mRestingStackPosition); mLayout.setVisibility(View.VISIBLE); // Animate in the top bubble now that we're visible. @@ -707,15 +708,20 @@ public class StackAnimationController extends Log.d(TAG, String.format("Setting position to (%f, %f).", pos.x, pos.y)); mStackPosition.set(pos.x, pos.y); - mLayout.cancelAllAnimations(); - cancelStackPositionAnimations(); - - // Since we're not using the chained animations, apply the offsets manually. - final float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X); - final float yOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_Y); - for (int i = 0; i < mLayout.getChildCount(); i++) { - mLayout.getChildAt(i).setTranslationX(pos.x + (i * xOffset)); - mLayout.getChildAt(i).setTranslationY(pos.y + (i * yOffset)); + // If we're not the active controller, we don't want to physically move the bubble views. + if (isActiveController()) { + mLayout.cancelAllAnimations(); + cancelStackPositionAnimations(); + + // Since we're not using the chained animations, apply the offsets manually. + final float xOffset = getOffsetForChainedPropertyAnimation( + DynamicAnimation.TRANSLATION_X); + final float yOffset = getOffsetForChainedPropertyAnimation( + DynamicAnimation.TRANSLATION_Y); + for (int i = 0; i < mLayout.getChildCount(); i++) { + mLayout.getChildAt(i).setTranslationX(pos.x + (i * xOffset)); + mLayout.getChildAt(i).setTranslationY(pos.y + (i * yOffset)); + } } } @@ -732,6 +738,10 @@ public class StackAnimationController extends /** Animates in the given bubble. */ private void animateInBubble(View child) { + if (!isActiveController()) { + return; + } + child.setTranslationY(mStackPosition.y); float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java index 756cf3e138f6..34f2f40bcaf8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java @@ -61,7 +61,7 @@ public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestC public void setUp() throws Exception { super.setUp(); addOneMoreThanRenderLimitBubbles(); - mLayout.setController(mExpandedController); + mLayout.setActiveController(mExpandedController); Resources res = mLayout.getResources(); mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java index eef6ddcf6d6b..4415f2e63633 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTest.java @@ -78,7 +78,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testRenderVisibility() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); // The last child should be GONE, the rest VISIBLE. @@ -90,7 +90,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testHierarchyChanges() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); // Make sure the controller was notified of all the views we added. @@ -115,7 +115,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testUpdateValueNotChained() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); // Don't chain any values. @@ -146,7 +146,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testSetEndActions() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); mTestableController.setChainedProperties(Sets.newHashSet()); @@ -189,7 +189,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testRemoveEndListeners() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); mTestableController.setChainedProperties(Sets.newHashSet()); @@ -230,7 +230,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { // Add the bubbles, then set the controller, to make sure that a controller added to an // already-initialized view works correctly. addOneMoreThanRenderLimitBubbles(); - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); testChainedTranslationAnimations(); TestableAnimationController secondController = @@ -243,7 +243,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { DynamicAnimation.SCALE_X, 10f); secondController.setRemoveImmediately(true); - mLayout.setController(secondController); + mLayout.setActiveController(secondController); mTestableController.animationForChildAtIndex(0) .scaleX(1.5f) .start(); @@ -266,7 +266,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { Mockito.verify(secondController, Mockito.atLeastOnce()) .getOffsetForChainedPropertyAnimation(eq(DynamicAnimation.SCALE_X)); - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); mTestableController.animationForChildAtIndex(0) .translationX(100f) .start(); @@ -283,7 +283,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testArePropertiesAnimating() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); assertFalse(mLayout.arePropertiesAnimating( @@ -307,7 +307,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testCancelAllAnimations() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); mTestableController.animationForChildAtIndex(0) @@ -323,7 +323,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testSetChildVisibility() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); // The last view should have been set to GONE by the controller, since we added one more @@ -342,7 +342,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { /** Standard test of chained translation animations. */ private void testChainedTranslationAnimations() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); assertEquals(0, mLayout.getChildAt(0).getTranslationX(), .1f); @@ -383,7 +383,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testPhysicsAnimator() throws InterruptedException { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); Runnable afterAll = Mockito.mock(Runnable.class); @@ -430,7 +430,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { // Don't chain since we're going to invoke each animation independently. mTestableController.setChainedProperties(new HashSet<>()); - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); addOneMoreThanRenderLimitBubbles(); @@ -452,7 +452,7 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { @Test public void testAnimationsForChildrenFromIndex_noChildren() { - mLayout.setController(mTestableController); + mLayout.setActiveController(mTestableController); final Runnable after = Mockito.mock(Runnable.class); mTestableController @@ -523,6 +523,9 @@ public class PhysicsAnimationLayoutTest extends PhysicsAnimationLayoutTestCase { } @Override + void onActiveControllerForLayout(PhysicsAnimationLayout layout) {} + + @Override protected void setChildVisibility(View child, int index, int visibility) { super.setChildVisibility(child, index, visibility); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java index c6acef5d4907..ec7337bc9622 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayoutTestCase.java @@ -138,6 +138,13 @@ public class PhysicsAnimationLayoutTestCase extends SysuiTestCase { } @Override + protected boolean isActiveController(PhysicsAnimationController controller) { + // Return true since otherwise all test controllers will be seen as inactive since they + // are wrapped by MainThreadAnimationControllerWrapper. + return true; + } + + @Override public boolean post(Runnable action) { return mMainThreadHandler.post(action); } @@ -148,9 +155,9 @@ public class PhysicsAnimationLayoutTestCase extends SysuiTestCase { } @Override - public void setController(PhysicsAnimationController controller) { + public void setActiveController(PhysicsAnimationController controller) { runOnMainThreadAndBlock( - () -> super.setController( + () -> super.setActiveController( new MainThreadAnimationControllerWrapper(controller))); } @@ -267,6 +274,12 @@ public class PhysicsAnimationLayoutTestCase extends SysuiTestCase { } @Override + void onActiveControllerForLayout(PhysicsAnimationLayout layout) { + runOnMainThreadAndBlock( + () -> mWrappedController.onActiveControllerForLayout(layout)); + } + + @Override protected void setChildVisibility(View child, int index, int visibility) { mWrappedController.setChildVisibility(child, index, visibility); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java index 9218a8b93f66..b458907c9df5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java @@ -54,7 +54,7 @@ public class StackAnimationControllerTest extends PhysicsAnimationLayoutTestCase @Before public void setUp() throws Exception { super.setUp(); - mLayout.setController(mStackController); + mLayout.setActiveController(mStackController); addOneMoreThanRenderLimitBubbles(); mStackOffset = mLayout.getResources().getDimensionPixelSize(R.dimen.bubble_stack_offset); } |