blob: 1ff6f4dac724f9c96c96237f5926ffabc7e1838b [file] [log] [blame]
Adrian Roos20d7df32016-01-12 18:59:43 +01001/*
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
17package com.android.server.am;
18
Wale Ogunwale64258362018-10-16 15:13:37 -070019import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Wale Ogunwale59507092018-10-29 09:00:30 -070020import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
Adrian Roos86cb6392018-12-13 16:42:43 +010021
Makoto Onukie276b442018-08-30 09:38:44 -070022import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
23import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
24import static com.android.server.am.ActivityManagerService.MY_PID;
25import static com.android.server.am.ActivityManagerService.SYSTEM_DEBUGGABLE;
Wale Ogunwale59507092018-10-29 09:00:30 -070026import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
27import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Adrian Roos20d7df32016-01-12 18:59:43 +010028
Adrian Roos20d7df32016-01-12 18:59:43 +010029import android.app.ActivityManager;
30import android.app.ActivityOptions;
Adrian Roos20d7df32016-01-12 18:59:43 +010031import android.app.ApplicationErrorReport;
32import android.app.Dialog;
33import android.content.ActivityNotFoundException;
34import android.content.Context;
35import android.content.Intent;
36import android.content.pm.ApplicationInfo;
bpetrivs0254ff62019-03-01 11:50:45 +000037import android.content.pm.ModuleInfo;
38import android.content.pm.PackageManager;
Zimuzo972e1cd2019-01-28 16:30:01 +000039import android.content.pm.VersionedPackage;
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080040import android.net.Uri;
Adrian Roos20d7df32016-01-12 18:59:43 +010041import android.os.Binder;
Adrian Roos20d7df32016-01-12 18:59:43 +010042import android.os.Message;
43import android.os.Process;
Adrian Roos20d7df32016-01-12 18:59:43 +010044import android.os.SystemClock;
45import android.os.SystemProperties;
46import android.os.UserHandle;
47import android.provider.Settings;
48import android.util.ArrayMap;
49import android.util.ArraySet;
50import android.util.EventLog;
Adrian Roos20d7df32016-01-12 18:59:43 +010051import android.util.Slog;
52import android.util.SparseArray;
53import android.util.TimeUtils;
Yi Jin148d7f42017-11-28 14:23:56 -080054import android.util.proto.ProtoOutputStream;
Adrian Roos20d7df32016-01-12 18:59:43 +010055
Makoto Onukie276b442018-08-30 09:38:44 -070056import com.android.internal.app.ProcessMap;
57import com.android.internal.logging.MetricsLogger;
58import com.android.internal.logging.nano.MetricsProto;
Zimuzo6efba542018-11-29 12:47:58 +000059import com.android.server.PackageWatchdog;
Makoto Onukie276b442018-08-30 09:38:44 -070060import com.android.server.RescueParty;
Wale Ogunwale59507092018-10-29 09:00:30 -070061import com.android.server.wm.WindowProcessController;
Makoto Onukie276b442018-08-30 09:38:44 -070062
Adrian Roos20d7df32016-01-12 18:59:43 +010063import java.io.FileDescriptor;
64import java.io.PrintWriter;
Adrian Roos20d7df32016-01-12 18:59:43 +010065import java.util.Collections;
Zimuzo972e1cd2019-01-28 16:30:01 +000066import java.util.List;
Adrian Roos20d7df32016-01-12 18:59:43 +010067
Adrian Roos20d7df32016-01-12 18:59:43 +010068/**
69 * Controls error conditions in applications.
70 */
71class AppErrors {
72
73 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppErrors" : TAG_AM;
74
75 private final ActivityManagerService mService;
76 private final Context mContext;
Zimuzo6efba542018-11-29 12:47:58 +000077 private final PackageWatchdog mPackageWatchdog;
Adrian Roos20d7df32016-01-12 18:59:43 +010078
79 private ArraySet<String> mAppsNotReportingCrashes;
80
81 /**
82 * The last time that various processes have crashed since they were last explicitly started.
83 */
84 private final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<>();
85
86 /**
87 * The last time that various processes have crashed (not reset even when explicitly started).
88 */
89 private final ProcessMap<Long> mProcessCrashTimesPersistent = new ProcessMap<>();
90
91 /**
92 * Set of applications that we consider to be bad, and will reject
93 * incoming broadcasts from (which the user has no control over).
94 * Processes are added to this set when they have crashed twice within
95 * a minimum amount of time; they are removed from it when they are
96 * later restarted (hopefully due to some user action). The value is the
97 * time it was added to the list.
98 */
99 private final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>();
100
101
Zimuzo6efba542018-11-29 12:47:58 +0000102 AppErrors(Context context, ActivityManagerService service, PackageWatchdog watchdog) {
Adam Lesinskia82b6262017-03-21 16:56:17 -0700103 context.assertRuntimeOverlayThemable();
Adrian Roos20d7df32016-01-12 18:59:43 +0100104 mService = service;
105 mContext = context;
Zimuzo6efba542018-11-29 12:47:58 +0000106 mPackageWatchdog = watchdog;
Adrian Roos20d7df32016-01-12 18:59:43 +0100107 }
108
Yi Jin148d7f42017-11-28 14:23:56 -0800109 void writeToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
110 if (mProcessCrashTimes.getMap().isEmpty() && mBadProcesses.getMap().isEmpty()) {
111 return;
112 }
113
114 final long token = proto.start(fieldId);
115 final long now = SystemClock.uptimeMillis();
116 proto.write(AppErrorsProto.NOW_UPTIME_MS, now);
117
118 if (!mProcessCrashTimes.getMap().isEmpty()) {
119 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
120 final int procCount = pmap.size();
121 for (int ip = 0; ip < procCount; ip++) {
122 final long ctoken = proto.start(AppErrorsProto.PROCESS_CRASH_TIMES);
123 final String pname = pmap.keyAt(ip);
124 final SparseArray<Long> uids = pmap.valueAt(ip);
125 final int uidCount = uids.size();
126
127 proto.write(AppErrorsProto.ProcessCrashTime.PROCESS_NAME, pname);
128 for (int i = 0; i < uidCount; i++) {
129 final int puid = uids.keyAt(i);
Amith Yamasani98a00922018-08-21 12:50:30 -0400130 final ProcessRecord r = mService.getProcessNames().get(pname, puid);
Yi Jin148d7f42017-11-28 14:23:56 -0800131 if (dumpPackage != null && (r == null || !r.pkgList.containsKey(dumpPackage))) {
132 continue;
133 }
134 final long etoken = proto.start(AppErrorsProto.ProcessCrashTime.ENTRIES);
135 proto.write(AppErrorsProto.ProcessCrashTime.Entry.UID, puid);
136 proto.write(AppErrorsProto.ProcessCrashTime.Entry.LAST_CRASHED_AT_MS,
137 uids.valueAt(i));
138 proto.end(etoken);
139 }
140 proto.end(ctoken);
141 }
142
143 }
144
145 if (!mBadProcesses.getMap().isEmpty()) {
146 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
147 final int processCount = pmap.size();
148 for (int ip = 0; ip < processCount; ip++) {
149 final long btoken = proto.start(AppErrorsProto.BAD_PROCESSES);
150 final String pname = pmap.keyAt(ip);
151 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
152 final int uidCount = uids.size();
153
154 proto.write(AppErrorsProto.BadProcess.PROCESS_NAME, pname);
155 for (int i = 0; i < uidCount; i++) {
156 final int puid = uids.keyAt(i);
Amith Yamasani98a00922018-08-21 12:50:30 -0400157 final ProcessRecord r = mService.getProcessNames().get(pname, puid);
Yi Jin148d7f42017-11-28 14:23:56 -0800158 if (dumpPackage != null && (r == null
159 || !r.pkgList.containsKey(dumpPackage))) {
160 continue;
161 }
162 final BadProcessInfo info = uids.valueAt(i);
163 final long etoken = proto.start(AppErrorsProto.BadProcess.ENTRIES);
164 proto.write(AppErrorsProto.BadProcess.Entry.UID, puid);
165 proto.write(AppErrorsProto.BadProcess.Entry.CRASHED_AT_MS, info.time);
166 proto.write(AppErrorsProto.BadProcess.Entry.SHORT_MSG, info.shortMsg);
167 proto.write(AppErrorsProto.BadProcess.Entry.LONG_MSG, info.longMsg);
168 proto.write(AppErrorsProto.BadProcess.Entry.STACK, info.stack);
169 proto.end(etoken);
170 }
171 proto.end(btoken);
172 }
173 }
174
175 proto.end(token);
176 }
177
178 boolean dumpLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, String dumpPackage) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100179 if (!mProcessCrashTimes.getMap().isEmpty()) {
180 boolean printed = false;
181 final long now = SystemClock.uptimeMillis();
182 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
183 final int processCount = pmap.size();
184 for (int ip = 0; ip < processCount; ip++) {
185 final String pname = pmap.keyAt(ip);
186 final SparseArray<Long> uids = pmap.valueAt(ip);
187 final int uidCount = uids.size();
188 for (int i = 0; i < uidCount; i++) {
189 final int puid = uids.keyAt(i);
Amith Yamasani98a00922018-08-21 12:50:30 -0400190 final ProcessRecord r = mService.getProcessNames().get(pname, puid);
Adrian Roos20d7df32016-01-12 18:59:43 +0100191 if (dumpPackage != null && (r == null
192 || !r.pkgList.containsKey(dumpPackage))) {
193 continue;
194 }
195 if (!printed) {
196 if (needSep) pw.println();
197 needSep = true;
198 pw.println(" Time since processes crashed:");
199 printed = true;
200 }
201 pw.print(" Process "); pw.print(pname);
202 pw.print(" uid "); pw.print(puid);
203 pw.print(": last crashed ");
204 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
205 pw.println(" ago");
206 }
207 }
208 }
209
210 if (!mBadProcesses.getMap().isEmpty()) {
211 boolean printed = false;
212 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
213 final int processCount = pmap.size();
214 for (int ip = 0; ip < processCount; ip++) {
215 final String pname = pmap.keyAt(ip);
216 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
217 final int uidCount = uids.size();
218 for (int i = 0; i < uidCount; i++) {
219 final int puid = uids.keyAt(i);
Amith Yamasani98a00922018-08-21 12:50:30 -0400220 final ProcessRecord r = mService.getProcessNames().get(pname, puid);
Adrian Roos20d7df32016-01-12 18:59:43 +0100221 if (dumpPackage != null && (r == null
222 || !r.pkgList.containsKey(dumpPackage))) {
223 continue;
224 }
225 if (!printed) {
226 if (needSep) pw.println();
227 needSep = true;
228 pw.println(" Bad processes:");
229 printed = true;
230 }
231 final BadProcessInfo info = uids.valueAt(i);
232 pw.print(" Bad process "); pw.print(pname);
233 pw.print(" uid "); pw.print(puid);
234 pw.print(": crashed at time "); pw.println(info.time);
235 if (info.shortMsg != null) {
236 pw.print(" Short msg: "); pw.println(info.shortMsg);
237 }
238 if (info.longMsg != null) {
239 pw.print(" Long msg: "); pw.println(info.longMsg);
240 }
241 if (info.stack != null) {
242 pw.println(" Stack:");
243 int lastPos = 0;
244 for (int pos = 0; pos < info.stack.length(); pos++) {
245 if (info.stack.charAt(pos) == '\n') {
246 pw.print(" ");
247 pw.write(info.stack, lastPos, pos-lastPos);
248 pw.println();
249 lastPos = pos+1;
250 }
251 }
252 if (lastPos < info.stack.length()) {
253 pw.print(" ");
254 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
255 pw.println();
256 }
257 }
258 }
259 }
260 }
261 return needSep;
262 }
263
264 boolean isBadProcessLocked(ApplicationInfo info) {
265 return mBadProcesses.get(info.processName, info.uid) != null;
266 }
267
268 void clearBadProcessLocked(ApplicationInfo info) {
269 mBadProcesses.remove(info.processName, info.uid);
270 }
271
272 void resetProcessCrashTimeLocked(ApplicationInfo info) {
273 mProcessCrashTimes.remove(info.processName, info.uid);
274 }
275
276 void resetProcessCrashTimeLocked(boolean resetEntireUser, int appId, int userId) {
277 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
278 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
279 SparseArray<Long> ba = pmap.valueAt(ip);
280 for (int i = ba.size() - 1; i >= 0; i--) {
281 boolean remove = false;
282 final int entUid = ba.keyAt(i);
283 if (!resetEntireUser) {
284 if (userId == UserHandle.USER_ALL) {
285 if (UserHandle.getAppId(entUid) == appId) {
286 remove = true;
287 }
288 } else {
289 if (entUid == UserHandle.getUid(userId, appId)) {
290 remove = true;
291 }
292 }
293 } else if (UserHandle.getUserId(entUid) == userId) {
294 remove = true;
295 }
296 if (remove) {
297 ba.removeAt(i);
298 }
299 }
300 if (ba.size() == 0) {
301 pmap.removeAt(ip);
302 }
303 }
304 }
305
306 void loadAppsNotReportingCrashesFromConfigLocked(String appsNotReportingCrashesConfig) {
307 if (appsNotReportingCrashesConfig != null) {
308 final String[] split = appsNotReportingCrashesConfig.split(",");
309 if (split.length > 0) {
310 mAppsNotReportingCrashes = new ArraySet<>();
311 Collections.addAll(mAppsNotReportingCrashes, split);
312 }
313 }
314 }
315
316 void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700317 app.setCrashing(false);
Adrian Roos20d7df32016-01-12 18:59:43 +0100318 app.crashingReport = null;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700319 app.setNotResponding(false);
Adrian Roos20d7df32016-01-12 18:59:43 +0100320 app.notRespondingReport = null;
321 if (app.anrDialog == fromDialog) {
322 app.anrDialog = null;
323 }
324 if (app.waitDialog == fromDialog) {
325 app.waitDialog = null;
326 }
327 if (app.pid > 0 && app.pid != MY_PID) {
328 handleAppCrashLocked(app, "user-terminated" /*reason*/,
329 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
330 app.kill("user request after error", true);
331 }
332 }
333
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800334 /**
335 * Induce a crash in the given app.
336 *
337 * @param uid if nonnegative, the required matching uid of the target to crash
338 * @param initialPid fast-path match for the target to crash
339 * @param packageName fallback match if the stated pid is not found or doesn't match uid
340 * @param userId If nonnegative, required to identify a match by package name
341 * @param message
342 */
343 void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
Adrian Roos20d7df32016-01-12 18:59:43 +0100344 String message) {
345 ProcessRecord proc = null;
346
347 // Figure out which process to kill. We don't trust that initialPid
348 // still has any relation to current pids, so must scan through the
349 // list.
350
351 synchronized (mService.mPidsSelfLocked) {
352 for (int i=0; i<mService.mPidsSelfLocked.size(); i++) {
353 ProcessRecord p = mService.mPidsSelfLocked.valueAt(i);
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800354 if (uid >= 0 && p.uid != uid) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100355 continue;
356 }
357 if (p.pid == initialPid) {
358 proc = p;
359 break;
360 }
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800361 if (p.pkgList.containsKey(packageName)
362 && (userId < 0 || p.userId == userId)) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100363 proc = p;
364 }
365 }
366 }
367
368 if (proc == null) {
369 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
370 + " initialPid=" + initialPid
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800371 + " packageName=" + packageName
372 + " userId=" + userId);
Adrian Roos20d7df32016-01-12 18:59:43 +0100373 return;
374 }
375
Joe Onorato57190282016-04-20 15:37:49 -0700376 proc.scheduleCrash(message);
Adrian Roos20d7df32016-01-12 18:59:43 +0100377 }
378
379 /**
380 * Bring up the "unexpected error" dialog box for a crashing app.
381 * Deal with edge cases (intercepts from instrumented applications,
382 * ActivityController, error intent receivers, that sort of thing).
383 * @param r the application crashing
384 * @param crashInfo describing the failure
385 */
386 void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Mark Lub5e24992016-11-21 15:38:13 +0800387 final int callingPid = Binder.getCallingPid();
388 final int callingUid = Binder.getCallingUid();
389
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700390 final long origId = Binder.clearCallingIdentity();
391 try {
Mark Lub5e24992016-11-21 15:38:13 +0800392 crashApplicationInner(r, crashInfo, callingPid, callingUid);
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700393 } finally {
394 Binder.restoreCallingIdentity(origId);
395 }
396 }
397
Mark Lub5e24992016-11-21 15:38:13 +0800398 void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo,
399 int callingPid, int callingUid) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100400 long timeMillis = System.currentTimeMillis();
401 String shortMsg = crashInfo.exceptionClassName;
402 String longMsg = crashInfo.exceptionMessage;
403 String stackTrace = crashInfo.stackTrace;
404 if (shortMsg != null && longMsg != null) {
405 longMsg = shortMsg + ": " + longMsg;
406 } else if (shortMsg != null) {
407 longMsg = shortMsg;
408 }
409
Zimuzo6efba542018-11-29 12:47:58 +0000410 if (r != null) {
bpetrivs0254ff62019-03-01 11:50:45 +0000411 boolean isApexModule = false;
412 try {
413 for (String androidPackage : r.getPackageList()) {
414 ModuleInfo moduleInfo = mContext.getPackageManager().getModuleInfo(
415 androidPackage, /*flags=*/ 0);
416 if (moduleInfo != null) {
417 isApexModule = true;
418 break;
419 }
420 }
421 } catch (IllegalStateException | PackageManager.NameNotFoundException e) {
422 // Call to PackageManager#getModuleInfo() can result in NameNotFoundException or
423 // IllegalStateException. In case they are thrown, there isn't much we can do
424 // other than proceed with app crash handling.
Zimuzo6efba542018-11-29 12:47:58 +0000425 }
bpetrivs0254ff62019-03-01 11:50:45 +0000426
427 if (r.isPersistent() || isApexModule) {
428 // If a persistent app or apex module is stuck in a crash loop, the device isn't
429 // very usable, so we want to consider sending out a rescue party.
430 RescueParty.noteAppCrash(mContext, r.uid);
431 }
432
433 mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode());
Jeff Sharkeyfe6f85c2017-01-20 10:42:57 -0700434 }
435
Garfield Tan2746ab52018-07-25 12:33:01 -0700436 final int relaunchReason = r != null
Wale Ogunwale64258362018-10-16 15:13:37 -0700437 ? r.getWindowProcessController().computeRelaunchReason() : RELAUNCH_REASON_NONE;
Garfield Tan2746ab52018-07-25 12:33:01 -0700438
Adrian Roos20d7df32016-01-12 18:59:43 +0100439 AppErrorResult result = new AppErrorResult();
Wale Ogunwale64258362018-10-16 15:13:37 -0700440 int taskId;
Adrian Roos20d7df32016-01-12 18:59:43 +0100441 synchronized (mService) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700442 /**
443 * If crash is handled by instance of {@link android.app.IActivityController},
444 * finish now and don't show the app error dialog.
445 */
446 if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace,
Mark Lub5e24992016-11-21 15:38:13 +0800447 timeMillis, callingPid, callingUid)) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700448 return;
Adrian Roos20d7df32016-01-12 18:59:43 +0100449 }
450
Garfield Tan2746ab52018-07-25 12:33:01 -0700451 // Suppress crash dialog if the process is being relaunched due to a crash during a free
452 // resize.
Wale Ogunwale64258362018-10-16 15:13:37 -0700453 if (relaunchReason == RELAUNCH_REASON_FREE_RESIZE) {
Garfield Tan2746ab52018-07-25 12:33:01 -0700454 return;
455 }
456
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700457 /**
458 * If this process was running instrumentation, finish now - it will be handled in
459 * {@link ActivityManagerService#handleAppDiedLocked}.
460 */
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700461 if (r != null && r.getActiveInstrumentation() != null) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100462 return;
463 }
464
465 // Log crash in battery stats.
466 if (r != null) {
467 mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
468 }
469
470 AppErrorDialog.Data data = new AppErrorDialog.Data();
471 data.result = result;
472 data.proc = r;
473
474 // If we can't identify the process or it's already exceeded its crash quota,
475 // quit right away without showing a crash dialog.
476 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100477 return;
478 }
479
Wale Ogunwale9645b0f2016-09-12 10:49:35 -0700480 final Message msg = Message.obtain();
Adrian Roos20d7df32016-01-12 18:59:43 +0100481 msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
482
Wale Ogunwale64258362018-10-16 15:13:37 -0700483 taskId = data.taskId;
Adrian Roos20d7df32016-01-12 18:59:43 +0100484 msg.obj = data;
485 mService.mUiHandler.sendMessage(msg);
Adrian Roos20d7df32016-01-12 18:59:43 +0100486 }
487
488 int res = result.get();
489
490 Intent appErrorIntent = null;
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700491 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
Adrian Roosad028c12016-05-17 14:30:42 -0700492 if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700493 res = AppErrorDialog.FORCE_QUIT;
494 }
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700495 synchronized (mService) {
496 if (res == AppErrorDialog.MUTE) {
497 stopReportingCrashesLocked(r);
498 }
499 if (res == AppErrorDialog.RESTART) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400500 mService.mProcessList.removeProcessLocked(r, false, true, "crash");
Wale Ogunwale64258362018-10-16 15:13:37 -0700501 if (taskId != INVALID_TASK_ID) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700502 try {
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700503 mService.startActivityFromRecents(taskId,
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700504 ActivityOptions.makeBasic().toBundle());
505 } catch (IllegalArgumentException e) {
Wale Ogunwale64258362018-10-16 15:13:37 -0700506 // Hmm...that didn't work. Task should either be in recents or associated
507 // with a stack.
508 Slog.e(TAG, "Could not restart taskId=" + taskId, e);
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700509 }
510 }
511 }
512 if (res == AppErrorDialog.FORCE_QUIT) {
513 long orig = Binder.clearCallingIdentity();
514 try {
515 // Kill it with fire!
Wale Ogunwale31913b52018-10-13 08:29:31 -0700516 mService.mAtmInternal.onHandleAppCrash(r.getWindowProcessController());
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700517 if (!r.isPersistent()) {
Amith Yamasani98a00922018-08-21 12:50:30 -0400518 mService.mProcessList.removeProcessLocked(r, false, false, "crash");
Wale Ogunwale31913b52018-10-13 08:29:31 -0700519 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700520 }
521 } finally {
522 Binder.restoreCallingIdentity(orig);
523 }
524 }
Andrew Sapperstein5b679c42018-01-16 11:13:40 -0800525 if (res == AppErrorDialog.APP_INFO) {
526 appErrorIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
527 appErrorIntent.setData(Uri.parse("package:" + r.info.packageName));
528 appErrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
529 }
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700530 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
531 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
532 }
533 if (r != null && !r.isolated && res != AppErrorDialog.RESTART) {
534 // XXX Can't keep track of crash time for isolated processes,
535 // since they don't have a persistent identity.
536 mProcessCrashTimes.put(r.info.processName, r.uid,
537 SystemClock.uptimeMillis());
538 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100539 }
540
541 if (appErrorIntent != null) {
542 try {
543 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
544 } catch (ActivityNotFoundException e) {
545 Slog.w(TAG, "bug report receiver dissappeared", e);
546 }
547 }
548 }
549
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700550 private boolean handleAppCrashInActivityController(ProcessRecord r,
551 ApplicationErrorReport.CrashInfo crashInfo,
552 String shortMsg, String longMsg,
Mark Lub5e24992016-11-21 15:38:13 +0800553 String stackTrace, long timeMillis,
554 int callingPid, int callingUid) {
Wale Ogunwalee2172292018-10-25 10:11:10 -0700555 String name = r != null ? r.processName : null;
556 int pid = r != null ? r.pid : callingPid;
557 int uid = r != null ? r.info.uid : callingUid;
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700558
Wale Ogunwalee2172292018-10-25 10:11:10 -0700559 return mService.mAtmInternal.handleAppCrashInActivityController(
560 name, pid, shortMsg, longMsg, timeMillis, crashInfo.stackTrace, () -> {
561 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
562 && "Native crash".equals(crashInfo.exceptionClassName)) {
563 Slog.w(TAG, "Skip killing native crashed app " + name
564 + "(" + pid + ") during testing");
565 } else {
566 Slog.w(TAG, "Force-killing crashed app " + name + " at watcher's request");
567 if (r != null) {
568 if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null)) {
569 r.kill("crash", true);
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700570 }
Wale Ogunwalee2172292018-10-25 10:11:10 -0700571 } else {
572 // Huh.
573 Process.killProcess(pid);
574 ProcessList.killProcessGroup(uid, pid);
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700575 }
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700576 }
Wale Ogunwalee2172292018-10-25 10:11:10 -0700577 });
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700578 }
579
Adrian Roos20d7df32016-01-12 18:59:43 +0100580 private boolean makeAppCrashingLocked(ProcessRecord app,
581 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700582 app.setCrashing(true);
Adrian Roos20d7df32016-01-12 18:59:43 +0100583 app.crashingReport = generateProcessError(app,
584 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700585 app.startAppProblemLocked();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700586 app.getWindowProcessController().stopFreezingActivities();
Adrian Roos20d7df32016-01-12 18:59:43 +0100587 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace,
588 data);
589 }
590
Adrian Roos20d7df32016-01-12 18:59:43 +0100591 /**
592 * Generate a process error record, suitable for attachment to a ProcessRecord.
593 *
594 * @param app The ProcessRecord in which the error occurred.
595 * @param condition Crashing, Application Not Responding, etc. Values are defined in
Sudheer Shankaf6690102017-10-16 10:20:32 -0700596 * ActivityManager.ProcessErrorStateInfo
Adrian Roos20d7df32016-01-12 18:59:43 +0100597 * @param activity The activity associated with the crash, if known.
598 * @param shortMsg Short message describing the crash.
599 * @param longMsg Long message describing the crash.
600 * @param stackTrace Full crash stack trace, may be null.
601 *
Sudheer Shankaf6690102017-10-16 10:20:32 -0700602 * @return Returns a fully-formed ProcessErrorStateInfo record.
Adrian Roos20d7df32016-01-12 18:59:43 +0100603 */
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700604 ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Adrian Roos20d7df32016-01-12 18:59:43 +0100605 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
606 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
607
608 report.condition = condition;
609 report.processName = app.processName;
610 report.pid = app.pid;
611 report.uid = app.info.uid;
612 report.tag = activity;
613 report.shortMsg = shortMsg;
614 report.longMsg = longMsg;
615 report.stackTrace = stackTrace;
616
617 return report;
618 }
619
620 Intent createAppErrorIntentLocked(ProcessRecord r,
621 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
622 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
623 if (report == null) {
624 return null;
625 }
626 Intent result = new Intent(Intent.ACTION_APP_ERROR);
627 result.setComponent(r.errorReportReceiver);
628 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
629 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
630 return result;
631 }
632
633 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
634 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
635 if (r.errorReportReceiver == null) {
636 return null;
637 }
638
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700639 if (!r.isCrashing() && !r.isNotResponding() && !r.forceCrashReport) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100640 return null;
641 }
642
643 ApplicationErrorReport report = new ApplicationErrorReport();
644 report.packageName = r.info.packageName;
645 report.installerPackageName = r.errorReportReceiver.getPackageName();
646 report.processName = r.processName;
647 report.time = timeMillis;
Wale Ogunwale59507092018-10-29 09:00:30 -0700648 report.systemApp = (r.info.flags & FLAG_SYSTEM) != 0;
Adrian Roos20d7df32016-01-12 18:59:43 +0100649
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700650 if (r.isCrashing() || r.forceCrashReport) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100651 report.type = ApplicationErrorReport.TYPE_CRASH;
652 report.crashInfo = crashInfo;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700653 } else if (r.isNotResponding()) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100654 report.type = ApplicationErrorReport.TYPE_ANR;
655 report.anrInfo = new ApplicationErrorReport.AnrInfo();
656
657 report.anrInfo.activity = r.notRespondingReport.tag;
658 report.anrInfo.cause = r.notRespondingReport.shortMsg;
659 report.anrInfo.info = r.notRespondingReport.longMsg;
660 }
661
662 return report;
663 }
664
665 boolean handleAppCrashLocked(ProcessRecord app, String reason,
666 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700667 final long now = SystemClock.uptimeMillis();
668 final boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
Adrian Roos6a7e0892016-08-23 14:26:39 +0200669 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Adrian Roos20d7df32016-01-12 18:59:43 +0100670
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700671 final boolean procIsBoundForeground =
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700672 (app.getCurProcState() == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700673
Adrian Roos20d7df32016-01-12 18:59:43 +0100674 Long crashTime;
675 Long crashTimePersistent;
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700676 boolean tryAgain = false;
677
Adrian Roos20d7df32016-01-12 18:59:43 +0100678 if (!app.isolated) {
679 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
680 crashTimePersistent = mProcessCrashTimesPersistent.get(app.info.processName, app.uid);
681 } else {
682 crashTime = crashTimePersistent = null;
683 }
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700684
685 // Bump up the crash count of any services currently running in the proc.
686 for (int i = app.services.size() - 1; i >= 0; i--) {
687 // Any services running in the application need to be placed
688 // back in the pending list.
689 ServiceRecord sr = app.services.valueAt(i);
690 // If the service was restarted a while ago, then reset crash count, else increment it.
691 if (now > sr.restartTime + ProcessList.MIN_CRASH_INTERVAL) {
692 sr.crashCount = 1;
693 } else {
694 sr.crashCount++;
695 }
696 // Allow restarting for started or bound foreground services that are crashing.
697 // This includes wallpapers.
698 if (sr.crashCount < mService.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY
699 && (sr.isForeground || procIsBoundForeground)) {
700 tryAgain = true;
701 }
702 }
703
704 if (crashTime != null && now < crashTime + ProcessList.MIN_CRASH_INTERVAL) {
705 // The process crashed again very quickly. If it was a bound foreground service, let's
706 // try to restart again in a while, otherwise the process loses!
Adrian Roos20d7df32016-01-12 18:59:43 +0100707 Slog.w(TAG, "Process " + app.info.processName
708 + " has crashed too many times: killing!");
709 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
710 app.userId, app.info.processName, app.uid);
Wale Ogunwale31913b52018-10-13 08:29:31 -0700711 mService.mAtmInternal.onHandleAppCrash(app.getWindowProcessController());
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700712 if (!app.isPersistent()) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100713 // We don't want to start this process again until the user
714 // explicitly does so... but for persistent process, we really
715 // need to keep it running. If a persistent process is actually
716 // repeatedly crashing, then badness for everyone.
717 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
718 app.info.processName);
719 if (!app.isolated) {
720 // XXX We don't have a way to mark isolated processes
721 // as bad, since they don't have a peristent identity.
722 mBadProcesses.put(app.info.processName, app.uid,
723 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
724 mProcessCrashTimes.remove(app.info.processName, app.uid);
725 }
726 app.bad = true;
727 app.removed = true;
728 // Don't let services in this process be restarted and potentially
729 // annoy the user repeatedly. Unless it is persistent, since those
730 // processes run critical code.
Amith Yamasani98a00922018-08-21 12:50:30 -0400731 mService.mProcessList.removeProcessLocked(app, false, tryAgain, "crash");
Wale Ogunwale31913b52018-10-13 08:29:31 -0700732 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
Adrian Roos6a7e0892016-08-23 14:26:39 +0200733 if (!showBackground) {
734 return false;
735 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100736 }
Wale Ogunwale31913b52018-10-13 08:29:31 -0700737 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
Adrian Roos20d7df32016-01-12 18:59:43 +0100738 } else {
Wale Ogunwale64258362018-10-16 15:13:37 -0700739 final int affectedTaskId = mService.mAtmInternal.finishTopCrashedActivities(
Wale Ogunwale31913b52018-10-13 08:29:31 -0700740 app.getWindowProcessController(), reason);
Adrian Roos20d7df32016-01-12 18:59:43 +0100741 if (data != null) {
Wale Ogunwale64258362018-10-16 15:13:37 -0700742 data.taskId = affectedTaskId;
Adrian Roos20d7df32016-01-12 18:59:43 +0100743 }
744 if (data != null && crashTimePersistent != null
745 && now < crashTimePersistent + ProcessList.MIN_CRASH_INTERVAL) {
746 data.repeating = true;
747 }
748 }
749
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700750 if (data != null && tryAgain) {
751 data.isRestartableForService = true;
Adrian Roos20d7df32016-01-12 18:59:43 +0100752 }
753
754 // If the crashing process is what we consider to be the "home process" and it has been
755 // replaced by a third-party app, clear the package preferred activities from packages
756 // with a home activity running in the process to prevent a repeatedly crashing app
757 // from blocking the user to manually clear the list.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700758 final WindowProcessController proc = app.getWindowProcessController();
Wale Ogunwaled4d67d02018-10-25 18:09:39 -0700759 final WindowProcessController homeProc = mService.mAtmInternal.getHomeProcess();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700760 if (proc == homeProc && proc.hasActivities()
Wale Ogunwale59507092018-10-29 09:00:30 -0700761 && (((ProcessRecord) homeProc.mOwner).info.flags & FLAG_SYSTEM) == 0) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700762 proc.clearPackagePreferredForHomeActivities();
Adrian Roos20d7df32016-01-12 18:59:43 +0100763 }
764
765 if (!app.isolated) {
766 // XXX Can't keep track of crash times for isolated processes,
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700767 // because they don't have a persistent identity.
Adrian Roos20d7df32016-01-12 18:59:43 +0100768 mProcessCrashTimes.put(app.info.processName, app.uid, now);
769 mProcessCrashTimesPersistent.put(app.info.processName, app.uid, now);
770 }
771
772 if (app.crashHandler != null) mService.mHandler.post(app.crashHandler);
773 return true;
774 }
775
776 void handleShowAppErrorUi(Message msg) {
777 AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
778 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
779 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Adrian Roosc3a06e52018-02-16 18:33:17 +0100780
781 AppErrorDialog dialogToShow = null;
782 final String packageName;
783 final int userId;
Adrian Roos20d7df32016-01-12 18:59:43 +0100784 synchronized (mService) {
Adrian Roosc3a06e52018-02-16 18:33:17 +0100785 final ProcessRecord proc = data.proc;
786 final AppErrorResult res = data.result;
787 if (proc == null) {
788 Slog.e(TAG, "handleShowAppErrorUi: proc is null");
789 return;
790 }
791 packageName = proc.info.packageName;
792 userId = proc.userId;
793 if (proc.crashDialog != null) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100794 Slog.e(TAG, "App already has crash dialog: " + proc);
795 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800796 res.set(AppErrorDialog.ALREADY_SHOWING);
Adrian Roos20d7df32016-01-12 18:59:43 +0100797 }
798 return;
799 }
800 boolean isBackground = (UserHandle.getAppId(proc.uid)
801 >= Process.FIRST_APPLICATION_UID
802 && proc.pid != MY_PID);
Adrian Roosc3a06e52018-02-16 18:33:17 +0100803 for (int profileId : mService.mUserController.getCurrentProfileIds()) {
804 isBackground &= (userId != profileId);
Adrian Roos20d7df32016-01-12 18:59:43 +0100805 }
806 if (isBackground && !showBackground) {
807 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
808 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800809 res.set(AppErrorDialog.BACKGROUND_USER);
Adrian Roos20d7df32016-01-12 18:59:43 +0100810 }
811 return;
812 }
Andrew Sapperstein43643ae2017-12-20 15:17:33 -0800813 final boolean showFirstCrash = Settings.Global.getInt(
814 mContext.getContentResolver(),
815 Settings.Global.SHOW_FIRST_CRASH_DIALOG, 0) != 0;
816 final boolean showFirstCrashDevOption = Settings.Secure.getIntForUser(
817 mContext.getContentResolver(),
818 Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
819 0,
Andrew Sappersteinfd5238c2018-01-21 09:45:05 -0800820 mService.mUserController.getCurrentUserId()) != 0;
Adrian Roos20d7df32016-01-12 18:59:43 +0100821 final boolean crashSilenced = mAppsNotReportingCrashes != null &&
822 mAppsNotReportingCrashes.contains(proc.info.packageName);
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700823 if ((mService.mAtmInternal.canShowErrorDialogs() || showBackground)
Wale Ogunwalef6733932018-06-27 05:14:34 -0700824 && !crashSilenced
Andrew Sapperstein43643ae2017-12-20 15:17:33 -0800825 && (showFirstCrash || showFirstCrashDevOption || data.repeating)) {
Adrian Roosc3a06e52018-02-16 18:33:17 +0100826 proc.crashDialog = dialogToShow = new AppErrorDialog(mContext, mService, data);
Adrian Roos20d7df32016-01-12 18:59:43 +0100827 } else {
828 // The device is asleep, so just pretend that the user
829 // saw a crash dialog and hit "force quit".
830 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800831 res.set(AppErrorDialog.CANT_SHOW);
Adrian Roos20d7df32016-01-12 18:59:43 +0100832 }
833 }
834 }
Phil Weaver445fd2a2016-03-17 17:26:24 -0700835 // If we've created a crash dialog, show it without the lock held
Adrian Roosc3a06e52018-02-16 18:33:17 +0100836 if (dialogToShow != null) {
837 Slog.i(TAG, "Showing crash dialog for package " + packageName + " u" + userId);
838 dialogToShow.show();
Phil Weaver445fd2a2016-03-17 17:26:24 -0700839 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100840 }
841
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700842 private void stopReportingCrashesLocked(ProcessRecord proc) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100843 if (mAppsNotReportingCrashes == null) {
844 mAppsNotReportingCrashes = new ArraySet<>();
845 }
846 mAppsNotReportingCrashes.add(proc.info.packageName);
847 }
848
Adrian Roos20d7df32016-01-12 18:59:43 +0100849 void handleShowAnrUi(Message msg) {
Adrian Roosc3a06e52018-02-16 18:33:17 +0100850 Dialog dialogToShow = null;
Zimuzo972e1cd2019-01-28 16:30:01 +0000851 List<VersionedPackage> packageList = null;
Adrian Roos20d7df32016-01-12 18:59:43 +0100852 synchronized (mService) {
Adrian Roosc3a06e52018-02-16 18:33:17 +0100853 AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;
854 final ProcessRecord proc = data.proc;
855 if (proc == null) {
856 Slog.e(TAG, "handleShowAnrUi: proc is null");
857 return;
858 }
Zimuzo6efba542018-11-29 12:47:58 +0000859 if (!proc.isPersistent()) {
Zimuzo972e1cd2019-01-28 16:30:01 +0000860 packageList = proc.getPackageListWithVersionCode();
Zimuzo6efba542018-11-29 12:47:58 +0000861 }
Adrian Roosc3a06e52018-02-16 18:33:17 +0100862 if (proc.anrDialog != null) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100863 Slog.e(TAG, "App already has anr dialog: " + proc);
Adrian Roos90462222016-02-17 15:45:09 -0800864 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
865 AppNotRespondingDialog.ALREADY_SHOWING);
Adrian Roos20d7df32016-01-12 18:59:43 +0100866 return;
867 }
868
Adrian Roos6a7e0892016-08-23 14:26:39 +0200869 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
870 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700871 if (mService.mAtmInternal.canShowErrorDialogs() || showBackground) {
Adrian Roosc3a06e52018-02-16 18:33:17 +0100872 dialogToShow = new AppNotRespondingDialog(mService, mContext, data);
873 proc.anrDialog = dialogToShow;
Adrian Roos20d7df32016-01-12 18:59:43 +0100874 } else {
Adrian Roos90462222016-02-17 15:45:09 -0800875 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
876 AppNotRespondingDialog.CANT_SHOW);
Adrian Roos20d7df32016-01-12 18:59:43 +0100877 // Just kill the app if there is no dialog to be shown.
878 mService.killAppAtUsersRequest(proc, null);
879 }
880 }
Phil Weaver445fd2a2016-03-17 17:26:24 -0700881 // If we've created a crash dialog, show it without the lock held
Adrian Roosc3a06e52018-02-16 18:33:17 +0100882 if (dialogToShow != null) {
883 dialogToShow.show();
Phil Weaver445fd2a2016-03-17 17:26:24 -0700884 }
Zimuzo6efba542018-11-29 12:47:58 +0000885 // Notify PackageWatchdog without the lock held
886 if (packageList != null) {
887 mPackageWatchdog.onPackageFailure(packageList);
888 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100889 }
890
891 /**
892 * Information about a process that is currently marked as bad.
893 */
894 static final class BadProcessInfo {
895 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
896 this.time = time;
897 this.shortMsg = shortMsg;
898 this.longMsg = longMsg;
899 this.stack = stack;
900 }
901
902 final long time;
903 final String shortMsg;
904 final String longMsg;
905 final String stack;
906 }
907
908}