1 /* 2 * Copyright (C) 2016 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 android.server.wm.activity; 18 19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 20 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 21 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 22 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; 23 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 24 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; 25 import static android.server.wm.CliIntentExtra.extraString; 26 import static android.server.wm.ComponentNameUtils.getWindowName; 27 import static android.server.wm.UiDeviceUtils.pressBackButton; 28 import static android.server.wm.VirtualDisplayHelper.waitForDefaultDisplayState; 29 import static android.server.wm.WindowManagerState.STATE_RESUMED; 30 import static android.server.wm.WindowManagerState.STATE_STOPPED; 31 import static android.server.wm.app.Components.ALT_LAUNCHING_ACTIVITY; 32 import static android.server.wm.app.Components.BROADCAST_RECEIVER_ACTIVITY; 33 import static android.server.wm.app.Components.DOCKED_ACTIVITY; 34 import static android.server.wm.app.Components.LAUNCHING_ACTIVITY; 35 import static android.server.wm.app.Components.MOVE_TASK_TO_BACK_ACTIVITY; 36 import static android.server.wm.app.Components.MoveTaskToBackActivity.EXTRA_FINISH_POINT; 37 import static android.server.wm.app.Components.MoveTaskToBackActivity.FINISH_POINT_ON_PAUSE; 38 import static android.server.wm.app.Components.MoveTaskToBackActivity.FINISH_POINT_ON_STOP; 39 import static android.server.wm.app.Components.NO_HISTORY_ACTIVITY; 40 import static android.server.wm.app.Components.RESIZEABLE_ACTIVITY; 41 import static android.server.wm.app.Components.SHOW_WHEN_LOCKED_DIALOG_ACTIVITY; 42 import static android.server.wm.app.Components.TEST_ACTIVITY; 43 import static android.server.wm.app.Components.TOP_ACTIVITY; 44 import static android.server.wm.app.Components.TRANSLUCENT_ACTIVITY; 45 import static android.server.wm.app.Components.TRANSLUCENT_TEST_ACTIVITY; 46 import static android.server.wm.app.Components.TRANSLUCENT_TOP_ACTIVITY; 47 import static android.server.wm.app.Components.TURN_SCREEN_ON_ACTIVITY; 48 import static android.server.wm.app.Components.TURN_SCREEN_ON_ATTR_ACTIVITY; 49 import static android.server.wm.app.Components.TURN_SCREEN_ON_ATTR_REMOVE_ATTR_ACTIVITY; 50 import static android.server.wm.app.Components.TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY; 51 import static android.server.wm.app.Components.TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY; 52 import static android.server.wm.app.Components.TURN_SCREEN_ON_WITH_RELAYOUT_ACTIVITY; 53 import static android.server.wm.app.Components.TopActivity.ACTION_CONVERT_FROM_TRANSLUCENT; 54 import static android.server.wm.app.Components.TopActivity.ACTION_CONVERT_TO_TRANSLUCENT; 55 import static android.view.Display.DEFAULT_DISPLAY; 56 import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; 57 58 import static org.junit.Assert.assertFalse; 59 import static org.junit.Assert.assertTrue; 60 import static org.junit.Assume.assumeTrue; 61 62 import android.content.ComponentName; 63 import android.platform.test.annotations.Presubmit; 64 import android.server.wm.ActivityManagerTestBase; 65 import android.server.wm.CommandSession.ActivitySession; 66 import android.server.wm.CommandSession.ActivitySessionClient; 67 import android.server.wm.LockScreenSession; 68 import android.server.wm.WaitForValidActivityState; 69 import android.server.wm.app.Components; 70 71 import org.junit.Rule; 72 import org.junit.Test; 73 74 /** 75 * Build/Install/Run: 76 * atest CtsWindowManagerDeviceActivity:ActivityVisibilityTests 77 */ 78 @Presubmit 79 @android.server.wm.annotation.Group2 80 public class ActivityVisibilityTests extends ActivityManagerTestBase { 81 82 @Rule 83 public final DisableScreenDozeRule mDisableScreenDozeRule = new DisableScreenDozeRule(); 84 85 /** 86 * Asserts that the home activity is visible when a translucent activity is launched in the 87 * fullscreen stack over the home activity. 88 */ 89 @Test testTranslucentActivityOnTopOfHome()90 public void testTranslucentActivityOnTopOfHome() { 91 if (!hasHomeScreen()) { 92 return; 93 } 94 95 launchHomeActivity(); 96 launchActivity(TRANSLUCENT_ACTIVITY, WINDOWING_MODE_FULLSCREEN); 97 98 int expectedWindowingMode = hasAutomotiveSplitscreenMultitaskingFeature() 99 // On auto devices with this feature enabled, the system is in a permanent 100 // split-screen UI where every app opens in MULTI_WINDOW mode. 101 ? WINDOWING_MODE_MULTI_WINDOW 102 : WINDOWING_MODE_FULLSCREEN; 103 mWmState.assertFrontStack("Fullscreen stack must be the front stack.", 104 expectedWindowingMode, ACTIVITY_TYPE_STANDARD); 105 mWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true); 106 mWmState.assertHomeActivityVisible(true); 107 } 108 109 @Test testTranslucentActivityOverMultiWindowActivity()110 public void testTranslucentActivityOverMultiWindowActivity() { 111 if (!supportsMultiWindow()) { 112 // Skipping test: no multi-window support 113 return; 114 } 115 116 launchActivitiesInSplitScreen( 117 getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY), 118 getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY)); 119 launchActivityInSecondarySplit(TRANSLUCENT_ACTIVITY); 120 mWmState.computeState( 121 new WaitForValidActivityState(TEST_ACTIVITY), 122 new WaitForValidActivityState(DOCKED_ACTIVITY), 123 new WaitForValidActivityState(TRANSLUCENT_ACTIVITY)); 124 mWmState.assertVisibility(DOCKED_ACTIVITY, true); 125 mWmState.assertVisibility(TEST_ACTIVITY, true); 126 mWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true); 127 } 128 129 /** 130 * Assert that the activity is visible when the intermediate activity finishes and a 131 * translucent activity is on the top most. 132 */ 133 @Test testVisibilityBehindTranslucentActivity_sameTask()134 public void testVisibilityBehindTranslucentActivity_sameTask() { 135 launchActivity(TEST_ACTIVITY); 136 mWmState.waitForActivityState(TEST_ACTIVITY, STATE_RESUMED); 137 138 launchAndFinishActivityBehindTranslucentActivity(true /* inSameTask */); 139 140 mWmState.computeState(new WaitForValidActivityState(TEST_ACTIVITY)); 141 mWmState.assertVisibility(TEST_ACTIVITY, true); 142 } 143 144 @Test testVisibilityBehindTranslucentActivity_diffTask()145 public void testVisibilityBehindTranslucentActivity_diffTask() { 146 launchActivity(TEST_ACTIVITY); 147 mWmState.waitForActivityState(TEST_ACTIVITY, STATE_RESUMED); 148 149 launchAndFinishActivityBehindTranslucentActivity(false /* inSameTask */); 150 151 mWmState.computeState(new WaitForValidActivityState(TEST_ACTIVITY)); 152 mWmState.assertVisibility(TEST_ACTIVITY, true); 153 } 154 155 /** 156 * Assert that the home activity is visible when the intermediate activity finishes and a 157 * translucent activity is on the top most. 158 */ 159 @Test testHomeVisibilityBehindTranslucentActivity_sameTask()160 public void testHomeVisibilityBehindTranslucentActivity_sameTask() { 161 if (!hasHomeScreen()) { 162 return; 163 } 164 launchHomeActivity(); 165 166 launchAndFinishActivityBehindTranslucentActivity(true /* inSameTask */); 167 168 mWmState.waitForHomeActivityVisible(); 169 mWmState.assertHomeActivityVisible(true); 170 } 171 172 @Test testHomeVisibilityBehindTranslucentActivity_diffTask()173 public void testHomeVisibilityBehindTranslucentActivity_diffTask() { 174 if (!hasHomeScreen()) { 175 return; 176 } 177 launchHomeActivity(); 178 179 launchAndFinishActivityBehindTranslucentActivity(false /* inSameTask */); 180 181 mWmState.waitForHomeActivityVisible(); 182 mWmState.assertHomeActivityVisible(true); 183 } 184 launchAndFinishActivityBehindTranslucentActivity(boolean inSameTask)185 private void launchAndFinishActivityBehindTranslucentActivity(boolean inSameTask) { 186 // Launch first activity 187 launchActivity(BROADCAST_RECEIVER_ACTIVITY); 188 mWmState.waitForActivityState(BROADCAST_RECEIVER_ACTIVITY, STATE_RESUMED); 189 190 // Launch translucent activity 191 if (inSameTask) { 192 launchActivity(TRANSLUCENT_TEST_ACTIVITY); 193 } else { 194 launchActivityInNewTask(TRANSLUCENT_TEST_ACTIVITY); 195 } 196 mWmState.waitForActivityState(TRANSLUCENT_TEST_ACTIVITY, STATE_RESUMED); 197 mWmState.assertVisibility(TRANSLUCENT_TEST_ACTIVITY, true); 198 199 // Finish first activity 200 mBroadcastActionTrigger.finishBroadcastReceiverActivity(); 201 mWmState.computeState(BROADCAST_RECEIVER_ACTIVITY); 202 mWmState.waitForActivityRemoved(BROADCAST_RECEIVER_ACTIVITY); 203 mWmState.computeState(new WaitForValidActivityState(TRANSLUCENT_TEST_ACTIVITY)); 204 } 205 206 @Test testTurnScreenOnActivity()207 public void testTurnScreenOnActivity() { 208 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 209 final ActivitySessionClient activityClient = createManagedActivityClientSession(); 210 testTurnScreenOnActivity(lockScreenSession, activityClient, 211 true /* useWindowFlags */); 212 testTurnScreenOnActivity(lockScreenSession, activityClient, 213 false /* useWindowFlags */); 214 215 // On Auto split-screen multi-tasking UI, testTurnScreenOnActivity() can lead to lifecycle 216 // state transitions in Home because of device sleep and also because of config change 217 // (b/308213530). 218 // Wait for the existing TurnScreenOnActivity to finish and the home activity to be in 219 // stopped state as the display is OFF. 220 if (!isDisplayOn(DEFAULT_DISPLAY)) { 221 mWmState.waitForAllStoppedActivities(); 222 } 223 224 // Start TURN_SCREEN_ON_ACTIVITY 225 launchActivity(TURN_SCREEN_ON_ACTIVITY, WINDOWING_MODE_FULLSCREEN); 226 mWmState.assertVisibility(TURN_SCREEN_ON_ACTIVITY, true); 227 assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY)); 228 229 // Start another activity on top and put device to sleep 230 final ActivitySession activity = activityClient.startActivity( 231 getLaunchActivityBuilder().setUseInstrumentation() 232 .setWaitForLaunched(false).setTargetActivity(TOP_ACTIVITY)); 233 if (supportsLockScreen()) { 234 // top activity is hidden behind lock screen 235 waitAndAssertActivityState(TOP_ACTIVITY, STATE_STOPPED, 236 "Top activity must be stopped."); 237 } else { 238 waitAndAssertActivityState(TOP_ACTIVITY, STATE_RESUMED, 239 "Top activity must be resumed."); 240 } 241 lockScreenSession.sleepDevice(); 242 243 // Finish the top activity and make sure the device still in sleep 244 activity.finish(); 245 waitAndAssertActivityState(TURN_SCREEN_ON_ACTIVITY, STATE_STOPPED, 246 "Activity must be stopped"); 247 mWmState.assertVisibility(TURN_SCREEN_ON_ACTIVITY, false); 248 assertFalse("Display must remain OFF", isDisplayOn(DEFAULT_DISPLAY)); 249 } 250 251 @Test testTurnScreenOnActivity_slowLaunch()252 public void testTurnScreenOnActivity_slowLaunch() { 253 254 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 255 final ActivitySessionClient activityClient = createManagedActivityClientSession(); 256 // The activity will be paused first because the flags turn-screen-on and show-when-locked 257 // haven't been applied from relayout. And if it is slow, the ensure-visibility from pause 258 // timeout should still notify the client activity to be visible. Then the relayout can 259 // send the visible request to apply the flags and turn on screen. 260 testTurnScreenOnActivity(lockScreenSession, activityClient, true /* useWindowFlags */, 261 1000 /* sleepMsInOnCreate */); 262 } 263 testTurnScreenOnActivity(LockScreenSession lockScreenSession, ActivitySessionClient activitySessionClient, boolean useWindowFlags)264 private void testTurnScreenOnActivity(LockScreenSession lockScreenSession, 265 ActivitySessionClient activitySessionClient, boolean useWindowFlags) { 266 testTurnScreenOnActivity(lockScreenSession, activitySessionClient, useWindowFlags, 267 0 /* sleepMsInOnCreate */); 268 } 269 testTurnScreenOnActivity(LockScreenSession lockScreenSession, ActivitySessionClient activitySessionClient, boolean useWindowFlags, int sleepMsInOnCreate)270 private void testTurnScreenOnActivity(LockScreenSession lockScreenSession, 271 ActivitySessionClient activitySessionClient, boolean useWindowFlags, 272 int sleepMsInOnCreate) { 273 ActivitySession activity = sleepDeviceAndLaunchTurnScreenOnActivity(lockScreenSession, 274 activitySessionClient, useWindowFlags, sleepMsInOnCreate, 275 WINDOWING_MODE_FULLSCREEN); 276 277 mWmState.assertVisibility(TURN_SCREEN_ON_ACTIVITY, true); 278 assertTrue("Display turns on by " + (useWindowFlags ? "flags" : "APIs"), 279 isDisplayOn(DEFAULT_DISPLAY)); 280 281 activity.finish(); 282 mWmState.waitForActivityRemoved(activity.getName()); 283 } 284 285 @Test testFreeformWindowToTurnScreenOn()286 public void testFreeformWindowToTurnScreenOn() { 287 assumeTrue(supportsLockScreen()); 288 assumeTrue(supportsFreeform()); 289 290 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 291 final ActivitySessionClient activityClient = createManagedActivityClientSession(); 292 293 testFreeformWindowTurnScreenOnActivity(lockScreenSession, activityClient, 294 true/* useWindowFlags */); 295 testFreeformWindowTurnScreenOnActivity(lockScreenSession, activityClient, 296 false/* useWindowFlags */); 297 } 298 testFreeformWindowTurnScreenOnActivity(LockScreenSession lockScreenSession, ActivitySessionClient activityClient, boolean useWindowFlags)299 private void testFreeformWindowTurnScreenOnActivity(LockScreenSession lockScreenSession, 300 ActivitySessionClient activityClient, boolean useWindowFlags) { 301 ActivitySession activity = sleepDeviceAndLaunchTurnScreenOnActivity(lockScreenSession, 302 activityClient, useWindowFlags, 0 /* sleepMsInOnCreate */, 303 WINDOWING_MODE_FREEFORM); 304 mWmState.waitForValidState( 305 new WaitForValidActivityState.Builder(TURN_SCREEN_ON_ACTIVITY) 306 .setWindowingMode(WINDOWING_MODE_FULLSCREEN) 307 .build()); 308 assertTrue(mWmState.containsActivityInWindowingMode( 309 TURN_SCREEN_ON_ACTIVITY, WINDOWING_MODE_FULLSCREEN)); 310 mWmState.assertVisibility(TURN_SCREEN_ON_ACTIVITY, true); 311 assertTrue("Display should be turned on by flags.", isDisplayOn(DEFAULT_DISPLAY)); 312 activity.finish(); 313 } 314 sleepDeviceAndLaunchTurnScreenOnActivity( LockScreenSession lockScreenSession, ActivitySessionClient activitySessionClient, boolean useWindowFlags, int sleepMsInOnCreate, int windowingMode)315 private ActivitySession sleepDeviceAndLaunchTurnScreenOnActivity( 316 LockScreenSession lockScreenSession, ActivitySessionClient activitySessionClient, 317 boolean useWindowFlags, int sleepMsInOnCreate, int windowingMode) { 318 lockScreenSession.sleepDevice(); 319 320 return activitySessionClient.startActivity( 321 getLaunchActivityBuilder().setUseInstrumentation().setIntentExtra(extra -> { 322 extra.putBoolean(Components.TurnScreenOnActivity.EXTRA_USE_WINDOW_FLAGS, 323 useWindowFlags); 324 extra.putLong(Components.TurnScreenOnActivity.EXTRA_SLEEP_MS_IN_ON_CREATE, 325 sleepMsInOnCreate); 326 }).setTargetActivity(TURN_SCREEN_ON_ACTIVITY).setWindowingMode(windowingMode)); 327 } 328 329 @Test testFinishActivityInNonFocusedStack()330 public void testFinishActivityInNonFocusedStack() { 331 if (!supportsMultiWindow()) { 332 // Skipping test: no multi-window support 333 return; 334 } 335 336 // Launch two activities in docked stack. 337 launchActivityInPrimarySplit(LAUNCHING_ACTIVITY); 338 getLaunchActivityBuilder() 339 .setTargetActivity(BROADCAST_RECEIVER_ACTIVITY) 340 .setWaitForLaunched(true) 341 .setUseInstrumentation() 342 .execute(); 343 mWmState.assertVisibility(BROADCAST_RECEIVER_ACTIVITY, true); 344 // Launch something to second split to make it focused. 345 launchActivityInSecondarySplit(TEST_ACTIVITY); 346 // Finish activity in non-focused (docked) stack. 347 mBroadcastActionTrigger.finishBroadcastReceiverActivity(); 348 349 mWmState.computeState(LAUNCHING_ACTIVITY); 350 // The testing activities support multiple resume (target SDK >= Q). 351 mWmState.waitForActivityState(LAUNCHING_ACTIVITY, STATE_RESUMED); 352 mWmState.assertVisibility(LAUNCHING_ACTIVITY, true); 353 mWmState.waitAndAssertActivityRemoved(BROADCAST_RECEIVER_ACTIVITY); 354 } 355 356 @Test testLaunchTaskOnHome()357 public void testLaunchTaskOnHome() { 358 if (!hasHomeScreen()) { 359 return; 360 } 361 362 getLaunchActivityBuilder().setTargetActivity(BROADCAST_RECEIVER_ACTIVITY) 363 .setWindowingMode(WINDOWING_MODE_FULLSCREEN) 364 .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute(); 365 366 getLaunchActivityBuilder().setTargetActivity(BROADCAST_RECEIVER_ACTIVITY) 367 .setWindowingMode(WINDOWING_MODE_FULLSCREEN) 368 .setIntentFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME).execute(); 369 370 mBroadcastActionTrigger.finishBroadcastReceiverActivity(); 371 mWmState.waitForHomeActivityVisible(); 372 mWmState.assertHomeActivityVisible(true); 373 } 374 375 /** 376 * This test case tests behavior of activity launched with FLAG_ACTIVITY_TASK_ON_HOME in lock 377 * task mode. The home task do not move to the front of the launched task if the home task 378 * is violated with the lock-task mode. 379 */ 380 @Test testLaunchTaskOnHomeInLockTaskMode()381 public void testLaunchTaskOnHomeInLockTaskMode() { 382 if (!hasHomeScreen()) { 383 return; 384 } 385 mWmState.computeState(); 386 final int homeTaskDisplayAreaFeatureId = 387 mWmState.getTaskDisplayAreaFeatureId(mWmState.getHomeActivityName()); 388 389 // Start LaunchingActivity and BroadcastReceiverActivity in two separate tasks. 390 getLaunchActivityBuilder().setTargetActivity(BROADCAST_RECEIVER_ACTIVITY) 391 .setWindowingMode(WINDOWING_MODE_FULLSCREEN) 392 .setLaunchTaskDisplayAreaFeatureId(homeTaskDisplayAreaFeatureId) 393 .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute(); 394 waitAndAssertResumedActivity(BROADCAST_RECEIVER_ACTIVITY,"Activity must be resumed"); 395 final int taskId = mWmState.getTaskByActivity(BROADCAST_RECEIVER_ACTIVITY).getTaskId(); 396 397 try { 398 runWithShellPermission(() -> mAtm.startSystemLockTaskMode(taskId)); 399 getLaunchActivityBuilder() 400 .setUseInstrumentation() 401 .setTargetActivity(BROADCAST_RECEIVER_ACTIVITY) 402 .setWindowingMode(WINDOWING_MODE_FULLSCREEN) 403 .setLaunchTaskDisplayAreaFeatureId(homeTaskDisplayAreaFeatureId) 404 .setIntentFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME).execute(); 405 mWmState.waitForActivityState(BROADCAST_RECEIVER_ACTIVITY, STATE_RESUMED); 406 } finally { 407 runWithShellPermission(() -> mAtm.stopSystemLockTaskMode()); 408 } 409 410 mBroadcastActionTrigger.finishBroadcastReceiverActivity(); 411 mWmState.waitAndAssertActivityRemoved(BROADCAST_RECEIVER_ACTIVITY); 412 413 if (!hasAutomotiveSplitscreenMultitaskingFeature()) { 414 // TODO(b/300009006): remove this if condition when root tasks setup is moved to SysUI. 415 mWmState.assertHomeActivityVisible(false); 416 } 417 } 418 419 @Test testFinishActivityWithMoveTaskToBackAfterPause()420 public void testFinishActivityWithMoveTaskToBackAfterPause() { 421 performFinishActivityWithMoveTaskToBack(FINISH_POINT_ON_PAUSE); 422 } 423 424 @Test testFinishActivityWithMoveTaskToBackAfterStop()425 public void testFinishActivityWithMoveTaskToBackAfterStop() { 426 performFinishActivityWithMoveTaskToBack(FINISH_POINT_ON_STOP); 427 } 428 performFinishActivityWithMoveTaskToBack(String finishPoint)429 private void performFinishActivityWithMoveTaskToBack(String finishPoint) { 430 // Make sure home activity is visible. 431 launchHomeActivity(); 432 if (hasHomeScreen()) { 433 mWmState.assertHomeActivityVisible(true /* visible */); 434 } 435 436 // If home activity is present we will launch the activities into the same TDA as the home, 437 // otherwise we will launch the second activity into the same TDA as the first one. 438 int launchTaskDisplayAreaFeatureId = hasHomeScreen() 439 ? mWmState.getTaskDisplayAreaFeatureId(mWmState.getHomeActivityName()) 440 : FEATURE_UNDEFINED; 441 442 // Launch an activity that calls "moveTaskToBack" to finish itself. 443 launchActivityOnTaskDisplayArea(MOVE_TASK_TO_BACK_ACTIVITY, WINDOWING_MODE_FULLSCREEN, 444 launchTaskDisplayAreaFeatureId, DEFAULT_DISPLAY, 445 extraString(EXTRA_FINISH_POINT, finishPoint)); 446 447 mWmState.assertVisibility(MOVE_TASK_TO_BACK_ACTIVITY, true); 448 449 // Launch a different activity on top into the same TaskDisplayArea. 450 launchTaskDisplayAreaFeatureId = 451 mWmState.getTaskDisplayAreaFeatureId(MOVE_TASK_TO_BACK_ACTIVITY); 452 launchActivityOnTaskDisplayArea(BROADCAST_RECEIVER_ACTIVITY, WINDOWING_MODE_FULLSCREEN, 453 launchTaskDisplayAreaFeatureId, DEFAULT_DISPLAY); 454 mWmState.waitForActivityState(BROADCAST_RECEIVER_ACTIVITY, STATE_RESUMED); 455 mWmState.waitForActivityState(MOVE_TASK_TO_BACK_ACTIVITY,STATE_STOPPED); 456 final boolean shouldBeVisible = 457 !mWmState.isBehindOpaqueActivities(MOVE_TASK_TO_BACK_ACTIVITY); 458 if (shouldBeVisible) { 459 mWmState.assertVisibility(MOVE_TASK_TO_BACK_ACTIVITY, true); 460 } else { 461 mWmState.waitAndAssertVisibilityGone(MOVE_TASK_TO_BACK_ACTIVITY); 462 } 463 mWmState.assertVisibility(BROADCAST_RECEIVER_ACTIVITY, true); 464 465 // Finish the top-most activity. 466 mBroadcastActionTrigger.finishBroadcastReceiverActivity(); 467 //TODO: BUG: MoveTaskToBackActivity returns to the top of the stack when 468 // BroadcastActivity finishes, so homeActivity is not visible afterwards 469 470 // Home must be visible. 471 if (hasHomeScreen()) { 472 mWmState.waitForHomeActivityVisible(); 473 mWmState.assertHomeActivityVisible(true /* visible */); 474 } 475 } 476 477 /** 478 * Asserts that launching between reorder to front activities exhibits the correct backstack 479 * behavior. 480 */ 481 @Test testReorderToFrontBackstack()482 public void testReorderToFrontBackstack() { 483 // Start with home on top 484 launchHomeActivity(); 485 if (hasHomeScreen()) { 486 mWmState.assertHomeActivityVisible(true /* visible */); 487 } 488 489 // Launch the launching activity to the foreground 490 launchActivity(LAUNCHING_ACTIVITY); 491 492 // Launch the alternate launching activity from launching activity with reorder to front. 493 getLaunchActivityBuilder().setTargetActivity(ALT_LAUNCHING_ACTIVITY) 494 .setReorderToFront(true).execute(); 495 496 // Launch the launching activity from the alternate launching activity with reorder to 497 // front. 498 getLaunchActivityBuilder().setTargetActivity(LAUNCHING_ACTIVITY) 499 .setLaunchingActivity(ALT_LAUNCHING_ACTIVITY) 500 .setReorderToFront(true) 501 .execute(); 502 503 // Press back 504 pressBackButton(); 505 506 mWmState.waitForValidState(ALT_LAUNCHING_ACTIVITY); 507 508 // Ensure the alternate launching activity is in focus 509 mWmState.assertFocusedActivity("Alt Launching Activity must be focused", 510 ALT_LAUNCHING_ACTIVITY); 511 } 512 513 /** 514 * Asserts that the activity focus and history is preserved moving between the activity and 515 * home stack. 516 */ 517 @Test testReorderToFrontChangingStack()518 public void testReorderToFrontChangingStack() { 519 // Start with home on top 520 launchHomeActivity(); 521 if (hasHomeScreen()) { 522 mWmState.assertHomeActivityVisible(true /* visible */); 523 } 524 525 // Launch the launching activity to the foreground 526 launchActivity(LAUNCHING_ACTIVITY); 527 528 // Launch the alternate launching activity from launching activity with reorder to front. 529 getLaunchActivityBuilder().setTargetActivity(ALT_LAUNCHING_ACTIVITY) 530 .setReorderToFront(true) 531 .execute(); 532 533 // Return home 534 launchHomeActivity(); 535 if (hasHomeScreen()) { 536 mWmState.assertHomeActivityVisible(true /* visible */); 537 } 538 // Launch the launching activity from the alternate launching activity with reorder to 539 // front. 540 541 // Bring launching activity back to the foreground 542 launchActivityNoWait(LAUNCHING_ACTIVITY); 543 // Wait for the most front activity of the task. 544 mWmState.waitForFocusedActivity("Waiting for Alt Launching Activity to be focused", 545 ALT_LAUNCHING_ACTIVITY); 546 547 // Ensure the alternate launching activity is still in focus. 548 mWmState.assertFocusedActivity("Alt Launching Activity must be focused", 549 ALT_LAUNCHING_ACTIVITY); 550 551 pressBackButton(); 552 553 // Wait for the bottom activity back to the foreground. 554 mWmState.waitForFocusedActivity("Waiting for Launching Activity to be focused", 555 LAUNCHING_ACTIVITY); 556 557 // Ensure launching activity was brought forward. 558 mWmState.assertFocusedActivity("Launching Activity must be focused", 559 LAUNCHING_ACTIVITY); 560 } 561 562 /** 563 * Asserts that a nohistory activity is stopped and removed immediately after a resumed activity 564 * above becomes visible and does not idle. 565 */ 566 @Test testNoHistoryActivityFinishedResumedActivityNotIdle()567 public void testNoHistoryActivityFinishedResumedActivityNotIdle() { 568 if (!hasHomeScreen()) { 569 return; 570 } 571 572 // Start with home on top 573 launchHomeActivity(); 574 575 // Launch no history activity 576 launchActivity(NO_HISTORY_ACTIVITY); 577 578 // Launch an activity that won't report idle. 579 launchNoIdleActivity(); 580 581 pressBackButton(); 582 mWmState.waitForHomeActivityVisible(); 583 mWmState.assertHomeActivityVisible(true); 584 } 585 586 /** 587 * Asserts that a no-history activity is not stopped and removed after a translucent activity 588 * above becomes resumed. 589 */ 590 @Test testNoHistoryActivityNotFinishedBehindTranslucentActivity()591 public void testNoHistoryActivityNotFinishedBehindTranslucentActivity() { 592 // Launch a no-history activity 593 launchActivity(NO_HISTORY_ACTIVITY); 594 595 // Launch a translucent activity 596 launchActivity(TRANSLUCENT_ACTIVITY); 597 598 // Wait for the activity resumed 599 mWmState.waitForActivityState(TRANSLUCENT_ACTIVITY, STATE_RESUMED); 600 mWmState.assertVisibility(NO_HISTORY_ACTIVITY, true); 601 602 pressBackButton(); 603 604 // Wait for the activity resumed 605 mWmState.waitForActivityState(NO_HISTORY_ACTIVITY, STATE_RESUMED); 606 mWmState.assertVisibility(NO_HISTORY_ACTIVITY, true); 607 } 608 609 /** 610 * If the next activity hasn't reported idle but it has drawn and the transition has done, the 611 * previous activity should be stopped and invisible without waiting for idle timeout. 612 */ 613 @Test testActivityStoppedWhileNextActivityNotIdle()614 public void testActivityStoppedWhileNextActivityNotIdle() { 615 final ComponentName activityWithSameAffinity = TURN_SCREEN_ON_ATTR_ACTIVITY; 616 launchActivity(activityWithSameAffinity); 617 launchNoIdleActivity(); 618 waitAndAssertActivityState(activityWithSameAffinity, STATE_STOPPED, 619 "Activity should be stopped before idle timeout"); 620 mWmState.assertVisibility(activityWithSameAffinity, false); 621 } 622 launchNoIdleActivity()623 private void launchNoIdleActivity() { 624 getLaunchActivityBuilder() 625 .setUseInstrumentation() 626 .setIntentExtra( 627 extra -> extra.putBoolean(Components.TestActivity.EXTRA_NO_IDLE, true)) 628 .setTargetActivity(TEST_ACTIVITY) 629 .setWindowingMode(WINDOWING_MODE_FULLSCREEN) 630 .execute(); 631 } 632 633 @Test testTurnScreenOnAttrNoLockScreen()634 public void testTurnScreenOnAttrNoLockScreen() { 635 assumeTrue(supportsLockScreen()); 636 637 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 638 lockScreenSession.disableLockScreen().sleepDevice(); 639 separateTestJournal(); 640 launchActivity(TURN_SCREEN_ON_ATTR_ACTIVITY, WINDOWING_MODE_FULLSCREEN); 641 mWmState.assertVisibility(TURN_SCREEN_ON_ATTR_ACTIVITY, true); 642 assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY)); 643 if (hasAutomotiveSplitscreenMultitaskingFeature()) { 644 // TODO(b/300009006): remove when root tasks setup is moved to SysUI. 645 waitAndAssertResumedActivity(TURN_SCREEN_ON_ATTR_ACTIVITY); 646 } else { 647 assertSingleLaunch(TURN_SCREEN_ON_ATTR_ACTIVITY); 648 } 649 } 650 651 @Test testTurnScreenOnAttrNoLockScreen_SplitScreen()652 public void testTurnScreenOnAttrNoLockScreen_SplitScreen() { 653 assumeTrue(supportsLockScreen()); 654 assumeTrue(supportsMultiWindow()); 655 656 launchActivitiesInSplitScreen( 657 getLaunchActivityBuilder().setTargetActivity(LAUNCHING_ACTIVITY), 658 getLaunchActivityBuilder().setTargetActivity(RESIZEABLE_ACTIVITY)); 659 660 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 661 lockScreenSession.disableLockScreen().sleepDevice(); 662 launchActivity(TURN_SCREEN_ON_ATTR_ACTIVITY, WINDOWING_MODE_FULLSCREEN); 663 mWmState.assertVisibility(TURN_SCREEN_ON_ATTR_ACTIVITY, true); 664 assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY)); 665 } 666 667 @Test testTurnScreenOnWithAttr_Freeform()668 public void testTurnScreenOnWithAttr_Freeform() { 669 assumeTrue(supportsLockScreen()); 670 assumeTrue(supportsFreeform()); 671 672 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 673 lockScreenSession.disableLockScreen().sleepDevice(); 674 675 launchActivity(TURN_SCREEN_ON_ATTR_ACTIVITY, WINDOWING_MODE_FREEFORM); 676 mWmState.assertVisibility(TURN_SCREEN_ON_ATTR_ACTIVITY, true); 677 assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY)); 678 } 679 680 @Test testTurnScreenOnAttrWithLockScreen()681 public void testTurnScreenOnAttrWithLockScreen() { 682 assumeTrue(supportsSecureLock()); 683 684 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 685 lockScreenSession.setLockCredential().sleepDevice(); 686 separateTestJournal(); 687 launchActivityNoWait(TURN_SCREEN_ON_ATTR_ACTIVITY, WINDOWING_MODE_FULLSCREEN); 688 // Wait for the activity stopped because lock screen prevent showing the activity. 689 mWmState.waitForActivityState(TURN_SCREEN_ON_ATTR_ACTIVITY, STATE_STOPPED); 690 assertFalse("Display keeps off", isDisplayOn(DEFAULT_DISPLAY)); 691 assertSingleLaunchAndStop(TURN_SCREEN_ON_ATTR_ACTIVITY); 692 } 693 694 @Test testTurnScreenOnShowOnLockAttr()695 public void testTurnScreenOnShowOnLockAttr() { 696 assumeTrue(supportsLockScreen()); 697 698 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 699 lockScreenSession.sleepDevice(); 700 mWmState.waitForAllStoppedActivities(); 701 separateTestJournal(); 702 launchActivity(TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY, WINDOWING_MODE_FULLSCREEN); 703 mWmState.assertVisibility(TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY, true); 704 assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY)); 705 if (hasAutomotiveSplitscreenMultitaskingFeature()) { 706 // TODO(b/300009006): remove when root tasks setup is moved to SysUI. 707 waitAndAssertResumedActivity(TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY); 708 } else { 709 assertSingleLaunch(TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY); 710 } 711 } 712 713 @Test testChangeToFullscreenWhenLockWithAttrInFreeform()714 public void testChangeToFullscreenWhenLockWithAttrInFreeform() { 715 assumeTrue(supportsLockScreen()); 716 assumeTrue(supportsFreeform()); 717 718 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 719 lockScreenSession.sleepDevice(); 720 mWmState.waitForAllStoppedActivities(); 721 722 launchActivityNoWait(TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY, WINDOWING_MODE_FREEFORM); 723 mWmState.waitForValidState( 724 new WaitForValidActivityState.Builder(TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY) 725 .setWindowingMode(WINDOWING_MODE_FULLSCREEN) 726 .build()); 727 assertTrue(mWmState.containsActivityInWindowingMode( 728 TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY, WINDOWING_MODE_FULLSCREEN)); 729 mWmState.assertVisibility(TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY, true); 730 assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY)); 731 } 732 733 @Test testTurnScreenOnAttrRemove()734 public void testTurnScreenOnAttrRemove() { 735 assumeTrue(supportsLockScreen()); 736 737 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 738 lockScreenSession.sleepDevice(); 739 mWmState.waitForAllStoppedActivities(); 740 separateTestJournal(); 741 launchActivity(TURN_SCREEN_ON_ATTR_REMOVE_ATTR_ACTIVITY); 742 assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY)); 743 assertSingleLaunch(TURN_SCREEN_ON_ATTR_REMOVE_ATTR_ACTIVITY); 744 745 lockScreenSession.sleepDevice(); 746 mWmState.waitForAllStoppedActivities(); 747 separateTestJournal(); 748 launchActivityNoWait(TURN_SCREEN_ON_ATTR_REMOVE_ATTR_ACTIVITY); 749 mWmState.waitForActivityState(TURN_SCREEN_ON_ATTR_REMOVE_ATTR_ACTIVITY, STATE_STOPPED); 750 // Display should keep off, because setTurnScreenOn(false) has been called at 751 // {@link TURN_SCREEN_ON_ATTR_REMOVE_ATTR_ACTIVITY}'s onStop. 752 assertFalse("Display keeps off", isDisplayOn(DEFAULT_DISPLAY)); 753 assertSingleStartAndStop(TURN_SCREEN_ON_ATTR_REMOVE_ATTR_ACTIVITY); 754 } 755 756 @Test testTurnScreenOnSingleTask()757 public void testTurnScreenOnSingleTask() { 758 assumeTrue(supportsLockScreen()); 759 760 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 761 lockScreenSession.sleepDevice(); 762 separateTestJournal(); 763 launchActivity(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY, WINDOWING_MODE_FULLSCREEN); 764 // wait for the UI to be stable. 765 mInstrumentation.getUiAutomation().syncInputTransactions(); 766 mWmState.assertVisibility(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY, true); 767 assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY)); 768 if (hasAutomotiveSplitscreenMultitaskingFeature()) { 769 // TODO(b/300009006): remove when root tasks setup is moved to SysUI. 770 waitAndAssertResumedActivity(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY); 771 } else { 772 assertSingleLaunch(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY); 773 } 774 775 lockScreenSession.sleepDevice(); 776 // We should make sure test activity stopped to prevent a false alarm stop state 777 // included in the lifecycle count. 778 waitAndAssertActivityState(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY, STATE_STOPPED, 779 "Activity should be stopped"); 780 separateTestJournal(); 781 launchActivity(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY); 782 mInstrumentation.getUiAutomation().syncInputTransactions(); 783 mWmState.assertVisibility(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY, true); 784 // Wait more for display state change since turning the display ON may take longer 785 // and reported after the activity launch. 786 waitForDefaultDisplayState(true /* wantOn */); 787 assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY)); 788 if (hasAutomotiveSplitscreenMultitaskingFeature()) { 789 // In the scenario when the Launcher HOME activity hosts the TaskView, the HOME activity 790 // itself will be resumed first before the Test activity resulting in 2 calls to 791 // ON_RESUME rather than 1. Is such case just check if the Test activity is resumed. 792 // TODO(b/300009006): assertSingleStart when fixed. 793 waitAndAssertResumedActivity(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY); 794 } else { 795 assertSingleStart(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY); 796 } 797 } 798 799 @Test testTurnScreenOnActivity_withRelayout()800 public void testTurnScreenOnActivity_withRelayout() { 801 assumeTrue(supportsLockScreen()); 802 803 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 804 lockScreenSession.sleepDevice(); 805 launchActivity(TURN_SCREEN_ON_WITH_RELAYOUT_ACTIVITY); 806 mWmState.assertVisibility(TURN_SCREEN_ON_WITH_RELAYOUT_ACTIVITY, true); 807 808 lockScreenSession.sleepDevice(); 809 waitAndAssertActivityState(TURN_SCREEN_ON_WITH_RELAYOUT_ACTIVITY, STATE_STOPPED, 810 "Activity should be stopped"); 811 assertFalse("Display keeps off", isDisplayOn(DEFAULT_DISPLAY)); 812 } 813 814 @Test testConvertTranslucentOnTranslucentActivity()815 public void testConvertTranslucentOnTranslucentActivity() { 816 final ActivitySessionClient activityClient = createManagedActivityClientSession(); 817 // Start CONVERT_TRANSLUCENT_DIALOG_ACTIVITY on top of LAUNCHING_ACTIVITY 818 final ActivitySession activity = activityClient.startActivity( 819 getLaunchActivityBuilder().setTargetActivity(TRANSLUCENT_TOP_ACTIVITY)); 820 verifyActivityVisibilities(TRANSLUCENT_TOP_ACTIVITY, false); 821 verifyActivityVisibilities(LAUNCHING_ACTIVITY, false); 822 823 activity.sendCommand(ACTION_CONVERT_FROM_TRANSLUCENT); 824 verifyActivityVisibilities(LAUNCHING_ACTIVITY, true); 825 826 activity.sendCommand(ACTION_CONVERT_TO_TRANSLUCENT); 827 verifyActivityVisibilities(LAUNCHING_ACTIVITY, false); 828 } 829 830 @Test testConvertTranslucentOnNonTopTranslucentActivity()831 public void testConvertTranslucentOnNonTopTranslucentActivity() { 832 final ActivitySessionClient activityClient = createManagedActivityClientSession(); 833 final ActivitySession activity = activityClient.startActivity( 834 getLaunchActivityBuilder().setTargetActivity(TRANSLUCENT_TOP_ACTIVITY)); 835 getLaunchActivityBuilder().setTargetActivity(SHOW_WHEN_LOCKED_DIALOG_ACTIVITY) 836 .setUseInstrumentation().execute(); 837 verifyActivityVisibilities(SHOW_WHEN_LOCKED_DIALOG_ACTIVITY, false); 838 verifyActivityVisibilities(TRANSLUCENT_TOP_ACTIVITY, false); 839 verifyActivityVisibilities(LAUNCHING_ACTIVITY, false); 840 841 activity.sendCommand(ACTION_CONVERT_FROM_TRANSLUCENT); 842 verifyActivityVisibilities(LAUNCHING_ACTIVITY, true); 843 844 activity.sendCommand(ACTION_CONVERT_TO_TRANSLUCENT); 845 verifyActivityVisibilities(LAUNCHING_ACTIVITY, false); 846 } 847 848 @Test testConvertTranslucentOnOpaqueActivity()849 public void testConvertTranslucentOnOpaqueActivity() { 850 final ActivitySessionClient activityClient = createManagedActivityClientSession(); 851 final ActivitySession activity = activityClient.startActivity( 852 getLaunchActivityBuilder().setTargetActivity(TOP_ACTIVITY)); 853 verifyActivityVisibilities(TOP_ACTIVITY, false); 854 verifyActivityVisibilities(LAUNCHING_ACTIVITY, true); 855 856 activity.sendCommand(ACTION_CONVERT_TO_TRANSLUCENT); 857 verifyActivityVisibilities(LAUNCHING_ACTIVITY, false); 858 859 activity.sendCommand(ACTION_CONVERT_FROM_TRANSLUCENT); 860 verifyActivityVisibilities(LAUNCHING_ACTIVITY, true); 861 } 862 863 @Test testConvertTranslucentOnNonTopOpaqueActivity()864 public void testConvertTranslucentOnNonTopOpaqueActivity() { 865 final ActivitySessionClient activityClient = createManagedActivityClientSession(); 866 final ActivitySession activity = activityClient.startActivity( 867 getLaunchActivityBuilder().setTargetActivity(TOP_ACTIVITY)); 868 getLaunchActivityBuilder().setTargetActivity(SHOW_WHEN_LOCKED_DIALOG_ACTIVITY) 869 .setUseInstrumentation().execute(); 870 verifyActivityVisibilities(SHOW_WHEN_LOCKED_DIALOG_ACTIVITY, false); 871 verifyActivityVisibilities(TOP_ACTIVITY, false); 872 verifyActivityVisibilities(LAUNCHING_ACTIVITY, true); 873 874 activity.sendCommand(ACTION_CONVERT_TO_TRANSLUCENT); 875 verifyActivityVisibilities(LAUNCHING_ACTIVITY, false); 876 877 activity.sendCommand(ACTION_CONVERT_FROM_TRANSLUCENT); 878 verifyActivityVisibilities(LAUNCHING_ACTIVITY, true); 879 } 880 verifyActivityVisibilities(ComponentName activityBehind, boolean behindFullScreen)881 private void verifyActivityVisibilities(ComponentName activityBehind, 882 boolean behindFullScreen) { 883 final boolean visible = !behindFullScreen; 884 if (!visible) { 885 mWmState.waitForActivityState(activityBehind, STATE_STOPPED); 886 } else { 887 mWmState.waitForValidState(activityBehind); 888 } 889 mWmState.waitForWindowSurfaceShown(getWindowName(activityBehind), visible); 890 mWmState.assertVisibility(activityBehind, visible); 891 } 892 } 893