• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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