• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.os.Process.SYSTEM_UID;
20 
21 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
22 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
23 import static com.android.server.am.ActivityManagerService.MY_PID;
24 import static com.android.server.am.ProcessRecord.TAG;
25 
26 import android.app.ActivityManager;
27 import android.app.AnrController;
28 import android.app.ApplicationErrorReport;
29 import android.app.ApplicationExitInfo;
30 import android.content.ComponentName;
31 import android.content.Context;
32 import android.content.pm.ApplicationInfo;
33 import android.content.pm.IncrementalStatesInfo;
34 import android.content.pm.PackageManagerInternal;
35 import android.os.IBinder;
36 import android.os.Message;
37 import android.os.Process;
38 import android.os.ServiceManager;
39 import android.os.SystemClock;
40 import android.os.incremental.IIncrementalService;
41 import android.os.incremental.IncrementalManager;
42 import android.os.incremental.IncrementalMetrics;
43 import android.provider.Settings;
44 import android.util.EventLog;
45 import android.util.Slog;
46 import android.util.SparseArray;
47 
48 import com.android.internal.annotations.CompositeRWLock;
49 import com.android.internal.annotations.GuardedBy;
50 import com.android.internal.annotations.VisibleForTesting;
51 import com.android.internal.os.ProcessCpuTracker;
52 import com.android.internal.util.FrameworkStatsLog;
53 import com.android.server.MemoryPressureUtil;
54 import com.android.server.criticalevents.CriticalEventLog;
55 import com.android.server.wm.WindowProcessController;
56 
57 import java.io.File;
58 import java.io.PrintWriter;
59 import java.io.StringWriter;
60 import java.util.ArrayList;
61 import java.util.UUID;
62 /**
63  * The error state of the process, such as if it's crashing/ANR etc.
64  */
65 class ProcessErrorStateRecord {
66     final ProcessRecord mApp;
67     private final ActivityManagerService mService;
68 
69     private final ActivityManagerGlobalLock mProcLock;
70 
71     /**
72      * True if disabled in the bad process list.
73      */
74     @CompositeRWLock({"mService", "mProcLock"})
75     private boolean mBad;
76 
77     /**
78      * Are we in the process of crashing?
79      */
80     @CompositeRWLock({"mService", "mProcLock"})
81     private boolean mCrashing;
82 
83     /**
84      * Suppress normal auto-dismiss of crash dialog & report UI?
85      */
86     @CompositeRWLock({"mService", "mProcLock"})
87     private boolean mForceCrashReport;
88 
89     /**
90      * Does the app have a not responding dialog?
91      */
92     @CompositeRWLock({"mService", "mProcLock"})
93     private boolean mNotResponding;
94 
95     /**
96      * The report about crash of the app, generated & stored when an app gets into a crash.
97      * Will be "null" when all is OK.
98      */
99     @CompositeRWLock({"mService", "mProcLock"})
100     private ActivityManager.ProcessErrorStateInfo mCrashingReport;
101 
102     /**
103      * The report about ANR of the app, generated & stored when an app gets into an ANR.
104      * Will be "null" when all is OK.
105      */
106     @CompositeRWLock({"mService", "mProcLock"})
107     private ActivityManager.ProcessErrorStateInfo mNotRespondingReport;
108 
109     /**
110      * Controller for error dialogs.
111      */
112     @CompositeRWLock({"mService", "mProcLock"})
113     private final ErrorDialogController mDialogController;
114 
115     /**
116      * Who will be notified of the error. This is usually an activity in the
117      * app that installed the package.
118      */
119     @CompositeRWLock({"mService", "mProcLock"})
120     private ComponentName mErrorReportReceiver;
121 
122     /**
123      * ANR dialog data used to dismiss any visible ANR dialogs if the app becomes responsive.
124      */
125     @CompositeRWLock({"mService", "mProcLock"})
126     private AppNotRespondingDialog.Data mAnrData;
127 
128     /**
129      * Annotation from process killed due to an ANR.
130      */
131     @GuardedBy("mService")
132     private String mAnrAnnotation;
133 
134     /**
135      * Optional local handler to be invoked in the process crash.
136      */
137     @CompositeRWLock({"mService", "mProcLock"})
138     private Runnable mCrashHandler;
139 
140     @GuardedBy(anyOf = {"mService", "mProcLock"})
isBad()141     boolean isBad() {
142         return mBad;
143     }
144 
145     @GuardedBy({"mService", "mProcLock"})
setBad(boolean bad)146     void setBad(boolean bad) {
147         mBad = bad;
148     }
149 
150     @GuardedBy(anyOf = {"mService", "mProcLock"})
isCrashing()151     boolean isCrashing() {
152         return mCrashing;
153     }
154 
155     @GuardedBy({"mService", "mProcLock"})
setCrashing(boolean crashing)156     void setCrashing(boolean crashing) {
157         mCrashing = crashing;
158         mApp.getWindowProcessController().setCrashing(crashing);
159     }
160 
161     @GuardedBy(anyOf = {"mService", "mProcLock"})
isForceCrashReport()162     boolean isForceCrashReport() {
163         return mForceCrashReport;
164     }
165 
166     @GuardedBy({"mService", "mProcLock"})
setForceCrashReport(boolean forceCrashReport)167     void setForceCrashReport(boolean forceCrashReport) {
168         mForceCrashReport = forceCrashReport;
169     }
170 
171     @GuardedBy(anyOf = {"mService", "mProcLock"})
isNotResponding()172     boolean isNotResponding() {
173         return mNotResponding;
174     }
175 
176     @GuardedBy({"mService", "mProcLock"})
setNotResponding(boolean notResponding)177     void setNotResponding(boolean notResponding) {
178         mNotResponding = notResponding;
179         mApp.getWindowProcessController().setNotResponding(notResponding);
180     }
181 
182     @GuardedBy(anyOf = {"mService", "mProcLock"})
getCrashHandler()183     Runnable getCrashHandler() {
184         return mCrashHandler;
185     }
186 
187     @GuardedBy({"mService", "mProcLock"})
setCrashHandler(Runnable crashHandler)188     void setCrashHandler(Runnable crashHandler) {
189         mCrashHandler = crashHandler;
190     }
191 
192     @GuardedBy(anyOf = {"mService", "mProcLock"})
getCrashingReport()193     ActivityManager.ProcessErrorStateInfo getCrashingReport() {
194         return mCrashingReport;
195     }
196 
197     @GuardedBy({"mService", "mProcLock"})
setCrashingReport(ActivityManager.ProcessErrorStateInfo crashingReport)198     void setCrashingReport(ActivityManager.ProcessErrorStateInfo crashingReport) {
199         mCrashingReport = crashingReport;
200     }
201 
202     @GuardedBy("mService")
getAnrAnnotation()203     String getAnrAnnotation() {
204         return mAnrAnnotation;
205     }
206 
207     @GuardedBy("mService")
setAnrAnnotation(String anrAnnotation)208     void setAnrAnnotation(String anrAnnotation) {
209         mAnrAnnotation = anrAnnotation;
210     }
211 
212     @GuardedBy(anyOf = {"mService", "mProcLock"})
getNotRespondingReport()213     ActivityManager.ProcessErrorStateInfo getNotRespondingReport() {
214         return mNotRespondingReport;
215     }
216 
217     @GuardedBy({"mService", "mProcLock"})
setNotRespondingReport(ActivityManager.ProcessErrorStateInfo notRespondingReport)218     void setNotRespondingReport(ActivityManager.ProcessErrorStateInfo notRespondingReport) {
219         mNotRespondingReport = notRespondingReport;
220     }
221 
222     @GuardedBy(anyOf = {"mService", "mProcLock"})
getErrorReportReceiver()223     ComponentName getErrorReportReceiver() {
224         return mErrorReportReceiver;
225     }
226 
227     @GuardedBy({"mService", "mProcLock"})
setErrorReportReceiver(ComponentName errorReportReceiver)228     void setErrorReportReceiver(ComponentName errorReportReceiver) {
229         mErrorReportReceiver = errorReportReceiver;
230     }
231 
232     @GuardedBy(anyOf = {"mService", "mProcLock"})
getDialogController()233     ErrorDialogController getDialogController() {
234         return mDialogController;
235     }
236 
237     @GuardedBy({"mService", "mProcLock"})
setAnrData(AppNotRespondingDialog.Data data)238     void setAnrData(AppNotRespondingDialog.Data data) {
239         mAnrData = data;
240     }
241 
242     @GuardedBy(anyOf = {"mService", "mProcLock"})
getAnrData()243     AppNotRespondingDialog.Data getAnrData() {
244         return mAnrData;
245     }
246 
ProcessErrorStateRecord(ProcessRecord app)247     ProcessErrorStateRecord(ProcessRecord app) {
248         mApp = app;
249         mService = app.mService;
250         mProcLock = mService.mProcLock;
251         mDialogController = new ErrorDialogController(app);
252     }
253 
appNotResponding(String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, WindowProcessController parentProcess, boolean aboveSystem, String annotation, boolean onlyDumpSelf)254     void appNotResponding(String activityShortComponentName, ApplicationInfo aInfo,
255             String parentShortComponentName, WindowProcessController parentProcess,
256             boolean aboveSystem, String annotation, boolean onlyDumpSelf) {
257         ArrayList<Integer> firstPids = new ArrayList<>(5);
258         SparseArray<Boolean> lastPids = new SparseArray<>(20);
259 
260         mApp.getWindowProcessController().appEarlyNotResponding(annotation, () -> {
261             synchronized (mService) {
262                 // Store annotation here as instance below races with this killLocked.
263                 setAnrAnnotation(annotation);
264                 mApp.killLocked("anr", ApplicationExitInfo.REASON_ANR, true);
265             }
266         });
267 
268         long anrTime = SystemClock.uptimeMillis();
269         if (isMonitorCpuUsage()) {
270             mService.updateCpuStatsNow();
271         }
272 
273         final boolean isSilentAnr;
274         final int pid = mApp.getPid();
275         final UUID errorId;
276         synchronized (mService) {
277             // Store annotation here as instance above will not be hit on all paths.
278             setAnrAnnotation(annotation);
279 
280             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
281             if (mService.mAtmInternal.isShuttingDown()) {
282                 Slog.i(TAG, "During shutdown skipping ANR: " + this + " " + annotation);
283                 return;
284             } else if (isNotResponding()) {
285                 Slog.i(TAG, "Skipping duplicate ANR: " + this + " " + annotation);
286                 return;
287             } else if (isCrashing()) {
288                 Slog.i(TAG, "Crashing app skipping ANR: " + this + " " + annotation);
289                 return;
290             } else if (mApp.isKilledByAm()) {
291                 Slog.i(TAG, "App already killed by AM skipping ANR: " + this + " " + annotation);
292                 return;
293             } else if (mApp.isKilled()) {
294                 Slog.i(TAG, "Skipping died app ANR: " + this + " " + annotation);
295                 return;
296             }
297 
298             // In case we come through here for the same app before completing
299             // this one, mark as anring now so we will bail out.
300             synchronized (mProcLock) {
301                 setNotResponding(true);
302             }
303 
304             // Log the ANR to the event log.
305             EventLog.writeEvent(EventLogTags.AM_ANR, mApp.userId, pid, mApp.processName,
306                     mApp.info.flags, annotation);
307 
308             if (mService.mTraceErrorLogger != null
309                     && mService.mTraceErrorLogger.isAddErrorIdEnabled()) {
310                 errorId = mService.mTraceErrorLogger.generateErrorId();
311                 mService.mTraceErrorLogger.addErrorIdToTrace(mApp.processName, errorId);
312                 mService.mTraceErrorLogger.addSubjectToTrace(annotation, errorId);
313             } else {
314                 errorId = null;
315             }
316 
317             // This atom is only logged with the purpose of triggering Perfetto and the logging
318             // needs to happen as close as possible to the time when the ANR is detected.
319             // Also, it needs to be logged after adding the error id to the trace, to make sure
320             // the error id is present in the trace when the Perfetto trace is captured.
321             FrameworkStatsLog.write(FrameworkStatsLog.ANR_OCCURRED_PROCESSING_STARTED,
322                     mApp.processName);
323 
324             // Dump thread traces as quickly as we can, starting with "interesting" processes.
325             firstPids.add(pid);
326 
327             // Don't dump other PIDs if it's a background ANR or is requested to only dump self.
328             isSilentAnr = isSilentAnr();
329             if (!isSilentAnr && !onlyDumpSelf) {
330                 int parentPid = pid;
331                 if (parentProcess != null && parentProcess.getPid() > 0) {
332                     parentPid = parentProcess.getPid();
333                 }
334                 if (parentPid != pid) firstPids.add(parentPid);
335 
336                 if (MY_PID != pid && MY_PID != parentPid) firstPids.add(MY_PID);
337 
338                 final int ppid = parentPid;
339                 mService.mProcessList.forEachLruProcessesLOSP(false, r -> {
340                     if (r != null && r.getThread() != null) {
341                         int myPid = r.getPid();
342                         if (myPid > 0 && myPid != pid && myPid != ppid && myPid != MY_PID) {
343                             if (r.isPersistent()) {
344                                 firstPids.add(myPid);
345                                 if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
346                             } else if (r.mServices.isTreatedLikeActivity()) {
347                                 firstPids.add(myPid);
348                                 if (DEBUG_ANR) Slog.i(TAG, "Adding likely IME: " + r);
349                             } else {
350                                 lastPids.put(myPid, Boolean.TRUE);
351                                 if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
352                             }
353                         }
354                     }
355                 });
356             }
357         }
358 
359         // Get critical event log before logging the ANR so that it doesn't occur in the log.
360         final String criticalEventLog =
361                 CriticalEventLog.getInstance().logLinesForTraceFile(
362                         mApp.getProcessClassEnum(), mApp.processName, mApp.uid);
363         CriticalEventLog.getInstance().logAnr(annotation, mApp.getProcessClassEnum(),
364                 mApp.processName, mApp.uid, mApp.mPid);
365 
366         // Log the ANR to the main log.
367         StringBuilder info = new StringBuilder();
368         info.setLength(0);
369         info.append("ANR in ").append(mApp.processName);
370         if (activityShortComponentName != null) {
371             info.append(" (").append(activityShortComponentName).append(")");
372         }
373         info.append("\n");
374         info.append("PID: ").append(pid).append("\n");
375         if (annotation != null) {
376             info.append("Reason: ").append(annotation).append("\n");
377         }
378         if (parentShortComponentName != null
379                 && parentShortComponentName.equals(activityShortComponentName)) {
380             info.append("Parent: ").append(parentShortComponentName).append("\n");
381         }
382         if (errorId != null) {
383             info.append("ErrorId: ").append(errorId.toString()).append("\n");
384         }
385         info.append("Frozen: ").append(mApp.mOptRecord.isFrozen()).append("\n");
386 
387         // Retrieve controller with max ANR delay from AnrControllers
388         // Note that we retrieve the controller before dumping stacks because dumping stacks can
389         // take a few seconds, after which the cause of the ANR delay might have completed and
390         // there might no longer be a valid ANR controller to cancel the dialog in that case
391         AnrController anrController = mService.mActivityTaskManager.getAnrController(aInfo);
392         long anrDialogDelayMs = 0;
393         if (anrController != null) {
394             String packageName = aInfo.packageName;
395             int uid = aInfo.uid;
396             anrDialogDelayMs = anrController.getAnrDelayMillis(packageName, uid);
397             // Might execute an async binder call to a system app to show an interim
398             // ANR progress UI
399             anrController.onAnrDelayStarted(packageName, uid);
400             Slog.i(TAG, "ANR delay of " + anrDialogDelayMs + "ms started for " + packageName);
401         }
402 
403         StringBuilder report = new StringBuilder();
404         report.append(MemoryPressureUtil.currentPsiState());
405         ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
406 
407         // don't dump native PIDs for background ANRs unless it is the process of interest
408         String[] nativeProcs = null;
409         if (isSilentAnr || onlyDumpSelf) {
410             for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) {
411                 if (NATIVE_STACKS_OF_INTEREST[i].equals(mApp.processName)) {
412                     nativeProcs = new String[] { mApp.processName };
413                     break;
414                 }
415             }
416         } else {
417             nativeProcs = NATIVE_STACKS_OF_INTEREST;
418         }
419 
420         int[] pids = nativeProcs == null ? null : Process.getPidsForCommands(nativeProcs);
421         ArrayList<Integer> nativePids = null;
422 
423         if (pids != null) {
424             nativePids = new ArrayList<>(pids.length);
425             for (int i : pids) {
426                 nativePids.add(i);
427             }
428         }
429 
430         // For background ANRs, don't pass the ProcessCpuTracker to
431         // avoid spending 1/2 second collecting stats to rank lastPids.
432         StringWriter tracesFileException = new StringWriter();
433         // To hold the start and end offset to the ANR trace file respectively.
434         final long[] offsets = new long[2];
435         File tracesFile = ActivityManagerService.dumpStackTraces(firstPids,
436                 isSilentAnr ? null : processCpuTracker, isSilentAnr ? null : lastPids,
437                 nativePids, tracesFileException, offsets, annotation, criticalEventLog);
438 
439         if (isMonitorCpuUsage()) {
440             mService.updateCpuStatsNow();
441             mService.mAppProfiler.printCurrentCpuState(report, anrTime);
442             info.append(processCpuTracker.printCurrentLoad());
443             info.append(report);
444         }
445         report.append(tracesFileException.getBuffer());
446 
447         info.append(processCpuTracker.printCurrentState(anrTime));
448 
449         Slog.e(TAG, info.toString());
450         if (tracesFile == null) {
451             // There is no trace file, so dump (only) the alleged culprit's threads to the log
452             Process.sendSignal(pid, Process.SIGNAL_QUIT);
453         } else if (offsets[1] > 0) {
454             // We've dumped into the trace file successfully
455             mService.mProcessList.mAppExitInfoTracker.scheduleLogAnrTrace(
456                     pid, mApp.uid, mApp.getPackageList(), tracesFile, offsets[0], offsets[1]);
457         }
458 
459         // Check if package is still being loaded
460         float loadingProgress = 1;
461         IncrementalMetrics incrementalMetrics = null;
462         final PackageManagerInternal packageManagerInternal = mService.getPackageManagerInternal();
463         if (mApp.info != null && mApp.info.packageName != null && packageManagerInternal != null) {
464             IncrementalStatesInfo incrementalStatesInfo =
465                     packageManagerInternal.getIncrementalStatesInfo(
466                             mApp.info.packageName, SYSTEM_UID, mApp.userId);
467             if (incrementalStatesInfo != null) {
468                 loadingProgress = incrementalStatesInfo.getProgress();
469             }
470             final String codePath = mApp.info.getCodePath();
471             if (codePath != null && !codePath.isEmpty()
472                     && IncrementalManager.isIncrementalPath(codePath)) {
473                 // Report in the main log that the incremental package is still loading
474                 Slog.e(TAG, "App ANR on incremental package " + mApp.info.packageName
475                         + " which is " + ((int) (loadingProgress * 100)) + "% loaded.");
476                 final IBinder incrementalService = ServiceManager.getService(
477                         Context.INCREMENTAL_SERVICE);
478                 if (incrementalService != null) {
479                     final IncrementalManager incrementalManager = new IncrementalManager(
480                             IIncrementalService.Stub.asInterface(incrementalService));
481                     incrementalMetrics = incrementalManager.getMetrics(codePath);
482                 }
483             }
484         }
485         if (incrementalMetrics != null) {
486             // Report in the main log about the incremental package
487             info.append("Package is ").append((int) (loadingProgress * 100)).append("% loaded.\n");
488         }
489 
490         FrameworkStatsLog.write(FrameworkStatsLog.ANR_OCCURRED, mApp.uid, mApp.processName,
491                 activityShortComponentName == null ? "unknown" : activityShortComponentName,
492                 annotation,
493                 (mApp.info != null) ? (mApp.info.isInstantApp()
494                         ? FrameworkStatsLog.ANROCCURRED__IS_INSTANT_APP__TRUE
495                         : FrameworkStatsLog.ANROCCURRED__IS_INSTANT_APP__FALSE)
496                         : FrameworkStatsLog.ANROCCURRED__IS_INSTANT_APP__UNAVAILABLE,
497                 mApp.isInterestingToUserLocked()
498                         ? FrameworkStatsLog.ANROCCURRED__FOREGROUND_STATE__FOREGROUND
499                         : FrameworkStatsLog.ANROCCURRED__FOREGROUND_STATE__BACKGROUND,
500                 mApp.getProcessClassEnum(),
501                 (mApp.info != null) ? mApp.info.packageName : "",
502                 incrementalMetrics != null /* isIncremental */, loadingProgress,
503                 incrementalMetrics != null ? incrementalMetrics.getMillisSinceOldestPendingRead()
504                         : -1,
505                 incrementalMetrics != null ? incrementalMetrics.getStorageHealthStatusCode()
506                         : -1,
507                 incrementalMetrics != null ? incrementalMetrics.getDataLoaderStatusCode()
508                         : -1,
509                 incrementalMetrics != null && incrementalMetrics.getReadLogsEnabled(),
510                 incrementalMetrics != null ? incrementalMetrics.getMillisSinceLastDataLoaderBind()
511                         : -1,
512                 incrementalMetrics != null ? incrementalMetrics.getDataLoaderBindDelayMillis()
513                         : -1,
514                 incrementalMetrics != null ? incrementalMetrics.getTotalDelayedReads()
515                         : -1,
516                 incrementalMetrics != null ? incrementalMetrics.getTotalFailedReads()
517                         : -1,
518                 incrementalMetrics != null ? incrementalMetrics.getLastReadErrorUid()
519                         : -1,
520                 incrementalMetrics != null ? incrementalMetrics.getMillisSinceLastReadError()
521                         : -1,
522                 incrementalMetrics != null ? incrementalMetrics.getLastReadErrorNumber()
523                         : 0,
524                 incrementalMetrics != null ? incrementalMetrics.getTotalDelayedReadsDurationMillis()
525                         : -1);
526         final ProcessRecord parentPr = parentProcess != null
527                 ? (ProcessRecord) parentProcess.mOwner : null;
528         mService.addErrorToDropBox("anr", mApp, mApp.processName, activityShortComponentName,
529                 parentShortComponentName, parentPr, null, report.toString(), tracesFile,
530                 null, new Float(loadingProgress), incrementalMetrics, errorId);
531 
532         if (mApp.getWindowProcessController().appNotResponding(info.toString(),
533                 () -> {
534                     synchronized (mService) {
535                         mApp.killLocked("anr", ApplicationExitInfo.REASON_ANR, true);
536                     }
537                 },
538                 () -> {
539                     synchronized (mService) {
540                         mService.mServices.scheduleServiceTimeoutLocked(mApp);
541                     }
542                 })) {
543             return;
544         }
545 
546         synchronized (mService) {
547             // mBatteryStatsService can be null if the AMS is constructed with injector only. This
548             // will only happen in tests.
549             if (mService.mBatteryStatsService != null) {
550                 mService.mBatteryStatsService.noteProcessAnr(mApp.processName, mApp.uid);
551             }
552 
553             if (isSilentAnr() && !mApp.isDebugging()) {
554                 mApp.killLocked("bg anr", ApplicationExitInfo.REASON_ANR, true);
555                 return;
556             }
557 
558             synchronized (mProcLock) {
559                 // Set the app's notResponding state, and look up the errorReportReceiver
560                 makeAppNotRespondingLSP(activityShortComponentName,
561                         annotation != null ? "ANR " + annotation : "ANR", info.toString());
562                 mDialogController.setAnrController(anrController);
563             }
564 
565             // mUiHandler can be null if the AMS is constructed with injector only. This will only
566             // happen in tests.
567             if (mService.mUiHandler != null) {
568                 // Bring up the infamous App Not Responding dialog
569                 Message msg = Message.obtain();
570                 msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
571                 msg.obj = new AppNotRespondingDialog.Data(mApp, aInfo, aboveSystem);
572 
573                 mService.mUiHandler.sendMessageDelayed(msg, anrDialogDelayMs);
574             }
575         }
576     }
577 
578     @GuardedBy({"mService", "mProcLock"})
makeAppNotRespondingLSP(String activity, String shortMsg, String longMsg)579     private void makeAppNotRespondingLSP(String activity, String shortMsg, String longMsg) {
580         setNotResponding(true);
581         // mAppErrors can be null if the AMS is constructed with injector only. This will only
582         // happen in tests.
583         if (mService.mAppErrors != null) {
584             mNotRespondingReport = mService.mAppErrors.generateProcessError(mApp,
585                     ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
586                     activity, shortMsg, longMsg, null);
587         }
588         startAppProblemLSP();
589         mApp.getWindowProcessController().stopFreezingActivities();
590     }
591 
592     @GuardedBy({"mService", "mProcLock"})
startAppProblemLSP()593     void startAppProblemLSP() {
594         // If this app is not running under the current user, then we can't give it a report button
595         // because that would require launching the report UI under a different user.
596         mErrorReportReceiver = null;
597 
598         for (int userId : mService.mUserController.getCurrentProfileIds()) {
599             if (mApp.userId == userId) {
600                 mErrorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
601                         mService.mContext, mApp.info.packageName, mApp.info.flags);
602             }
603         }
604         mService.skipCurrentReceiverLocked(mApp);
605     }
606 
607     @GuardedBy("mService")
isInterestingForBackgroundTraces()608     private boolean isInterestingForBackgroundTraces() {
609         // The system_server is always considered interesting.
610         if (mApp.getPid() == MY_PID) {
611             return true;
612         }
613 
614         // A package is considered interesting if any of the following is true :
615         //
616         // - It's displaying an activity.
617         // - It's the SystemUI.
618         // - It has an overlay or a top UI visible.
619         //
620         // NOTE: The check whether a given ProcessRecord belongs to the systemui
621         // process is a bit of a kludge, but the same pattern seems repeated at
622         // several places in the system server.
623         return mApp.isInterestingToUserLocked()
624                 || (mApp.info != null && "com.android.systemui".equals(mApp.info.packageName))
625                 || (mApp.mState.hasTopUi() || mApp.mState.hasOverlayUi());
626     }
627 
getShowBackground()628     private boolean getShowBackground() {
629         return Settings.Secure.getInt(mService.mContext.getContentResolver(),
630                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
631     }
632 
633     /**
634      * Unless configured otherwise, swallow ANRs in background processes & kill the process.
635      * Non-private access is for tests only.
636      */
637     @VisibleForTesting
638     @GuardedBy("mService")
isSilentAnr()639     boolean isSilentAnr() {
640         return !getShowBackground() && !isInterestingForBackgroundTraces();
641     }
642 
643     /** Non-private access is for tests only. */
644     @VisibleForTesting
isMonitorCpuUsage()645     boolean isMonitorCpuUsage() {
646         return mService.mAppProfiler.MONITOR_CPU_USAGE;
647     }
648 
649     @GuardedBy({"mService", "mProcLock"})
onCleanupApplicationRecordLSP()650     void onCleanupApplicationRecordLSP() {
651         // Dismiss any open dialogs.
652         getDialogController().clearAllErrorDialogs();
653 
654         setCrashing(false);
655         setNotResponding(false);
656     }
657 
dump(PrintWriter pw, String prefix, long nowUptime)658     void dump(PrintWriter pw, String prefix, long nowUptime) {
659         synchronized (mProcLock) {
660             if (mCrashing || mDialogController.hasCrashDialogs() || mNotResponding
661                     || mDialogController.hasAnrDialogs() || mBad) {
662                 pw.print(prefix);
663                 pw.print(" mCrashing=" + mCrashing);
664                 pw.print(" " + mDialogController.getCrashDialogs());
665                 pw.print(" mNotResponding=" + mNotResponding);
666                 pw.print(" " + mDialogController.getAnrDialogs());
667                 pw.print(" bad=" + mBad);
668 
669                 // mCrashing or mNotResponding is always set before errorReportReceiver
670                 if (mErrorReportReceiver != null) {
671                     pw.print(" errorReportReceiver=");
672                     pw.print(mErrorReportReceiver.flattenToShortString());
673                 }
674                 pw.println();
675             }
676         }
677     }
678 }
679