blob: 463ceeb9f2a2798d64e77f0d8590daa4ea9363ab [file] [log] [blame]
Jorim Jaggi21c39a72017-10-20 15:47:51 +02001/*
2 * Copyright (C) 2017 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.server.wm;
18
Jorim Jaggi980c9de2017-11-17 01:41:37 +010019import static org.junit.Assert.assertEquals;
Jorim Jaggi21c39a72017-10-20 15:47:51 +020020import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertNotNull;
22import static org.junit.Assert.assertNull;
23import static org.junit.Assert.assertTrue;
24import static org.mockito.ArgumentMatchers.eq;
25import static org.mockito.Mockito.any;
26import static org.mockito.Mockito.verify;
27import static org.mockito.Mockito.verifyZeroInteractions;
28
29import android.platform.test.annotations.Presubmit;
Jorim Jaggi8fb00b22018-01-05 13:14:39 +010030import android.support.test.filters.FlakyTest;
Jorim Jaggi21c39a72017-10-20 15:47:51 +020031import android.support.test.filters.SmallTest;
32import android.support.test.runner.AndroidJUnit4;
33import android.view.SurfaceControl;
34import android.view.SurfaceControl.Builder;
35import android.view.SurfaceControl.Transaction;
36import android.view.SurfaceSession;
37
Jorim Jaggi21c39a72017-10-20 15:47:51 +020038import com.android.server.wm.SurfaceAnimator.Animatable;
39import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
40
41import org.junit.Before;
Jorim Jaggi8fb00b22018-01-05 13:14:39 +010042import org.junit.Ignore;
Jorim Jaggi21c39a72017-10-20 15:47:51 +020043import org.junit.Test;
44import org.junit.runner.RunWith;
45import org.mockito.ArgumentCaptor;
46import org.mockito.Mock;
47import org.mockito.MockitoAnnotations;
48
49import java.util.ArrayList;
Jorim Jaggia3844032018-01-03 15:54:43 +010050import java.util.concurrent.CountDownLatch;
Jorim Jaggi21c39a72017-10-20 15:47:51 +020051
52/**
53 * Test class for {@link SurfaceAnimatorTest}.
54 *
Jorim Jaggia5e10572017-11-15 14:36:26 +010055 * atest FrameworksServicesTests:com.android.server.wm.SurfaceAnimatorTest
Jorim Jaggi21c39a72017-10-20 15:47:51 +020056 */
57@SmallTest
58@Presubmit
59@RunWith(AndroidJUnit4.class)
60public class SurfaceAnimatorTest extends WindowTestsBase {
61
Jorim Jaggia5e10572017-11-15 14:36:26 +010062 @Mock AnimationAdapter mSpec;
63 @Mock AnimationAdapter mSpec2;
Jorim Jaggi21c39a72017-10-20 15:47:51 +020064 @Mock Transaction mTransaction;
65
Jorim Jaggi21c39a72017-10-20 15:47:51 +020066 private SurfaceSession mSession = new SurfaceSession();
Jorim Jaggia5e10572017-11-15 14:36:26 +010067 private MyAnimatable mAnimatable;
Jorim Jaggi980c9de2017-11-17 01:41:37 +010068 private MyAnimatable mAnimatable2;
Jorim Jaggi21c39a72017-10-20 15:47:51 +020069
Jorim Jaggia5e10572017-11-15 14:36:26 +010070 @Before
71 public void setUp() throws Exception {
72 super.setUp();
73 MockitoAnnotations.initMocks(this);
74 mAnimatable = new MyAnimatable();
Jorim Jaggi980c9de2017-11-17 01:41:37 +010075 mAnimatable2 = new MyAnimatable();
Jorim Jaggia5e10572017-11-15 14:36:26 +010076 }
77
Jorim Jaggi8fb00b22018-01-05 13:14:39 +010078 // TODO: Tests are flaky, and timeout after 5 minutes. Instead of wasting everybody's time we
79 // mark them as ignore.
Jorim Jaggia5e10572017-11-15 14:36:26 +010080 @Test
Jorim Jaggi8fb00b22018-01-05 13:14:39 +010081 @Ignore
Jorim Jaggia5e10572017-11-15 14:36:26 +010082 public void testRunAnimation() throws Exception {
83 mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
84 final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
85 OnAnimationFinishedCallback.class);
Jorim Jaggi980c9de2017-11-17 01:41:37 +010086 assertAnimating(mAnimatable);
Jorim Jaggia5e10572017-11-15 14:36:26 +010087 verify(mTransaction).reparent(eq(mAnimatable.mSurface), eq(mAnimatable.mLeash.getHandle()));
88 verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
89
90 callbackCaptor.getValue().onAnimationFinished(mSpec);
Jorim Jaggia3844032018-01-03 15:54:43 +010091 waitUntilPrepareSurfaces();
Jorim Jaggi980c9de2017-11-17 01:41:37 +010092 assertNotAnimating(mAnimatable);
Jorim Jaggia5e10572017-11-15 14:36:26 +010093 assertTrue(mAnimatable.mFinishedCallbackCalled);
94 assertTrue(mAnimatable.mPendingDestroySurfaces.contains(mAnimatable.mLeash));
95 // TODO: Verify reparenting once we use mPendingTransaction to reparent it back
96 }
97
Jorim Jaggi8fb00b22018-01-05 13:14:39 +010098 // TODO: Tests are flaky, and timeout after 5 minutes. Instead of wasting everybody's time we
99 // mark them as ignore.
Jorim Jaggia5e10572017-11-15 14:36:26 +0100100 @Test
Jorim Jaggi8fb00b22018-01-05 13:14:39 +0100101 @Ignore
Jorim Jaggia5e10572017-11-15 14:36:26 +0100102 public void testOverrideAnimation() throws Exception {
103 mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
104 final SurfaceControl firstLeash = mAnimatable.mLeash;
105 mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec2, true /* hidden */);
106
107 assertTrue(mAnimatable.mPendingDestroySurfaces.contains(firstLeash));
108 assertFalse(mAnimatable.mFinishedCallbackCalled);
109
110 final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
111 OnAnimationFinishedCallback.class);
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100112 assertAnimating(mAnimatable);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100113 verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
114
115 // First animation was finished, but this shouldn't cancel the second animation
116 callbackCaptor.getValue().onAnimationFinished(mSpec);
Jorim Jaggia3844032018-01-03 15:54:43 +0100117 waitUntilPrepareSurfaces();
Jorim Jaggia5e10572017-11-15 14:36:26 +0100118 assertTrue(mAnimatable.mSurfaceAnimator.isAnimating());
119
120 // Second animation was finished
121 verify(mSpec2).startAnimation(any(), any(), callbackCaptor.capture());
122 callbackCaptor.getValue().onAnimationFinished(mSpec2);
Jorim Jaggia3844032018-01-03 15:54:43 +0100123 waitUntilPrepareSurfaces();
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100124 assertNotAnimating(mAnimatable);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100125 assertTrue(mAnimatable.mFinishedCallbackCalled);
126 }
127
128 @Test
129 public void testCancelAnimation() throws Exception {
130 mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100131 assertAnimating(mAnimatable);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100132 mAnimatable.mSurfaceAnimator.cancelAnimation();
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100133 assertNotAnimating(mAnimatable);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100134 verify(mSpec).onAnimationCancelled(any());
135 assertTrue(mAnimatable.mFinishedCallbackCalled);
136 assertTrue(mAnimatable.mPendingDestroySurfaces.contains(mAnimatable.mLeash));
137 }
138
139 @Test
140 public void testDelayingAnimationStart() throws Exception {
141 mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
142 mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
143 verifyZeroInteractions(mSpec);
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100144 assertAnimating(mAnimatable);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100145 mAnimatable.mSurfaceAnimator.endDelayingAnimationStart();
146 verify(mSpec).startAnimation(any(), any(), any());
147 }
148
149 @Test
150 public void testDelayingAnimationStartAndCancelled() throws Exception {
151 mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
152 mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
153 mAnimatable.mSurfaceAnimator.cancelAnimation();
154 verifyZeroInteractions(mSpec);
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100155 assertNotAnimating(mAnimatable);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100156 assertTrue(mAnimatable.mFinishedCallbackCalled);
157 assertTrue(mAnimatable.mPendingDestroySurfaces.contains(mAnimatable.mLeash));
158 }
159
Jorim Jaggi8fb00b22018-01-05 13:14:39 +0100160 // TODO: Tests are flaky, and timeout after 5 minutes. Instead of wasting everybody's time we
161 // mark them as ignore.
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100162 @Test
Jorim Jaggi8fb00b22018-01-05 13:14:39 +0100163 @Ignore
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100164 public void testTransferAnimation() throws Exception {
165 mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
166
167 final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
168 OnAnimationFinishedCallback.class);
169 verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
170 final SurfaceControl leash = mAnimatable.mLeash;
171
172 mAnimatable2.mSurfaceAnimator.transferAnimation(mAnimatable.mSurfaceAnimator);
173 assertNotAnimating(mAnimatable);
174 assertAnimating(mAnimatable2);
175 assertEquals(leash, mAnimatable2.mSurfaceAnimator.mLeash);
176 assertFalse(mAnimatable.mPendingDestroySurfaces.contains(leash));
177 callbackCaptor.getValue().onAnimationFinished(mSpec);
Jorim Jaggia3844032018-01-03 15:54:43 +0100178 waitUntilPrepareSurfaces();
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100179 assertNotAnimating(mAnimatable2);
180 assertTrue(mAnimatable2.mFinishedCallbackCalled);
181 assertTrue(mAnimatable2.mPendingDestroySurfaces.contains(leash));
182 }
183
184 private void assertAnimating(MyAnimatable animatable) {
185 assertTrue(animatable.mSurfaceAnimator.isAnimating());
186 assertNotNull(animatable.mSurfaceAnimator.getAnimation());
187 }
188
189 private void assertNotAnimating(MyAnimatable animatable) {
190 assertFalse(animatable.mSurfaceAnimator.isAnimating());
191 assertNull(animatable.mSurfaceAnimator.getAnimation());
192 }
193
Jorim Jaggia3844032018-01-03 15:54:43 +0100194 private void waitUntilPrepareSurfaces() throws Exception {
195 final CountDownLatch latch = new CountDownLatch(1);
196 synchronized (sWm.mWindowMap) {
197 sWm.mAnimator.addAfterPrepareSurfacesRunnable(latch::countDown);
198 }
199 latch.await();
200 }
201
Jorim Jaggia5e10572017-11-15 14:36:26 +0100202 private class MyAnimatable implements Animatable {
203
204 final SurfaceControl mParent;
205 final SurfaceControl mSurface;
206 final ArrayList<SurfaceControl> mPendingDestroySurfaces = new ArrayList<>();
207 final SurfaceAnimator mSurfaceAnimator;
208 SurfaceControl mLeash;
209 boolean mFinishedCallbackCalled;
210
211 MyAnimatable() {
212 mParent = sWm.makeSurfaceBuilder(mSession)
213 .setName("test surface parent")
214 .setSize(3000, 3000)
215 .build();
216 mSurface = sWm.makeSurfaceBuilder(mSession)
217 .setName("test surface")
218 .setSize(1, 1)
219 .build();
220 mFinishedCallbackCalled = false;
221 mLeash = null;
222 mSurfaceAnimator = new SurfaceAnimator(this, mFinishedCallback, sWm);
223 }
224
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200225 @Override
226 public Transaction getPendingTransaction() {
227 return mTransaction;
228 }
229
230 @Override
231 public void commitPendingTransaction() {
232 }
233
234 @Override
Jorim Jaggia5e10572017-11-15 14:36:26 +0100235 public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200236 }
237
238 @Override
Jorim Jaggia5e10572017-11-15 14:36:26 +0100239 public void onAnimationLeashDestroyed(Transaction t) {
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200240 }
241
242 @Override
Jorim Jaggia5e10572017-11-15 14:36:26 +0100243 public void destroyAfterPendingTransaction(SurfaceControl surface) {
244 mPendingDestroySurfaces.add(surface);
245 }
246
247 @Override
248 public Builder makeAnimationLeash() {
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200249 return new SurfaceControl.Builder(mSession) {
250
251 @Override
252 public SurfaceControl build() {
253 mLeash = super.build();
254 return mLeash;
255 }
256 }.setParent(mParent);
257 }
258
259 @Override
Jorim Jaggi596a1992017-12-29 14:48:02 +0100260 public SurfaceControl getAnimationLeashParent() {
261 return mParent;
262 }
263
264 @Override
Jorim Jaggia5e10572017-11-15 14:36:26 +0100265 public SurfaceControl getSurfaceControl() {
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200266 return mSurface;
267 }
268
269 @Override
Jorim Jaggia5e10572017-11-15 14:36:26 +0100270 public SurfaceControl getParentSurfaceControl() {
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200271 return mParent;
272 }
273
274 @Override
275 public int getSurfaceWidth() {
276 return 1;
277 }
278
279 @Override
280 public int getSurfaceHeight() {
281 return 1;
282 }
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200283
Jorim Jaggi980c9de2017-11-17 01:41:37 +0100284 private final Runnable mFinishedCallback = () -> mFinishedCallbackCalled = true;
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200285 }
286}