1 /* 2 * Copyright (C) 2018 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 17 package com.android.server.wm; 18 19 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 20 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 21 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; 22 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN; 23 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; 24 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; 25 import static android.view.WindowManager.TRANSIT_OLD_NONE; 26 import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE; 27 import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN; 28 29 import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast; 30 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 31 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; 32 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; 33 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; 34 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions; 35 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; 36 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION; 37 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION; 38 39 import static junit.framework.Assert.assertFalse; 40 import static junit.framework.Assert.fail; 41 42 import static org.junit.Assert.assertEquals; 43 import static org.junit.Assert.assertNotNull; 44 import static org.junit.Assert.assertTrue; 45 import static org.mockito.ArgumentMatchers.any; 46 import static org.mockito.ArgumentMatchers.anyBoolean; 47 import static org.mockito.ArgumentMatchers.anyFloat; 48 import static org.mockito.ArgumentMatchers.anyInt; 49 import static org.mockito.ArgumentMatchers.eq; 50 import static org.mockito.Mockito.mock; 51 52 import android.graphics.Point; 53 import android.graphics.Rect; 54 import android.os.Binder; 55 import android.os.IBinder; 56 import android.os.IInterface; 57 import android.os.RemoteException; 58 import android.platform.test.annotations.Presubmit; 59 import android.view.IRemoteAnimationFinishedCallback; 60 import android.view.IRemoteAnimationRunner; 61 import android.view.RemoteAnimationAdapter; 62 import android.view.RemoteAnimationTarget; 63 import android.view.SurfaceControl; 64 import android.view.SurfaceControl.Transaction; 65 66 import androidx.test.filters.SmallTest; 67 68 import com.android.server.testutils.OffsettableClock; 69 import com.android.server.testutils.TestHandler; 70 import com.android.server.wm.RemoteAnimationController.RemoteAnimationRecord; 71 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; 72 73 import org.junit.Before; 74 import org.junit.Test; 75 import org.junit.runner.RunWith; 76 import org.mockito.ArgumentCaptor; 77 import org.mockito.Mock; 78 import org.mockito.MockitoAnnotations; 79 80 /** 81 * Build/Install/Run: 82 * atest WmTests:RemoteAnimationControllerTest 83 */ 84 @SmallTest 85 @Presubmit 86 @RunWith(WindowTestRunner.class) 87 public class RemoteAnimationControllerTest extends WindowTestsBase { 88 89 @Mock 90 SurfaceControl mMockLeash; 91 @Mock 92 SurfaceControl mMockThumbnailLeash; 93 @Mock 94 Transaction mMockTransaction; 95 @Mock 96 OnAnimationFinishedCallback mFinishedCallback; 97 @Mock 98 OnAnimationFinishedCallback mThumbnailFinishedCallback; 99 @Mock 100 IRemoteAnimationRunner mMockRunner; 101 private RemoteAnimationAdapter mAdapter; 102 private RemoteAnimationController mController; 103 private final OffsettableClock mClock = new OffsettableClock.Stopped(); 104 private TestHandler mHandler; 105 106 @Before setUp()107 public void setUp() throws Exception { 108 MockitoAnnotations.initMocks(this); 109 110 when(mMockRunner.asBinder()).thenReturn(new Binder()); 111 mAdapter = new RemoteAnimationAdapter(mMockRunner, 100, 50, true /* changeNeedsSnapshot */); 112 mAdapter.setCallingPidUid(123, 456); 113 runWithScissors(mWm.mH, () -> mHandler = new TestHandler(null, mClock), 0); 114 mController = new RemoteAnimationController(mWm, mDisplayContent, mAdapter, 115 mHandler, false /*isActivityEmbedding*/); 116 } 117 createAppOverlayWindow()118 private WindowState createAppOverlayWindow() { 119 final WindowState win = createWindow(null /* parent */, TYPE_APPLICATION_OVERLAY, 120 "testOverlayWindow"); 121 win.mActivityRecord = null; 122 win.mHasSurface = true; 123 return win; 124 } 125 126 @Test testForwardsShowBackdrop()127 public void testForwardsShowBackdrop() throws Exception { 128 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 129 mDisplayContent.mOpeningApps.add(win.mActivityRecord); 130 final WindowState overlayWin = createAppOverlayWindow(); 131 try { 132 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 133 win.mActivityRecord, 134 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, 135 true /* showBackdrop */).mAdapter; 136 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 137 mFinishedCallback); 138 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 139 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 140 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 141 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 142 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 143 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 144 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 145 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 146 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 147 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 148 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), 149 appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), 150 finishedCaptor.capture()); 151 assertEquals(1, appsCaptor.getValue().length); 152 final RemoteAnimationTarget app = appsCaptor.getValue()[0]; 153 assertTrue(app.showBackdrop); 154 } finally { 155 mDisplayContent.mOpeningApps.clear(); 156 } 157 } 158 159 @Test testRun()160 public void testRun() throws Exception { 161 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 162 mDisplayContent.mOpeningApps.add(win.mActivityRecord); 163 final WindowState overlayWin = createAppOverlayWindow(); 164 try { 165 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 166 win.mActivityRecord, 167 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter; 168 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 169 mFinishedCallback); 170 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 171 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 172 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 173 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 174 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 175 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 176 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 177 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 178 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 179 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 180 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), 181 appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), 182 finishedCaptor.capture()); 183 assertEquals(1, appsCaptor.getValue().length); 184 final RemoteAnimationTarget app = appsCaptor.getValue()[0]; 185 assertEquals(new Point(50, 100), app.position); 186 assertEquals(new Rect(50, 100, 150, 150), app.sourceContainerBounds); 187 assertEquals(win.mActivityRecord.getPrefixOrderIndex(), app.prefixOrderIndex); 188 assertEquals(win.mActivityRecord.getTask().mTaskId, app.taskId); 189 assertEquals(mMockLeash, app.leash); 190 assertEquals(false, app.isTranslucent); 191 verify(mMockTransaction).setPosition(mMockLeash, app.position.x, app.position.y); 192 verify(mMockTransaction).setWindowCrop(mMockLeash, 100, 50); 193 194 finishedCaptor.getValue().onAnimationFinished(); 195 verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), 196 eq(adapter)); 197 assertEquals(0, nonAppsCaptor.getValue().length); 198 } finally { 199 mDisplayContent.mOpeningApps.clear(); 200 } 201 } 202 203 @Test testCancel()204 public void testCancel() throws Exception { 205 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 206 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 207 win.mActivityRecord, 208 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter; 209 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 210 mFinishedCallback); 211 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 212 213 adapter.onAnimationCancelled(mMockLeash); 214 verify(mMockRunner).onAnimationCancelled(); 215 } 216 217 @Test testTimeout()218 public void testTimeout() throws Exception { 219 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 220 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 221 win.mActivityRecord, 222 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter; 223 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 224 mFinishedCallback); 225 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 226 227 mClock.fastForward(10500); 228 mHandler.timeAdvance(); 229 230 verify(mMockRunner).onAnimationCancelled(); 231 verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), 232 eq(adapter)); 233 } 234 235 @Test testTimeout_scaled()236 public void testTimeout_scaled() throws Exception { 237 try { 238 mWm.setAnimationScale(2, 5.0f); 239 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, 240 "testWin"); 241 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 242 win.mActivityRecord, new Point(50, 100), null, new Rect(50, 100, 150, 150), 243 null, false).mAdapter; 244 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 245 mFinishedCallback); 246 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 247 248 mClock.fastForward(10500); 249 mHandler.timeAdvance(); 250 251 verify(mMockRunner, never()).onAnimationCancelled(); 252 253 mClock.fastForward(52500); 254 mHandler.timeAdvance(); 255 256 verify(mMockRunner).onAnimationCancelled(); 257 verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), 258 eq(adapter)); 259 } finally { 260 mWm.setAnimationScale(2, 1.0f); 261 } 262 } 263 264 @Test testZeroAnimations()265 public void testZeroAnimations() throws Exception { 266 mController.goodToGo(TRANSIT_OLD_NONE); 267 verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); 268 verify(mMockRunner).onAnimationCancelled(); 269 } 270 271 @Test testNotReallyStarted()272 public void testNotReallyStarted() throws Exception { 273 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 274 mController.createRemoteAnimationRecord(win.mActivityRecord, 275 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false); 276 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 277 verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); 278 verify(mMockRunner).onAnimationCancelled(); 279 } 280 281 @Test testOneNotStarted()282 public void testOneNotStarted() throws Exception { 283 final WindowState win1 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin1"); 284 final WindowState win2 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin2"); 285 mController.createRemoteAnimationRecord(win1.mActivityRecord, 286 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false); 287 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 288 win2.mActivityRecord, 289 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter; 290 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 291 mFinishedCallback); 292 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 293 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 294 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 295 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 296 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 297 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 298 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 299 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 300 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 301 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 302 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), 303 appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), 304 finishedCaptor.capture()); 305 assertEquals(1, appsCaptor.getValue().length); 306 assertEquals(mMockLeash, appsCaptor.getValue()[0].leash); 307 } 308 309 @Test testRemovedBeforeStarted()310 public void testRemovedBeforeStarted() throws Exception { 311 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 312 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 313 win.mActivityRecord, 314 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter; 315 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 316 mFinishedCallback); 317 win.mActivityRecord.removeImmediately(); 318 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 319 verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); 320 verify(mMockRunner).onAnimationCancelled(); 321 verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), 322 eq(adapter)); 323 } 324 325 @Test testOpeningTaskWithTopFinishingActivity()326 public void testOpeningTaskWithTopFinishingActivity() { 327 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "win"); 328 final Task task = win.getTask(); 329 final ActivityRecord topFinishing = new ActivityBuilder(mAtm).setTask(task).build(); 330 // Now the task contains: 331 // - Activity[1] (top, finishing, no window) 332 // - Activity[0] (has window) 333 topFinishing.finishing = true; 334 spyOn(mDisplayContent.mAppTransition); 335 doReturn(mController).when(mDisplayContent.mAppTransition).getRemoteAnimationController(); 336 task.applyAnimationUnchecked(null /* lp */, true /* enter */, TRANSIT_OLD_TASK_OPEN, 337 false /* isVoiceInteraction */, null /* sources */); 338 mController.goodToGo(TRANSIT_OLD_TASK_OPEN); 339 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 340 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 341 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 342 try { 343 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN), 344 appsCaptor.capture(), any(), any(), any()); 345 } catch (RemoteException ignored) { 346 } 347 assertEquals(1, appsCaptor.getValue().length); 348 assertEquals(RemoteAnimationTarget.MODE_OPENING, appsCaptor.getValue()[0].mode); 349 } 350 351 @Test testChangeToSmallerSize()352 public void testChangeToSmallerSize() throws Exception { 353 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 354 mDisplayContent.mChangingContainers.add(win.mActivityRecord); 355 try { 356 final RemoteAnimationRecord record = mController.createRemoteAnimationRecord( 357 win.mActivityRecord, new Point(50, 100), null, new Rect(50, 100, 150, 150), 358 new Rect(0, 0, 200, 200), false); 359 assertNotNull(record.mThumbnailAdapter); 360 ((AnimationAdapter) record.mAdapter) 361 .startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, 362 mFinishedCallback); 363 ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash, 364 mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback); 365 mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE); 366 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 367 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 368 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 369 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 370 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 371 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 372 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 373 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 374 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 375 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE), 376 appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), 377 finishedCaptor.capture()); 378 assertEquals(1, appsCaptor.getValue().length); 379 final RemoteAnimationTarget app = appsCaptor.getValue()[0]; 380 assertEquals(RemoteAnimationTarget.MODE_CHANGING, app.mode); 381 assertEquals(new Point(50, 100), app.position); 382 assertEquals(new Rect(50, 100, 150, 150), app.sourceContainerBounds); 383 assertEquals(new Rect(0, 0, 200, 200), app.startBounds); 384 assertEquals(mMockLeash, app.leash); 385 assertEquals(mMockThumbnailLeash, app.startLeash); 386 assertEquals(false, app.isTranslucent); 387 verify(mMockTransaction).setPosition( 388 mMockLeash, app.startBounds.left, app.startBounds.top); 389 verify(mMockTransaction).setWindowCrop( 390 mMockLeash, app.startBounds.width(), app.startBounds.height()); 391 verify(mMockTransaction).setPosition(mMockThumbnailLeash, 0, 0); 392 verify(mMockTransaction).setWindowCrop(mMockThumbnailLeash, app.startBounds.width(), 393 app.startBounds.height()); 394 395 finishedCaptor.getValue().onAnimationFinished(); 396 verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_WINDOW_ANIMATION), 397 eq(record.mAdapter)); 398 verify(mThumbnailFinishedCallback).onAnimationFinished( 399 eq(ANIMATION_TYPE_WINDOW_ANIMATION), eq(record.mThumbnailAdapter)); 400 } finally { 401 mDisplayContent.mChangingContainers.clear(); 402 } 403 } 404 405 @Test testChangeTolargerSize()406 public void testChangeTolargerSize() throws Exception { 407 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 408 mDisplayContent.mChangingContainers.add(win.mActivityRecord); 409 try { 410 final RemoteAnimationRecord record = mController.createRemoteAnimationRecord( 411 win.mActivityRecord, new Point(0, 0), null, new Rect(0, 0, 200, 200), 412 new Rect(50, 100, 150, 150), false); 413 assertNotNull(record.mThumbnailAdapter); 414 ((AnimationAdapter) record.mAdapter) 415 .startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, 416 mFinishedCallback); 417 ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash, 418 mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback); 419 mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE); 420 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 421 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 422 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 423 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 424 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 425 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 426 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 427 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 428 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 429 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE), 430 appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), 431 finishedCaptor.capture()); 432 assertEquals(1, appsCaptor.getValue().length); 433 final RemoteAnimationTarget app = appsCaptor.getValue()[0]; 434 assertEquals(RemoteAnimationTarget.MODE_CHANGING, app.mode); 435 assertEquals(new Point(0, 0), app.position); 436 assertEquals(new Rect(0, 0, 200, 200), app.sourceContainerBounds); 437 assertEquals(new Rect(50, 100, 150, 150), app.startBounds); 438 assertEquals(mMockLeash, app.leash); 439 assertEquals(mMockThumbnailLeash, app.startLeash); 440 assertEquals(false, app.isTranslucent); 441 verify(mMockTransaction).setPosition( 442 mMockLeash, app.startBounds.left, app.startBounds.top); 443 verify(mMockTransaction).setWindowCrop( 444 mMockLeash, app.startBounds.width(), app.startBounds.height()); 445 verify(mMockTransaction).setPosition(mMockThumbnailLeash, 0, 0); 446 verify(mMockTransaction).setWindowCrop(mMockThumbnailLeash, app.startBounds.width(), 447 app.startBounds.height()); 448 449 finishedCaptor.getValue().onAnimationFinished(); 450 verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_WINDOW_ANIMATION), 451 eq(record.mAdapter)); 452 verify(mThumbnailFinishedCallback).onAnimationFinished( 453 eq(ANIMATION_TYPE_WINDOW_ANIMATION), eq(record.mThumbnailAdapter)); 454 } finally { 455 mDisplayContent.mChangingContainers.clear(); 456 } 457 } 458 459 @Test testChangeToDifferentPosition()460 public void testChangeToDifferentPosition() throws Exception { 461 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 462 mDisplayContent.mChangingContainers.add(win.mActivityRecord); 463 try { 464 final RemoteAnimationRecord record = mController.createRemoteAnimationRecord( 465 win.mActivityRecord, new Point(100, 100), null, new Rect(150, 150, 400, 400), 466 new Rect(50, 100, 150, 150), false); 467 assertNotNull(record.mThumbnailAdapter); 468 ((AnimationAdapter) record.mAdapter) 469 .startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, 470 mFinishedCallback); 471 ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash, 472 mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback); 473 mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE); 474 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 475 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 476 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 477 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 478 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 479 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 480 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 481 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 482 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 483 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE), 484 appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), 485 finishedCaptor.capture()); 486 assertEquals(1, appsCaptor.getValue().length); 487 final RemoteAnimationTarget app = appsCaptor.getValue()[0]; 488 assertEquals(RemoteAnimationTarget.MODE_CHANGING, app.mode); 489 assertEquals(new Point(100, 100), app.position); 490 assertEquals(new Rect(150, 150, 400, 400), app.sourceContainerBounds); 491 assertEquals(new Rect(50, 100, 150, 150), app.startBounds); 492 assertEquals(mMockLeash, app.leash); 493 assertEquals(mMockThumbnailLeash, app.startLeash); 494 assertEquals(false, app.isTranslucent); 495 verify(mMockTransaction).setPosition( 496 mMockLeash, app.position.x + app.startBounds.left - app.screenSpaceBounds.left, 497 app.position.y + app.startBounds.top - app.screenSpaceBounds.top); 498 verify(mMockTransaction).setWindowCrop( 499 mMockLeash, app.startBounds.width(), app.startBounds.height()); 500 verify(mMockTransaction).setPosition(mMockThumbnailLeash, 0, 0); 501 verify(mMockTransaction).setWindowCrop(mMockThumbnailLeash, app.startBounds.width(), 502 app.startBounds.height()); 503 504 finishedCaptor.getValue().onAnimationFinished(); 505 verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_WINDOW_ANIMATION), 506 eq(record.mAdapter)); 507 verify(mThumbnailFinishedCallback).onAnimationFinished( 508 eq(ANIMATION_TYPE_WINDOW_ANIMATION), eq(record.mThumbnailAdapter)); 509 } finally { 510 mDisplayContent.mChangingContainers.clear(); 511 } 512 } 513 514 @Test testWallpaperIncluded_expectTarget()515 public void testWallpaperIncluded_expectTarget() throws Exception { 516 final WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class), 517 true, mDisplayContent, true /* ownerCanManageAppTokens */); 518 spyOn(mDisplayContent.mWallpaperController); 519 doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible(); 520 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 521 mDisplayContent.mOpeningApps.add(win.mActivityRecord); 522 try { 523 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 524 win.mActivityRecord, 525 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter; 526 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 527 mFinishedCallback); 528 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 529 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 530 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 531 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 532 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 533 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 534 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 535 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 536 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 537 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 538 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), 539 appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), 540 finishedCaptor.capture()); 541 assertEquals(1, wallpapersCaptor.getValue().length); 542 } finally { 543 mDisplayContent.mOpeningApps.clear(); 544 } 545 } 546 547 @Test testWallpaperAnimatorCanceled_expectAnimationKeepsRunning()548 public void testWallpaperAnimatorCanceled_expectAnimationKeepsRunning() throws Exception { 549 final WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class), 550 true, mDisplayContent, true /* ownerCanManageAppTokens */); 551 spyOn(mDisplayContent.mWallpaperController); 552 doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible(); 553 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 554 mDisplayContent.mOpeningApps.add(win.mActivityRecord); 555 try { 556 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 557 win.mActivityRecord, 558 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter; 559 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 560 mFinishedCallback); 561 mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); 562 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 563 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 564 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 565 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 566 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 567 final ArgumentCaptor<RemoteAnimationTarget[]> nonAPpsCaptor = 568 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 569 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 570 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 571 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), 572 appsCaptor.capture(), wallpapersCaptor.capture(), nonAPpsCaptor.capture(), 573 finishedCaptor.capture()); 574 assertEquals(1, wallpapersCaptor.getValue().length); 575 576 // Cancel the wallpaper window animator and ensure the runner is not canceled 577 wallpaperWindowToken.cancelAnimation(); 578 verify(mMockRunner, never()).onAnimationCancelled(); 579 } finally { 580 mDisplayContent.mOpeningApps.clear(); 581 } 582 } 583 584 @Test testNonAppIncluded_keygaurdGoingAway()585 public void testNonAppIncluded_keygaurdGoingAway() throws Exception { 586 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 587 mDisplayContent.mOpeningApps.add(win.mActivityRecord); 588 // Add overlay window hidden by the keyguard. 589 final WindowState overlayWin = createAppOverlayWindow(); 590 overlayWin.hide(false /* doAnimation */, false /* requestAnim */); 591 try { 592 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 593 win.mActivityRecord, new Point(50, 100), null, 594 new Rect(50, 100, 150, 150), null, false).mAdapter; 595 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 596 mFinishedCallback); 597 mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY); 598 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 599 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 600 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 601 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 602 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 603 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 604 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 605 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 606 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 607 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_KEYGUARD_GOING_AWAY), 608 appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), 609 finishedCaptor.capture()); 610 assertEquals(1, appsCaptor.getValue().length); 611 final RemoteAnimationTarget app = appsCaptor.getValue()[0]; 612 assertEquals(new Point(50, 100), app.position); 613 assertEquals(new Rect(50, 100, 150, 150), app.sourceContainerBounds); 614 assertEquals(win.mActivityRecord.getPrefixOrderIndex(), app.prefixOrderIndex); 615 assertEquals(win.mActivityRecord.getTask().mTaskId, app.taskId); 616 assertEquals(mMockLeash, app.leash); 617 assertEquals(false, app.isTranslucent); 618 verify(mMockTransaction).setPosition(mMockLeash, app.position.x, app.position.y); 619 verify(mMockTransaction).setWindowCrop(mMockLeash, 100, 50); 620 621 finishedCaptor.getValue().onAnimationFinished(); 622 verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), 623 eq(adapter)); 624 assertEquals(1, nonAppsCaptor.getValue().length); 625 } finally { 626 mDisplayContent.mOpeningApps.clear(); 627 } 628 } 629 630 @Test testNonAppIncluded_keygaurdGoingAwayToWallpaper()631 public void testNonAppIncluded_keygaurdGoingAwayToWallpaper() throws Exception { 632 final WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class), 633 true, mDisplayContent, true /* ownerCanManageAppTokens */); 634 spyOn(mDisplayContent.mWallpaperController); 635 doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible(); 636 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 637 mDisplayContent.mOpeningApps.add(win.mActivityRecord); 638 // Add overlay window hidden by the keyguard. 639 final WindowState overlayWin = createAppOverlayWindow(); 640 overlayWin.hide(false /* doAnimation */, false /* requestAnim */); 641 try { 642 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 643 win.mActivityRecord, new Point(50, 100), null, 644 new Rect(50, 100, 150, 150), null, false).mAdapter; 645 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 646 mFinishedCallback); 647 mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER); 648 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 649 final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = 650 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 651 final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = 652 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 653 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 654 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 655 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 656 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 657 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER), 658 appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), 659 finishedCaptor.capture()); 660 assertEquals(1, wallpapersCaptor.getValue().length); 661 assertEquals(1, nonAppsCaptor.getValue().length); 662 } finally { 663 mDisplayContent.mOpeningApps.clear(); 664 } 665 } 666 667 @Test testNonAppTarget_sendNavBar()668 public void testNonAppTarget_sendNavBar() throws Exception { 669 final int transit = TRANSIT_OLD_TASK_OPEN; 670 final AnimationAdapter adapter = setupForNonAppTargetNavBar(transit, true); 671 672 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 673 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 674 final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor = 675 ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); 676 verify(mMockRunner).onAnimationStart(eq(transit), any(), any(), 677 nonAppsCaptor.capture(), finishedCaptor.capture()); 678 boolean containNavTarget = false; 679 for (int i = 0; i < nonAppsCaptor.getValue().length; i++) { 680 if (nonAppsCaptor.getValue()[0].windowType == TYPE_NAVIGATION_BAR) { 681 containNavTarget = true; 682 break; 683 } 684 } 685 assertTrue(containNavTarget); 686 assertEquals(1, mController.mPendingNonAppAnimations.size()); 687 final NonAppWindowAnimationAdapter nonAppAdapter = 688 mController.mPendingNonAppAnimations.get(0); 689 spyOn(nonAppAdapter.getLeashFinishedCallback()); 690 691 finishedCaptor.getValue().onAnimationFinished(); 692 verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), 693 eq(adapter)); 694 verify(nonAppAdapter.getLeashFinishedCallback()) 695 .onAnimationFinished(nonAppAdapter.getLastAnimationType(), nonAppAdapter); 696 } 697 698 @Test testNonAppTarget_notSendNavBar_notAttachToApp()699 public void testNonAppTarget_notSendNavBar_notAttachToApp() throws Exception { 700 final int transit = TRANSIT_OLD_TASK_OPEN; 701 setupForNonAppTargetNavBar(transit, false); 702 703 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 704 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 705 verify(mMockRunner).onAnimationStart(eq(transit), 706 any(), any(), nonAppsCaptor.capture(), any()); 707 for (int i = 0; i < nonAppsCaptor.getValue().length; i++) { 708 if (nonAppsCaptor.getValue()[0].windowType == TYPE_NAVIGATION_BAR) { 709 fail("Non-app animation target must not contain navbar"); 710 } 711 } 712 } 713 714 @Test testNonAppTarget_notSendNavBar_controlledByFadeRotation()715 public void testNonAppTarget_notSendNavBar_controlledByFadeRotation() throws Exception { 716 final AsyncRotationController mockController = 717 mock(AsyncRotationController.class); 718 doReturn(mockController).when(mDisplayContent).getAsyncRotationController(); 719 final int transit = TRANSIT_OLD_TASK_OPEN; 720 setupForNonAppTargetNavBar(transit, true); 721 722 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 723 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 724 verify(mMockRunner).onAnimationStart(eq(transit), 725 any(), any(), nonAppsCaptor.capture(), any()); 726 for (int i = 0; i < nonAppsCaptor.getValue().length; i++) { 727 if (nonAppsCaptor.getValue()[0].windowType == TYPE_NAVIGATION_BAR) { 728 fail("Non-app animation target must not contain navbar"); 729 } 730 } 731 } 732 733 @Test testNonAppTarget_notSendNavBar_controlledByRecents()734 public void testNonAppTarget_notSendNavBar_controlledByRecents() throws Exception { 735 final RecentsAnimationController mockController = 736 mock(RecentsAnimationController.class); 737 doReturn(mockController).when(mWm).getRecentsAnimationController(); 738 final int transit = TRANSIT_OLD_TASK_OPEN; 739 setupForNonAppTargetNavBar(transit, true); 740 741 final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor = 742 ArgumentCaptor.forClass(RemoteAnimationTarget[].class); 743 verify(mMockRunner).onAnimationStart(eq(transit), 744 any(), any(), nonAppsCaptor.capture(), any()); 745 for (int i = 0; i < nonAppsCaptor.getValue().length; i++) { 746 if (nonAppsCaptor.getValue()[0].windowType == TYPE_NAVIGATION_BAR) { 747 fail("Non-app animation target must not contain navbar"); 748 } 749 } 750 } 751 752 @SetupWindows(addWindows = W_INPUT_METHOD) 753 @Test testLaunchRemoteAnimationWithoutImeBehind()754 public void testLaunchRemoteAnimationWithoutImeBehind() { 755 final WindowState win1 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin1"); 756 final WindowState win2 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin2"); 757 758 // Simulating win1 has shown IME and being IME layering/input target 759 mDisplayContent.setImeLayeringTarget(win1); 760 mDisplayContent.setImeInputTarget(win1); 761 mImeWindow.mWinAnimator.mSurfaceController = mock(WindowSurfaceController.class); 762 mImeWindow.mWinAnimator.hide(mDisplayContent.getPendingTransaction(), "test"); 763 spyOn(mDisplayContent); 764 doReturn(true).when(mImeWindow.mWinAnimator.mSurfaceController).hasSurface(); 765 doReturn(true).when(mImeWindow.mWinAnimator.mSurfaceController) 766 .prepareToShowInTransaction(any(), anyFloat()); 767 makeWindowVisibleAndDrawn(mImeWindow); 768 assertTrue(mImeWindow.isOnScreen()); 769 assertFalse(mImeWindow.isParentWindowHidden()); 770 771 try { 772 // Simulating now win1 is being covered by the lockscreen which has no surface, 773 // and then launching an activity win2 with the remote animation 774 win1.mHasSurface = false; 775 win1.mActivityRecord.setVisibility(false); 776 mDisplayContent.mOpeningApps.add(win2.mActivityRecord); 777 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 778 win2.mActivityRecord, new Point(50, 100), null, 779 new Rect(50, 100, 150, 150), null, false).mAdapter; 780 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 781 mFinishedCallback); 782 783 mDisplayContent.applySurfaceChangesTransaction(); 784 mController.goodToGo(TRANSIT_OLD_TASK_OPEN); 785 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 786 787 verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN), 788 any(), any(), any(), any()); 789 // Verify the IME window won't apply surface change transaction with forAllImeWindows 790 verify(mDisplayContent, never()).forAllImeWindows(any(), eq(true)); 791 } catch (Exception e) { 792 // no-op 793 } finally { 794 mDisplayContent.mOpeningApps.clear(); 795 } 796 } 797 setupForNonAppTargetNavBar(int transit, boolean shouldAttachNavBar)798 private AnimationAdapter setupForNonAppTargetNavBar(int transit, boolean shouldAttachNavBar) { 799 final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); 800 mDisplayContent.mOpeningApps.add(win.mActivityRecord); 801 final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar"); 802 mDisplayContent.getDisplayPolicy().addWindowLw(navBar, navBar.mAttrs); 803 final DisplayPolicy policy = mDisplayContent.getDisplayPolicy(); 804 spyOn(policy); 805 doReturn(shouldAttachNavBar).when(policy).shouldAttachNavBarToAppDuringTransition(); 806 807 final AnimationAdapter adapter = mController.createRemoteAnimationRecord( 808 win.mActivityRecord, new Point(50, 100), null, 809 new Rect(50, 100, 150, 150), null, false).mAdapter; 810 adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, 811 mFinishedCallback); 812 mController.goodToGo(transit); 813 mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); 814 return adapter; 815 } 816 verifyNoMoreInteractionsExceptAsBinder(IInterface binder)817 private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) { 818 verify(binder, atLeast(0)).asBinder(); 819 verifyNoMoreInteractions(binder); 820 } 821 } 822