OSDN Git Service

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