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.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
20 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
21 import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
22 import static android.server.wm.ComponentNameUtils.getActivityName;
23 import static android.server.wm.app.Components.ENTRY_POINT_ALIAS_ACTIVITY;
24 import static android.server.wm.app.Components.LAUNCHING_ACTIVITY;
25 import static android.server.wm.app.Components.SINGLE_TASK_ACTIVITY;
26 import static android.server.wm.app.Components.TEST_ACTIVITY;
27 import static android.view.Display.DEFAULT_DISPLAY;
28 
29 import static org.hamcrest.MatcherAssert.assertThat;
30 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
31 import static org.junit.Assert.assertNotEquals;
32 
33 import android.content.ComponentName;
34 import android.platform.test.annotations.Presubmit;
35 
36 import org.junit.Test;
37 
38 /**
39  * Build/Install/Run:
40  *     atest CtsWindowManagerDeviceTestCases:AmStartOptionsTests
41  */
42 @Presubmit
43 public class AmStartOptionsTests extends ActivityManagerTestBase {
44 
45     @Test
testDashD()46     public void testDashD() {
47         // Run at least 2 rounds to verify that -D works with an existing process.
48         // -D could fail in this case if the force stop of process is broken.
49         int prevProcId = -1;
50         for (int i = 0; i < 2; i++) {
51             executeShellCommand("am start -n " + getActivityName(TEST_ACTIVITY) + " -D");
52 
53             mWmState.waitForDebuggerWindowVisible(TEST_ACTIVITY);
54             int procId = mWmState.getActivityProcId(TEST_ACTIVITY);
55 
56             assertThat("Invalid ProcId.", procId, greaterThanOrEqualTo(0));
57             if (i > 0) {
58                 assertNotEquals("Run " + i + " didn't start new proc.", prevProcId, procId);
59             }
60             prevProcId = procId;
61         }
62     }
63 
64     @Test
testDashW_Direct()65     public void testDashW_Direct() throws Exception {
66         testDashW(SINGLE_TASK_ACTIVITY, SINGLE_TASK_ACTIVITY);
67     }
68 
69     @Test
testDashW_Indirect()70     public void testDashW_Indirect() throws Exception {
71         testDashW(ENTRY_POINT_ALIAS_ACTIVITY, SINGLE_TASK_ACTIVITY);
72     }
73 
74     @Test
testDashW_FinishingTop()75     public void testDashW_FinishingTop() {
76         // Start LaunchingActivity and TestActivity
77         getLaunchActivityBuilder().setLaunchingActivity(LAUNCHING_ACTIVITY)
78                 .setTargetActivity(TEST_ACTIVITY).execute();
79 
80         // Return to home
81         launchHomeActivity();
82 
83         // Start LaunchingActivity again and finish TestActivity
84         final int flags =
85                 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP;
86         executeShellCommand("am start -W -f " + flags + " -n " + getActivityName(LAUNCHING_ACTIVITY)
87                 + " --display " + DEFAULT_DISPLAY);
88         waitAndAssertTopResumedActivity(LAUNCHING_ACTIVITY, DEFAULT_DISPLAY,
89                 "Activity must be launched.");
90     }
91 
testDashW(final ComponentName entryActivity, final ComponentName actualActivity)92     private void testDashW(final ComponentName entryActivity, final ComponentName actualActivity)
93             throws Exception {
94         // Test cold start
95         startActivityAndVerifyResult(entryActivity, actualActivity, true);
96 
97         // Test warm start
98         launchHomeActivity();
99         startActivityAndVerifyResult(entryActivity, actualActivity, false);
100 
101         // Test "hot" start (app already in front)
102         startActivityAndVerifyResult(entryActivity, actualActivity, false);
103     }
104 
startActivityAndVerifyResult(final ComponentName entryActivity, final ComponentName actualActivity, boolean shouldStart)105     private void startActivityAndVerifyResult(final ComponentName entryActivity,
106             final ComponentName actualActivity, boolean shouldStart) {
107         mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
108 
109         // Pass in different data only when cold starting. This is to make the intent
110         // different in subsequent warm/hot launches, so that the entrypoint alias
111         // activity is always started, but the actual activity is not started again
112         // because of the NEW_TASK and singleTask flags.
113         executeShellCommand("am start -n " + getActivityName(entryActivity) + " -W --display "
114                 + DEFAULT_DISPLAY + (shouldStart ? " -d about:blank" : ""));
115 
116         waitAndAssertTopResumedActivity(actualActivity, DEFAULT_DISPLAY,
117                 "Activity must be launched");
118     }
119 }
120