blob: b8add89243ced949ff515eb20ce7d534f09c837a [file] [log] [blame]
Joshua Tsujib1a796b2019-01-16 15:43:12 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.bubbles.animation;
18
19import static org.junit.Assert.assertEquals;
20
21import android.content.res.Resources;
Mady Mellor44ee2fe2019-01-30 17:51:16 -080022import android.graphics.Point;
Joshua Tsujib1a796b2019-01-16 15:43:12 -080023import android.graphics.PointF;
Joshua Tsujib1a796b2019-01-16 15:43:12 -080024import android.testing.AndroidTestingRunner;
Joshua Tsuji442b6272019-02-08 13:23:43 -050025import android.view.View;
26import android.widget.FrameLayout;
Joshua Tsujib1a796b2019-01-16 15:43:12 -080027
28import androidx.dynamicanimation.animation.DynamicAnimation;
Brett Chabot84151d92019-02-27 15:37:59 -080029import androidx.test.filters.SmallTest;
Joshua Tsujib1a796b2019-01-16 15:43:12 -080030
31import com.android.systemui.R;
32
33import org.junit.Before;
34import org.junit.Test;
35import org.junit.runner.RunWith;
36import org.mockito.Mockito;
37import org.mockito.Spy;
38
39@SmallTest
40@RunWith(AndroidTestingRunner.class)
41public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestCase {
42
43 @Spy
Mady Mellor44ee2fe2019-01-30 17:51:16 -080044 private ExpandedAnimationController mExpandedController =
45 new ExpandedAnimationController(new Point(500, 1000) /* displaySize */);
Joshua Tsujib1a796b2019-01-16 15:43:12 -080046
47 private int mStackOffset;
48 private float mBubblePadding;
49 private float mBubbleSize;
50
51 private PointF mExpansionPoint;
52
53 @Before
54 public void setUp() throws Exception {
55 super.setUp();
56 addOneMoreThanRenderLimitBubbles();
57 mLayout.setController(mExpandedController);
58 Resources res = mLayout.getResources();
59 mStackOffset = res.getDimensionPixelSize(R.dimen.bubble_stack_offset);
60 mBubblePadding = res.getDimensionPixelSize(R.dimen.bubble_padding);
61 mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size);
Joshua Tsuji1575e6b2019-01-30 13:43:28 -050062
63 mExpansionPoint = new PointF(100, 100);
Joshua Tsujib1a796b2019-01-16 15:43:12 -080064 }
65
66 @Test
67 public void testExpansionAndCollapse() throws InterruptedException {
Joshua Tsujib1a796b2019-01-16 15:43:12 -080068 Runnable afterExpand = Mockito.mock(Runnable.class);
69 mExpandedController.expandFromStack(mExpansionPoint, afterExpand);
Joshua Tsujib1a796b2019-01-16 15:43:12 -080070 waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
71
Joshua Tsuji442b6272019-02-08 13:23:43 -050072 testBubblesInCorrectExpandedPositions();
Joshua Tsujib1a796b2019-01-16 15:43:12 -080073 Mockito.verify(afterExpand).run();
74
75 Runnable afterCollapse = Mockito.mock(Runnable.class);
76 mExpandedController.collapseBackToStack(afterCollapse);
Joshua Tsujib1a796b2019-01-16 15:43:12 -080077 waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
78
79 testStackedAtPosition(mExpansionPoint.x, mExpansionPoint.y, -1);
80 Mockito.verify(afterExpand).run();
81 }
82
Joshua Tsuji1575e6b2019-01-30 13:43:28 -050083 @Test
Joshua Tsuji442b6272019-02-08 13:23:43 -050084 public void testOnChildAdded() throws InterruptedException {
85 expand();
86
87 // Add another new view and wait for its animation.
88 final View newView = new FrameLayout(getContext());
89 mLayout.addView(newView, 0);
Joshua Tsuji1575e6b2019-01-30 13:43:28 -050090 waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
Joshua Tsuji442b6272019-02-08 13:23:43 -050091
92 testBubblesInCorrectExpandedPositions();
93 }
94
95 @Test
96 public void testOnChildRemoved() throws InterruptedException {
97 expand();
Joshua Tsuji1575e6b2019-01-30 13:43:28 -050098
99 // Remove some views and see if the remaining child views still pass the expansion test.
100 mLayout.removeView(mViews.get(0));
101 mLayout.removeView(mViews.get(3));
102 waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
Joshua Tsuji442b6272019-02-08 13:23:43 -0500103 testBubblesInCorrectExpandedPositions();
104 }
105
106 @Test
107 public void testBubbleDraggedNotDismissedSnapsBack() throws InterruptedException {
108 expand();
109
110 final View draggedBubble = mViews.get(0);
111 mExpandedController.prepareForBubbleDrag(draggedBubble);
112 mExpandedController.dragBubbleOut(draggedBubble, 500f, 500f);
113
114 assertEquals(500f, draggedBubble.getTranslationX(), 1f);
115 assertEquals(500f, draggedBubble.getTranslationY(), 1f);
116
117 // Snap it back and make sure it made it back correctly.
118 mExpandedController.snapBubbleBack(draggedBubble, 0f, 0f);
119 waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
120 testBubblesInCorrectExpandedPositions();
121 }
122
123 @Test
124 public void testBubbleDismissed() throws InterruptedException {
125 expand();
126
127 final View draggedBubble = mViews.get(0);
128 mExpandedController.prepareForBubbleDrag(draggedBubble);
129 mExpandedController.dragBubbleOut(draggedBubble, 500f, 500f);
130
131 assertEquals(500f, draggedBubble.getTranslationX(), 1f);
132 assertEquals(500f, draggedBubble.getTranslationY(), 1f);
133
134 // Snap it back and make sure it made it back correctly.
135 mExpandedController.prepareForDismissalWithVelocity(draggedBubble, 0f, 0f);
136 mLayout.removeView(draggedBubble);
137 waitForLayoutMessageQueue();
138 waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
139
140 assertEquals(-1, mLayout.indexOfChild(draggedBubble));
141 testBubblesInCorrectExpandedPositions();
142 }
143
144 /** Expand the stack and wait for animations to finish. */
145 private void expand() throws InterruptedException {
146 mExpandedController.expandFromStack(mExpansionPoint, Mockito.mock(Runnable.class));
147 waitForPropertyAnimations(DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y);
Joshua Tsuji1575e6b2019-01-30 13:43:28 -0500148 }
149
Joshua Tsujib1a796b2019-01-16 15:43:12 -0800150 /** Check that children are in the correct positions for being stacked. */
151 private void testStackedAtPosition(float x, float y, int offsetMultiplier) {
152 // Make sure the rest of the stack moved again, including the first bubble not moving, and
153 // is stacked to the right now that we're on the right side of the screen.
154 for (int i = 0; i < mLayout.getChildCount(); i++) {
155 assertEquals(x + i * offsetMultiplier * mStackOffset,
Joshua Tsuji1575e6b2019-01-30 13:43:28 -0500156 mLayout.getChildAt(i).getTranslationX(), 2f);
157 assertEquals(y, mLayout.getChildAt(i).getTranslationY(), 2f);
158
159 if (i < mMaxRenderedBubbles) {
160 assertEquals(1f, mLayout.getChildAt(i).getAlpha(), .01f);
161 }
Joshua Tsujib1a796b2019-01-16 15:43:12 -0800162 }
163 }
164
165 /** Check that children are in the correct positions for being expanded. */
Joshua Tsuji442b6272019-02-08 13:23:43 -0500166 private void testBubblesInCorrectExpandedPositions() {
Joshua Tsuji1575e6b2019-01-30 13:43:28 -0500167 // Check all the visible bubbles to see if they're in the right place.
168 for (int i = 0; i < Math.min(mLayout.getChildCount(), mMaxRenderedBubbles); i++) {
Joshua Tsujib1a796b2019-01-16 15:43:12 -0800169 assertEquals(mBubblePadding + (i * (mBubbleSize + mBubblePadding)),
Joshua Tsuji1575e6b2019-01-30 13:43:28 -0500170 mLayout.getChildAt(i).getTranslationX(),
Joshua Tsujib1a796b2019-01-16 15:43:12 -0800171 2f);
Mady Mellor44ee2fe2019-01-30 17:51:16 -0800172 assertEquals(mExpandedController.getExpandedY(),
Joshua Tsuji1575e6b2019-01-30 13:43:28 -0500173 mLayout.getChildAt(i).getTranslationY(), 2f);
174
175 if (i < mMaxRenderedBubbles) {
176 assertEquals(1f, mLayout.getChildAt(i).getAlpha(), .01f);
177 }
Joshua Tsujib1a796b2019-01-16 15:43:12 -0800178 }
179 }
180}