• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.server.wm.app.Components.HOST_ACTIVITY;
20 import static android.server.wm.app.Components.UNRESPONSIVE_ACTIVITY;
21 import static android.server.wm.app.Components.UnresponsiveActivity;
22 import static android.server.wm.app.Components.UnresponsiveActivity.EXTRA_DELAY_UI_THREAD_MS;
23 import static android.server.wm.app.Components.UnresponsiveActivity.EXTRA_ON_CREATE_DELAY_MS;
24 import static android.server.wm.app.Components.UnresponsiveActivity.EXTRA_ON_KEYDOWN_DELAY_MS;
25 import static android.server.wm.app.Components.UnresponsiveActivity.EXTRA_ON_MOTIONEVENT_DELAY_MS;
26 import static android.view.Display.DEFAULT_DISPLAY;
27 
28 import static org.junit.Assert.fail;
29 import static org.junit.Assume.assumeTrue;
30 
31 import android.app.ActivityTaskManager;
32 import android.content.ComponentName;
33 import android.os.SystemClock;
34 import android.platform.test.annotations.Presubmit;
35 import android.server.wm.app.Components.RenderService;
36 import android.provider.Settings;
37 import android.server.wm.settings.SettingsSession;
38 import android.support.test.uiautomator.By;
39 import android.support.test.uiautomator.UiDevice;
40 import android.support.test.uiautomator.UiObject2;
41 import android.support.test.uiautomator.Until;
42 import android.util.EventLog;
43 import android.util.Log;
44 import android.view.KeyEvent;
45 
46 import org.junit.After;
47 import org.junit.Before;
48 import org.junit.Test;
49 
50 import java.util.List;
51 
52 import androidx.test.filters.FlakyTest;
53 import androidx.test.platform.app.InstrumentationRegistry;
54 
55 /**
56  * Test scenarios that lead to ANR dialog being shown.
57  *
58  * <p>Build/Install/Run:
59  *     atest CtsWindowManagerDeviceTestCases:AnrTests
60  */
61 @Presubmit
62 @FlakyTest(bugId = 143047723)
63 @android.server.wm.annotation.Group3
64 public class AnrTests extends ActivityManagerTestBase {
65     private static final String TAG = "AnrTests";
66     private LogSeparator mLogSeparator;
67     private SettingsSession<Integer> mHideDialogSetting;
68 
69     @Before
setup()70     public void setup() throws Exception {
71         super.setUp();
72         assumeTrue(mAtm.currentUiModeSupportsErrorDialogs(mContext));
73 
74         mLogSeparator = separateLogs(); // add a new separator for logs
75         mHideDialogSetting = new SettingsSession<>(
76                 Settings.Global.getUriFor(Settings.Global.HIDE_ERROR_DIALOGS),
77                 Settings.Global::getInt, Settings.Global::putInt);
78         mHideDialogSetting.set(0);
79     }
80 
81     @After
teardown()82     public void teardown() {
83         if (mHideDialogSetting != null) mHideDialogSetting.close();
84         stopTestPackage(UNRESPONSIVE_ACTIVITY.getPackageName());
85         stopTestPackage(HOST_ACTIVITY.getPackageName());
86     }
87 
88     @Test
slowOnCreateWithKeyEventTriggersAnr()89     public void slowOnCreateWithKeyEventTriggersAnr() {
90         startUnresponsiveActivity(EXTRA_ON_CREATE_DELAY_MS, false /* waitForCompletion */,
91                 UNRESPONSIVE_ACTIVITY);
92         // wait for app to be focused
93         mWmState.waitAndAssertAppFocus(UNRESPONSIVE_ACTIVITY.getPackageName(),
94                 2000 /* waitTime_ms */);
95         // wait for input manager to get the new focus app. This sleep can be removed once we start
96         // listing to input about the focused app.
97         SystemClock.sleep(500);
98         injectKey(KeyEvent.KEYCODE_BACK, false /* longpress */, false /* sync */);
99         clickCloseAppOnAnrDialog();
100         assertEventLogsContainsAnr(UnresponsiveActivity.PROCESS_NAME);
101     }
102 
103     @Test
slowUiThreadWithKeyEventTriggersAnr()104     public void slowUiThreadWithKeyEventTriggersAnr() {
105         startUnresponsiveActivity(EXTRA_DELAY_UI_THREAD_MS, true /* waitForCompletion */,
106                 UNRESPONSIVE_ACTIVITY);
107         injectKey(KeyEvent.KEYCODE_BACK, false /* longpress */, false /* sync */);
108         clickCloseAppOnAnrDialog();
109         assertEventLogsContainsAnr(UnresponsiveActivity.PROCESS_NAME);
110     }
111 
112     @Test
slowOnKeyEventHandleTriggersAnr()113     public void slowOnKeyEventHandleTriggersAnr() {
114         startUnresponsiveActivity(EXTRA_ON_KEYDOWN_DELAY_MS, true /* waitForCompletion */,
115                 UNRESPONSIVE_ACTIVITY);
116         injectKey(KeyEvent.KEYCODE_BACK, false /* longpress */, false /* sync */);
117         clickCloseAppOnAnrDialog();
118         assertEventLogsContainsAnr(UnresponsiveActivity.PROCESS_NAME);
119     }
120 
121     @Test
slowOnTouchEventHandleTriggersAnr()122     public void slowOnTouchEventHandleTriggersAnr() {
123         startUnresponsiveActivity(EXTRA_ON_MOTIONEVENT_DELAY_MS, true /* waitForCompletion */,
124                 UNRESPONSIVE_ACTIVITY);
125 
126         // TODO(b/143566069) investigate why we need multiple taps on display to trigger anr.
127         mWmState.computeState();
128         tapOnDisplayCenterAsync(DEFAULT_DISPLAY);
129         SystemClock.sleep(1000);
130         tapOnDisplayCenterAsync(DEFAULT_DISPLAY);
131 
132         clickCloseAppOnAnrDialog();
133         assertEventLogsContainsAnr(UnresponsiveActivity.PROCESS_NAME);
134     }
135 
136     /**
137      * Verify embedded windows can trigger ANR and the verify embedded app is blamed.
138      */
139     @Test
embeddedWindowTriggersAnr()140     public void embeddedWindowTriggersAnr() {
141         startUnresponsiveActivity(EXTRA_ON_MOTIONEVENT_DELAY_MS, true  /* waitForCompletion */,
142                 HOST_ACTIVITY);
143 
144         // TODO(b/143566069) investigate why we need multiple taps on display to trigger anr.
145         mWmState.computeState();
146         tapOnDisplayCenterAsync(DEFAULT_DISPLAY);
147         SystemClock.sleep(1000);
148         tapOnDisplayCenterAsync(DEFAULT_DISPLAY);
149 
150         clickCloseAppOnAnrDialog();
151         assertEventLogsContainsAnr(RenderService.PROCESS_NAME);
152     }
153 
assertEventLogsContainsAnr(String processName)154     private void assertEventLogsContainsAnr(String processName) {
155         final List<EventLog.Event> events = getEventLogsForComponents(mLogSeparator,
156                 android.util.EventLog.getTagCode("am_anr"));
157         for (EventLog.Event event : events) {
158             Object[] arr = (Object[]) event.getData();
159             final String name = (String) arr[2];
160             if (name.equals(processName)) {
161                 return;
162             }
163         }
164         fail("Could not find anr kill event for " + processName);
165     }
166 
clickCloseAppOnAnrDialog()167     private void clickCloseAppOnAnrDialog() {
168         // Find anr dialog and kill app
169         UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
170         UiObject2 closeAppButton = uiDevice.wait(Until.findObject(By.res("android:id/aerr_close")),
171                 20000);
172         if (closeAppButton != null) {
173             Log.d(TAG, "found permission dialog after searching all windows, clicked");
174             closeAppButton.click();
175             return;
176         }
177         fail("Could not find anr dialog");
178     }
179 
startUnresponsiveActivity(String delayTypeExtra, boolean waitForCompletion, ComponentName activity)180     private void startUnresponsiveActivity(String delayTypeExtra, boolean waitForCompletion,
181             ComponentName activity) {
182         String flags = waitForCompletion ? " -W -n " : " -n ";
183         String startCmd = "am start" + flags + activity.flattenToString() +
184                 " --ei " + delayTypeExtra + " 30000";
185         executeShellCommand(startCmd);
186     }
187 }
188