blob: 5b85980d3f1cf2330eacdb14743434f5fd67f732 [file] [log] [blame]
Yunfan Chen585f2932019-01-29 16:04:45 +09001/*
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
17package com.android.server.am;
18
19import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
20
21import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
22
23import static org.junit.Assert.assertFalse;
24import static org.junit.Assert.assertTrue;
25import static org.mockito.Mockito.doNothing;
26import static org.mockito.Mockito.doReturn;
27import static org.mockito.Mockito.mock;
28import static org.mockito.Mockito.spy;
29
30import android.content.Context;
31import android.platform.test.annotations.Presubmit;
32
33import androidx.test.filters.FlakyTest;
34
35import com.android.server.wm.ActivityTaskManagerService;
36
37import org.junit.Before;
38import org.junit.BeforeClass;
39import org.junit.Test;
40
41import java.util.Collections;
42
43/**
44 * Build/Install/Run:
45 * atest FrameworksServicesTests:ProcessRecordTests
46 */
47@Presubmit
48@FlakyTest(detail = "Promote to presubmit when shown to be stable.")
49public class ProcessRecordTests {
50 private static Context sContext;
51 private static ActivityManagerService sService;
52
53 private ProcessRecord mProcessRecord;
54
55 @BeforeClass
56 public static void setUpOnce() throws Exception {
57 sContext = getInstrumentation().getTargetContext();
58
59 // We need to run with dexmaker share class loader to make use of ActivityTaskManagerService
60 // from wm package.
61 runWithDexmakerShareClassLoader(() -> {
62 sService = mock(ActivityManagerService.class);
63 sService.mActivityTaskManager = new ActivityTaskManagerService(sContext);
64 sService.mActivityTaskManager.initialize(null, null, sContext.getMainLooper());
65 sService.mAtmInternal = sService.mActivityTaskManager.getAtmInternal();
66 });
67 }
68
69 @Before
70 public void setUpProcess() throws Exception {
71 // Need to run with dexmaker share class loader to mock package private class.
72 runWithDexmakerShareClassLoader(() -> {
73 mProcessRecord = spy(new ProcessRecord(sService, sContext.getApplicationInfo(),
74 "name", 12345));
75 doNothing().when(mProcessRecord).startAppProblemLocked();
76 doReturn(false).when(mProcessRecord).isSilentAnr();
77 doReturn(false).when(mProcessRecord).isMonitorCpuUsage();
78 doReturn(Collections.emptyList()).when(mProcessRecord).getLruProcessList();
79 });
80 }
81
82
83 /**
84 * This test verifies the process default status. If this doesn't pass, none of the other tests
85 * should be able to pass.
86 */
87 @Test
88 public void testProcessDefaultAnrRelatedStatus() {
89 assertFalse(mProcessRecord.isNotResponding());
90 assertFalse(mProcessRecord.isCrashing());
91 assertFalse(mProcessRecord.killedByAm);
92 assertFalse(mProcessRecord.killed);
93 }
94
95 /**
96 * This test verifies that if the process is crashing, Anr will do nothing.
97 */
98 @Test
99 public void testAnrWhenCrash() {
100 mProcessRecord.setCrashing(true);
101 assertTrue(mProcessRecord.isCrashing());
102 mProcessRecord.appNotResponding(null, null, null, null, false, "Test ANR when crash");
103 assertFalse(mProcessRecord.isNotResponding());
104 assertFalse(mProcessRecord.killedByAm);
105 assertFalse(mProcessRecord.killed);
106 }
107
108 /**
109 * This test verifies that if the process is killed by AM, Anr will do nothing.
110 */
111 @Test
112 public void testAnrWhenKilledByAm() {
113 mProcessRecord.killedByAm = true;
114 mProcessRecord.appNotResponding(null, null, null, null, false,
115 "Test ANR when killed by AM");
116 assertFalse(mProcessRecord.isNotResponding());
117 assertFalse(mProcessRecord.isCrashing());
118 assertFalse(mProcessRecord.killed);
119 }
120
121 /**
122 * This test verifies that if the process is killed, Anr will do nothing.
123 */
124 @Test
125 public void testAnrWhenKilled() {
126 mProcessRecord.killed = true;
127 mProcessRecord.appNotResponding(null, null, null, null, false, "Test ANR when killed");
128 assertFalse(mProcessRecord.isNotResponding());
129 assertFalse(mProcessRecord.isCrashing());
130 assertFalse(mProcessRecord.killedByAm);
131 }
132
133 /**
134 * This test verifies that non-silent ANR can run through successfully and the corresponding
135 * flags can be set correctly.
136 */
137 @Test
138 public void testNonSilentAnr() {
139 mProcessRecord.appNotResponding(null, null, null, null, false, "Test non-silent ANR");
140 assertTrue(mProcessRecord.isNotResponding());
141 assertFalse(mProcessRecord.isCrashing());
142 assertFalse(mProcessRecord.killedByAm);
143 assertFalse(mProcessRecord.killed);
144 }
145
146 /**
147 * This test verifies that silent ANR can run through successfully and the corresponding flags
148 * can be set correctly.
149 */
150 @Test
151 public void testSilentAnr() {
152 // Silent Anr will run through even without a parent process, and directly killed by AM.
153 doReturn(true).when(mProcessRecord).isSilentAnr();
154 mProcessRecord.appNotResponding(null, null, null, null, false, "Test silent ANR");
155 assertTrue(mProcessRecord.isNotResponding());
156 assertFalse(mProcessRecord.isCrashing());
157 assertTrue(mProcessRecord.killedByAm);
158 assertTrue(mProcessRecord.killed);
159 }
160}