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