• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         proc.scheduleCrashLocked(message, exceptionTypeId, extras);
538         if (force) {
539             // If the app is responsive, the scheduled crash will happen as expected
540             // and then the delayed summary kill will be a no-op.
541             final ProcessRecord p = proc;
542             mService.mHandler.postDelayed(
543                     () -> {
544                         synchronized (mService) {
545                             synchronized (mProcLock) {
546                                 killAppImmediateLSP(p, ApplicationExitInfo.REASON_OTHER,
547                                         ApplicationExitInfo.SUBREASON_INVALID_STATE,
548                                         "forced", "killed for invalid state");
549                             }
550                         }
551                     },
552                     5000L);
553         }
554     }
555 
556     /**
557      * Bring up the "unexpected error" dialog box for a crashing app.
558      * Deal with edge cases (intercepts from instrumented applications,
559      * ActivityController, error intent receivers, that sort of thing).
560      * @param r the application crashing
561      * @param crashInfo describing the failure
562      */
crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo)563     void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
564         final int callingPid = Binder.getCallingPid();
565         final int callingUid = Binder.getCallingUid();
566 
567         final long origId = Binder.clearCallingIdentity();
568         try {
569             crashApplicationInner(r, crashInfo, callingPid, callingUid);
570         } finally {
571             Binder.restoreCallingIdentity(origId);
572         }
573     }
574 
crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo, int callingPid, int callingUid)575     private void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo,
576             int callingPid, int callingUid) {
577         long timeMillis = System.currentTimeMillis();
578         String shortMsg = crashInfo.exceptionClassName;
579         String longMsg = crashInfo.exceptionMessage;
580         String stackTrace = crashInfo.stackTrace;
581         if (shortMsg != null && longMsg != null) {
582             longMsg = shortMsg + ": " + longMsg;
583         } else if (shortMsg != null) {
584             longMsg = shortMsg;
585         }
586 
587         if (r != null) {
588             mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode(),
589                     PackageWatchdog.FAILURE_REASON_APP_CRASH);
590 
591             synchronized (mService) {
592                 mService.mProcessList.noteAppKill(r, (crashInfo != null
593                           && "Native crash".equals(crashInfo.exceptionClassName))
594                           ? ApplicationExitInfo.REASON_CRASH_NATIVE
595                           : ApplicationExitInfo.REASON_CRASH,
596                           ApplicationExitInfo.SUBREASON_UNKNOWN,
597                         "crash");
598             }
599         }
600 
601         final int relaunchReason = r != null
602                 ? r.getWindowProcessController().computeRelaunchReason() : RELAUNCH_REASON_NONE;
603 
604         AppErrorResult result = new AppErrorResult();
605         int taskId;
606         synchronized (mService) {
607             /**
608              * If crash is handled by instance of {@link android.app.IActivityController},
609              * finish now and don't show the app error dialog.
610              */
611             if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace,
612                     timeMillis, callingPid, callingUid)) {
613                 return;
614             }
615 
616             // Suppress crash dialog if the process is being relaunched due to a crash during a free
617             // resize.
618             if (relaunchReason == RELAUNCH_REASON_FREE_RESIZE) {
619                 return;
620             }
621 
622             /**
623              * If this process was running instrumentation, finish now - it will be handled in
624              * {@link ActivityManagerService#handleAppDiedLocked}.
625              */
626             if (r != null && r.getActiveInstrumentation() != null) {
627                 return;
628             }
629 
630             // Log crash in battery stats.
631             if (r != null) {
632                 mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
633             }
634 
635             AppErrorDialog.Data data = new AppErrorDialog.Data();
636             data.result = result;
637             data.proc = r;
638 
639             // If we can't identify the process or it's already exceeded its crash quota,
640             // quit right away without showing a crash dialog.
641             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
642                 return;
643             }
644 
645             final Message msg = Message.obtain();
646             msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
647 
648             taskId = data.taskId;
649             msg.obj = data;
650             mService.mUiHandler.sendMessage(msg);
651         }
652 
653         int res = result.get();
654 
655         Intent appErrorIntent = null;
656         MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
657         if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) {
658             res = AppErrorDialog.FORCE_QUIT;
659         }
660         switch (res) {
661             case AppErrorDialog.MUTE:
662                 synchronized (mBadProcessLock) {
663                     stopReportingCrashesLBp(r);
664                 }
665                 break;
666             case AppErrorDialog.RESTART:
667                 synchronized (mService) {
668                     mService.mProcessList.removeProcessLocked(r, false, true,
669                             ApplicationExitInfo.REASON_CRASH, "crash");
670                 }
671                 if (taskId != INVALID_TASK_ID) {
672                     try {
673                         mService.startActivityFromRecents(taskId,
674                                 ActivityOptions.makeBasic().toBundle());
675                     } catch (IllegalArgumentException e) {
676                         // Hmm...that didn't work. Task should either be in recents or associated
677                         // with a stack.
678                         Slog.e(TAG, "Could not restart taskId=" + taskId, e);
679                     }
680                 }
681                 break;
682             case AppErrorDialog.FORCE_QUIT:
683                 final long orig = Binder.clearCallingIdentity();
684                 try {
685                     // Kill it with fire!
686                     mService.mAtmInternal.onHandleAppCrash(r.getWindowProcessController());
687                     if (!r.isPersistent()) {
688                         synchronized (mService) {
689                             mService.mProcessList.removeProcessLocked(r, false, false,
690                                     ApplicationExitInfo.REASON_CRASH, "crash");
691                         }
692                         mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
693                     }
694                 } finally {
695                     Binder.restoreCallingIdentity(orig);
696                 }
697                 break;
698             case AppErrorDialog.APP_INFO:
699                 appErrorIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
700                 appErrorIntent.setData(Uri.parse("package:" + r.info.packageName));
701                 appErrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
702                 break;
703             case AppErrorDialog.FORCE_QUIT_AND_REPORT:
704                 synchronized (mProcLock) {
705                     appErrorIntent = createAppErrorIntentLOSP(r, timeMillis, crashInfo);
706                 }
707                 break;
708         }
709 
710         if (appErrorIntent != null) {
711             try {
712                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
713             } catch (ActivityNotFoundException e) {
714                 Slog.w(TAG, "bug report receiver dissappeared", e);
715             }
716         }
717     }
718 
719     @GuardedBy("mService")
handleAppCrashInActivityController(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo, String shortMsg, String longMsg, String stackTrace, long timeMillis, int callingPid, int callingUid)720     private boolean handleAppCrashInActivityController(ProcessRecord r,
721                                                        ApplicationErrorReport.CrashInfo crashInfo,
722                                                        String shortMsg, String longMsg,
723                                                        String stackTrace, long timeMillis,
724                                                        int callingPid, int callingUid) {
725         String name = r != null ? r.processName : null;
726         int pid = r != null ? r.getPid() : callingPid;
727         int uid = r != null ? r.info.uid : callingUid;
728 
729         return mService.mAtmInternal.handleAppCrashInActivityController(
730                 name, pid, shortMsg, longMsg, timeMillis, crashInfo.stackTrace, () -> {
731                 if (Build.IS_DEBUGGABLE
732                         && "Native crash".equals(crashInfo.exceptionClassName)) {
733                     Slog.w(TAG, "Skip killing native crashed app " + name
734                             + "(" + pid + ") during testing");
735                 } else {
736                     Slog.w(TAG, "Force-killing crashed app " + name + " at watcher's request");
737                     if (r != null) {
738                         if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null)) {
739                             r.killLocked("crash", ApplicationExitInfo.REASON_CRASH, true);
740                         }
741                     } else {
742                         // Huh.
743                         Process.killProcess(pid);
744                         ProcessList.killProcessGroup(uid, pid);
745                         mService.mProcessList.noteAppKill(pid, uid,
746                                 ApplicationExitInfo.REASON_CRASH,
747                                 ApplicationExitInfo.SUBREASON_UNKNOWN,
748                                 "crash");
749                     }
750                 }
751         });
752     }
753 
754     @GuardedBy("mService")
755     private boolean makeAppCrashingLocked(ProcessRecord app,
756             String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
757         synchronized (mProcLock) {
758             final ProcessErrorStateRecord errState = app.mErrorState;
759             errState.setCrashing(true);
760             errState.setCrashingReport(generateProcessError(app,
761                     ActivityManager.ProcessErrorStateInfo.CRASHED,
762                     null, shortMsg, longMsg, stackTrace));
763             errState.startAppProblemLSP();
764             app.getWindowProcessController().stopFreezingActivities();
765             synchronized (mBadProcessLock) {
766                 return handleAppCrashLSPB(app, "force-crash" /*reason*/, shortMsg, longMsg,
767                         stackTrace, data);
768             }
769         }
770     }
771 
772     /**
773      * Generate a process error record, suitable for attachment to a ProcessRecord.
774      *
775      * @param app The ProcessRecord in which the error occurred.
776      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
777      *                      ActivityManager.ProcessErrorStateInfo
778      * @param activity The activity associated with the crash, if known.
779      * @param shortMsg Short message describing the crash.
780      * @param longMsg Long message describing the crash.
781      * @param stackTrace Full crash stack trace, may be null.
782      *
783      * @return Returns a fully-formed ProcessErrorStateInfo record.
784      */
785     ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
786             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
787         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
788 
789         report.condition = condition;
790         report.processName = app.processName;
791         report.pid = app.getPid();
792         report.uid = app.info.uid;
793         report.tag = activity;
794         report.shortMsg = shortMsg;
795         report.longMsg = longMsg;
796         report.stackTrace = stackTrace;
797 
798         return report;
799     }
800 
801     @GuardedBy(anyOf = {"mService", "mProcLock"})
802     Intent createAppErrorIntentLOSP(ProcessRecord r,
803             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
804         ApplicationErrorReport report = createAppErrorReportLOSP(r, timeMillis, crashInfo);
805         if (report == null) {
806             return null;
807         }
808         Intent result = new Intent(Intent.ACTION_APP_ERROR);
809         result.setComponent(r.mErrorState.getErrorReportReceiver());
810         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
811         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
812         return result;
813     }
814 
815     @GuardedBy(anyOf = {"mService", "mProcLock"})
816     private ApplicationErrorReport createAppErrorReportLOSP(ProcessRecord r,
817             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
818         final ProcessErrorStateRecord errState = r.mErrorState;
819         if (errState.getErrorReportReceiver() == null) {
820             return null;
821         }
822 
823         if (!errState.isCrashing() && !errState.isNotResponding()
824                 && !errState.isForceCrashReport()) {
825             return null;
826         }
827 
828         ApplicationErrorReport report = new ApplicationErrorReport();
829         report.packageName = r.info.packageName;
830         report.installerPackageName = errState.getErrorReportReceiver().getPackageName();
831         report.processName = r.processName;
832         report.time = timeMillis;
833         report.systemApp = (r.info.flags & FLAG_SYSTEM) != 0;
834 
835         if (errState.isCrashing() || errState.isForceCrashReport()) {
836             report.type = ApplicationErrorReport.TYPE_CRASH;
837             report.crashInfo = crashInfo;
838         } else if (errState.isNotResponding()) {
839             final ActivityManager.ProcessErrorStateInfo anrReport =
840                     errState.getNotRespondingReport();
841             if (anrReport == null) {
842                 // The ANR dump is still ongoing, ignore it for now.
843                 return null;
844             }
845             report.type = ApplicationErrorReport.TYPE_ANR;
846             report.anrInfo = new ApplicationErrorReport.AnrInfo();
847 
848             report.anrInfo.activity = anrReport.tag;
849             report.anrInfo.cause = anrReport.shortMsg;
850             report.anrInfo.info = anrReport.longMsg;
851         }
852 
853         return report;
854     }
855 
856     @GuardedBy({"mService", "mProcLock", "mBadProcessLock"})
857     private boolean handleAppCrashLSPB(ProcessRecord app, String reason,
858             String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
859         final long now = SystemClock.uptimeMillis();
860         final boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
861                 Settings.Secure.ANR_SHOW_BACKGROUND, 0,
862                 mService.mUserController.getCurrentUserId()) != 0;
863 
864         Long crashTime;
865         Long crashTimePersistent;
866         final String processName = app.processName;
867         final int uid = app.uid;
868         final int userId = app.userId;
869         final boolean isolated = app.isolated;
870         final boolean persistent = app.isPersistent();
871         final WindowProcessController proc = app.getWindowProcessController();
872         final ProcessErrorStateRecord errState = app.mErrorState;
873 
874         if (!app.isolated) {
875             crashTime = mProcessCrashTimes.get(processName, uid);
876             crashTimePersistent = mProcessCrashTimesPersistent.get(processName, uid);
877         } else {
878             crashTime = crashTimePersistent = null;
879         }
880 
881         // Bump up the crash count of any services currently running in the proc.
882         boolean tryAgain = app.mServices.incServiceCrashCountLocked(now);
883 
884         final boolean quickCrash = crashTime != null
885                 && now < crashTime + ActivityManagerConstants.MIN_CRASH_INTERVAL;
886         if (quickCrash || isProcOverCrashLimitLBp(app, now)) {
887             // The process either crashed again very quickly or has been crashing periodically in
888             // the last few hours. If it was a bound foreground service, let's try to restart again
889             // in a while, otherwise the process loses!
890             Slog.w(TAG, "Process " + processName + " has crashed too many times, killing!"
891                     + " Reason: " + (quickCrash ? "crashed quickly" : "over process crash limit"));
892             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
893                     userId, processName, uid);
894             mService.mAtmInternal.onHandleAppCrash(proc);
895             if (!persistent) {
896                 // We don't want to start this process again until the user
897                 // explicitly does so...  but for persistent process, we really
898                 // need to keep it running.  If a persistent process is actually
899                 // repeatedly crashing, then badness for everyone.
900                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, userId, uid,
901                         processName);
902                 if (!isolated) {
903                     // XXX We don't have a way to mark isolated processes
904                     // as bad, since they don't have a persistent identity.
905                     markBadProcess(processName, app.uid,
906                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
907                     mProcessCrashTimes.remove(processName, app.uid);
908                     mProcessCrashCounts.remove(processName, app.uid);
909                 }
910                 errState.setBad(true);
911                 app.setRemoved(true);
912                 final AppStandbyInternal appStandbyInternal =
913                         LocalServices.getService(AppStandbyInternal.class);
914                 if (appStandbyInternal != null) {
915                     appStandbyInternal.restrictApp(
916                             // Sometimes the processName is the same as the package name, so use
917                             // that if we don't have the ApplicationInfo object.
918                             // AppStandbyController will just return if it can't find the app.
919                             app.info != null ? app.info.packageName : processName,
920                             userId, UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY);
921                 }
922                 // Don't let services in this process be restarted and potentially
923                 // annoy the user repeatedly.  Unless it is persistent, since those
924                 // processes run critical code.
925                 mService.mProcessList.removeProcessLocked(app, false, tryAgain,
926                         ApplicationExitInfo.REASON_CRASH, "crash");
927                 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
928                 if (!showBackground) {
929                     return false;
930                 }
931             }
932             mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
933         } else {
934             final int affectedTaskId = mService.mAtmInternal.finishTopCrashedActivities(
935                             proc, reason);
936             if (data != null) {
937                 data.taskId = affectedTaskId;
938             }
939             if (data != null && crashTimePersistent != null
940                     && now < crashTimePersistent + ActivityManagerConstants.MIN_CRASH_INTERVAL) {
941                 data.repeating = true;
942             }
943         }
944 
945         if (data != null && tryAgain) {
946             data.isRestartableForService = true;
947         }
948 
949         // If the crashing process is what we consider to be the "home process" and it has been
950         // replaced by a third-party app, clear the package preferred activities from packages
951         // with a home activity running in the process to prevent a repeatedly crashing app
952         // from blocking the user to manually clear the list.
953         if (proc.isHomeProcess() && proc.hasActivities() && (app.info.flags & FLAG_SYSTEM) == 0) {
954             proc.clearPackagePreferredForHomeActivities();
955         }
956 
957         if (!isolated) {
958             // XXX Can't keep track of crash times for isolated processes,
959             // because they don't have a persistent identity.
960             mProcessCrashTimes.put(processName, uid, now);
961             mProcessCrashTimesPersistent.put(processName, uid, now);
962             updateProcessCrashCountLBp(processName, uid, now);
963         }
964 
965         if (errState.getCrashHandler() != null) {
966             mService.mHandler.post(errState.getCrashHandler());
967         }
968         return true;
969     }
970 
971     @GuardedBy("mBadProcessLock")
972     private void updateProcessCrashCountLBp(String processName, int uid, long now) {
973         Pair<Long, Integer> count = mProcessCrashCounts.get(processName, uid);
974         if (count == null || (count.first + PROCESS_CRASH_COUNT_RESET_INTERVAL) < now) {
975             count = new Pair<>(now, 1);
976         } else {
977             count = new Pair<>(count.first, count.second + 1);
978         }
979         mProcessCrashCounts.put(processName, uid, count);
980     }
981 
982     @GuardedBy("mBadProcessLock")
983     private boolean isProcOverCrashLimitLBp(ProcessRecord app, long now) {
984         final Pair<Long, Integer> crashCount = mProcessCrashCounts.get(app.processName, app.uid);
985         return !app.isolated && crashCount != null
986                 && now < (crashCount.first + PROCESS_CRASH_COUNT_RESET_INTERVAL)
987                 && crashCount.second >= PROCESS_CRASH_COUNT_LIMIT;
988     }
989 
990     void handleShowAppErrorUi(Message msg) {
991         AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
992         boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
993                 Settings.Secure.ANR_SHOW_BACKGROUND, 0,
994                 mService.mUserController.getCurrentUserId()) != 0;
995 
996         final int userId;
997         synchronized (mProcLock) {
998             final ProcessRecord proc = data.proc;
999             final AppErrorResult res = data.result;
1000             if (proc == null) {
1001                 Slog.e(TAG, "handleShowAppErrorUi: proc is null");
1002                 return;
1003             }
1004             final ProcessErrorStateRecord errState = proc.mErrorState;
1005             userId = proc.userId;
1006             if (errState.getDialogController().hasCrashDialogs()) {
1007                 Slog.e(TAG, "App already has crash dialog: " + proc);
1008                 if (res != null) {
1009                     res.set(AppErrorDialog.ALREADY_SHOWING);
1010                 }
1011                 return;
1012             }
1013             boolean isBackground = (UserHandle.getAppId(proc.uid)
1014                     >= Process.FIRST_APPLICATION_UID
1015                     && proc.getPid() != MY_PID);
1016             for (int profileId : mService.mUserController.getCurrentProfileIds()) {
1017                 isBackground &= (userId != profileId);
1018             }
1019             if (isBackground && !showBackground) {
1020                 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1021                 if (res != null) {
1022                     res.set(AppErrorDialog.BACKGROUND_USER);
1023                 }
1024                 return;
1025             }
1026             Long crashShowErrorTime = null;
1027             synchronized (mBadProcessLock) {
1028                 if (!proc.isolated) {
1029                     crashShowErrorTime = mProcessCrashShowDialogTimes.get(proc.processName,
1030                             proc.uid);
1031                 }
1032                 final boolean showFirstCrash = Settings.Global.getInt(
1033                         mContext.getContentResolver(),
1034                         Settings.Global.SHOW_FIRST_CRASH_DIALOG, 0) != 0;
1035                 final boolean showFirstCrashDevOption = Settings.Secure.getIntForUser(
1036                         mContext.getContentResolver(),
1037                         Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
1038                         0,
1039                         mService.mUserController.getCurrentUserId()) != 0;
1040                 final String packageName = proc.info.packageName;
1041                 final boolean crashSilenced = mAppsNotReportingCrashes != null
1042                         && mAppsNotReportingCrashes.contains(proc.info.packageName);
1043                 final long now = SystemClock.uptimeMillis();
1044                 final boolean shouldThottle = crashShowErrorTime != null
1045                         && now < crashShowErrorTime + ActivityManagerConstants.MIN_CRASH_INTERVAL;
1046                 if ((mService.mAtmInternal.canShowErrorDialogs() || showBackground)
1047                         && !crashSilenced && !shouldThottle
1048                         && (showFirstCrash || showFirstCrashDevOption || data.repeating)) {
1049                     Slog.i(TAG, "Showing crash dialog for package " + packageName + " u" + userId);
1050                     errState.getDialogController().showCrashDialogs(data);
1051                     if (!proc.isolated) {
1052                         mProcessCrashShowDialogTimes.put(proc.processName, proc.uid, now);
1053                     }
1054                 } else {
1055                     // The device is asleep, so just pretend that the user
1056                     // saw a crash dialog and hit "force quit".
1057                     if (res != null) {
1058                         res.set(AppErrorDialog.CANT_SHOW);
1059                     }
1060                 }
1061             }
1062         }
1063     }
1064 
1065     @GuardedBy("mBadProcessLock")
1066     private void stopReportingCrashesLBp(ProcessRecord proc) {
1067         if (mAppsNotReportingCrashes == null) {
1068             mAppsNotReportingCrashes = new ArraySet<>();
1069         }
1070         mAppsNotReportingCrashes.add(proc.info.packageName);
1071     }
1072 
1073     void handleShowAnrUi(Message msg) {
1074         List<VersionedPackage> packageList = null;
1075         boolean doKill = false;
1076         AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;
1077         final ProcessRecord proc = data.proc;
1078         if (proc == null) {
1079             Slog.e(TAG, "handleShowAnrUi: proc is null");
1080             return;
1081         }
1082         synchronized (mProcLock) {
1083             final ProcessErrorStateRecord errState = proc.mErrorState;
1084             errState.setAnrData(data);
1085             if (!proc.isPersistent()) {
1086                 packageList = proc.getPackageListWithVersionCode();
1087             }
1088             if (errState.getDialogController().hasAnrDialogs()) {
1089                 Slog.e(TAG, "App already has anr dialog: " + proc);
1090                 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1091                         AppNotRespondingDialog.ALREADY_SHOWING);
1092                 return;
1093             }
1094 
1095             boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
1096                     Settings.Secure.ANR_SHOW_BACKGROUND, 0,
1097                     mService.mUserController.getCurrentUserId()) != 0;
1098             if (mService.mAtmInternal.canShowErrorDialogs() || showBackground) {
1099                 AnrController anrController = errState.getDialogController().getAnrController();
1100                 if (anrController == null) {
1101                     errState.getDialogController().showAnrDialogs(data);
1102                 } else {
1103                     String packageName = proc.info.packageName;
1104                     int uid = proc.info.uid;
1105                     boolean showDialog = anrController.onAnrDelayCompleted(packageName, uid);
1106 
1107                     if (showDialog) {
1108                         Slog.d(TAG, "ANR delay completed. Showing ANR dialog for package: "
1109                                 + packageName);
1110                         errState.getDialogController().showAnrDialogs(data);
1111                     } else {
1112                         Slog.d(TAG, "ANR delay completed. Cancelling ANR dialog for package: "
1113                                 + packageName);
1114                         errState.setNotResponding(false);
1115                         errState.setNotRespondingReport(null);
1116                         errState.getDialogController().clearAnrDialogs();
1117                     }
1118                 }
1119             } else {
1120                 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1121                         AppNotRespondingDialog.CANT_SHOW);
1122                 // Just kill the app if there is no dialog to be shown.
1123                 doKill = true;
1124             }
1125         }
1126         if (doKill) {
1127             mService.killAppAtUsersRequest(proc);
1128         }
1129         // Notify PackageWatchdog without the lock held
1130         if (packageList != null) {
1131             mPackageWatchdog.onPackageFailure(packageList,
1132                     PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
1133         }
1134     }
1135 
1136     void handleDismissAnrDialogs(ProcessRecord proc) {
1137         synchronized (mProcLock) {
1138             final ProcessErrorStateRecord errState = proc.mErrorState;
1139 
1140             // Cancel any rescheduled ANR dialogs
1141             mService.mUiHandler.removeMessages(
1142                     ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG, errState.getAnrData());
1143 
1144             // Dismiss any ANR dialogs currently visible
1145             if (errState.getDialogController().hasAnrDialogs()) {
1146                 errState.setNotResponding(false);
1147                 errState.setNotRespondingReport(null);
1148                 errState.getDialogController().clearAnrDialogs();
1149             }
1150             proc.mErrorState.setAnrData(null);
1151         }
1152     }
1153 
1154     /**
1155      * Information about a process that is currently marked as bad.
1156      */
1157     static final class BadProcessInfo {
1158         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
1159             this.time = time;
1160             this.shortMsg = shortMsg;
1161             this.longMsg = longMsg;
1162             this.stack = stack;
1163         }
1164 
1165         final long time;
1166         final String shortMsg;
1167         final String longMsg;
1168         final String stack;
1169     }
1170 
1171 }
1172