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.am; 18 19 import static android.server.am.ComponentNameUtils.getActivityName; 20 import static android.server.am.Components.ENTRY_POINT_ALIAS_ACTIVITY; 21 import static android.server.am.Components.SINGLE_TASK_ACTIVITY; 22 import static android.server.am.Components.TEST_ACTIVITY; 23 import static android.server.am.UiDeviceUtils.pressHomeButton; 24 25 import static org.hamcrest.MatcherAssert.assertThat; 26 import static org.hamcrest.Matchers.greaterThanOrEqualTo; 27 import static org.junit.Assert.assertEquals; 28 import static org.junit.Assert.assertNotEquals; 29 import static org.junit.Assert.fail; 30 31 import android.content.ComponentName; 32 33 import org.junit.Test; 34 35 import java.util.regex.Matcher; 36 import java.util.regex.Pattern; 37 38 /** 39 * Build/Install/Run: 40 * atest CtsActivityManagerDeviceTestCases:ActivityManagerAmStartOptionsTests 41 */ 42 public class ActivityManagerAmStartOptionsTests extends ActivityManagerTestBase { 43 44 @Test testDashD()45 public void testDashD() { 46 // Run at least 2 rounds to verify that -D works with an existing process. 47 // -D could fail in this case if the force stop of process is broken. 48 int prevProcId = -1; 49 for (int i = 0; i < 2; i++) { 50 executeShellCommand("am start -n " + getActivityName(TEST_ACTIVITY) + " -D"); 51 52 mAmWmState.waitForDebuggerWindowVisible(TEST_ACTIVITY); 53 int procId = mAmWmState.getAmState().getActivityProcId(TEST_ACTIVITY); 54 55 assertThat("Invalid ProcId.", procId, greaterThanOrEqualTo(0)); 56 if (i > 0) { 57 assertNotEquals("Run " + i + " didn't start new proc.", prevProcId, procId); 58 } 59 prevProcId = procId; 60 } 61 } 62 63 @Test testDashW_Direct()64 public void testDashW_Direct() throws Exception { 65 testDashW(SINGLE_TASK_ACTIVITY, SINGLE_TASK_ACTIVITY); 66 } 67 68 @Test testDashW_Indirect()69 public void testDashW_Indirect() throws Exception { 70 testDashW(ENTRY_POINT_ALIAS_ACTIVITY, SINGLE_TASK_ACTIVITY); 71 } 72 testDashW(final ComponentName entryActivity, final ComponentName actualActivity)73 private void testDashW(final ComponentName entryActivity, final ComponentName actualActivity) 74 throws Exception { 75 // Test cold start 76 startActivityAndVerifyResult(entryActivity, actualActivity, true); 77 78 // Test warm start 79 pressHomeButton(); 80 startActivityAndVerifyResult(entryActivity, actualActivity, false); 81 82 // Test "hot" start (app already in front) 83 startActivityAndVerifyResult(entryActivity, actualActivity, false); 84 } 85 startActivityAndVerifyResult(final ComponentName entryActivity, final ComponentName actualActivity, boolean shouldStart)86 private void startActivityAndVerifyResult(final ComponentName entryActivity, 87 final ComponentName actualActivity, boolean shouldStart) { 88 // See TODO below 89 // final LogSeparator logSeparator = separateLogs(); 90 91 // Pass in different data only when cold starting. This is to make the intent 92 // different in subsequent warm/hot launches, so that the entrypoint alias 93 // activity is always started, but the actual activity is not started again 94 // because of the NEW_TASK and singleTask flags. 95 final String result = executeShellCommand( 96 "am start -n " + getActivityName(entryActivity) + " -W" 97 + (shouldStart ? " -d about:blank" : "")); 98 99 // Verify shell command return value 100 verifyShellOutput(result, actualActivity, shouldStart); 101 102 // TODO: Disable logcat check for now. 103 // Logcat of WM or AM tag could be lost (eg. chatty if earlier events generated 104 // too many lines), and make the test look flaky. We need to either use event 105 // log or swith to other mechanisms. Only verify shell output for now, it should 106 // still catch most failures. 107 108 // Verify adb logcat log 109 //verifyLogcat(actualActivity, shouldStart, logSeparator); 110 } 111 112 private static final Pattern sNotStartedWarningPattern = Pattern.compile( 113 "Warning: Activity not started(.*)"); 114 private static final Pattern sStatusPattern = Pattern.compile( 115 "Status: (.*)"); 116 private static final Pattern sActivityPattern = Pattern.compile( 117 "Activity: (.*)"); 118 private static final String sStatusOk = "ok"; 119 verifyShellOutput( final String result, final ComponentName activity, boolean shouldStart)120 private void verifyShellOutput( 121 final String result, final ComponentName activity, boolean shouldStart) { 122 boolean warningFound = false; 123 String status = null; 124 String reportedActivity = null; 125 126 final String[] lines = result.split("\\n"); 127 // Going from the end of logs to beginning in case if some other activity is started first. 128 for (int i = lines.length - 1; i >= 0; i--) { 129 final String line = lines[i].trim(); 130 Matcher matcher = sNotStartedWarningPattern.matcher(line); 131 if (matcher.matches()) { 132 warningFound = true; 133 continue; 134 } 135 matcher = sStatusPattern.matcher(line); 136 if (matcher.matches()) { 137 status = matcher.group(1); 138 continue; 139 } 140 matcher = sActivityPattern.matcher(line); 141 if (matcher.matches()) { 142 reportedActivity = matcher.group(1); 143 continue; 144 } 145 } 146 147 assertEquals("Status is ok", sStatusOk, status); 148 assertEquals("Reported activity is " + getActivityName(activity), 149 getActivityName(activity), reportedActivity); 150 151 if (shouldStart && warningFound) { 152 fail("Should start new activity but brought something to front."); 153 } else if (!shouldStart && !warningFound){ 154 fail("Should bring existing activity to front but started new activity."); 155 } 156 } 157 } 158