android_frameworks_base/packages/SystemUI/docs/physics-animation-testing.md
Joshua Tsuji b1a796b155 Adds DynamicAnimation-based movement to the bubbles.
See go/bubble-stack-design for a high level overview of these changes. This is a large CL, but required in order to allow continued development and team testing without breaking functionality over the course of multiple CL submissions.

To integrate the new animations, the following changes have been made to existing code:
* (BubbleStackView) The bubble container (and thus, the stack view) are MATCH_PARENT to allow the bubbles to independently translate anywhere on the screen.
* (BubbleStackView) Start position is set by the stack controller, not BubbleStackView.
* (BubbleStackView) Expand positon is set by the expansion controller, not BubbleStackView.
* (BubbleStackView/BubbleTouchHandler) Added the methods onDragStart/onDragged/onDragFinish, and onBubbleDragStart/onBubbleDragged/onBubbleDragFinish, for cleaner dispatch of touch events to the appropriate animation controller.
* (BubbleStackView/BubbleController) The stack view's getBoundsOnScreen returns the first bubble's bounds, if the stack is not expanded.
* (BubbleStackView) applyCurrentState no longer manages translation of bubbles, or the expanded view, these are controlled by animation.
* (BubbleMovementHelper) Deleted, no longer needed.
* (Everywhere) Changed uses of Point to PointF, since translation values are floats anyway.

Known issues to be fixed in subsequent, far smaller CLs:
* (b/123022862) Bubble dragging out/dismissing is not animated, and the bubbles can be deposited anywhere. Tap outside the stack to collapse them back to normal.
* (b/123023502) New bubbles added while the stack is expanded are not positioned properly.
* (b/123022982) Expanded view arrow is sometimes in the wrong position.
* (b/123023410) If the stack is expanded while animating, it collapses to its original position even if not along the edge of the screen.
* (b/123023904) The expanded view doesn't animate out, it disappears instantly.
* (b/123026584) Bounds in landscape are a bit wonky.

Bug: 111236845
Test: atest SystemUITests
Test: physics-animation-testing.md
Change-Id: Icaca09e5db89c635c9bb7ca82d7d2714362e344e
2019-01-24 19:23:17 -05:00

2.4 KiB
Raw Blame History

Physics Animation Testing

Physics animations are notoriously difficult to test, since theyre essentially small simulations. They have no set duration, and theyre considered finished only when the movements imparted by the animation are too small to be user-visible. Mid-states are not deterministic.

For this reason, we only test the end state of animations. Manual testing should be sufficient to reveal flaws in the en-route animation visuals. In a worst-case failure case, as long as the end state is correct, usability will not be affected - animations might just look a bit off until the UI elements settle to their proper positions.

Waiting for Animations to End

Testing any kind of animation can be tricky, since animations need to run on the main thread, and theyre asynchronous - the test has to wait for the animation to finish before we can assert anything about its end state. For normal animations, we can invoke skipToEnd to avoid waiting. While this method is available for SpringAnimation, its not available for FlingAnimation since its end state is not initially known. A FlingAnimations end is when the friction simulation reports that motion has slowed to an invisible level. For this reason, we have to actually run the physics animations.

To accommodate this, all tests of the layout itself, as well as any animation controller subclasses, use PhysicsAnimationLayoutTestCase. The layout provided to controllers by the test case is a TestablePhysicsAnimationLayout, a subclass of PhysicsAnimationLayout whose animation-related methods have been overridden to force them to run on the main thread via a Handler. Animations will simply crash if theyre called directly from the test thread, so this is important.

The test case also provides waitForPropertyAnimations, which uses a CountDownLatch to wait for all animations on a given property to complete before continuing the test. This works since the test is not running on the same thread as the animation, so a blocking call to latch.await() does not affect the animations progress. The latch is initialized with a count equal to the number of properties were listening to. We then add end listeners to the layout for each property, which call latch.countDown(). Once all of the properties animations have completed, the latch count reaches zero and the tests call to await() returns, with the animations complete.