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 import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
26 
27 import android.annotation.Nullable;
28 import android.app.ActivityManager;
29 import android.app.AnrController;
30 import android.app.ApplicationErrorReport;
31 import android.app.ApplicationExitInfo;
32 import android.content.ComponentName;
33 import android.content.ContentResolver;
34 import android.content.Context;
35 import android.content.pm.ApplicationInfo;
36 import android.content.pm.IncrementalStatesInfo;
37 import android.content.pm.PackageManagerInternal;
38 import android.os.IBinder;
39 import android.os.Message;
40 import android.os.Process;
41 import android.os.ServiceManager;
42 import android.os.SystemClock;
43 import android.os.incremental.IIncrementalService;
44 import android.os.incremental.IncrementalManager;
45 import android.os.incremental.IncrementalMetrics;
46 import android.provider.Settings;
47 import android.util.EventLog;
48 import android.util.Slog;
49 import android.util.SparseBooleanArray;
50 
51 import com.android.internal.annotations.CompositeRWLock;
52 import com.android.internal.annotations.GuardedBy;
53 import com.android.internal.annotations.VisibleForTesting;
54 import com.android.internal.os.ProcessCpuTracker;
55 import com.android.internal.os.TimeoutRecord;
56 import com.android.internal.os.anr.AnrLatencyTracker;
57 import com.android.internal.util.FrameworkStatsLog;
58 import com.android.modules.expresslog.Counter;
59 import com.android.server.ResourcePressureUtil;
60 import com.android.server.criticalevents.CriticalEventLog;
61 import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
62 import com.android.server.wm.WindowProcessController;
63 import com.android.server.utils.AnrTimer;
64 
65 import java.io.File;
66 import java.io.PrintWriter;
67 import java.io.StringWriter;
68 import java.time.Instant;
69 import java.time.ZoneId;
70 import java.time.ZonedDateTime;
71 import java.util.ArrayList;
72 import java.util.UUID;
73 import java.util.concurrent.ExecutionException;
74 import java.util.concurrent.ExecutorService;
75 import java.util.concurrent.Future;
76 import java.util.concurrent.atomic.AtomicLong;
77 
78 
79 /**
80  * The error state of the process, such as if it's crashing/ANR etc.
81  */
82 class ProcessErrorStateRecord {
83     final ProcessRecord mApp;
84     private final ActivityManagerService mService;
85 
86     private final ActivityManagerGlobalLock mProcLock;
87 
88     /**
89      * True if disabled in the bad process list.
90      */
91     @CompositeRWLock({"mService", "mProcLock"})
92     private boolean mBad;
93 
94     /**
95      * Are we in the process of crashing?
96      */
97     @CompositeRWLock({"mService", "mProcLock"})
98     private boolean mCrashing;
99 
100     /**
101      * Suppress normal auto-dismiss of crash dialog & report UI?
102      */
103     @CompositeRWLock({"mService", "mProcLock"})
104     private boolean mForceCrashReport;
105 
106     /**
107      * Does the app have a not responding dialog?
108      */
109     @CompositeRWLock({"mService", "mProcLock"})
110     private boolean mNotResponding;
111 
112     /**
113      * The report about crash of the app, generated & stored when an app gets into a crash.
114      * Will be "null" when all is OK.
115      */
116     @CompositeRWLock({"mService", "mProcLock"})
117     private ActivityManager.ProcessErrorStateInfo mCrashingReport;
118 
119     /**
120      * The report about ANR of the app, generated & stored when an app gets into an ANR.
121      * Will be "null" when all is OK.
122      */
123     @CompositeRWLock({"mService", "mProcLock"})
124     private ActivityManager.ProcessErrorStateInfo mNotRespondingReport;
125 
126     /**
127      * Controller for error dialogs.
128      */
129     @CompositeRWLock({"mService", "mProcLock"})
130     private final ErrorDialogController mDialogController;
131 
132     /**
133      * Who will be notified of the error. This is usually an activity in the
134      * app that installed the package.
135      */
136     @CompositeRWLock({"mService", "mProcLock"})
137     private ComponentName mErrorReportReceiver;
138 
139     /**
140      * ANR dialog data used to dismiss any visible ANR dialogs if the app becomes responsive.
141      */
142     @CompositeRWLock({"mService", "mProcLock"})
143     private AppNotRespondingDialog.Data mAnrData;
144 
145     /**
146      * Annotation from process killed due to an ANR.
147      */
148     @GuardedBy("mService")
149     private String mAnrAnnotation;
150 
151     /**
152      * Optional local handler to be invoked in the process crash.
153      */
154     @CompositeRWLock({"mService", "mProcLock"})
155     private Runnable mCrashHandler;
156 
157     @GuardedBy(anyOf = {"mService", "mProcLock"})
isBad()158     boolean isBad() {
159         return mBad;
160     }
161 
162     @GuardedBy({"mService", "mProcLock"})
setBad(boolean bad)163     void setBad(boolean bad) {
164         mBad = bad;
165     }
166 
167     @GuardedBy(anyOf = {"mService", "mProcLock"})
isCrashing()168     boolean isCrashing() {
169         return mCrashing;
170     }
171 
172     @GuardedBy({"mService", "mProcLock"})
setCrashing(boolean crashing)173     void setCrashing(boolean crashing) {
174         mCrashing = crashing;
175         mApp.getWindowProcessController().setCrashing(crashing);
176     }
177 
178     @GuardedBy(anyOf = {"mService", "mProcLock"})
isForceCrashReport()179     boolean isForceCrashReport() {
180         return mForceCrashReport;
181     }
182 
183     @GuardedBy({"mService", "mProcLock"})
setForceCrashReport(boolean forceCrashReport)184     void setForceCrashReport(boolean forceCrashReport) {
185         mForceCrashReport = forceCrashReport;
186     }
187 
188     @GuardedBy(anyOf = {"mService", "mProcLock"})
isNotResponding()189     boolean isNotResponding() {
190         return mNotResponding;
191     }
192 
193     @GuardedBy({"mService", "mProcLock"})
setNotResponding(boolean notResponding)194     void setNotResponding(boolean notResponding) {
195         mNotResponding = notResponding;
196         mApp.getWindowProcessController().setNotResponding(notResponding);
197     }
198 
199     @GuardedBy(anyOf = {"mService", "mProcLock"})
getCrashHandler()200     Runnable getCrashHandler() {
201         return mCrashHandler;
202     }
203 
204     @GuardedBy({"mService", "mProcLock"})
setCrashHandler(Runnable crashHandler)205     void setCrashHandler(Runnable crashHandler) {
206         mCrashHandler = crashHandler;
207     }
208 
209     @GuardedBy(anyOf = {"mService", "mProcLock"})
getCrashingReport()210     ActivityManager.ProcessErrorStateInfo getCrashingReport() {
211         return mCrashingReport;
212     }
213 
214     @GuardedBy({"mService", "mProcLock"})
setCrashingReport(ActivityManager.ProcessErrorStateInfo crashingReport)215     void setCrashingReport(ActivityManager.ProcessErrorStateInfo crashingReport) {
216         mCrashingReport = crashingReport;
217     }
218 
219     @GuardedBy("mService")
getAnrAnnotation()220     String getAnrAnnotation() {
221         return mAnrAnnotation;
222     }
223 
224     @GuardedBy("mService")
setAnrAnnotation(String anrAnnotation)225     void setAnrAnnotation(String anrAnnotation) {
226         mAnrAnnotation = anrAnnotation;
227     }
228 
229     @GuardedBy(anyOf = {"mService", "mProcLock"})
getNotRespondingReport()230     ActivityManager.ProcessErrorStateInfo getNotRespondingReport() {
231         return mNotRespondingReport;
232     }
233 
234     @GuardedBy({"mService", "mProcLock"})
setNotRespondingReport(ActivityManager.ProcessErrorStateInfo notRespondingReport)235     void setNotRespondingReport(ActivityManager.ProcessErrorStateInfo notRespondingReport) {
236         mNotRespondingReport = notRespondingReport;
237     }
238 
239     @GuardedBy(anyOf = {"mService", "mProcLock"})
getErrorReportReceiver()240     ComponentName getErrorReportReceiver() {
241         return mErrorReportReceiver;
242     }
243 
244     @GuardedBy({"mService", "mProcLock"})
setErrorReportReceiver(ComponentName errorReportReceiver)245     void setErrorReportReceiver(ComponentName errorReportReceiver) {
246         mErrorReportReceiver = errorReportReceiver;
247     }
248 
249     @GuardedBy(anyOf = {"mService", "mProcLock"})
getDialogController()250     ErrorDialogController getDialogController() {
251         return mDialogController;
252     }
253 
254     @GuardedBy({"mService", "mProcLock"})
setAnrData(AppNotRespondingDialog.Data data)255     void setAnrData(AppNotRespondingDialog.Data data) {
256         mAnrData = data;
257     }
258 
259     @GuardedBy(anyOf = {"mService", "mProcLock"})
getAnrData()260     AppNotRespondingDialog.Data getAnrData() {
261         return mAnrData;
262     }
263 
ProcessErrorStateRecord(ProcessRecord app)264     ProcessErrorStateRecord(ProcessRecord app) {
265         mApp = app;
266         mService = app.mService;
267         mProcLock = mService.mProcLock;
268         mDialogController = new ErrorDialogController(app);
269     }
270 
271     @GuardedBy("mService")
skipAnrLocked(String annotation)272     boolean skipAnrLocked(String annotation) {
273         // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
274         if (mService.mAtmInternal.isShuttingDown()) {
275             Slog.i(TAG, "During shutdown skipping ANR: " + this + " " + annotation);
276             return true;
277         } else if (isNotResponding()) {
278             Slog.i(TAG, "Skipping duplicate ANR: " + this + " " + annotation);
279             return true;
280         } else if (isCrashing()) {
281             Slog.i(TAG, "Crashing app skipping ANR: " + this + " " + annotation);
282             return true;
283         } else if (mApp.isKilledByAm()) {
284             Slog.i(TAG, "App already killed by AM skipping ANR: " + this + " " + annotation);
285             return true;
286         } else if (mApp.isKilled()) {
287             Slog.i(TAG, "Skipping died app ANR: " + this + " " + annotation);
288             return true;
289         }
290         return false;
291     }
292 
appNotResponding(String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, WindowProcessController parentProcess, boolean aboveSystem, TimeoutRecord timeoutRecord, ExecutorService auxiliaryTaskExecutor, boolean onlyDumpSelf, boolean isContinuousAnr, Future<File> firstPidFilePromise)293     void appNotResponding(String activityShortComponentName, ApplicationInfo aInfo,
294             String parentShortComponentName, WindowProcessController parentProcess,
295             boolean aboveSystem, TimeoutRecord timeoutRecord,
296             ExecutorService auxiliaryTaskExecutor, boolean onlyDumpSelf,
297             boolean isContinuousAnr, Future<File> firstPidFilePromise) {
298         String annotation = timeoutRecord.mReason;
299         AnrLatencyTracker latencyTracker = timeoutRecord.mLatencyTracker;
300         Future<?> updateCpuStatsNowFirstCall = null;
301 
302         ArrayList<Integer> firstPids = new ArrayList<>(5);
303         SparseBooleanArray lastPids = new SparseBooleanArray(20);
304         ActivityManagerService.VolatileDropboxEntryStates volatileDropboxEntriyStates = null;
305 
306         // Release the expired timer preparatory to starting the dump or returning without dumping.
307         timeoutRecord.closeExpiredTimer();
308 
309         if (mApp.isDebugging()) {
310             Slog.i(TAG, "Skipping debugged app ANR: " + this + " " + annotation);
311             return;
312         }
313 
314         mApp.getWindowProcessController().appEarlyNotResponding(annotation, () -> {
315             latencyTracker.waitingOnAMSLockStarted();
316             synchronized (mService) {
317                 latencyTracker.waitingOnAMSLockEnded();
318                 // Store annotation here as instance below races with this killLocked.
319                 setAnrAnnotation(annotation);
320                 mApp.killLocked("anr", ApplicationExitInfo.REASON_ANR, true);
321             }
322         });
323 
324         long anrTime = SystemClock.uptimeMillis();
325 
326         if (isMonitorCpuUsage()) {
327             updateCpuStatsNowFirstCall = auxiliaryTaskExecutor.submit(
328                     () -> {
329                     latencyTracker.updateCpuStatsNowCalled();
330                     mService.updateCpuStatsNow();
331                     latencyTracker.updateCpuStatsNowReturned();
332                 });
333 
334         }
335 
336         final boolean isSilentAnr;
337         final int pid;
338         final UUID errorId;
339         latencyTracker.waitingOnAMSLockStarted();
340         synchronized (mService) {
341             latencyTracker.waitingOnAMSLockEnded();
342             // Get the process's pid after obtaining the global lock.
343             pid = mApp.getPid();
344             // Store annotation here as instance above will not be hit on all paths.
345             setAnrAnnotation(annotation);
346 
347             Counter.logIncrement("stability_anr.value_total_anrs");
348             if (skipAnrLocked(annotation)) {
349                 latencyTracker.anrSkippedProcessErrorStateRecordAppNotResponding();
350                 Counter.logIncrement("stability_anr.value_skipped_anrs");
351                 return;
352             }
353             // In case we come through here for the same app before completing
354             // this one, mark as anring now so we will bail out.
355             latencyTracker.waitingOnProcLockStarted();
356             synchronized (mProcLock) {
357                 latencyTracker.waitingOnProcLockEnded();
358                 setNotResponding(true);
359 
360                 ZonedDateTime timestamp = null;
361                 if (timeoutRecord != null && timeoutRecord.mEndUptimeMillis > 0) {
362                     long millisSinceEndUptimeMs = anrTime - timeoutRecord.mEndUptimeMillis;
363                     timestamp = Instant.now().minusMillis(millisSinceEndUptimeMs)
364                                     .atZone(ZoneId.systemDefault());
365                 }
366 
367                 volatileDropboxEntriyStates =
368                         ActivityManagerService.VolatileDropboxEntryStates
369                                 .withProcessFrozenStateAndTimestamp(
370                                         mApp.mOptRecord.isFrozen(), timestamp);
371             }
372 
373             // Log the ANR to the event log.
374             EventLog.writeEvent(EventLogTags.AM_ANR, mApp.userId, pid, mApp.processName,
375                     mApp.info.flags, annotation);
376 
377             if (mService.mTraceErrorLogger != null
378                     && mService.mTraceErrorLogger.isAddErrorIdEnabled()) {
379                 errorId = mService.mTraceErrorLogger.generateErrorId();
380                 mService.mTraceErrorLogger.addProcessInfoAndErrorIdToTrace(
381                         mApp.processName, pid, errorId);
382                 mService.mTraceErrorLogger.addSubjectToTrace(annotation, errorId);
383             } else {
384                 errorId = null;
385             }
386 
387             // This atom is only logged with the purpose of triggering Perfetto and the logging
388             // needs to happen as close as possible to the time when the ANR is detected.
389             // Also, it needs to be logged after adding the error id to the trace, to make sure
390             // the error id is present in the trace when the Perfetto trace is captured.
391             FrameworkStatsLog.write(FrameworkStatsLog.ANR_OCCURRED_PROCESSING_STARTED,
392                     mApp.processName);
393 
394             // Dump thread traces as quickly as we can, starting with "interesting" processes.
395             firstPids.add(pid);
396 
397             // Don't dump other PIDs if it's a background ANR or is requested to only dump self.
398             // Note that the primary pid is added here just in case, as it should normally be
399             // dumped on the early dump thread, and would only be dumped on the Anr consumer thread
400             // as a fallback.
401             isSilentAnr = isSilentAnr();
402             if (!isSilentAnr && !onlyDumpSelf) {
403                 int parentPid = pid;
404                 if (parentProcess != null && parentProcess.getPid() > 0) {
405                     parentPid = parentProcess.getPid();
406                 }
407                 if (parentPid != pid) firstPids.add(parentPid);
408 
409                 if (MY_PID != pid && MY_PID != parentPid) firstPids.add(MY_PID);
410 
411                 final int ppid = parentPid;
412                 mService.mProcessList.forEachLruProcessesLOSP(false, r -> {
413                     if (r != null && r.getThread() != null) {
414                         int myPid = r.getPid();
415                         if (myPid > 0 && myPid != pid && myPid != ppid && myPid != MY_PID) {
416                             if (r.isPersistent()) {
417                                 firstPids.add(myPid);
418                                 if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
419                             } else if (r.mServices.isTreatedLikeActivity()) {
420                                 firstPids.add(myPid);
421                                 if (DEBUG_ANR) Slog.i(TAG, "Adding likely IME: " + r);
422                             } else {
423                                 lastPids.put(myPid, true);
424                                 if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
425                             }
426                         }
427                     }
428                 });
429             }
430         }
431         // Build memory headers for the ANRing process.
432         String memoryHeaders = buildMemoryHeadersFor(pid);
433 
434         // Get critical event log before logging the ANR so that it doesn't occur in the log.
435         latencyTracker.criticalEventLogStarted();
436         final String criticalEventLog =
437                 CriticalEventLog.getInstance().logLinesForTraceFile(
438                         mApp.getProcessClassEnum(), mApp.processName, mApp.uid);
439         latencyTracker.criticalEventLogEnded();
440         CriticalEventLog.getInstance().logAnr(annotation, mApp.getProcessClassEnum(),
441                 mApp.processName, mApp.uid, mApp.mPid);
442 
443         // Log the ANR to the main log.
444         StringBuilder info = new StringBuilder();
445         info.setLength(0);
446         info.append("ANR in ").append(mApp.processName);
447         if (activityShortComponentName != null) {
448             info.append(" (").append(activityShortComponentName).append(")");
449         }
450         info.append("\n");
451         info.append("PID: ").append(pid).append("\n");
452         if (annotation != null) {
453             info.append("Reason: ").append(annotation).append("\n");
454         }
455         if (parentShortComponentName != null
456                 && parentShortComponentName.equals(activityShortComponentName)) {
457             info.append("Parent: ").append(parentShortComponentName).append("\n");
458         }
459         if (errorId != null) {
460             info.append("ErrorId: ").append(errorId.toString()).append("\n");
461         }
462         info.append("Frozen: ").append(mApp.mOptRecord.isFrozen()).append("\n");
463 
464         // Retrieve controller with max ANR delay from AnrControllers
465         // Note that we retrieve the controller before dumping stacks because dumping stacks can
466         // take a few seconds, after which the cause of the ANR delay might have completed and
467         // there might no longer be a valid ANR controller to cancel the dialog in that case
468         AnrController anrController = mService.mActivityTaskManager.getAnrController(aInfo);
469         long anrDialogDelayMs = 0;
470         if (anrController != null) {
471             String packageName = aInfo.packageName;
472             int uid = aInfo.uid;
473             anrDialogDelayMs = anrController.getAnrDelayMillis(packageName, uid);
474             // Might execute an async binder call to a system app to show an interim
475             // ANR progress UI
476             anrController.onAnrDelayStarted(packageName, uid);
477             Slog.i(TAG, "ANR delay of " + anrDialogDelayMs + "ms started for " + packageName);
478         }
479 
480         StringBuilder report = new StringBuilder();
481 
482         latencyTracker.currentPsiStateCalled();
483         String currentPsiState = ResourcePressureUtil.currentPsiState();
484         latencyTracker.currentPsiStateReturned();
485         report.append(currentPsiState);
486         // The 'processCpuTracker' variable is a shared resource that might be initialized and
487         // updated in a different thread. In order to prevent thread visibility issues, which
488         // can occur when one thread does not immediately see the changes made to
489         // 'processCpuTracker' by another thread, it is necessary to use synchronization whenever
490         // 'processCpuTracker' is accessed or modified.
491         ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
492 
493         // We push the native pids collection task to the helper thread through
494         // the Anr auxiliary task executor, and wait on it later after dumping the first pids
495         Future<ArrayList<Integer>> nativePidsFuture =
496                 auxiliaryTaskExecutor.submit(
497                     () -> {
498                         latencyTracker.nativePidCollectionStarted();
499                         // don't dump native PIDs for background ANRs unless
500                         // it is the process of interest
501                         String[] nativeProcs = null;
502                         boolean isSystemApp = mApp.info.isSystemApp() || mApp.info.isSystemExt();
503                         // Do not collect system daemons dumps as this is not likely to be useful
504                         // for non-system apps.
505                         if (!isSystemApp || isSilentAnr || onlyDumpSelf) {
506                             for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) {
507                                 if (NATIVE_STACKS_OF_INTEREST[i].equals(mApp.processName)) {
508                                     nativeProcs = new String[] { mApp.processName };
509                                     break;
510                                 }
511                             }
512                         } else {
513                             nativeProcs = NATIVE_STACKS_OF_INTEREST;
514                         }
515 
516                         int[] pids = nativeProcs == null
517                                 ? null : Process.getPidsForCommands(nativeProcs);
518                         ArrayList<Integer> nativePids = null;
519 
520                         if (pids != null) {
521                             nativePids = new ArrayList<>(pids.length);
522                             for (int i : pids) {
523                                 nativePids.add(i);
524                             }
525                         }
526                         latencyTracker.nativePidCollectionEnded();
527                         return nativePids;
528                     });
529 
530         // For background ANRs, don't pass the ProcessCpuTracker to
531         // avoid spending 1/2 second collecting stats to rank lastPids.
532         StringWriter tracesFileException = new StringWriter();
533         // To hold the start and end offset to the ANR trace file respectively.
534         final AtomicLong firstPidEndOffset = new AtomicLong(-1);
535         File tracesFile = StackTracesDumpHelper.dumpStackTraces(firstPids,
536                 isSilentAnr ? null : processCpuTracker, isSilentAnr ? null : lastPids,
537                 nativePidsFuture, tracesFileException, firstPidEndOffset, annotation,
538                 criticalEventLog, memoryHeaders, auxiliaryTaskExecutor, firstPidFilePromise,
539                 latencyTracker);
540 
541         if (isMonitorCpuUsage()) {
542             // Wait for the first call to finish
543             try {
544                 updateCpuStatsNowFirstCall.get();
545             } catch (ExecutionException e) {
546                 Slog.w(TAG, "Failed to update the CPU stats", e.getCause());
547             } catch (InterruptedException e) {
548                 Slog.w(TAG, "Interrupted while updating the CPU stats", e);
549             }
550             mService.updateCpuStatsNow();
551             mService.mAppProfiler.printCurrentCpuState(report, anrTime);
552             synchronized (processCpuTracker) {
553                 info.append(processCpuTracker.printCurrentLoad());
554             }
555             info.append(report);
556         }
557         report.append(tracesFileException.getBuffer());
558 
559         synchronized (processCpuTracker) {
560             info.append(processCpuTracker.printCurrentState(anrTime));
561         }
562 
563         Slog.e(TAG, info.toString());
564         if (tracesFile == null) {
565             // There is no trace file, so dump (only) the alleged culprit's threads to the log
566             Process.sendSignal(pid, Process.SIGNAL_QUIT);
567         } else if (firstPidEndOffset.get() > 0) {
568             // We've dumped into the trace file successfully
569             // We pass the start and end offsets of the first section of
570             // the ANR file (the headers and first process dump)
571             final long startOffset = 0L;
572             final long endOffset = firstPidEndOffset.get();
573             mService.mProcessList.mAppExitInfoTracker.scheduleLogAnrTrace(
574                     pid, mApp.uid, mApp.getPackageList(), tracesFile, startOffset, endOffset);
575         }
576 
577         // Check if package is still being loaded
578         float loadingProgress = 1;
579         IncrementalMetrics incrementalMetrics = null;
580         final PackageManagerInternal packageManagerInternal = mService.getPackageManagerInternal();
581         if (mApp.info != null && mApp.info.packageName != null && packageManagerInternal != null) {
582             IncrementalStatesInfo incrementalStatesInfo =
583                     packageManagerInternal.getIncrementalStatesInfo(
584                             mApp.info.packageName, SYSTEM_UID, mApp.userId);
585             if (incrementalStatesInfo != null) {
586                 loadingProgress = incrementalStatesInfo.getProgress();
587             }
588             final String codePath = mApp.info.getCodePath();
589             if (codePath != null && !codePath.isEmpty()
590                     && IncrementalManager.isIncrementalPath(codePath)) {
591                 // Report in the main log that the incremental package is still loading
592                 Slog.e(TAG, "App ANR on incremental package " + mApp.info.packageName
593                         + " which is " + ((int) (loadingProgress * 100)) + "% loaded.");
594                 final IBinder incrementalService = ServiceManager.getService(
595                         Context.INCREMENTAL_SERVICE);
596                 if (incrementalService != null) {
597                     final IncrementalManager incrementalManager = new IncrementalManager(
598                             IIncrementalService.Stub.asInterface(incrementalService));
599                     incrementalMetrics = incrementalManager.getMetrics(codePath);
600                 }
601             }
602         }
603         if (incrementalMetrics != null) {
604             // Report in the main log about the incremental package
605             info.append("Package is ").append((int) (loadingProgress * 100)).append("% loaded.\n");
606         }
607 
608         FrameworkStatsLog.write(FrameworkStatsLog.ANR_OCCURRED, mApp.uid, mApp.processName,
609                 activityShortComponentName == null ? "unknown" : activityShortComponentName,
610                 annotation,
611                 (mApp.info != null) ? (mApp.info.isInstantApp()
612                         ? FrameworkStatsLog.ANROCCURRED__IS_INSTANT_APP__TRUE
613                         : FrameworkStatsLog.ANROCCURRED__IS_INSTANT_APP__FALSE)
614                         : FrameworkStatsLog.ANROCCURRED__IS_INSTANT_APP__UNAVAILABLE,
615                 mApp.isInterestingToUserLocked()
616                         ? FrameworkStatsLog.ANROCCURRED__FOREGROUND_STATE__FOREGROUND
617                         : FrameworkStatsLog.ANROCCURRED__FOREGROUND_STATE__BACKGROUND,
618                 mApp.getProcessClassEnum(),
619                 (mApp.info != null) ? mApp.info.packageName : "",
620                 incrementalMetrics != null /* isIncremental */, loadingProgress,
621                 incrementalMetrics != null ? incrementalMetrics.getMillisSinceOldestPendingRead()
622                         : -1,
623                 incrementalMetrics != null ? incrementalMetrics.getStorageHealthStatusCode()
624                         : -1,
625                 incrementalMetrics != null ? incrementalMetrics.getDataLoaderStatusCode()
626                         : -1,
627                 incrementalMetrics != null && incrementalMetrics.getReadLogsEnabled(),
628                 incrementalMetrics != null ? incrementalMetrics.getMillisSinceLastDataLoaderBind()
629                         : -1,
630                 incrementalMetrics != null ? incrementalMetrics.getDataLoaderBindDelayMillis()
631                         : -1,
632                 incrementalMetrics != null ? incrementalMetrics.getTotalDelayedReads()
633                         : -1,
634                 incrementalMetrics != null ? incrementalMetrics.getTotalFailedReads()
635                         : -1,
636                 incrementalMetrics != null ? incrementalMetrics.getLastReadErrorUid()
637                         : -1,
638                 incrementalMetrics != null ? incrementalMetrics.getMillisSinceLastReadError()
639                         : -1,
640                 incrementalMetrics != null ? incrementalMetrics.getLastReadErrorNumber()
641                         : 0,
642                 incrementalMetrics != null ? incrementalMetrics.getTotalDelayedReadsDurationMillis()
643                         : -1);
644         final ProcessRecord parentPr = parentProcess != null
645                 ? (ProcessRecord) parentProcess.mOwner : null;
646         mService.addErrorToDropBox("anr", mApp, mApp.processName, activityShortComponentName,
647                 parentShortComponentName, parentPr, null, report.toString(), tracesFile,
648                 null, new Float(loadingProgress), incrementalMetrics, errorId,
649                 volatileDropboxEntriyStates);
650 
651         if (mApp.getWindowProcessController().appNotResponding(info.toString(),
652                 () -> {
653                     synchronized (mService) {
654                         mApp.killLocked("anr", ApplicationExitInfo.REASON_ANR, true);
655                     }
656                 },
657                 () -> {
658                     synchronized (mService) {
659                         mService.mServices.scheduleServiceTimeoutLocked(mApp);
660                     }
661                 })) {
662             return;
663         }
664 
665         synchronized (mService) {
666             // mBatteryStatsService can be null if the AMS is constructed with injector only. This
667             // will only happen in tests.
668             if (mService.mBatteryStatsService != null) {
669                 mService.mBatteryStatsService.noteProcessAnr(mApp.processName, mApp.uid);
670             }
671 
672             if (isSilentAnr() && !mApp.isDebugging()) {
673                 mApp.killLocked("bg anr", ApplicationExitInfo.REASON_ANR, true);
674                 return;
675             }
676 
677             synchronized (mProcLock) {
678                 // Set the app's notResponding state, and look up the errorReportReceiver
679                 makeAppNotRespondingLSP(activityShortComponentName,
680                         annotation != null ? "ANR " + annotation : "ANR", info.toString());
681                 mDialogController.setAnrController(anrController);
682             }
683 
684             // mUiHandler can be null if the AMS is constructed with injector only. This will only
685             // happen in tests.
686             if (mService.mUiHandler != null) {
687                 // Bring up the infamous App Not Responding dialog
688                 Message msg = Message.obtain();
689                 msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
690                 msg.obj = new AppNotRespondingDialog.Data(mApp, aInfo, aboveSystem,
691                         isContinuousAnr);
692 
693                 mService.mUiHandler.sendMessageDelayed(msg, anrDialogDelayMs);
694             }
695         }
696     }
697 
698     @GuardedBy({"mService", "mProcLock"})
makeAppNotRespondingLSP(String activity, String shortMsg, String longMsg)699     private void makeAppNotRespondingLSP(String activity, String shortMsg, String longMsg) {
700         setNotResponding(true);
701         // mAppErrors can be null if the AMS is constructed with injector only. This will only
702         // happen in tests.
703         if (mService.mAppErrors != null) {
704             mNotRespondingReport = mService.mAppErrors.generateProcessError(mApp,
705                     ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
706                     activity, shortMsg, longMsg, null);
707         }
708         startAppProblemLSP();
709         mApp.getWindowProcessController().stopFreezingActivities();
710     }
711 
712     @GuardedBy({"mService", "mProcLock"})
startAppProblemLSP()713     void startAppProblemLSP() {
714         // If this app is not running under the current user, then we can't give it a report button
715         // because that would require launching the report UI under a different user.
716         mErrorReportReceiver = null;
717 
718         for (int userId : mService.mUserController.getCurrentProfileIds()) {
719             if (mApp.userId == userId) {
720                 mErrorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
721                         mService.mContext, mApp.info.packageName, mApp.info.flags);
722             }
723         }
724         mService.getBroadcastQueue().onApplicationProblemLocked(mApp);
725     }
726 
727     @GuardedBy("mService")
isInterestingForBackgroundTraces()728     private boolean isInterestingForBackgroundTraces() {
729         // The system_server is always considered interesting.
730         if (mApp.getPid() == MY_PID) {
731             return true;
732         }
733 
734         // A package is considered interesting if any of the following is true :
735         //
736         // - It's displaying an activity.
737         // - It's the SystemUI.
738         // - It has an overlay or a top UI visible.
739         //
740         // NOTE: The check whether a given ProcessRecord belongs to the systemui
741         // process is a bit of a kludge, but the same pattern seems repeated at
742         // several places in the system server.
743         return mApp.isInterestingToUserLocked()
744                 || (mApp.info != null && "com.android.systemui".equals(mApp.info.packageName))
745                 || (mApp.mState.hasTopUi() || mApp.mState.hasOverlayUi());
746     }
747 
getShowBackground()748     private boolean getShowBackground() {
749         final ContentResolver resolver = mService.mContext.getContentResolver();
750         return Settings.Secure.getIntForUser(resolver,
751             Settings.Secure.ANR_SHOW_BACKGROUND,
752             0,
753             resolver.getUserId()) != 0;
754     }
755 
buildMemoryHeadersFor(int pid)756     private @Nullable String buildMemoryHeadersFor(int pid) {
757         if (pid <= 0) {
758             Slog.i(TAG, "Memory header requested with invalid pid: " + pid);
759             return null;
760         }
761         MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
762         if (snapshot == null) {
763             Slog.i(TAG, "Failed to get memory snapshot for pid:" + pid);
764             return null;
765         }
766 
767         StringBuilder memoryHeaders = new StringBuilder();
768         memoryHeaders.append("RssHwmKb: ")
769             .append(snapshot.rssHighWaterMarkInKilobytes)
770             .append("\n");
771         memoryHeaders.append("RssKb: ").append(snapshot.rssInKilobytes).append("\n");
772         memoryHeaders.append("RssAnonKb: ").append(snapshot.anonRssInKilobytes).append("\n");
773         memoryHeaders.append("RssShmemKb: ").append(snapshot.rssShmemKilobytes).append("\n");
774         memoryHeaders.append("VmSwapKb: ").append(snapshot.swapInKilobytes).append("\n");
775         return memoryHeaders.toString();
776     }
777     /**
778      * Unless configured otherwise, swallow ANRs in background processes & kill the process.
779      * Non-private access is for tests only.
780      */
781     @VisibleForTesting
782     @GuardedBy("mService")
isSilentAnr()783     boolean isSilentAnr() {
784         return !getShowBackground() && !isInterestingForBackgroundTraces();
785     }
786 
787     /** Non-private access is for tests only. */
788     @VisibleForTesting
isMonitorCpuUsage()789     boolean isMonitorCpuUsage() {
790         return mService.mAppProfiler.MONITOR_CPU_USAGE;
791     }
792 
793     @GuardedBy({"mService", "mProcLock"})
onCleanupApplicationRecordLSP()794     void onCleanupApplicationRecordLSP() {
795         // Dismiss any open dialogs.
796         getDialogController().clearAllErrorDialogs();
797 
798         setCrashing(false);
799         setNotResponding(false);
800     }
801 
dump(PrintWriter pw, String prefix, long nowUptime)802     void dump(PrintWriter pw, String prefix, long nowUptime) {
803         synchronized (mProcLock) {
804             if (mCrashing || mDialogController.hasCrashDialogs() || mNotResponding
805                     || mDialogController.hasAnrDialogs() || mBad) {
806                 pw.print(prefix);
807                 pw.print(" mCrashing=" + mCrashing);
808                 pw.print(" " + mDialogController.getCrashDialogs());
809                 pw.print(" mNotResponding=" + mNotResponding);
810                 pw.print(" " + mDialogController.getAnrDialogs());
811                 pw.print(" bad=" + mBad);
812 
813                 // mCrashing or mNotResponding is always set before errorReportReceiver
814                 if (mErrorReportReceiver != null) {
815                     pw.print(" errorReportReceiver=");
816                     pw.print(mErrorReportReceiver.flattenToShortString());
817                 }
818                 pw.println();
819             }
820         }
821     }
822 }
823