OSDN Git Service

Merge "DO NOT MERGE Backporting potential usb tapjacking precaution." into lmp-dev...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / AppErrors.java
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 com.android.internal.app.ProcessMap;
20 import com.android.internal.logging.MetricsLogger;
21 import com.android.internal.logging.MetricsProto;
22 import com.android.internal.os.ProcessCpuTracker;
23 import com.android.server.Watchdog;
24
25 import android.app.ActivityManager;
26 import android.app.ActivityOptions;
27 import android.app.ActivityThread;
28 import android.app.AppOpsManager;
29 import android.app.ApplicationErrorReport;
30 import android.app.Dialog;
31 import android.content.ActivityNotFoundException;
32 import android.content.Context;
33 import android.content.Intent;
34 import android.content.pm.ApplicationInfo;
35 import android.os.Binder;
36 import android.os.Message;
37 import android.os.Process;
38 import android.os.RemoteException;
39 import android.os.SystemClock;
40 import android.os.SystemProperties;
41 import android.os.UserHandle;
42 import android.provider.Settings;
43 import android.util.ArrayMap;
44 import android.util.ArraySet;
45 import android.util.EventLog;
46 import android.util.Log;
47 import android.util.Slog;
48 import android.util.SparseArray;
49 import android.util.TimeUtils;
50
51 import java.io.File;
52 import java.io.FileDescriptor;
53 import java.io.PrintWriter;
54 import java.util.ArrayList;
55 import java.util.Collections;
56 import java.util.HashMap;
57 import java.util.Set;
58
59 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
60 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
61 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
62 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
63 import static com.android.server.am.ActivityManagerService.MY_PID;
64 import static com.android.server.am.ActivityManagerService.SYSTEM_DEBUGGABLE;
65
66 /**
67  * Controls error conditions in applications.
68  */
69 class AppErrors {
70
71     private static final String TAG = TAG_WITH_CLASS_NAME ? "AppErrors" : TAG_AM;
72
73     private final ActivityManagerService mService;
74     private final Context mContext;
75
76     private ArraySet<String> mAppsNotReportingCrashes;
77
78     /**
79      * The last time that various processes have crashed since they were last explicitly started.
80      */
81     private final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<>();
82
83     /**
84      * The last time that various processes have crashed (not reset even when explicitly started).
85      */
86     private final ProcessMap<Long> mProcessCrashTimesPersistent = new ProcessMap<>();
87
88     /**
89      * Set of applications that we consider to be bad, and will reject
90      * incoming broadcasts from (which the user has no control over).
91      * Processes are added to this set when they have crashed twice within
92      * a minimum amount of time; they are removed from it when they are
93      * later restarted (hopefully due to some user action).  The value is the
94      * time it was added to the list.
95      */
96     private final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>();
97
98
99     AppErrors(Context context, ActivityManagerService service) {
100         mService = service;
101         mContext = context;
102     }
103
104     boolean dumpLocked(FileDescriptor fd, PrintWriter pw, boolean needSep,
105             String dumpPackage) {
106         if (!mProcessCrashTimes.getMap().isEmpty()) {
107             boolean printed = false;
108             final long now = SystemClock.uptimeMillis();
109             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
110             final int processCount = pmap.size();
111             for (int ip = 0; ip < processCount; ip++) {
112                 final String pname = pmap.keyAt(ip);
113                 final SparseArray<Long> uids = pmap.valueAt(ip);
114                 final int uidCount = uids.size();
115                 for (int i = 0; i < uidCount; i++) {
116                     final int puid = uids.keyAt(i);
117                     final ProcessRecord r = mService.mProcessNames.get(pname, puid);
118                     if (dumpPackage != null && (r == null
119                             || !r.pkgList.containsKey(dumpPackage))) {
120                         continue;
121                     }
122                     if (!printed) {
123                         if (needSep) pw.println();
124                         needSep = true;
125                         pw.println("  Time since processes crashed:");
126                         printed = true;
127                     }
128                     pw.print("    Process "); pw.print(pname);
129                     pw.print(" uid "); pw.print(puid);
130                     pw.print(": last crashed ");
131                     TimeUtils.formatDuration(now-uids.valueAt(i), pw);
132                     pw.println(" ago");
133                 }
134             }
135         }
136
137         if (!mBadProcesses.getMap().isEmpty()) {
138             boolean printed = false;
139             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
140             final int processCount = pmap.size();
141             for (int ip = 0; ip < processCount; ip++) {
142                 final String pname = pmap.keyAt(ip);
143                 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
144                 final int uidCount = uids.size();
145                 for (int i = 0; i < uidCount; i++) {
146                     final int puid = uids.keyAt(i);
147                     final ProcessRecord r = mService.mProcessNames.get(pname, puid);
148                     if (dumpPackage != null && (r == null
149                             || !r.pkgList.containsKey(dumpPackage))) {
150                         continue;
151                     }
152                     if (!printed) {
153                         if (needSep) pw.println();
154                         needSep = true;
155                         pw.println("  Bad processes:");
156                         printed = true;
157                     }
158                     final BadProcessInfo info = uids.valueAt(i);
159                     pw.print("    Bad process "); pw.print(pname);
160                     pw.print(" uid "); pw.print(puid);
161                     pw.print(": crashed at time "); pw.println(info.time);
162                     if (info.shortMsg != null) {
163                         pw.print("      Short msg: "); pw.println(info.shortMsg);
164                     }
165                     if (info.longMsg != null) {
166                         pw.print("      Long msg: "); pw.println(info.longMsg);
167                     }
168                     if (info.stack != null) {
169                         pw.println("      Stack:");
170                         int lastPos = 0;
171                         for (int pos = 0; pos < info.stack.length(); pos++) {
172                             if (info.stack.charAt(pos) == '\n') {
173                                 pw.print("        ");
174                                 pw.write(info.stack, lastPos, pos-lastPos);
175                                 pw.println();
176                                 lastPos = pos+1;
177                             }
178                         }
179                         if (lastPos < info.stack.length()) {
180                             pw.print("        ");
181                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
182                             pw.println();
183                         }
184                     }
185                 }
186             }
187         }
188         return needSep;
189     }
190
191     boolean isBadProcessLocked(ApplicationInfo info) {
192         return mBadProcesses.get(info.processName, info.uid) != null;
193     }
194
195     void clearBadProcessLocked(ApplicationInfo info) {
196         mBadProcesses.remove(info.processName, info.uid);
197     }
198
199     void resetProcessCrashTimeLocked(ApplicationInfo info) {
200         mProcessCrashTimes.remove(info.processName, info.uid);
201     }
202
203     void resetProcessCrashTimeLocked(boolean resetEntireUser, int appId, int userId) {
204         final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
205         for (int ip = pmap.size() - 1; ip >= 0; ip--) {
206             SparseArray<Long> ba = pmap.valueAt(ip);
207             for (int i = ba.size() - 1; i >= 0; i--) {
208                 boolean remove = false;
209                 final int entUid = ba.keyAt(i);
210                 if (!resetEntireUser) {
211                     if (userId == UserHandle.USER_ALL) {
212                         if (UserHandle.getAppId(entUid) == appId) {
213                             remove = true;
214                         }
215                     } else {
216                         if (entUid == UserHandle.getUid(userId, appId)) {
217                             remove = true;
218                         }
219                     }
220                 } else if (UserHandle.getUserId(entUid) == userId) {
221                     remove = true;
222                 }
223                 if (remove) {
224                     ba.removeAt(i);
225                 }
226             }
227             if (ba.size() == 0) {
228                 pmap.removeAt(ip);
229             }
230         }
231     }
232
233     void loadAppsNotReportingCrashesFromConfigLocked(String appsNotReportingCrashesConfig) {
234         if (appsNotReportingCrashesConfig != null) {
235             final String[] split = appsNotReportingCrashesConfig.split(",");
236             if (split.length > 0) {
237                 mAppsNotReportingCrashes = new ArraySet<>();
238                 Collections.addAll(mAppsNotReportingCrashes, split);
239             }
240         }
241     }
242
243     void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) {
244         app.crashing = false;
245         app.crashingReport = null;
246         app.notResponding = false;
247         app.notRespondingReport = null;
248         if (app.anrDialog == fromDialog) {
249             app.anrDialog = null;
250         }
251         if (app.waitDialog == fromDialog) {
252             app.waitDialog = null;
253         }
254         if (app.pid > 0 && app.pid != MY_PID) {
255             handleAppCrashLocked(app, "user-terminated" /*reason*/,
256                     null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
257             app.kill("user request after error", true);
258         }
259     }
260
261     void scheduleAppCrashLocked(int uid, int initialPid, String packageName,
262             String message) {
263         ProcessRecord proc = null;
264
265         // Figure out which process to kill.  We don't trust that initialPid
266         // still has any relation to current pids, so must scan through the
267         // list.
268
269         synchronized (mService.mPidsSelfLocked) {
270             for (int i=0; i<mService.mPidsSelfLocked.size(); i++) {
271                 ProcessRecord p = mService.mPidsSelfLocked.valueAt(i);
272                 if (p.uid != uid) {
273                     continue;
274                 }
275                 if (p.pid == initialPid) {
276                     proc = p;
277                     break;
278                 }
279                 if (p.pkgList.containsKey(packageName)) {
280                     proc = p;
281                 }
282             }
283         }
284
285         if (proc == null) {
286             Slog.w(TAG, "crashApplication: nothing for uid=" + uid
287                     + " initialPid=" + initialPid
288                     + " packageName=" + packageName);
289             return;
290         }
291
292         proc.scheduleCrash(message);
293     }
294
295     /**
296      * Bring up the "unexpected error" dialog box for a crashing app.
297      * Deal with edge cases (intercepts from instrumented applications,
298      * ActivityController, error intent receivers, that sort of thing).
299      * @param r the application crashing
300      * @param crashInfo describing the failure
301      */
302     void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
303         final long origId = Binder.clearCallingIdentity();
304         try {
305             crashApplicationInner(r, crashInfo);
306         } finally {
307             Binder.restoreCallingIdentity(origId);
308         }
309     }
310
311     void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
312         long timeMillis = System.currentTimeMillis();
313         String shortMsg = crashInfo.exceptionClassName;
314         String longMsg = crashInfo.exceptionMessage;
315         String stackTrace = crashInfo.stackTrace;
316         if (shortMsg != null && longMsg != null) {
317             longMsg = shortMsg + ": " + longMsg;
318         } else if (shortMsg != null) {
319             longMsg = shortMsg;
320         }
321
322         AppErrorResult result = new AppErrorResult();
323         TaskRecord task;
324         synchronized (mService) {
325             /**
326              * If crash is handled by instance of {@link android.app.IActivityController},
327              * finish now and don't show the app error dialog.
328              */
329             if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace,
330                     timeMillis)) {
331                 return;
332             }
333
334             /**
335              * If this process was running instrumentation, finish now - it will be handled in
336              * {@link ActivityManagerService#handleAppDiedLocked}.
337              */
338             if (r != null && r.instrumentationClass != null) {
339                 return;
340             }
341
342             // Log crash in battery stats.
343             if (r != null) {
344                 mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
345             }
346
347             AppErrorDialog.Data data = new AppErrorDialog.Data();
348             data.result = result;
349             data.proc = r;
350
351             // If we can't identify the process or it's already exceeded its crash quota,
352             // quit right away without showing a crash dialog.
353             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
354                 return;
355             }
356
357             final Message msg = Message.obtain();
358             msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
359
360             task = data.task;
361             msg.obj = data;
362             mService.mUiHandler.sendMessage(msg);
363         }
364
365         int res = result.get();
366
367         Intent appErrorIntent = null;
368         MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
369         if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) {
370             res = AppErrorDialog.FORCE_QUIT;
371         }
372         synchronized (mService) {
373             if (res == AppErrorDialog.MUTE) {
374                 stopReportingCrashesLocked(r);
375             }
376             if (res == AppErrorDialog.RESTART) {
377                 mService.removeProcessLocked(r, false, true, "crash");
378                 if (task != null) {
379                     try {
380                         mService.startActivityFromRecents(task.taskId,
381                                 ActivityOptions.makeBasic().toBundle());
382                     } catch (IllegalArgumentException e) {
383                         // Hmm, that didn't work, app might have crashed before creating a
384                         // recents entry. Let's see if we have a safe-to-restart intent.
385                         final Set<String> cats = task.intent.getCategories();
386                         if (cats != null && cats.contains(Intent.CATEGORY_LAUNCHER)) {
387                             mService.startActivityInPackage(task.mCallingUid,
388                                     task.mCallingPackage, task.intent,
389                                     null, null, null, 0, 0,
390                                     ActivityOptions.makeBasic().toBundle(),
391                                     task.userId, null, null);
392                         }
393                     }
394                 }
395             }
396             if (res == AppErrorDialog.FORCE_QUIT) {
397                 long orig = Binder.clearCallingIdentity();
398                 try {
399                     // Kill it with fire!
400                     mService.mStackSupervisor.handleAppCrashLocked(r);
401                     if (!r.persistent) {
402                         mService.removeProcessLocked(r, false, false, "crash");
403                         mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
404                     }
405                 } finally {
406                     Binder.restoreCallingIdentity(orig);
407                 }
408             }
409             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
410                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
411             }
412             if (r != null && !r.isolated && res != AppErrorDialog.RESTART) {
413                 // XXX Can't keep track of crash time for isolated processes,
414                 // since they don't have a persistent identity.
415                 mProcessCrashTimes.put(r.info.processName, r.uid,
416                         SystemClock.uptimeMillis());
417             }
418         }
419
420         if (appErrorIntent != null) {
421             try {
422                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
423             } catch (ActivityNotFoundException e) {
424                 Slog.w(TAG, "bug report receiver dissappeared", e);
425             }
426         }
427     }
428
429     private boolean handleAppCrashInActivityController(ProcessRecord r,
430                                                        ApplicationErrorReport.CrashInfo crashInfo,
431                                                        String shortMsg, String longMsg,
432                                                        String stackTrace, long timeMillis) {
433         if (mService.mController == null) {
434             return false;
435         }
436
437         try {
438             String name = r != null ? r.processName : null;
439             int pid = r != null ? r.pid : Binder.getCallingPid();
440             int uid = r != null ? r.info.uid : Binder.getCallingUid();
441             if (!mService.mController.appCrashed(name, pid,
442                     shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
443                 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
444                         && "Native crash".equals(crashInfo.exceptionClassName)) {
445                     Slog.w(TAG, "Skip killing native crashed app " + name
446                             + "(" + pid + ") during testing");
447                 } else {
448                     Slog.w(TAG, "Force-killing crashed app " + name
449                             + " at watcher's request");
450                     if (r != null) {
451                         if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null))
452                         {
453                             r.kill("crash", true);
454                         }
455                     } else {
456                         // Huh.
457                         Process.killProcess(pid);
458                         ActivityManagerService.killProcessGroup(uid, pid);
459                     }
460                 }
461                 return true;
462             }
463         } catch (RemoteException e) {
464             mService.mController = null;
465             Watchdog.getInstance().setActivityController(null);
466         }
467         return false;
468     }
469
470     private boolean makeAppCrashingLocked(ProcessRecord app,
471             String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
472         app.crashing = true;
473         app.crashingReport = generateProcessError(app,
474                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
475         startAppProblemLocked(app);
476         app.stopFreezingAllLocked();
477         return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace,
478                 data);
479     }
480
481     void startAppProblemLocked(ProcessRecord app) {
482         // If this app is not running under the current user, then we
483         // can't give it a report button because that would require
484         // launching the report UI under a different user.
485         app.errorReportReceiver = null;
486
487         for (int userId : mService.mUserController.getCurrentProfileIdsLocked()) {
488             if (app.userId == userId) {
489                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
490                         mContext, app.info.packageName, app.info.flags);
491             }
492         }
493         mService.skipCurrentReceiverLocked(app);
494     }
495
496     /**
497      * Generate a process error record, suitable for attachment to a ProcessRecord.
498      *
499      * @param app The ProcessRecord in which the error occurred.
500      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
501      *                      ActivityManager.AppErrorStateInfo
502      * @param activity The activity associated with the crash, if known.
503      * @param shortMsg Short message describing the crash.
504      * @param longMsg Long message describing the crash.
505      * @param stackTrace Full crash stack trace, may be null.
506      *
507      * @return Returns a fully-formed AppErrorStateInfo record.
508      */
509     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
510             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
511         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
512
513         report.condition = condition;
514         report.processName = app.processName;
515         report.pid = app.pid;
516         report.uid = app.info.uid;
517         report.tag = activity;
518         report.shortMsg = shortMsg;
519         report.longMsg = longMsg;
520         report.stackTrace = stackTrace;
521
522         return report;
523     }
524
525     Intent createAppErrorIntentLocked(ProcessRecord r,
526             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
527         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
528         if (report == null) {
529             return null;
530         }
531         Intent result = new Intent(Intent.ACTION_APP_ERROR);
532         result.setComponent(r.errorReportReceiver);
533         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
534         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
535         return result;
536     }
537
538     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
539             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
540         if (r.errorReportReceiver == null) {
541             return null;
542         }
543
544         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
545             return null;
546         }
547
548         ApplicationErrorReport report = new ApplicationErrorReport();
549         report.packageName = r.info.packageName;
550         report.installerPackageName = r.errorReportReceiver.getPackageName();
551         report.processName = r.processName;
552         report.time = timeMillis;
553         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
554
555         if (r.crashing || r.forceCrashReport) {
556             report.type = ApplicationErrorReport.TYPE_CRASH;
557             report.crashInfo = crashInfo;
558         } else if (r.notResponding) {
559             report.type = ApplicationErrorReport.TYPE_ANR;
560             report.anrInfo = new ApplicationErrorReport.AnrInfo();
561
562             report.anrInfo.activity = r.notRespondingReport.tag;
563             report.anrInfo.cause = r.notRespondingReport.shortMsg;
564             report.anrInfo.info = r.notRespondingReport.longMsg;
565         }
566
567         return report;
568     }
569
570     boolean handleAppCrashLocked(ProcessRecord app, String reason,
571             String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
572         long now = SystemClock.uptimeMillis();
573         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
574                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
575
576         Long crashTime;
577         Long crashTimePersistent;
578         if (!app.isolated) {
579             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
580             crashTimePersistent = mProcessCrashTimesPersistent.get(app.info.processName, app.uid);
581         } else {
582             crashTime = crashTimePersistent = null;
583         }
584         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
585             // This process loses!
586             Slog.w(TAG, "Process " + app.info.processName
587                     + " has crashed too many times: killing!");
588             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
589                     app.userId, app.info.processName, app.uid);
590             mService.mStackSupervisor.handleAppCrashLocked(app);
591             if (!app.persistent) {
592                 // We don't want to start this process again until the user
593                 // explicitly does so...  but for persistent process, we really
594                 // need to keep it running.  If a persistent process is actually
595                 // repeatedly crashing, then badness for everyone.
596                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
597                         app.info.processName);
598                 if (!app.isolated) {
599                     // XXX We don't have a way to mark isolated processes
600                     // as bad, since they don't have a peristent identity.
601                     mBadProcesses.put(app.info.processName, app.uid,
602                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
603                     mProcessCrashTimes.remove(app.info.processName, app.uid);
604                 }
605                 app.bad = true;
606                 app.removed = true;
607                 // Don't let services in this process be restarted and potentially
608                 // annoy the user repeatedly.  Unless it is persistent, since those
609                 // processes run critical code.
610                 mService.removeProcessLocked(app, false, false, "crash");
611                 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
612                 if (!showBackground) {
613                     return false;
614                 }
615             }
616             mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
617         } else {
618             TaskRecord affectedTask =
619                     mService.mStackSupervisor.finishTopRunningActivityLocked(app, reason);
620             if (data != null) {
621                 data.task = affectedTask;
622             }
623             if (data != null && crashTimePersistent != null
624                     && now < crashTimePersistent + ProcessList.MIN_CRASH_INTERVAL) {
625                 data.repeating = true;
626             }
627         }
628
629         boolean procIsBoundForeground =
630                 (app.curProcState == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
631         // Bump up the crash count of any services currently running in the proc.
632         for (int i=app.services.size()-1; i>=0; i--) {
633             // Any services running in the application need to be placed
634             // back in the pending list.
635             ServiceRecord sr = app.services.valueAt(i);
636             sr.crashCount++;
637
638             // Allow restarting for started or bound foreground services that are crashing the
639             // first time. This includes wallpapers.
640             if ((data != null) && (sr.crashCount <= 1)
641                     && (sr.isForeground || procIsBoundForeground)) {
642                 data.isRestartableForService = true;
643             }
644         }
645
646         // If the crashing process is what we consider to be the "home process" and it has been
647         // replaced by a third-party app, clear the package preferred activities from packages
648         // with a home activity running in the process to prevent a repeatedly crashing app
649         // from blocking the user to manually clear the list.
650         final ArrayList<ActivityRecord> activities = app.activities;
651         if (app == mService.mHomeProcess && activities.size() > 0
652                 && (mService.mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
653             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
654                 final ActivityRecord r = activities.get(activityNdx);
655                 if (r.isHomeActivity()) {
656                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
657                     try {
658                         ActivityThread.getPackageManager()
659                                 .clearPackagePreferredActivities(r.packageName);
660                     } catch (RemoteException c) {
661                         // pm is in same process, this will never happen.
662                     }
663                 }
664             }
665         }
666
667         if (!app.isolated) {
668             // XXX Can't keep track of crash times for isolated processes,
669             // because they don't have a perisistent identity.
670             mProcessCrashTimes.put(app.info.processName, app.uid, now);
671             mProcessCrashTimesPersistent.put(app.info.processName, app.uid, now);
672         }
673
674         if (app.crashHandler != null) mService.mHandler.post(app.crashHandler);
675         return true;
676     }
677
678     void handleShowAppErrorUi(Message msg) {
679         AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
680         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
681                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
682         synchronized (mService) {
683             ProcessRecord proc = data.proc;
684             AppErrorResult res = data.result;
685             if (proc != null && proc.crashDialog != null) {
686                 Slog.e(TAG, "App already has crash dialog: " + proc);
687                 if (res != null) {
688                     res.set(AppErrorDialog.ALREADY_SHOWING);
689                 }
690                 return;
691             }
692             boolean isBackground = (UserHandle.getAppId(proc.uid)
693                     >= Process.FIRST_APPLICATION_UID
694                     && proc.pid != MY_PID);
695             for (int userId : mService.mUserController.getCurrentProfileIdsLocked()) {
696                 isBackground &= (proc.userId != userId);
697             }
698             if (isBackground && !showBackground) {
699                 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
700                 if (res != null) {
701                     res.set(AppErrorDialog.BACKGROUND_USER);
702                 }
703                 return;
704             }
705             final boolean crashSilenced = mAppsNotReportingCrashes != null &&
706                     mAppsNotReportingCrashes.contains(proc.info.packageName);
707             if ((mService.canShowErrorDialogs() || showBackground) && !crashSilenced) {
708                 proc.crashDialog = new AppErrorDialog(mContext, mService, data);
709             } else {
710                 // The device is asleep, so just pretend that the user
711                 // saw a crash dialog and hit "force quit".
712                 if (res != null) {
713                     res.set(AppErrorDialog.CANT_SHOW);
714                 }
715             }
716         }
717         // If we've created a crash dialog, show it without the lock held
718         if(data.proc.crashDialog != null) {
719             data.proc.crashDialog.show();
720         }
721     }
722
723     void stopReportingCrashesLocked(ProcessRecord proc) {
724         if (mAppsNotReportingCrashes == null) {
725             mAppsNotReportingCrashes = new ArraySet<>();
726         }
727         mAppsNotReportingCrashes.add(proc.info.packageName);
728     }
729
730     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
731             ActivityRecord parent, boolean aboveSystem, final String annotation) {
732         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
733         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
734
735         if (mService.mController != null) {
736             try {
737                 // 0 == continue, -1 = kill process immediately
738                 int res = mService.mController.appEarlyNotResponding(
739                         app.processName, app.pid, annotation);
740                 if (res < 0 && app.pid != MY_PID) {
741                     app.kill("anr", true);
742                 }
743             } catch (RemoteException e) {
744                 mService.mController = null;
745                 Watchdog.getInstance().setActivityController(null);
746             }
747         }
748
749         long anrTime = SystemClock.uptimeMillis();
750         if (ActivityManagerService.MONITOR_CPU_USAGE) {
751             mService.updateCpuStatsNow();
752         }
753
754         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
755         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
756                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
757
758         boolean isSilentANR;
759
760         synchronized (mService) {
761             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
762             if (mService.mShuttingDown) {
763                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
764                 return;
765             } else if (app.notResponding) {
766                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
767                 return;
768             } else if (app.crashing) {
769                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
770                 return;
771             }
772
773             // In case we come through here for the same app before completing
774             // this one, mark as anring now so we will bail out.
775             app.notResponding = true;
776
777             // Log the ANR to the event log.
778             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
779                     app.processName, app.info.flags, annotation);
780
781             // Dump thread traces as quickly as we can, starting with "interesting" processes.
782             firstPids.add(app.pid);
783
784             // Don't dump other PIDs if it's a background ANR
785             isSilentANR = !showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID;
786             if (!isSilentANR) {
787                 int parentPid = app.pid;
788                 if (parent != null && parent.app != null && parent.app.pid > 0) {
789                     parentPid = parent.app.pid;
790                 }
791                 if (parentPid != app.pid) firstPids.add(parentPid);
792
793                 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
794
795                 for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) {
796                     ProcessRecord r = mService.mLruProcesses.get(i);
797                     if (r != null && r.thread != null) {
798                         int pid = r.pid;
799                         if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
800                             if (r.persistent) {
801                                 firstPids.add(pid);
802                                 if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
803                             } else {
804                                 lastPids.put(pid, Boolean.TRUE);
805                                 if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
806                             }
807                         }
808                     }
809                 }
810             }
811         }
812
813         // Log the ANR to the main log.
814         StringBuilder info = new StringBuilder();
815         info.setLength(0);
816         info.append("ANR in ").append(app.processName);
817         if (activity != null && activity.shortComponentName != null) {
818             info.append(" (").append(activity.shortComponentName).append(")");
819         }
820         info.append("\n");
821         info.append("PID: ").append(app.pid).append("\n");
822         if (annotation != null) {
823             info.append("Reason: ").append(annotation).append("\n");
824         }
825         if (parent != null && parent != activity) {
826             info.append("Parent: ").append(parent.shortComponentName).append("\n");
827         }
828
829         ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
830
831         String[] nativeProcs = NATIVE_STACKS_OF_INTEREST;
832         // don't dump native PIDs for background ANRs
833         File tracesFile = null;
834         if (isSilentANR) {
835             tracesFile = mService.dumpStackTraces(true, firstPids, null, lastPids,
836                 null);
837         } else {
838             tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
839                 nativeProcs);
840         }
841
842         String cpuInfo = null;
843         if (ActivityManagerService.MONITOR_CPU_USAGE) {
844             mService.updateCpuStatsNow();
845             synchronized (mService.mProcessCpuTracker) {
846                 cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime);
847             }
848             info.append(processCpuTracker.printCurrentLoad());
849             info.append(cpuInfo);
850         }
851
852         info.append(processCpuTracker.printCurrentState(anrTime));
853
854         Slog.e(TAG, info.toString());
855         if (tracesFile == null) {
856             // There is no trace file, so dump (only) the alleged culprit's threads to the log
857             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
858         }
859
860         mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
861                 cpuInfo, tracesFile, null);
862
863         if (mService.mController != null) {
864             try {
865                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
866                 int res = mService.mController.appNotResponding(
867                         app.processName, app.pid, info.toString());
868                 if (res != 0) {
869                     if (res < 0 && app.pid != MY_PID) {
870                         app.kill("anr", true);
871                     } else {
872                         synchronized (mService) {
873                             mService.mServices.scheduleServiceTimeoutLocked(app);
874                         }
875                     }
876                     return;
877                 }
878             } catch (RemoteException e) {
879                 mService.mController = null;
880                 Watchdog.getInstance().setActivityController(null);
881             }
882         }
883
884         synchronized (mService) {
885             mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
886
887             if (isSilentANR) {
888                 app.kill("bg anr", true);
889                 return;
890             }
891
892             // Set the app's notResponding state, and look up the errorReportReceiver
893             makeAppNotRespondingLocked(app,
894                     activity != null ? activity.shortComponentName : null,
895                     annotation != null ? "ANR " + annotation : "ANR",
896                     info.toString());
897
898             // Bring up the infamous App Not Responding dialog
899             Message msg = Message.obtain();
900             HashMap<String, Object> map = new HashMap<String, Object>();
901             msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
902             msg.obj = map;
903             msg.arg1 = aboveSystem ? 1 : 0;
904             map.put("app", app);
905             if (activity != null) {
906                 map.put("activity", activity);
907             }
908
909             mService.mUiHandler.sendMessage(msg);
910         }
911     }
912
913     private void makeAppNotRespondingLocked(ProcessRecord app,
914             String activity, String shortMsg, String longMsg) {
915         app.notResponding = true;
916         app.notRespondingReport = generateProcessError(app,
917                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
918                 activity, shortMsg, longMsg, null);
919         startAppProblemLocked(app);
920         app.stopFreezingAllLocked();
921     }
922
923     void handleShowAnrUi(Message msg) {
924         Dialog d = null;
925         synchronized (mService) {
926             HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
927             ProcessRecord proc = (ProcessRecord)data.get("app");
928             if (proc != null && proc.anrDialog != null) {
929                 Slog.e(TAG, "App already has anr dialog: " + proc);
930                 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
931                         AppNotRespondingDialog.ALREADY_SHOWING);
932                 return;
933             }
934
935             Intent intent = new Intent("android.intent.action.ANR");
936             if (!mService.mProcessesReady) {
937                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
938                         | Intent.FLAG_RECEIVER_FOREGROUND);
939             }
940             mService.broadcastIntentLocked(null, null, intent,
941                     null, null, 0, null, null, null, AppOpsManager.OP_NONE,
942                     null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
943
944             boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
945                     Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
946             if (mService.canShowErrorDialogs() || showBackground) {
947                 d = new AppNotRespondingDialog(mService,
948                         mContext, proc, (ActivityRecord)data.get("activity"),
949                         msg.arg1 != 0);
950                 proc.anrDialog = d;
951             } else {
952                 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
953                         AppNotRespondingDialog.CANT_SHOW);
954                 // Just kill the app if there is no dialog to be shown.
955                 mService.killAppAtUsersRequest(proc, null);
956             }
957         }
958         // If we've created a crash dialog, show it without the lock held
959         if (d != null) {
960             d.show();
961         }
962     }
963
964     /**
965      * Information about a process that is currently marked as bad.
966      */
967     static final class BadProcessInfo {
968         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
969             this.time = time;
970             this.shortMsg = shortMsg;
971             this.longMsg = longMsg;
972             this.stack = stack;
973         }
974
975         final long time;
976         final String shortMsg;
977         final String longMsg;
978         final String stack;
979     }
980
981 }