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