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 com.android.server.am;
18 
19 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
20 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
21 
22 import static com.android.server.am.ActivityManagerConstants.PROCESS_CRASH_COUNT_LIMIT;
23 import static com.android.server.am.ActivityManagerConstants.PROCESS_CRASH_COUNT_RESET_INTERVAL;
24 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
25 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
26 import static com.android.server.am.ActivityManagerService.MY_PID;
27 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
28 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
29 
30 import android.annotation.Nullable;
31 import android.app.ActivityManager;
32 import android.app.ActivityOptions;
33 import android.app.AnrController;
34 import android.app.ApplicationErrorReport;
35 import android.app.ApplicationExitInfo;
36 import android.app.RemoteServiceException.CrashedByAdbException;
37 import android.app.usage.UsageStatsManager;
38 import android.content.ActivityNotFoundException;
39 import android.content.Context;
40 import android.content.Intent;
41 import android.content.pm.VersionedPackage;
42 import android.net.Uri;
43 import android.os.Binder;
44 import android.os.Build;
45 import android.os.Bundle;
46 import android.os.Message;
47 import android.os.Process;
48 import android.os.SystemClock;
49 import android.os.UserHandle;
50 import android.provider.Settings;
51 import android.util.ArrayMap;
52 import android.util.ArraySet;
53 import android.util.EventLog;
54 import android.util.Pair;
55 import android.util.Slog;
56 import android.util.SparseArray;
57 import android.util.TimeUtils;
58 import android.util.proto.ProtoOutputStream;
59 
60 import com.android.internal.annotations.GuardedBy;
61 import com.android.internal.app.ProcessMap;
62 import com.android.internal.logging.MetricsLogger;
63 import com.android.internal.logging.nano.MetricsProto;
64 import com.android.server.LocalServices;
65 import com.android.server.PackageWatchdog;
66 import com.android.server.usage.AppStandbyInternal;
67 import com.android.server.wm.WindowProcessController;
68 
69 import java.io.FileDescriptor;
70 import java.io.PrintWriter;
71 import java.util.Collections;
72 import java.util.List;
73 
74 /**
75  * Controls error conditions in applications.
76  */
77 class AppErrors {
78 
79     private static final String TAG = TAG_WITH_CLASS_NAME ? "AppErrors" : TAG_AM;
80 
81     private final ActivityManagerService mService;
82     private final ActivityManagerGlobalLock mProcLock;
83     private final Context mContext;
84     private final PackageWatchdog mPackageWatchdog;
85 
86     @GuardedBy("mBadProcessLock")
87     private ArraySet<String> mAppsNotReportingCrashes;
88 
89     /**
90      * The last time that various processes have crashed since they were last explicitly started.
91      */
92     @GuardedBy("mBadProcessLock")
93     private final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<>();
94 
95     /**
96      * The last time that various processes have crashed (not reset even when explicitly started).
97      */
98     @GuardedBy("mBadProcessLock")
99     private final ProcessMap<Long> mProcessCrashTimesPersistent = new ProcessMap<>();
100 
101     /**
102      * The last time that various processes have crashed and shown an error dialog.
103      */
104     @GuardedBy("mBadProcessLock")
105     private final ProcessMap<Long> mProcessCrashShowDialogTimes = new ProcessMap<>();
106 
107     /**
108      * A pairing between how many times various processes have crashed since a given time.
109      * Entry and exit conditions for this map are similar to mProcessCrashTimes.
110      */
111     @GuardedBy("mBadProcessLock")
112     private final ProcessMap<Pair<Long, Integer>> mProcessCrashCounts = new ProcessMap<>();
113 
114     /**
115      * Set of applications that we consider to be bad, and will reject
116      * incoming broadcasts from (which the user has no control over).
117      * Processes are added to this set when they have crashed twice within
118      * a minimum amount of time; they are removed from it when they are
119      * later restarted (hopefully due to some user action).  The value is the
120      * time it was added to the list.
121      *
122      * Read access is UNLOCKED, and must either be based on a single lookup
123      * call on the current mBadProcesses instance, or a local copy of that
124      * reference must be made and the local copy treated as the source of
125      * truth.  Mutations are performed by synchronizing on mBadProcessLock,
126      * cloning the existing mBadProcesses instance, performing the mutation,
127      * then changing the volatile "live" mBadProcesses reference to point to the
128      * mutated version.  These operations are very rare compared to lookups:
129      * we intentionally trade additional cost for mutations for eliminating
130      * lock operations from the simple lookup cases.
131      */
132     private volatile ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>();
133 
134     /**
135      * Dedicated lock for {@link #mAppsNotReportingCrashes}, {@link #mProcessCrashTimes},
136      * {@link #mProcessCrashTimesPersistent}, {@link #mProcessCrashShowDialogTimes},
137      * {@link #mProcessCrashCounts} and {@link #mBadProcesses}.
138      *
139      * <p>The naming convention of the function with this lock should be "-LBp"</b>
140      *
141      * @See mBadProcesses
142      */
143     private final Object mBadProcessLock = new Object();
144 
AppErrors(Context context, ActivityManagerService service, PackageWatchdog watchdog)145     AppErrors(Context context, ActivityManagerService service, PackageWatchdog watchdog) {
146         context.assertRuntimeOverlayThemable();
147         mService = service;
148         mProcLock = service.mProcLock;
149         mContext = context;
150         mPackageWatchdog = watchdog;
151     }
152 
153     /** Resets the current state but leaves the constructor-provided fields unchanged. */
resetState()154     public void resetState() {
155         Slog.i(TAG, "Resetting AppErrors");
156         synchronized (mBadProcessLock) {
157             mAppsNotReportingCrashes.clear();
158             mProcessCrashTimes.clear();
159             mProcessCrashTimesPersistent.clear();
160             mProcessCrashShowDialogTimes.clear();
161             mProcessCrashCounts.clear();
162             mBadProcesses = new ProcessMap<>();
163         }
164     }
165 
166     @GuardedBy("mProcLock")
dumpDebugLPr(ProtoOutputStream proto, long fieldId, String dumpPackage)167     void dumpDebugLPr(ProtoOutputStream proto, long fieldId, String dumpPackage) {
168         final ProcessMap<BadProcessInfo> badProcesses = mBadProcesses;
169         if (mProcessCrashTimes.getMap().isEmpty() && badProcesses.getMap().isEmpty()) {
170             return;
171         }
172 
173         final long token = proto.start(fieldId);
174         final long now = SystemClock.uptimeMillis();
175         proto.write(AppErrorsProto.NOW_UPTIME_MS, now);
176 
177         if (!badProcesses.getMap().isEmpty()) {
178             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = badProcesses.getMap();
179             final int processCount = pmap.size();
180             for (int ip = 0; ip < processCount; ip++) {
181                 final long btoken = proto.start(AppErrorsProto.BAD_PROCESSES);
182                 final String pname = pmap.keyAt(ip);
183                 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
184                 final int uidCount = uids.size();
185 
186                 proto.write(AppErrorsProto.BadProcess.PROCESS_NAME, pname);
187                 for (int i = 0; i < uidCount; i++) {
188                     final int puid = uids.keyAt(i);
189                     final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid);
190                     if (dumpPackage != null && (r == null
191                             || !r.getPkgList().containsKey(dumpPackage))) {
192                         continue;
193                     }
194                     final BadProcessInfo info = uids.valueAt(i);
195                     final long etoken = proto.start(AppErrorsProto.BadProcess.ENTRIES);
196                     proto.write(AppErrorsProto.BadProcess.Entry.UID, puid);
197                     proto.write(AppErrorsProto.BadProcess.Entry.CRASHED_AT_MS, info.time);
198                     proto.write(AppErrorsProto.BadProcess.Entry.SHORT_MSG, info.shortMsg);
199                     proto.write(AppErrorsProto.BadProcess.Entry.LONG_MSG, info.longMsg);
200                     proto.write(AppErrorsProto.BadProcess.Entry.STACK, info.stack);
201                     proto.end(etoken);
202                 }
203                 proto.end(btoken);
204             }
205         }
206 
207         synchronized (mBadProcessLock) {
208             if (!mProcessCrashTimes.getMap().isEmpty()) {
209                 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
210                 final int procCount = pmap.size();
211                 for (int ip = 0; ip < procCount; ip++) {
212                     final long ctoken = proto.start(AppErrorsProto.PROCESS_CRASH_TIMES);
213                     final String pname = pmap.keyAt(ip);
214                     final SparseArray<Long> uids = pmap.valueAt(ip);
215                     final int uidCount = uids.size();
216 
217                     proto.write(AppErrorsProto.ProcessCrashTime.PROCESS_NAME, pname);
218                     for (int i = 0; i < uidCount; i++) {
219                         final int puid = uids.keyAt(i);
220                         final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid);
221                         if (dumpPackage != null
222                                 && (r == null || !r.getPkgList().containsKey(dumpPackage))) {
223                             continue;
224                         }
225                         final long etoken = proto.start(AppErrorsProto.ProcessCrashTime.ENTRIES);
226                         proto.write(AppErrorsProto.ProcessCrashTime.Entry.UID, puid);
227                         proto.write(AppErrorsProto.ProcessCrashTime.Entry.LAST_CRASHED_AT_MS,
228                                 uids.valueAt(i));
229                         proto.end(etoken);
230                     }
231                     proto.end(ctoken);
232                 }
233             }
234         }
235 
236         proto.end(token);
237     }
238 
239     @GuardedBy("mProcLock")
dumpLPr(FileDescriptor fd, PrintWriter pw, boolean needSep, String dumpPackage)240     boolean dumpLPr(FileDescriptor fd, PrintWriter pw, boolean needSep, String dumpPackage) {
241         final long now = SystemClock.uptimeMillis();
242         synchronized (mBadProcessLock) {
243             if (!mProcessCrashTimes.getMap().isEmpty()) {
244                 boolean printed = false;
245                 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
246                 final int processCount = pmap.size();
247                 for (int ip = 0; ip < processCount; ip++) {
248                     final String pname = pmap.keyAt(ip);
249                     final SparseArray<Long> uids = pmap.valueAt(ip);
250                     final int uidCount = uids.size();
251                     for (int i = 0; i < uidCount; i++) {
252                         final int puid = uids.keyAt(i);
253                         final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid);
254                         if (dumpPackage != null
255                                 && (r == null || !r.getPkgList().containsKey(dumpPackage))) {
256                             continue;
257                         }
258                         if (!printed) {
259                             if (needSep) pw.println();
260                             needSep = true;
261                             pw.println("  Time since processes crashed:");
262                             printed = true;
263                         }
264                         pw.print("    Process "); pw.print(pname);
265                         pw.print(" uid "); pw.print(puid);
266                         pw.print(": last crashed ");
267                         TimeUtils.formatDuration(now - uids.valueAt(i), pw);
268                         pw.println(" ago");
269                     }
270                 }
271             }
272 
273             if (!mProcessCrashCounts.getMap().isEmpty()) {
274                 boolean printed = false;
275                 final ArrayMap<String, SparseArray<Pair<Long, Integer>>> pmap =
276                         mProcessCrashCounts.getMap();
277                 final int processCount = pmap.size();
278                 for (int ip = 0; ip < processCount; ip++) {
279                     final String pname = pmap.keyAt(ip);
280                     final SparseArray<Pair<Long, Integer>> uids = pmap.valueAt(ip);
281                     final int uidCount = uids.size();
282                     for (int i = 0; i < uidCount; i++) {
283                         final int puid = uids.keyAt(i);
284                         final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid);
285                         if (dumpPackage != null
286                                 && (r == null || !r.getPkgList().containsKey(dumpPackage))) {
287                             continue;
288                         }
289                         if (!printed) {
290                             if (needSep) pw.println();
291                             needSep = true;
292                             pw.println("  First time processes crashed and counts:");
293                             printed = true;
294                         }
295                         pw.print("    Process "); pw.print(pname);
296                         pw.print(" uid "); pw.print(puid);
297                         pw.print(": first crashed ");
298                         TimeUtils.formatDuration(now - uids.valueAt(i).first, pw);
299                         pw.print(" ago; crashes since then: "); pw.println(uids.valueAt(i).second);
300                     }
301                 }
302             }
303         }
304 
305         final ProcessMap<BadProcessInfo> badProcesses = mBadProcesses;
306         if (!badProcesses.getMap().isEmpty()) {
307             boolean printed = false;
308             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = badProcesses.getMap();
309             final int processCount = pmap.size();
310             for (int ip = 0; ip < processCount; ip++) {
311                 final String pname = pmap.keyAt(ip);
312                 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
313                 final int uidCount = uids.size();
314                 for (int i = 0; i < uidCount; i++) {
315                     final int puid = uids.keyAt(i);
316                     final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid);
317                     if (dumpPackage != null && (r == null
318                             || !r.getPkgList().containsKey(dumpPackage))) {
319                         continue;
320                     }
321                     if (!printed) {
322                         if (needSep) pw.println();
323                         needSep = true;
324                         pw.println("  Bad processes:");
325                         printed = true;
326                     }
327                     final BadProcessInfo info = uids.valueAt(i);
328                     pw.print("    Bad process "); pw.print(pname);
329                     pw.print(" uid "); pw.print(puid);
330                     pw.print(": crashed at time "); pw.println(info.time);
331                     if (info.shortMsg != null) {
332                         pw.print("      Short msg: "); pw.println(info.shortMsg);
333                     }
334                     if (info.longMsg != null) {
335                         pw.print("      Long msg: "); pw.println(info.longMsg);
336                     }
337                     if (info.stack != null) {
338                         pw.println("      Stack:");
339                         int lastPos = 0;
340                         for (int pos = 0; pos < info.stack.length(); pos++) {
341                             if (info.stack.charAt(pos) == '\n') {
342                                 pw.print("        ");
343                                 pw.write(info.stack, lastPos, pos - lastPos);
344                                 pw.println();
345                                 lastPos = pos + 1;
346                             }
347                         }
348                         if (lastPos < info.stack.length()) {
349                             pw.print("        ");
350                             pw.write(info.stack, lastPos, info.stack.length() - lastPos);
351                             pw.println();
352                         }
353                     }
354                 }
355             }
356         }
357         return needSep;
358     }
359 
isBadProcess(final String processName, final int uid)360     boolean isBadProcess(final String processName, final int uid) {
361         // NO LOCKING for the simple lookup
362         return mBadProcesses.get(processName, uid) != null;
363     }
364 
clearBadProcess(final String processName, final int uid)365     void clearBadProcess(final String processName, final int uid) {
366         synchronized (mBadProcessLock) {
367             final ProcessMap<BadProcessInfo> badProcesses = new ProcessMap<>();
368             badProcesses.putAll(mBadProcesses);
369             badProcesses.remove(processName, uid);
370             mBadProcesses = badProcesses;
371         }
372     }
373 
markBadProcess(final String processName, final int uid, BadProcessInfo info)374     void markBadProcess(final String processName, final int uid, BadProcessInfo info) {
375         synchronized (mBadProcessLock) {
376             final ProcessMap<BadProcessInfo> badProcesses = new ProcessMap<>();
377             badProcesses.putAll(mBadProcesses);
378             badProcesses.put(processName, uid, info);
379             mBadProcesses = badProcesses;
380         }
381     }
382 
resetProcessCrashTime(final String processName, final int uid)383     void resetProcessCrashTime(final String processName, final int uid) {
384         synchronized (mBadProcessLock) {
385             mProcessCrashTimes.remove(processName, uid);
386             mProcessCrashCounts.remove(processName, uid);
387         }
388     }
389 
resetProcessCrashTime(boolean resetEntireUser, int appId, int userId)390     void resetProcessCrashTime(boolean resetEntireUser, int appId, int userId) {
391         synchronized (mBadProcessLock) {
392             final ArrayMap<String, SparseArray<Long>> pTimeMap = mProcessCrashTimes.getMap();
393             for (int ip = pTimeMap.size() - 1; ip >= 0; ip--) {
394                 SparseArray<Long> ba = pTimeMap.valueAt(ip);
395                 resetProcessCrashMapLBp(ba, resetEntireUser, appId, userId);
396                 if (ba.size() == 0) {
397                     pTimeMap.removeAt(ip);
398                 }
399             }
400 
401             final ArrayMap<String, SparseArray<Pair<Long, Integer>>> pCountMap =
402                     mProcessCrashCounts.getMap();
403             for (int ip = pCountMap.size() - 1; ip >= 0; ip--) {
404                 SparseArray<Pair<Long, Integer>> ba = pCountMap.valueAt(ip);
405                 resetProcessCrashMapLBp(ba, resetEntireUser, appId, userId);
406                 if (ba.size() == 0) {
407                     pCountMap.removeAt(ip);
408                 }
409             }
410         }
411     }
412 
413     @GuardedBy("mBadProcessLock")
resetProcessCrashMapLBp(SparseArray<?> ba, boolean resetEntireUser, int appId, int userId)414     private void resetProcessCrashMapLBp(SparseArray<?> ba, boolean resetEntireUser,
415             int appId, int userId) {
416         for (int i = ba.size() - 1; i >= 0; i--) {
417             boolean remove = false;
418             final int entUid = ba.keyAt(i);
419             if (!resetEntireUser) {
420                 if (userId == UserHandle.USER_ALL) {
421                     if (UserHandle.getAppId(entUid) == appId) {
422                         remove = true;
423                     }
424                 } else {
425                     if (entUid == UserHandle.getUid(userId, appId)) {
426                         remove = true;
427                     }
428                 }
429             } else if (UserHandle.getUserId(entUid) == userId) {
430                 remove = true;
431             }
432             if (remove) {
433                 ba.removeAt(i);
434             }
435         }
436     }
437 
loadAppsNotReportingCrashesFromConfig(String appsNotReportingCrashesConfig)438     void loadAppsNotReportingCrashesFromConfig(String appsNotReportingCrashesConfig) {
439         if (appsNotReportingCrashesConfig != null) {
440             final String[] split = appsNotReportingCrashesConfig.split(",");
441             if (split.length > 0) {
442                 synchronized (mBadProcessLock) {
443                     mAppsNotReportingCrashes = new ArraySet<>();
444                     Collections.addAll(mAppsNotReportingCrashes, split);
445                 }
446             }
447         }
448     }
449 
450     @GuardedBy("mService")
killAppAtUserRequestLocked(ProcessRecord app)451     void killAppAtUserRequestLocked(ProcessRecord app) {
452         ErrorDialogController controller = app.mErrorState.getDialogController();
453 
454         int reasonCode = ApplicationExitInfo.REASON_ANR;
455         int subReason = ApplicationExitInfo.SUBREASON_UNKNOWN;
456         synchronized (mProcLock) {
457             if (controller.hasDebugWaitingDialog()) {
458                 reasonCode = ApplicationExitInfo.REASON_OTHER;
459                 subReason = ApplicationExitInfo.SUBREASON_WAIT_FOR_DEBUGGER;
460             }
461             controller.clearAllErrorDialogs();
462             killAppImmediateLSP(app, reasonCode, subReason,
463                     "user-terminated", "user request after error");
464         }
465     }
466 
467     @GuardedBy({"mService", "mProcLock"})
killAppImmediateLSP(ProcessRecord app, int reasonCode, int subReason, String reason, String killReason)468     private void killAppImmediateLSP(ProcessRecord app, int reasonCode, int subReason,
469             String reason, String killReason) {
470         final ProcessErrorStateRecord errState = app.mErrorState;
471         errState.setCrashing(false);
472         errState.setCrashingReport(null);
473         errState.setNotResponding(false);
474         errState.setNotRespondingReport(null);
475         final int pid = errState.mApp.getPid();
476         if (pid > 0 && pid != MY_PID) {
477             synchronized (mBadProcessLock) {
478                 handleAppCrashLSPB(app, reason,
479                         null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
480             }
481             app.killLocked(killReason, reasonCode, subReason, true);
482         }
483     }
484 
485     /**
486      * Induce a crash in the given app.
487      *
488      * @param uid if nonnegative, the required matching uid of the target to crash
489      * @param initialPid fast-path match for the target to crash
490      * @param packageName fallback match if the stated pid is not found or doesn't match uid
491      * @param userId If nonnegative, required to identify a match by package name
492      * @param message
493      */
scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId, String message, boolean force, int exceptionTypeId, @Nullable Bundle extras)494     void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
495             String message, boolean force, int exceptionTypeId, @Nullable Bundle extras) {
496         ProcessRecord proc = null;
497 
498         // Figure out which process to kill.  We don't trust that initialPid
499         // still has any relation to current pids, so must scan through the
500         // list.
501 
502         synchronized (mService.mPidsSelfLocked) {
503             for (int i=0; i<mService.mPidsSelfLocked.size(); i++) {
504                 ProcessRecord p = mService.mPidsSelfLocked.valueAt(i);
505                 if (uid >= 0 && p.uid != uid) {
506                     continue;
507                 }
508                 if (p.getPid() == initialPid) {
509                     proc = p;
510                     break;
511                 }
512                 if (p.getPkgList().containsKey(packageName)
513                         && (userId < 0 || p.userId == userId)) {
514                     proc = p;
515                 }
516             }
517         }
518 
519         if (proc == null) {
520             Slog.w(TAG, "crashApplication: nothing for uid=" + uid
521                     + " initialPid=" + initialPid
522                     + " packageName=" + packageName
523                     + " userId=" + userId);
524             return;
525         }
526 
527         if (exceptionTypeId == CrashedByAdbException.TYPE_ID) {
528             String[] packages = proc.getPackageList();
529             for (int i = 0; i < packages.length; i++) {
530                 if (mService.mPackageManagerInt.isPackageStateProtected(packages[i], proc.userId)) {
531                     Slog.w(TAG, "crashApplication: Can not crash protected package " + packages[i]);
532                     return;
533                 }
534             }
535         }
536 
537         mService.mOomAdjuster.mCachedAppOptimizer.unfreezeProcess(initialPid,
538                 CachedAppOptimizer.UNFREEZE_REASON_PROCESS_END);
539         proc.scheduleCrashLocked(message, exceptionTypeId, extras);
540         if (force) {
541             // If the app is responsive, the scheduled crash will happen as expected
542             // and then the delayed summary kill will be a no-op.
543             final ProcessRecord p = proc;
544             mService.mHandler.postDelayed(
545                     () -> {
546                         synchronized (mService) {
547                             synchronized (mProcLock) {
548                                 killAppImmediateLSP(p, ApplicationExitInfo.REASON_OTHER,
549                                         ApplicationExitInfo.SUBREASON_INVALID_STATE,
550                                         "forced", "killed for invalid state");
551                             }
552                         }
553                     },
554                     5000L);
555         }
556     }
557 
sendRecoverableCrashToAppExitInfo( ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo)558     void sendRecoverableCrashToAppExitInfo(
559             ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
560         if (r == null || crashInfo == null
561                 || !"Native crash".equals(crashInfo.exceptionClassName)) return;
562         synchronized (mService) {
563             mService.mProcessList.noteAppRecoverableCrash(r);
564         }
565     }
566 
567     /**
568      * Bring up the "unexpected error" dialog box for a crashing app.
569      * Deal with edge cases (intercepts from instrumented applications,
570      * ActivityController, error intent receivers, that sort of thing).
571      * @param r the application crashing
572      * @param crashInfo describing the failure
573      */
crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo)574     void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
575         final int callingPid = Binder.getCallingPid();
576         final int callingUid = Binder.getCallingUid();
577 
578         final long origId = Binder.clearCallingIdentity();
579         try {
580             crashApplicationInner(r, crashInfo, callingPid, callingUid);
581         } finally {
582             Binder.restoreCallingIdentity(origId);
583         }
584     }
585 
crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo, int callingPid, int callingUid)586     private void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo,
587             int callingPid, int callingUid) {
588         long timeMillis = System.currentTimeMillis();
589         String shortMsg = crashInfo.exceptionClassName;
590         String longMsg = crashInfo.exceptionMessage;
591         String stackTrace = crashInfo.stackTrace;
592         if (shortMsg != null && longMsg != null) {
593             longMsg = shortMsg + ": " + longMsg;
594         } else if (shortMsg != null) {
595             longMsg = shortMsg;
596         }
597 
598         if (r != null) {
599             mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode(),
600                     PackageWatchdog.FAILURE_REASON_APP_CRASH);
601 
602             synchronized (mService) {
603                 mService.mProcessList.noteAppKill(r, (crashInfo != null
604                           && "Native crash".equals(crashInfo.exceptionClassName))
605                           ? ApplicationExitInfo.REASON_CRASH_NATIVE
606                           : ApplicationExitInfo.REASON_CRASH,
607                           ApplicationExitInfo.SUBREASON_UNKNOWN,
608                         "crash");
609             }
610         }
611 
612         final int relaunchReason = r != null
613                 ? r.getWindowProcessController().computeRelaunchReason() : RELAUNCH_REASON_NONE;
614 
615         AppErrorResult result = new AppErrorResult();
616         int taskId;
617         synchronized (mService) {
618             /**
619              * If crash is handled by instance of {@link android.app.IActivityController},
620              * finish now and don't show the app error dialog.
621              */
622             if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace,
623                     timeMillis, callingPid, callingUid)) {
624                 return;
625             }
626 
627             // Suppress crash dialog if the process is being relaunched due to a crash during a free
628             // resize.
629             if (relaunchReason == RELAUNCH_REASON_FREE_RESIZE) {
630                 return;
631             }
632 
633             /**
634              * If this process was running instrumentation, finish now - it will be handled in
635              * {@link ActivityManagerService#handleAppDiedLocked}.
636              */
637             if (r != null && r.getActiveInstrumentation() != null) {
638                 return;
639             }
640 
641             // Log crash in battery stats.
642             if (r != null) {
643                 mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
644             }
645 
646             AppErrorDialog.Data data = new AppErrorDialog.Data();
647             data.result = result;
648             data.proc = r;
649 
650             // If we can't identify the process or it's already exceeded its crash quota,
651             // quit right away without showing a crash dialog.
652             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
653                 return;
654             }
655 
656             final Message msg = Message.obtain();
657             msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
658 
659             taskId = data.taskId;
660             msg.obj = data;
661             mService.mUiHandler.sendMessage(msg);
662         }
663 
664         int res = result.get();
665 
666         Intent appErrorIntent = null;
667         MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
668         if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) {
669             res = AppErrorDialog.FORCE_QUIT;
670         }
671         switch (res) {
672             case AppErrorDialog.MUTE:
673                 synchronized (mBadProcessLock) {
674                     stopReportingCrashesLBp(r);
675                 }
676                 break;
677             case AppErrorDialog.RESTART:
678                 synchronized (mService) {
679                     mService.mProcessList.removeProcessLocked(r, false, true,
680                             ApplicationExitInfo.REASON_CRASH, "crash");
681                 }
682                 if (taskId != INVALID_TASK_ID) {
683                     try {
684                         mService.startActivityFromRecents(taskId,
685                                 ActivityOptions.makeBasic().toBundle());
686                     } catch (IllegalArgumentException e) {
687                         // Hmm...that didn't work. Task should either be in recents or associated
688                         // with a stack.
689                         Slog.e(TAG, "Could not restart taskId=" + taskId, e);
690                     }
691                 }
692                 break;
693             case AppErrorDialog.FORCE_QUIT:
694                 final long orig = Binder.clearCallingIdentity();
695                 try {
696                     // Kill it with fire!
697                     mService.mAtmInternal.onHandleAppCrash(r.getWindowProcessController());
698                     if (!r.isPersistent()) {
699                         synchronized (mService) {
700                             mService.mProcessList.removeProcessLocked(r, false, false,
701                                     ApplicationExitInfo.REASON_CRASH, "crash");
702                         }
703                         mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
704                     }
705                 } finally {
706                     Binder.restoreCallingIdentity(orig);
707                 }
708                 break;
709             case AppErrorDialog.APP_INFO:
710                 appErrorIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
711                 appErrorIntent.setData(Uri.parse("package:" + r.info.packageName));
712                 appErrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
713                 break;
714             case AppErrorDialog.FORCE_QUIT_AND_REPORT:
715                 synchronized (mProcLock) {
716                     appErrorIntent = createAppErrorIntentLOSP(r, timeMillis, crashInfo);
717                 }
718                 break;
719         }
720 
721         if (appErrorIntent != null) {
722             try {
723                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
724             } catch (ActivityNotFoundException e) {
725                 Slog.w(TAG, "bug report receiver dissappeared", e);
726             }
727         }
728     }
729 
730     @GuardedBy("mService")
handleAppCrashInActivityController(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo, String shortMsg, String longMsg, String stackTrace, long timeMillis, int callingPid, int callingUid)731     private boolean handleAppCrashInActivityController(ProcessRecord r,
732                                                        ApplicationErrorReport.CrashInfo crashInfo,
733                                                        String shortMsg, String longMsg,
734                                                        String stackTrace, long timeMillis,
735                                                        int callingPid, int callingUid) {
736         String name = r != null ? r.processName : null;
737         int pid = r != null ? r.getPid() : callingPid;
738         int uid = r != null ? r.info.uid : callingUid;
739 
740         return mService.mAtmInternal.handleAppCrashInActivityController(
741                 name, pid, shortMsg, longMsg, timeMillis, crashInfo.stackTrace, () -> {
742                 if (Build.IS_DEBUGGABLE
743                         && "Native crash".equals(crashInfo.exceptionClassName)) {
744                     Slog.w(TAG, "Skip killing native crashed app " + name
745                             + "(" + pid + ") during testing");
746                 } else {
747                     Slog.w(TAG, "Force-killing crashed app " + name + " at watcher's request");
748                     if (r != null) {
749                         if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null)) {
750                             r.killLocked("crash", ApplicationExitInfo.REASON_CRASH, true);
751                         }
752                     } else {
753                         // Huh.
754                         Process.killProcess(pid);
755                         ProcessList.killProcessGroup(uid, pid);
756                         mService.mProcessList.noteAppKill(pid, uid,
757                                 ApplicationExitInfo.REASON_CRASH,
758                                 ApplicationExitInfo.SUBREASON_UNKNOWN,
759                                 "crash");
760                     }
761                 }
762         });
763     }
764 
765     @GuardedBy("mService")
766     private boolean makeAppCrashingLocked(ProcessRecord app,
767             String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
768         synchronized (mProcLock) {
769             final ProcessErrorStateRecord errState = app.mErrorState;
770             errState.setCrashing(true);
771             errState.setCrashingReport(generateProcessError(app,
772                     ActivityManager.ProcessErrorStateInfo.CRASHED,
773                     null, shortMsg, longMsg, stackTrace));
774             errState.startAppProblemLSP();
775             app.getWindowProcessController().stopFreezingActivities();
776             synchronized (mBadProcessLock) {
777                 return handleAppCrashLSPB(app, "force-crash" /*reason*/, shortMsg, longMsg,
778                         stackTrace, data);
779             }
780         }
781     }
782 
783     /**
784      * Generate a process error record, suitable for attachment to a ProcessRecord.
785      *
786      * @param app The ProcessRecord in which the error occurred.
787      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
788      *                      ActivityManager.ProcessErrorStateInfo
789      * @param activity The activity associated with the crash, if known.
790      * @param shortMsg Short message describing the crash.
791      * @param longMsg Long message describing the crash.
792      * @param stackTrace Full crash stack trace, may be null.
793      *
794      * @return Returns a fully-formed ProcessErrorStateInfo record.
795      */
796     ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
797             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
798         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
799 
800         report.condition = condition;
801         report.processName = app.processName;
802         report.pid = app.getPid();
803         report.uid = app.info.uid;
804         report.tag = activity;
805         report.shortMsg = shortMsg;
806         report.longMsg = longMsg;
807         report.stackTrace = stackTrace;
808 
809         return report;
810     }
811 
812     @GuardedBy(anyOf = {"mService", "mProcLock"})
813     Intent createAppErrorIntentLOSP(ProcessRecord r,
814             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
815         ApplicationErrorReport report = createAppErrorReportLOSP(r, timeMillis, crashInfo);
816         if (report == null) {
817             return null;
818         }
819         Intent result = new Intent(Intent.ACTION_APP_ERROR);
820         result.setComponent(r.mErrorState.getErrorReportReceiver());
821         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
822         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
823         return result;
824     }
825 
826     @GuardedBy(anyOf = {"mService", "mProcLock"})
827     private ApplicationErrorReport createAppErrorReportLOSP(ProcessRecord r,
828             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
829         final ProcessErrorStateRecord errState = r.mErrorState;
830         if (errState.getErrorReportReceiver() == null) {
831             return null;
832         }
833 
834         if (!errState.isCrashing() && !errState.isNotResponding()
835                 && !errState.isForceCrashReport()) {
836             return null;
837         }
838 
839         ApplicationErrorReport report = new ApplicationErrorReport();
840         report.packageName = r.info.packageName;
841         report.installerPackageName = errState.getErrorReportReceiver().getPackageName();
842         report.processName = r.processName;
843         report.time = timeMillis;
844         report.systemApp = (r.info.flags & FLAG_SYSTEM) != 0;
845 
846         if (errState.isCrashing() || errState.isForceCrashReport()) {
847             report.type = ApplicationErrorReport.TYPE_CRASH;
848             report.crashInfo = crashInfo;
849         } else if (errState.isNotResponding()) {
850             final ActivityManager.ProcessErrorStateInfo anrReport =
851                     errState.getNotRespondingReport();
852             if (anrReport == null) {
853                 // The ANR dump is still ongoing, ignore it for now.
854                 return null;
855             }
856             report.type = ApplicationErrorReport.TYPE_ANR;
857             report.anrInfo = new ApplicationErrorReport.AnrInfo();
858 
859             report.anrInfo.activity = anrReport.tag;
860             report.anrInfo.cause = anrReport.shortMsg;
861             report.anrInfo.info = anrReport.longMsg;
862         }
863 
864         return report;
865     }
866 
867     @GuardedBy({"mService", "mProcLock", "mBadProcessLock"})
868     private boolean handleAppCrashLSPB(ProcessRecord app, String reason,
869             String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
870         final long now = SystemClock.uptimeMillis();
871         final boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
872                 Settings.Secure.ANR_SHOW_BACKGROUND, 0,
873                 mService.mUserController.getCurrentUserId()) != 0;
874 
875         Long crashTime;
876         Long crashTimePersistent;
877         final String processName = app.processName;
878         final int uid = app.uid;
879         final int userId = app.userId;
880         final boolean isolated = app.isolated;
881         final boolean persistent = app.isPersistent();
882         final WindowProcessController proc = app.getWindowProcessController();
883         final ProcessErrorStateRecord errState = app.mErrorState;
884 
885         if (!app.isolated) {
886             crashTime = mProcessCrashTimes.get(processName, uid);
887             crashTimePersistent = mProcessCrashTimesPersistent.get(processName, uid);
888         } else {
889             crashTime = crashTimePersistent = null;
890         }
891 
892         // Bump up the crash count of any services currently running in the proc.
893         boolean tryAgain = app.mServices.incServiceCrashCountLocked(now);
894 
895         final boolean quickCrash = crashTime != null
896                 && now < crashTime + ActivityManagerConstants.MIN_CRASH_INTERVAL;
897         if (quickCrash || isProcOverCrashLimitLBp(app, now)) {
898             // The process either crashed again very quickly or has been crashing periodically in
899             // the last few hours. If it was a bound foreground service, let's try to restart again
900             // in a while, otherwise the process loses!
901             Slog.w(TAG, "Process " + processName + " has crashed too many times, killing!"
902                     + " Reason: " + (quickCrash ? "crashed quickly" : "over process crash limit"));
903             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
904                     userId, processName, uid);
905             mService.mAtmInternal.onHandleAppCrash(proc);
906             if (!persistent) {
907                 // We don't want to start this process again until the user
908                 // explicitly does so...  but for persistent process, we really
909                 // need to keep it running.  If a persistent process is actually
910                 // repeatedly crashing, then badness for everyone.
911                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, userId, uid,
912                         processName);
913                 if (!isolated) {
914                     // XXX We don't have a way to mark isolated processes
915                     // as bad, since they don't have a persistent identity.
916                     markBadProcess(processName, app.uid,
917                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
918                     mProcessCrashTimes.remove(processName, app.uid);
919                     mProcessCrashCounts.remove(processName, app.uid);
920                 }
921                 errState.setBad(true);
922                 app.setRemoved(true);
923                 final AppStandbyInternal appStandbyInternal =
924                         LocalServices.getService(AppStandbyInternal.class);
925                 if (appStandbyInternal != null) {
926                     appStandbyInternal.restrictApp(
927                             // Sometimes the processName is the same as the package name, so use
928                             // that if we don't have the ApplicationInfo object.
929                             // AppStandbyController will just return if it can't find the app.
930                             app.info != null ? app.info.packageName : processName,
931                             userId, UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY);
932                 }
933                 // Don't let services in this process be restarted and potentially
934                 // annoy the user repeatedly.  Unless it is persistent, since those
935                 // processes run critical code.
936                 mService.mProcessList.removeProcessLocked(app, false, tryAgain,
937                         ApplicationExitInfo.REASON_CRASH, "crash");
938                 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
939                 if (!showBackground) {
940                     return false;
941                 }
942             }
943             mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
944         } else {
945             final int affectedTaskId = mService.mAtmInternal.finishTopCrashedActivities(
946                             proc, reason);
947             if (data != null) {
948                 data.taskId = affectedTaskId;
949             }
950             if (data != null && crashTimePersistent != null
951                     && now < crashTimePersistent + ActivityManagerConstants.MIN_CRASH_INTERVAL) {
952                 data.repeating = true;
953             }
954         }
955 
956         if (data != null && tryAgain) {
957             data.isRestartableForService = true;
958         }
959 
960         // If the crashing process is what we consider to be the "home process" and it has been
961         // replaced by a third-party app, clear the package preferred activities from packages
962         // with a home activity running in the process to prevent a repeatedly crashing app
963         // from blocking the user to manually clear the list.
964         if (proc.isHomeProcess() && proc.hasActivities() && (app.info.flags & FLAG_SYSTEM) == 0) {
965             proc.clearPackagePreferredForHomeActivities();
966         }
967 
968         if (!isolated) {
969             // XXX Can't keep track of crash times for isolated processes,
970             // because they don't have a persistent identity.
971             mProcessCrashTimes.put(processName, uid, now);
972             mProcessCrashTimesPersistent.put(processName, uid, now);
973             updateProcessCrashCountLBp(processName, uid, now);
974         }
975 
976         if (errState.getCrashHandler() != null) {
977             mService.mHandler.post(errState.getCrashHandler());
978         }
979         return true;
980     }
981 
982     @GuardedBy("mBadProcessLock")
983     private void updateProcessCrashCountLBp(String processName, int uid, long now) {
984         Pair<Long, Integer> count = mProcessCrashCounts.get(processName, uid);
985         if (count == null || (count.first + PROCESS_CRASH_COUNT_RESET_INTERVAL) < now) {
986             count = new Pair<>(now, 1);
987         } else {
988             count = new Pair<>(count.first, count.second + 1);
989         }
990         mProcessCrashCounts.put(processName, uid, count);
991     }
992 
993     @GuardedBy("mBadProcessLock")
994     private boolean isProcOverCrashLimitLBp(ProcessRecord app, long now) {
995         final Pair<Long, Integer> crashCount = mProcessCrashCounts.get(app.processName, app.uid);
996         return !app.isolated && crashCount != null
997                 && now < (crashCount.first + PROCESS_CRASH_COUNT_RESET_INTERVAL)
998                 && crashCount.second >= PROCESS_CRASH_COUNT_LIMIT;
999     }
1000 
1001     void handleShowAppErrorUi(Message msg) {
1002         AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
1003         boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
1004                 Settings.Secure.ANR_SHOW_BACKGROUND, 0,
1005                 mService.mUserController.getCurrentUserId()) != 0;
1006 
1007         final int userId;
1008         synchronized (mProcLock) {
1009             final ProcessRecord proc = data.proc;
1010             final AppErrorResult res = data.result;
1011             if (proc == null) {
1012                 Slog.e(TAG, "handleShowAppErrorUi: proc is null");
1013                 return;
1014             }
1015             final ProcessErrorStateRecord errState = proc.mErrorState;
1016             userId = proc.userId;
1017             if (errState.getDialogController().hasCrashDialogs()) {
1018                 Slog.e(TAG, "App already has crash dialog: " + proc);
1019                 if (res != null) {
1020                     res.set(AppErrorDialog.ALREADY_SHOWING);
1021                 }
1022                 return;
1023             }
1024             boolean isBackground = (UserHandle.getAppId(proc.uid)
1025                     >= Process.FIRST_APPLICATION_UID
1026                     && proc.getPid() != MY_PID);
1027             for (int profileId : mService.mUserController.getCurrentProfileIds()) {
1028                 isBackground &= (userId != profileId);
1029             }
1030             if (isBackground && !showBackground) {
1031                 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1032                 if (res != null) {
1033                     res.set(AppErrorDialog.BACKGROUND_USER);
1034                 }
1035                 return;
1036             }
1037             Long crashShowErrorTime = null;
1038             synchronized (mBadProcessLock) {
1039                 if (!proc.isolated) {
1040                     crashShowErrorTime = mProcessCrashShowDialogTimes.get(proc.processName,
1041                             proc.uid);
1042                 }
1043                 final boolean showFirstCrash = Settings.Global.getInt(
1044                         mContext.getContentResolver(),
1045                         Settings.Global.SHOW_FIRST_CRASH_DIALOG, 0) != 0;
1046                 final boolean showFirstCrashDevOption = Settings.Secure.getIntForUser(
1047                         mContext.getContentResolver(),
1048                         Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
1049                         0,
1050                         mService.mUserController.getCurrentUserId()) != 0;
1051                 final String packageName = proc.info.packageName;
1052                 final boolean crashSilenced = mAppsNotReportingCrashes != null
1053                         && mAppsNotReportingCrashes.contains(proc.info.packageName);
1054                 final long now = SystemClock.uptimeMillis();
1055                 final boolean shouldThottle = crashShowErrorTime != null
1056                         && now < crashShowErrorTime + ActivityManagerConstants.MIN_CRASH_INTERVAL;
1057                 if ((mService.mAtmInternal.canShowErrorDialogs() || showBackground)
1058                         && !crashSilenced && !shouldThottle
1059                         && (showFirstCrash || showFirstCrashDevOption || data.repeating)) {
1060                     Slog.i(TAG, "Showing crash dialog for package " + packageName + " u" + userId);
1061                     errState.getDialogController().showCrashDialogs(data);
1062                     if (!proc.isolated) {
1063                         mProcessCrashShowDialogTimes.put(proc.processName, proc.uid, now);
1064                     }
1065                 } else {
1066                     // The device is asleep, so just pretend that the user
1067                     // saw a crash dialog and hit "force quit".
1068                     if (res != null) {
1069                         res.set(AppErrorDialog.CANT_SHOW);
1070                     }
1071                 }
1072             }
1073         }
1074     }
1075 
1076     @GuardedBy("mBadProcessLock")
1077     private void stopReportingCrashesLBp(ProcessRecord proc) {
1078         if (mAppsNotReportingCrashes == null) {
1079             mAppsNotReportingCrashes = new ArraySet<>();
1080         }
1081         mAppsNotReportingCrashes.add(proc.info.packageName);
1082     }
1083 
1084     void handleShowAnrUi(Message msg) {
1085         List<VersionedPackage> packageList = null;
1086         boolean doKill = false;
1087         AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;
1088         final ProcessRecord proc = data.proc;
1089         if (proc == null) {
1090             Slog.e(TAG, "handleShowAnrUi: proc is null");
1091             return;
1092         }
1093         synchronized (mProcLock) {
1094             final ProcessErrorStateRecord errState = proc.mErrorState;
1095             errState.setAnrData(data);
1096             if (!proc.isPersistent()) {
1097                 packageList = proc.getPackageListWithVersionCode();
1098             }
1099             if (errState.getDialogController().hasAnrDialogs()) {
1100                 Slog.e(TAG, "App already has anr dialog: " + proc);
1101                 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1102                         AppNotRespondingDialog.ALREADY_SHOWING);
1103                 return;
1104             }
1105 
1106             boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
1107                     Settings.Secure.ANR_SHOW_BACKGROUND, 0,
1108                     mService.mUserController.getCurrentUserId()) != 0;
1109             if (mService.mAtmInternal.canShowErrorDialogs() || showBackground) {
1110                 AnrController anrController = errState.getDialogController().getAnrController();
1111                 if (anrController == null) {
1112                     errState.getDialogController().showAnrDialogs(data);
1113                 } else {
1114                     String packageName = proc.info.packageName;
1115                     int uid = proc.info.uid;
1116                     boolean showDialog = anrController.onAnrDelayCompleted(packageName, uid);
1117 
1118                     if (showDialog) {
1119                         Slog.d(TAG, "ANR delay completed. Showing ANR dialog for package: "
1120                                 + packageName);
1121                         errState.getDialogController().showAnrDialogs(data);
1122                     } else {
1123                         Slog.d(TAG, "ANR delay completed. Cancelling ANR dialog for package: "
1124                                 + packageName);
1125                         errState.setNotResponding(false);
1126                         errState.setNotRespondingReport(null);
1127                         errState.getDialogController().clearAnrDialogs();
1128                     }
1129                 }
1130             } else {
1131                 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1132                         AppNotRespondingDialog.CANT_SHOW);
1133                 // Just kill the app if there is no dialog to be shown.
1134                 doKill = true;
1135             }
1136         }
1137         if (doKill) {
1138             mService.killAppAtUsersRequest(proc);
1139         }
1140         // Notify PackageWatchdog without the lock held
1141         if (packageList != null) {
1142             mPackageWatchdog.onPackageFailure(packageList,
1143                     PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
1144         }
1145     }
1146 
1147     void handleDismissAnrDialogs(ProcessRecord proc) {
1148         synchronized (mProcLock) {
1149             final ProcessErrorStateRecord errState = proc.mErrorState;
1150 
1151             // Cancel any rescheduled ANR dialogs
1152             mService.mUiHandler.removeMessages(
1153                     ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG, errState.getAnrData());
1154 
1155             // Dismiss any ANR dialogs currently visible
1156             if (errState.getDialogController().hasAnrDialogs()) {
1157                 errState.setNotResponding(false);
1158                 errState.setNotRespondingReport(null);
1159                 errState.getDialogController().clearAnrDialogs();
1160             }
1161             proc.mErrorState.setAnrData(null);
1162         }
1163     }
1164 
1165     /**
1166      * Information about a process that is currently marked as bad.
1167      */
1168     static final class BadProcessInfo {
1169         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
1170             this.time = time;
1171             this.shortMsg = shortMsg;
1172             this.longMsg = longMsg;
1173             this.stack = stack;
1174         }
1175 
1176         final long time;
1177         final String shortMsg;
1178         final String longMsg;
1179         final String stack;
1180     }
1181 
1182 }
1183