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