1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.am; 18 19 import static android.app.ActivityTaskManager.INVALID_TASK_ID; 20 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM; 21 22 import static com.android.server.am.ActivityManagerConstants.PROCESS_CRASH_COUNT_LIMIT; 23 import static com.android.server.am.ActivityManagerConstants.PROCESS_CRASH_COUNT_RESET_INTERVAL; 24 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 25 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 26 import static com.android.server.am.ActivityManagerService.MY_PID; 27 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE; 28 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; 29 30 import android.annotation.Nullable; 31 import android.app.ActivityManager; 32 import android.app.ActivityOptions; 33 import android.app.AnrController; 34 import android.app.ApplicationErrorReport; 35 import android.app.ApplicationExitInfo; 36 import android.app.RemoteServiceException.CrashedByAdbException; 37 import android.app.usage.UsageStatsManager; 38 import android.content.ActivityNotFoundException; 39 import android.content.Context; 40 import android.content.Intent; 41 import android.content.pm.VersionedPackage; 42 import android.net.Uri; 43 import android.os.Binder; 44 import android.os.Build; 45 import android.os.Bundle; 46 import android.os.Message; 47 import android.os.Process; 48 import android.os.SystemClock; 49 import android.os.UserHandle; 50 import android.provider.Settings; 51 import android.util.ArrayMap; 52 import android.util.ArraySet; 53 import android.util.EventLog; 54 import android.util.Pair; 55 import android.util.Slog; 56 import android.util.SparseArray; 57 import android.util.TimeUtils; 58 import android.util.proto.ProtoOutputStream; 59 60 import com.android.internal.annotations.GuardedBy; 61 import com.android.internal.app.ProcessMap; 62 import com.android.internal.logging.MetricsLogger; 63 import com.android.internal.logging.nano.MetricsProto; 64 import com.android.server.LocalServices; 65 import com.android.server.PackageWatchdog; 66 import com.android.server.usage.AppStandbyInternal; 67 import com.android.server.wm.WindowProcessController; 68 69 import java.io.FileDescriptor; 70 import java.io.PrintWriter; 71 import java.util.Collections; 72 import java.util.List; 73 74 /** 75 * Controls error conditions in applications. 76 */ 77 class AppErrors { 78 79 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppErrors" : TAG_AM; 80 81 private final ActivityManagerService mService; 82 private final ActivityManagerGlobalLock mProcLock; 83 private final Context mContext; 84 private final PackageWatchdog mPackageWatchdog; 85 86 @GuardedBy("mBadProcessLock") 87 private ArraySet<String> mAppsNotReportingCrashes; 88 89 /** 90 * The last time that various processes have crashed since they were last explicitly started. 91 */ 92 @GuardedBy("mBadProcessLock") 93 private final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<>(); 94 95 /** 96 * The last time that various processes have crashed (not reset even when explicitly started). 97 */ 98 @GuardedBy("mBadProcessLock") 99 private final ProcessMap<Long> mProcessCrashTimesPersistent = new ProcessMap<>(); 100 101 /** 102 * The last time that various processes have crashed and shown an error dialog. 103 */ 104 @GuardedBy("mBadProcessLock") 105 private final ProcessMap<Long> mProcessCrashShowDialogTimes = new ProcessMap<>(); 106 107 /** 108 * A pairing between how many times various processes have crashed since a given time. 109 * Entry and exit conditions for this map are similar to mProcessCrashTimes. 110 */ 111 @GuardedBy("mBadProcessLock") 112 private final ProcessMap<Pair<Long, Integer>> mProcessCrashCounts = new ProcessMap<>(); 113 114 /** 115 * Set of applications that we consider to be bad, and will reject 116 * incoming broadcasts from (which the user has no control over). 117 * Processes are added to this set when they have crashed twice within 118 * a minimum amount of time; they are removed from it when they are 119 * later restarted (hopefully due to some user action). The value is the 120 * time it was added to the list. 121 * 122 * Read access is UNLOCKED, and must either be based on a single lookup 123 * call on the current mBadProcesses instance, or a local copy of that 124 * reference must be made and the local copy treated as the source of 125 * truth. Mutations are performed by synchronizing on mBadProcessLock, 126 * cloning the existing mBadProcesses instance, performing the mutation, 127 * then changing the volatile "live" mBadProcesses reference to point to the 128 * mutated version. These operations are very rare compared to lookups: 129 * we intentionally trade additional cost for mutations for eliminating 130 * lock operations from the simple lookup cases. 131 */ 132 private volatile ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>(); 133 134 /** 135 * Dedicated lock for {@link #mAppsNotReportingCrashes}, {@link #mProcessCrashTimes}, 136 * {@link #mProcessCrashTimesPersistent}, {@link #mProcessCrashShowDialogTimes}, 137 * {@link #mProcessCrashCounts} and {@link #mBadProcesses}. 138 * 139 * <p>The naming convention of the function with this lock should be "-LBp"</b> 140 * 141 * @See mBadProcesses 142 */ 143 private final Object mBadProcessLock = new Object(); 144 AppErrors(Context context, ActivityManagerService service, PackageWatchdog watchdog)145 AppErrors(Context context, ActivityManagerService service, PackageWatchdog watchdog) { 146 context.assertRuntimeOverlayThemable(); 147 mService = service; 148 mProcLock = service.mProcLock; 149 mContext = context; 150 mPackageWatchdog = watchdog; 151 } 152 153 /** Resets the current state but leaves the constructor-provided fields unchanged. */ resetState()154 public void resetState() { 155 Slog.i(TAG, "Resetting AppErrors"); 156 synchronized (mBadProcessLock) { 157 mAppsNotReportingCrashes.clear(); 158 mProcessCrashTimes.clear(); 159 mProcessCrashTimesPersistent.clear(); 160 mProcessCrashShowDialogTimes.clear(); 161 mProcessCrashCounts.clear(); 162 mBadProcesses = new ProcessMap<>(); 163 } 164 } 165 166 @GuardedBy("mProcLock") dumpDebugLPr(ProtoOutputStream proto, long fieldId, String dumpPackage)167 void dumpDebugLPr(ProtoOutputStream proto, long fieldId, String dumpPackage) { 168 final ProcessMap<BadProcessInfo> badProcesses = mBadProcesses; 169 if (mProcessCrashTimes.getMap().isEmpty() && badProcesses.getMap().isEmpty()) { 170 return; 171 } 172 173 final long token = proto.start(fieldId); 174 final long now = SystemClock.uptimeMillis(); 175 proto.write(AppErrorsProto.NOW_UPTIME_MS, now); 176 177 if (!badProcesses.getMap().isEmpty()) { 178 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = badProcesses.getMap(); 179 final int processCount = pmap.size(); 180 for (int ip = 0; ip < processCount; ip++) { 181 final long btoken = proto.start(AppErrorsProto.BAD_PROCESSES); 182 final String pname = pmap.keyAt(ip); 183 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 184 final int uidCount = uids.size(); 185 186 proto.write(AppErrorsProto.BadProcess.PROCESS_NAME, pname); 187 for (int i = 0; i < uidCount; i++) { 188 final int puid = uids.keyAt(i); 189 final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid); 190 if (dumpPackage != null && (r == null 191 || !r.getPkgList().containsKey(dumpPackage))) { 192 continue; 193 } 194 final BadProcessInfo info = uids.valueAt(i); 195 final long etoken = proto.start(AppErrorsProto.BadProcess.ENTRIES); 196 proto.write(AppErrorsProto.BadProcess.Entry.UID, puid); 197 proto.write(AppErrorsProto.BadProcess.Entry.CRASHED_AT_MS, info.time); 198 proto.write(AppErrorsProto.BadProcess.Entry.SHORT_MSG, info.shortMsg); 199 proto.write(AppErrorsProto.BadProcess.Entry.LONG_MSG, info.longMsg); 200 proto.write(AppErrorsProto.BadProcess.Entry.STACK, info.stack); 201 proto.end(etoken); 202 } 203 proto.end(btoken); 204 } 205 } 206 207 synchronized (mBadProcessLock) { 208 if (!mProcessCrashTimes.getMap().isEmpty()) { 209 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 210 final int procCount = pmap.size(); 211 for (int ip = 0; ip < procCount; ip++) { 212 final long ctoken = proto.start(AppErrorsProto.PROCESS_CRASH_TIMES); 213 final String pname = pmap.keyAt(ip); 214 final SparseArray<Long> uids = pmap.valueAt(ip); 215 final int uidCount = uids.size(); 216 217 proto.write(AppErrorsProto.ProcessCrashTime.PROCESS_NAME, pname); 218 for (int i = 0; i < uidCount; i++) { 219 final int puid = uids.keyAt(i); 220 final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid); 221 if (dumpPackage != null 222 && (r == null || !r.getPkgList().containsKey(dumpPackage))) { 223 continue; 224 } 225 final long etoken = proto.start(AppErrorsProto.ProcessCrashTime.ENTRIES); 226 proto.write(AppErrorsProto.ProcessCrashTime.Entry.UID, puid); 227 proto.write(AppErrorsProto.ProcessCrashTime.Entry.LAST_CRASHED_AT_MS, 228 uids.valueAt(i)); 229 proto.end(etoken); 230 } 231 proto.end(ctoken); 232 } 233 } 234 } 235 236 proto.end(token); 237 } 238 239 @GuardedBy("mProcLock") dumpLPr(FileDescriptor fd, PrintWriter pw, boolean needSep, String dumpPackage)240 boolean dumpLPr(FileDescriptor fd, PrintWriter pw, boolean needSep, String dumpPackage) { 241 final long now = SystemClock.uptimeMillis(); 242 synchronized (mBadProcessLock) { 243 if (!mProcessCrashTimes.getMap().isEmpty()) { 244 boolean printed = false; 245 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 246 final int processCount = pmap.size(); 247 for (int ip = 0; ip < processCount; ip++) { 248 final String pname = pmap.keyAt(ip); 249 final SparseArray<Long> uids = pmap.valueAt(ip); 250 final int uidCount = uids.size(); 251 for (int i = 0; i < uidCount; i++) { 252 final int puid = uids.keyAt(i); 253 final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid); 254 if (dumpPackage != null 255 && (r == null || !r.getPkgList().containsKey(dumpPackage))) { 256 continue; 257 } 258 if (!printed) { 259 if (needSep) pw.println(); 260 needSep = true; 261 pw.println(" Time since processes crashed:"); 262 printed = true; 263 } 264 pw.print(" Process "); pw.print(pname); 265 pw.print(" uid "); pw.print(puid); 266 pw.print(": last crashed "); 267 TimeUtils.formatDuration(now - uids.valueAt(i), pw); 268 pw.println(" ago"); 269 } 270 } 271 } 272 273 if (!mProcessCrashCounts.getMap().isEmpty()) { 274 boolean printed = false; 275 final ArrayMap<String, SparseArray<Pair<Long, Integer>>> pmap = 276 mProcessCrashCounts.getMap(); 277 final int processCount = pmap.size(); 278 for (int ip = 0; ip < processCount; ip++) { 279 final String pname = pmap.keyAt(ip); 280 final SparseArray<Pair<Long, Integer>> uids = pmap.valueAt(ip); 281 final int uidCount = uids.size(); 282 for (int i = 0; i < uidCount; i++) { 283 final int puid = uids.keyAt(i); 284 final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid); 285 if (dumpPackage != null 286 && (r == null || !r.getPkgList().containsKey(dumpPackage))) { 287 continue; 288 } 289 if (!printed) { 290 if (needSep) pw.println(); 291 needSep = true; 292 pw.println(" First time processes crashed and counts:"); 293 printed = true; 294 } 295 pw.print(" Process "); pw.print(pname); 296 pw.print(" uid "); pw.print(puid); 297 pw.print(": first crashed "); 298 TimeUtils.formatDuration(now - uids.valueAt(i).first, pw); 299 pw.print(" ago; crashes since then: "); pw.println(uids.valueAt(i).second); 300 } 301 } 302 } 303 } 304 305 final ProcessMap<BadProcessInfo> badProcesses = mBadProcesses; 306 if (!badProcesses.getMap().isEmpty()) { 307 boolean printed = false; 308 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = badProcesses.getMap(); 309 final int processCount = pmap.size(); 310 for (int ip = 0; ip < processCount; ip++) { 311 final String pname = pmap.keyAt(ip); 312 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 313 final int uidCount = uids.size(); 314 for (int i = 0; i < uidCount; i++) { 315 final int puid = uids.keyAt(i); 316 final ProcessRecord r = mService.getProcessNamesLOSP().get(pname, puid); 317 if (dumpPackage != null && (r == null 318 || !r.getPkgList().containsKey(dumpPackage))) { 319 continue; 320 } 321 if (!printed) { 322 if (needSep) pw.println(); 323 needSep = true; 324 pw.println(" Bad processes:"); 325 printed = true; 326 } 327 final BadProcessInfo info = uids.valueAt(i); 328 pw.print(" Bad process "); pw.print(pname); 329 pw.print(" uid "); pw.print(puid); 330 pw.print(": crashed at time "); pw.println(info.time); 331 if (info.shortMsg != null) { 332 pw.print(" Short msg: "); pw.println(info.shortMsg); 333 } 334 if (info.longMsg != null) { 335 pw.print(" Long msg: "); pw.println(info.longMsg); 336 } 337 if (info.stack != null) { 338 pw.println(" Stack:"); 339 int lastPos = 0; 340 for (int pos = 0; pos < info.stack.length(); pos++) { 341 if (info.stack.charAt(pos) == '\n') { 342 pw.print(" "); 343 pw.write(info.stack, lastPos, pos - lastPos); 344 pw.println(); 345 lastPos = pos + 1; 346 } 347 } 348 if (lastPos < info.stack.length()) { 349 pw.print(" "); 350 pw.write(info.stack, lastPos, info.stack.length() - lastPos); 351 pw.println(); 352 } 353 } 354 } 355 } 356 } 357 return needSep; 358 } 359 isBadProcess(final String processName, final int uid)360 boolean isBadProcess(final String processName, final int uid) { 361 // NO LOCKING for the simple lookup 362 return mBadProcesses.get(processName, uid) != null; 363 } 364 clearBadProcess(final String processName, final int uid)365 void clearBadProcess(final String processName, final int uid) { 366 synchronized (mBadProcessLock) { 367 final ProcessMap<BadProcessInfo> badProcesses = new ProcessMap<>(); 368 badProcesses.putAll(mBadProcesses); 369 badProcesses.remove(processName, uid); 370 mBadProcesses = badProcesses; 371 } 372 } 373 markBadProcess(final String processName, final int uid, BadProcessInfo info)374 void markBadProcess(final String processName, final int uid, BadProcessInfo info) { 375 synchronized (mBadProcessLock) { 376 final ProcessMap<BadProcessInfo> badProcesses = new ProcessMap<>(); 377 badProcesses.putAll(mBadProcesses); 378 badProcesses.put(processName, uid, info); 379 mBadProcesses = badProcesses; 380 } 381 } 382 resetProcessCrashTime(final String processName, final int uid)383 void resetProcessCrashTime(final String processName, final int uid) { 384 synchronized (mBadProcessLock) { 385 mProcessCrashTimes.remove(processName, uid); 386 mProcessCrashCounts.remove(processName, uid); 387 } 388 } 389 resetProcessCrashTime(boolean resetEntireUser, int appId, int userId)390 void resetProcessCrashTime(boolean resetEntireUser, int appId, int userId) { 391 synchronized (mBadProcessLock) { 392 final ArrayMap<String, SparseArray<Long>> pTimeMap = mProcessCrashTimes.getMap(); 393 for (int ip = pTimeMap.size() - 1; ip >= 0; ip--) { 394 SparseArray<Long> ba = pTimeMap.valueAt(ip); 395 resetProcessCrashMapLBp(ba, resetEntireUser, appId, userId); 396 if (ba.size() == 0) { 397 pTimeMap.removeAt(ip); 398 } 399 } 400 401 final ArrayMap<String, SparseArray<Pair<Long, Integer>>> pCountMap = 402 mProcessCrashCounts.getMap(); 403 for (int ip = pCountMap.size() - 1; ip >= 0; ip--) { 404 SparseArray<Pair<Long, Integer>> ba = pCountMap.valueAt(ip); 405 resetProcessCrashMapLBp(ba, resetEntireUser, appId, userId); 406 if (ba.size() == 0) { 407 pCountMap.removeAt(ip); 408 } 409 } 410 } 411 } 412 413 @GuardedBy("mBadProcessLock") resetProcessCrashMapLBp(SparseArray<?> ba, boolean resetEntireUser, int appId, int userId)414 private void resetProcessCrashMapLBp(SparseArray<?> ba, boolean resetEntireUser, 415 int appId, int userId) { 416 for (int i = ba.size() - 1; i >= 0; i--) { 417 boolean remove = false; 418 final int entUid = ba.keyAt(i); 419 if (!resetEntireUser) { 420 if (userId == UserHandle.USER_ALL) { 421 if (UserHandle.getAppId(entUid) == appId) { 422 remove = true; 423 } 424 } else { 425 if (entUid == UserHandle.getUid(userId, appId)) { 426 remove = true; 427 } 428 } 429 } else if (UserHandle.getUserId(entUid) == userId) { 430 remove = true; 431 } 432 if (remove) { 433 ba.removeAt(i); 434 } 435 } 436 } 437 loadAppsNotReportingCrashesFromConfig(String appsNotReportingCrashesConfig)438 void loadAppsNotReportingCrashesFromConfig(String appsNotReportingCrashesConfig) { 439 if (appsNotReportingCrashesConfig != null) { 440 final String[] split = appsNotReportingCrashesConfig.split(","); 441 if (split.length > 0) { 442 synchronized (mBadProcessLock) { 443 mAppsNotReportingCrashes = new ArraySet<>(); 444 Collections.addAll(mAppsNotReportingCrashes, split); 445 } 446 } 447 } 448 } 449 450 @GuardedBy("mService") killAppAtUserRequestLocked(ProcessRecord app)451 void killAppAtUserRequestLocked(ProcessRecord app) { 452 ErrorDialogController controller = app.mErrorState.getDialogController(); 453 454 int reasonCode = ApplicationExitInfo.REASON_ANR; 455 int subReason = ApplicationExitInfo.SUBREASON_UNKNOWN; 456 synchronized (mProcLock) { 457 if (controller.hasDebugWaitingDialog()) { 458 reasonCode = ApplicationExitInfo.REASON_OTHER; 459 subReason = ApplicationExitInfo.SUBREASON_WAIT_FOR_DEBUGGER; 460 } 461 controller.clearAllErrorDialogs(); 462 killAppImmediateLSP(app, reasonCode, subReason, 463 "user-terminated", "user request after error"); 464 } 465 } 466 467 @GuardedBy({"mService", "mProcLock"}) killAppImmediateLSP(ProcessRecord app, int reasonCode, int subReason, String reason, String killReason)468 private void killAppImmediateLSP(ProcessRecord app, int reasonCode, int subReason, 469 String reason, String killReason) { 470 final ProcessErrorStateRecord errState = app.mErrorState; 471 errState.setCrashing(false); 472 errState.setCrashingReport(null); 473 errState.setNotResponding(false); 474 errState.setNotRespondingReport(null); 475 final int pid = errState.mApp.getPid(); 476 if (pid > 0 && pid != MY_PID) { 477 synchronized (mBadProcessLock) { 478 handleAppCrashLSPB(app, reason, 479 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/); 480 } 481 app.killLocked(killReason, reasonCode, subReason, true); 482 } 483 } 484 485 /** 486 * Induce a crash in the given app. 487 * 488 * @param uid if nonnegative, the required matching uid of the target to crash 489 * @param initialPid fast-path match for the target to crash 490 * @param packageName fallback match if the stated pid is not found or doesn't match uid 491 * @param userId If nonnegative, required to identify a match by package name 492 * @param message 493 */ scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId, String message, boolean force, int exceptionTypeId, @Nullable Bundle extras)494 void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId, 495 String message, boolean force, int exceptionTypeId, @Nullable Bundle extras) { 496 ProcessRecord proc = null; 497 498 // Figure out which process to kill. We don't trust that initialPid 499 // still has any relation to current pids, so must scan through the 500 // list. 501 502 synchronized (mService.mPidsSelfLocked) { 503 for (int i=0; i<mService.mPidsSelfLocked.size(); i++) { 504 ProcessRecord p = mService.mPidsSelfLocked.valueAt(i); 505 if (uid >= 0 && p.uid != uid) { 506 continue; 507 } 508 if (p.getPid() == initialPid) { 509 proc = p; 510 break; 511 } 512 if (p.getPkgList().containsKey(packageName) 513 && (userId < 0 || p.userId == userId)) { 514 proc = p; 515 } 516 } 517 } 518 519 if (proc == null) { 520 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 521 + " initialPid=" + initialPid 522 + " packageName=" + packageName 523 + " userId=" + userId); 524 return; 525 } 526 527 if (exceptionTypeId == CrashedByAdbException.TYPE_ID) { 528 String[] packages = proc.getPackageList(); 529 for (int i = 0; i < packages.length; i++) { 530 if (mService.mPackageManagerInt.isPackageStateProtected(packages[i], proc.userId)) { 531 Slog.w(TAG, "crashApplication: Can not crash protected package " + packages[i]); 532 return; 533 } 534 } 535 } 536 537 mService.mOomAdjuster.mCachedAppOptimizer.unfreezeProcess(initialPid, 538 CachedAppOptimizer.UNFREEZE_REASON_PROCESS_END); 539 proc.scheduleCrashLocked(message, exceptionTypeId, extras); 540 if (force) { 541 // If the app is responsive, the scheduled crash will happen as expected 542 // and then the delayed summary kill will be a no-op. 543 final ProcessRecord p = proc; 544 mService.mHandler.postDelayed( 545 () -> { 546 synchronized (mService) { 547 synchronized (mProcLock) { 548 killAppImmediateLSP(p, ApplicationExitInfo.REASON_OTHER, 549 ApplicationExitInfo.SUBREASON_INVALID_STATE, 550 "forced", "killed for invalid state"); 551 } 552 } 553 }, 554 5000L); 555 } 556 } 557 sendRecoverableCrashToAppExitInfo( ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo)558 void sendRecoverableCrashToAppExitInfo( 559 ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 560 if (r == null || crashInfo == null 561 || !"Native crash".equals(crashInfo.exceptionClassName)) return; 562 synchronized (mService) { 563 mService.mProcessList.noteAppRecoverableCrash(r); 564 } 565 } 566 567 /** 568 * Bring up the "unexpected error" dialog box for a crashing app. 569 * Deal with edge cases (intercepts from instrumented applications, 570 * ActivityController, error intent receivers, that sort of thing). 571 * @param r the application crashing 572 * @param crashInfo describing the failure 573 */ crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo)574 void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 575 final int callingPid = Binder.getCallingPid(); 576 final int callingUid = Binder.getCallingUid(); 577 578 final long origId = Binder.clearCallingIdentity(); 579 try { 580 crashApplicationInner(r, crashInfo, callingPid, callingUid); 581 } finally { 582 Binder.restoreCallingIdentity(origId); 583 } 584 } 585 crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo, int callingPid, int callingUid)586 private void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo, 587 int callingPid, int callingUid) { 588 long timeMillis = System.currentTimeMillis(); 589 String shortMsg = crashInfo.exceptionClassName; 590 String longMsg = crashInfo.exceptionMessage; 591 String stackTrace = crashInfo.stackTrace; 592 if (shortMsg != null && longMsg != null) { 593 longMsg = shortMsg + ": " + longMsg; 594 } else if (shortMsg != null) { 595 longMsg = shortMsg; 596 } 597 598 if (r != null) { 599 mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode(), 600 PackageWatchdog.FAILURE_REASON_APP_CRASH); 601 602 synchronized (mService) { 603 mService.mProcessList.noteAppKill(r, (crashInfo != null 604 && "Native crash".equals(crashInfo.exceptionClassName)) 605 ? ApplicationExitInfo.REASON_CRASH_NATIVE 606 : ApplicationExitInfo.REASON_CRASH, 607 ApplicationExitInfo.SUBREASON_UNKNOWN, 608 "crash"); 609 } 610 } 611 612 final int relaunchReason = r != null 613 ? r.getWindowProcessController().computeRelaunchReason() : RELAUNCH_REASON_NONE; 614 615 AppErrorResult result = new AppErrorResult(); 616 int taskId; 617 synchronized (mService) { 618 /** 619 * If crash is handled by instance of {@link android.app.IActivityController}, 620 * finish now and don't show the app error dialog. 621 */ 622 if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace, 623 timeMillis, callingPid, callingUid)) { 624 return; 625 } 626 627 // Suppress crash dialog if the process is being relaunched due to a crash during a free 628 // resize. 629 if (relaunchReason == RELAUNCH_REASON_FREE_RESIZE) { 630 return; 631 } 632 633 /** 634 * If this process was running instrumentation, finish now - it will be handled in 635 * {@link ActivityManagerService#handleAppDiedLocked}. 636 */ 637 if (r != null && r.getActiveInstrumentation() != null) { 638 return; 639 } 640 641 // Log crash in battery stats. 642 if (r != null) { 643 mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 644 } 645 646 AppErrorDialog.Data data = new AppErrorDialog.Data(); 647 data.result = result; 648 data.proc = r; 649 650 // If we can't identify the process or it's already exceeded its crash quota, 651 // quit right away without showing a crash dialog. 652 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) { 653 return; 654 } 655 656 final Message msg = Message.obtain(); 657 msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG; 658 659 taskId = data.taskId; 660 msg.obj = data; 661 mService.mUiHandler.sendMessage(msg); 662 } 663 664 int res = result.get(); 665 666 Intent appErrorIntent = null; 667 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res); 668 if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) { 669 res = AppErrorDialog.FORCE_QUIT; 670 } 671 switch (res) { 672 case AppErrorDialog.MUTE: 673 synchronized (mBadProcessLock) { 674 stopReportingCrashesLBp(r); 675 } 676 break; 677 case AppErrorDialog.RESTART: 678 synchronized (mService) { 679 mService.mProcessList.removeProcessLocked(r, false, true, 680 ApplicationExitInfo.REASON_CRASH, "crash"); 681 } 682 if (taskId != INVALID_TASK_ID) { 683 try { 684 mService.startActivityFromRecents(taskId, 685 ActivityOptions.makeBasic().toBundle()); 686 } catch (IllegalArgumentException e) { 687 // Hmm...that didn't work. Task should either be in recents or associated 688 // with a stack. 689 Slog.e(TAG, "Could not restart taskId=" + taskId, e); 690 } 691 } 692 break; 693 case AppErrorDialog.FORCE_QUIT: 694 final long orig = Binder.clearCallingIdentity(); 695 try { 696 // Kill it with fire! 697 mService.mAtmInternal.onHandleAppCrash(r.getWindowProcessController()); 698 if (!r.isPersistent()) { 699 synchronized (mService) { 700 mService.mProcessList.removeProcessLocked(r, false, false, 701 ApplicationExitInfo.REASON_CRASH, "crash"); 702 } 703 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */); 704 } 705 } finally { 706 Binder.restoreCallingIdentity(orig); 707 } 708 break; 709 case AppErrorDialog.APP_INFO: 710 appErrorIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 711 appErrorIntent.setData(Uri.parse("package:" + r.info.packageName)); 712 appErrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 713 break; 714 case AppErrorDialog.FORCE_QUIT_AND_REPORT: 715 synchronized (mProcLock) { 716 appErrorIntent = createAppErrorIntentLOSP(r, timeMillis, crashInfo); 717 } 718 break; 719 } 720 721 if (appErrorIntent != null) { 722 try { 723 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 724 } catch (ActivityNotFoundException e) { 725 Slog.w(TAG, "bug report receiver dissappeared", e); 726 } 727 } 728 } 729 730 @GuardedBy("mService") handleAppCrashInActivityController(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo, String shortMsg, String longMsg, String stackTrace, long timeMillis, int callingPid, int callingUid)731 private boolean handleAppCrashInActivityController(ProcessRecord r, 732 ApplicationErrorReport.CrashInfo crashInfo, 733 String shortMsg, String longMsg, 734 String stackTrace, long timeMillis, 735 int callingPid, int callingUid) { 736 String name = r != null ? r.processName : null; 737 int pid = r != null ? r.getPid() : callingPid; 738 int uid = r != null ? r.info.uid : callingUid; 739 740 return mService.mAtmInternal.handleAppCrashInActivityController( 741 name, pid, shortMsg, longMsg, timeMillis, crashInfo.stackTrace, () -> { 742 if (Build.IS_DEBUGGABLE 743 && "Native crash".equals(crashInfo.exceptionClassName)) { 744 Slog.w(TAG, "Skip killing native crashed app " + name 745 + "(" + pid + ") during testing"); 746 } else { 747 Slog.w(TAG, "Force-killing crashed app " + name + " at watcher's request"); 748 if (r != null) { 749 if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null)) { 750 r.killLocked("crash", ApplicationExitInfo.REASON_CRASH, true); 751 } 752 } else { 753 // Huh. 754 Process.killProcess(pid); 755 ProcessList.killProcessGroup(uid, pid); 756 mService.mProcessList.noteAppKill(pid, uid, 757 ApplicationExitInfo.REASON_CRASH, 758 ApplicationExitInfo.SUBREASON_UNKNOWN, 759 "crash"); 760 } 761 } 762 }); 763 } 764 765 @GuardedBy("mService") 766 private boolean makeAppCrashingLocked(ProcessRecord app, 767 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { 768 synchronized (mProcLock) { 769 final ProcessErrorStateRecord errState = app.mErrorState; 770 errState.setCrashing(true); 771 errState.setCrashingReport(generateProcessError(app, 772 ActivityManager.ProcessErrorStateInfo.CRASHED, 773 null, shortMsg, longMsg, stackTrace)); 774 errState.startAppProblemLSP(); 775 app.getWindowProcessController().stopFreezingActivities(); 776 synchronized (mBadProcessLock) { 777 return handleAppCrashLSPB(app, "force-crash" /*reason*/, shortMsg, longMsg, 778 stackTrace, data); 779 } 780 } 781 } 782 783 /** 784 * Generate a process error record, suitable for attachment to a ProcessRecord. 785 * 786 * @param app The ProcessRecord in which the error occurred. 787 * @param condition Crashing, Application Not Responding, etc. Values are defined in 788 * ActivityManager.ProcessErrorStateInfo 789 * @param activity The activity associated with the crash, if known. 790 * @param shortMsg Short message describing the crash. 791 * @param longMsg Long message describing the crash. 792 * @param stackTrace Full crash stack trace, may be null. 793 * 794 * @return Returns a fully-formed ProcessErrorStateInfo record. 795 */ 796 ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 797 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 798 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 799 800 report.condition = condition; 801 report.processName = app.processName; 802 report.pid = app.getPid(); 803 report.uid = app.info.uid; 804 report.tag = activity; 805 report.shortMsg = shortMsg; 806 report.longMsg = longMsg; 807 report.stackTrace = stackTrace; 808 809 return report; 810 } 811 812 @GuardedBy(anyOf = {"mService", "mProcLock"}) 813 Intent createAppErrorIntentLOSP(ProcessRecord r, 814 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 815 ApplicationErrorReport report = createAppErrorReportLOSP(r, timeMillis, crashInfo); 816 if (report == null) { 817 return null; 818 } 819 Intent result = new Intent(Intent.ACTION_APP_ERROR); 820 result.setComponent(r.mErrorState.getErrorReportReceiver()); 821 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 822 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 823 return result; 824 } 825 826 @GuardedBy(anyOf = {"mService", "mProcLock"}) 827 private ApplicationErrorReport createAppErrorReportLOSP(ProcessRecord r, 828 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 829 final ProcessErrorStateRecord errState = r.mErrorState; 830 if (errState.getErrorReportReceiver() == null) { 831 return null; 832 } 833 834 if (!errState.isCrashing() && !errState.isNotResponding() 835 && !errState.isForceCrashReport()) { 836 return null; 837 } 838 839 ApplicationErrorReport report = new ApplicationErrorReport(); 840 report.packageName = r.info.packageName; 841 report.installerPackageName = errState.getErrorReportReceiver().getPackageName(); 842 report.processName = r.processName; 843 report.time = timeMillis; 844 report.systemApp = (r.info.flags & FLAG_SYSTEM) != 0; 845 846 if (errState.isCrashing() || errState.isForceCrashReport()) { 847 report.type = ApplicationErrorReport.TYPE_CRASH; 848 report.crashInfo = crashInfo; 849 } else if (errState.isNotResponding()) { 850 final ActivityManager.ProcessErrorStateInfo anrReport = 851 errState.getNotRespondingReport(); 852 if (anrReport == null) { 853 // The ANR dump is still ongoing, ignore it for now. 854 return null; 855 } 856 report.type = ApplicationErrorReport.TYPE_ANR; 857 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 858 859 report.anrInfo.activity = anrReport.tag; 860 report.anrInfo.cause = anrReport.shortMsg; 861 report.anrInfo.info = anrReport.longMsg; 862 } 863 864 return report; 865 } 866 867 @GuardedBy({"mService", "mProcLock", "mBadProcessLock"}) 868 private boolean handleAppCrashLSPB(ProcessRecord app, String reason, 869 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { 870 final long now = SystemClock.uptimeMillis(); 871 final boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(), 872 Settings.Secure.ANR_SHOW_BACKGROUND, 0, 873 mService.mUserController.getCurrentUserId()) != 0; 874 875 Long crashTime; 876 Long crashTimePersistent; 877 final String processName = app.processName; 878 final int uid = app.uid; 879 final int userId = app.userId; 880 final boolean isolated = app.isolated; 881 final boolean persistent = app.isPersistent(); 882 final WindowProcessController proc = app.getWindowProcessController(); 883 final ProcessErrorStateRecord errState = app.mErrorState; 884 885 if (!app.isolated) { 886 crashTime = mProcessCrashTimes.get(processName, uid); 887 crashTimePersistent = mProcessCrashTimesPersistent.get(processName, uid); 888 } else { 889 crashTime = crashTimePersistent = null; 890 } 891 892 // Bump up the crash count of any services currently running in the proc. 893 boolean tryAgain = app.mServices.incServiceCrashCountLocked(now); 894 895 final boolean quickCrash = crashTime != null 896 && now < crashTime + ActivityManagerConstants.MIN_CRASH_INTERVAL; 897 if (quickCrash || isProcOverCrashLimitLBp(app, now)) { 898 // The process either crashed again very quickly or has been crashing periodically in 899 // the last few hours. If it was a bound foreground service, let's try to restart again 900 // in a while, otherwise the process loses! 901 Slog.w(TAG, "Process " + processName + " has crashed too many times, killing!" 902 + " Reason: " + (quickCrash ? "crashed quickly" : "over process crash limit")); 903 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 904 userId, processName, uid); 905 mService.mAtmInternal.onHandleAppCrash(proc); 906 if (!persistent) { 907 // We don't want to start this process again until the user 908 // explicitly does so... but for persistent process, we really 909 // need to keep it running. If a persistent process is actually 910 // repeatedly crashing, then badness for everyone. 911 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, userId, uid, 912 processName); 913 if (!isolated) { 914 // XXX We don't have a way to mark isolated processes 915 // as bad, since they don't have a persistent identity. 916 markBadProcess(processName, app.uid, 917 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 918 mProcessCrashTimes.remove(processName, app.uid); 919 mProcessCrashCounts.remove(processName, app.uid); 920 } 921 errState.setBad(true); 922 app.setRemoved(true); 923 final AppStandbyInternal appStandbyInternal = 924 LocalServices.getService(AppStandbyInternal.class); 925 if (appStandbyInternal != null) { 926 appStandbyInternal.restrictApp( 927 // Sometimes the processName is the same as the package name, so use 928 // that if we don't have the ApplicationInfo object. 929 // AppStandbyController will just return if it can't find the app. 930 app.info != null ? app.info.packageName : processName, 931 userId, UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY); 932 } 933 // Don't let services in this process be restarted and potentially 934 // annoy the user repeatedly. Unless it is persistent, since those 935 // processes run critical code. 936 mService.mProcessList.removeProcessLocked(app, false, tryAgain, 937 ApplicationExitInfo.REASON_CRASH, "crash"); 938 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */); 939 if (!showBackground) { 940 return false; 941 } 942 } 943 mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */); 944 } else { 945 final int affectedTaskId = mService.mAtmInternal.finishTopCrashedActivities( 946 proc, reason); 947 if (data != null) { 948 data.taskId = affectedTaskId; 949 } 950 if (data != null && crashTimePersistent != null 951 && now < crashTimePersistent + ActivityManagerConstants.MIN_CRASH_INTERVAL) { 952 data.repeating = true; 953 } 954 } 955 956 if (data != null && tryAgain) { 957 data.isRestartableForService = true; 958 } 959 960 // If the crashing process is what we consider to be the "home process" and it has been 961 // replaced by a third-party app, clear the package preferred activities from packages 962 // with a home activity running in the process to prevent a repeatedly crashing app 963 // from blocking the user to manually clear the list. 964 if (proc.isHomeProcess() && proc.hasActivities() && (app.info.flags & FLAG_SYSTEM) == 0) { 965 proc.clearPackagePreferredForHomeActivities(); 966 } 967 968 if (!isolated) { 969 // XXX Can't keep track of crash times for isolated processes, 970 // because they don't have a persistent identity. 971 mProcessCrashTimes.put(processName, uid, now); 972 mProcessCrashTimesPersistent.put(processName, uid, now); 973 updateProcessCrashCountLBp(processName, uid, now); 974 } 975 976 if (errState.getCrashHandler() != null) { 977 mService.mHandler.post(errState.getCrashHandler()); 978 } 979 return true; 980 } 981 982 @GuardedBy("mBadProcessLock") 983 private void updateProcessCrashCountLBp(String processName, int uid, long now) { 984 Pair<Long, Integer> count = mProcessCrashCounts.get(processName, uid); 985 if (count == null || (count.first + PROCESS_CRASH_COUNT_RESET_INTERVAL) < now) { 986 count = new Pair<>(now, 1); 987 } else { 988 count = new Pair<>(count.first, count.second + 1); 989 } 990 mProcessCrashCounts.put(processName, uid, count); 991 } 992 993 @GuardedBy("mBadProcessLock") 994 private boolean isProcOverCrashLimitLBp(ProcessRecord app, long now) { 995 final Pair<Long, Integer> crashCount = mProcessCrashCounts.get(app.processName, app.uid); 996 return !app.isolated && crashCount != null 997 && now < (crashCount.first + PROCESS_CRASH_COUNT_RESET_INTERVAL) 998 && crashCount.second >= PROCESS_CRASH_COUNT_LIMIT; 999 } 1000 1001 void handleShowAppErrorUi(Message msg) { 1002 AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj; 1003 boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(), 1004 Settings.Secure.ANR_SHOW_BACKGROUND, 0, 1005 mService.mUserController.getCurrentUserId()) != 0; 1006 1007 final int userId; 1008 synchronized (mProcLock) { 1009 final ProcessRecord proc = data.proc; 1010 final AppErrorResult res = data.result; 1011 if (proc == null) { 1012 Slog.e(TAG, "handleShowAppErrorUi: proc is null"); 1013 return; 1014 } 1015 final ProcessErrorStateRecord errState = proc.mErrorState; 1016 userId = proc.userId; 1017 if (errState.getDialogController().hasCrashDialogs()) { 1018 Slog.e(TAG, "App already has crash dialog: " + proc); 1019 if (res != null) { 1020 res.set(AppErrorDialog.ALREADY_SHOWING); 1021 } 1022 return; 1023 } 1024 boolean isBackground = (UserHandle.getAppId(proc.uid) 1025 >= Process.FIRST_APPLICATION_UID 1026 && proc.getPid() != MY_PID); 1027 for (int profileId : mService.mUserController.getCurrentProfileIds()) { 1028 isBackground &= (userId != profileId); 1029 } 1030 if (isBackground && !showBackground) { 1031 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1032 if (res != null) { 1033 res.set(AppErrorDialog.BACKGROUND_USER); 1034 } 1035 return; 1036 } 1037 Long crashShowErrorTime = null; 1038 synchronized (mBadProcessLock) { 1039 if (!proc.isolated) { 1040 crashShowErrorTime = mProcessCrashShowDialogTimes.get(proc.processName, 1041 proc.uid); 1042 } 1043 final boolean showFirstCrash = Settings.Global.getInt( 1044 mContext.getContentResolver(), 1045 Settings.Global.SHOW_FIRST_CRASH_DIALOG, 0) != 0; 1046 final boolean showFirstCrashDevOption = Settings.Secure.getIntForUser( 1047 mContext.getContentResolver(), 1048 Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION, 1049 0, 1050 mService.mUserController.getCurrentUserId()) != 0; 1051 final String packageName = proc.info.packageName; 1052 final boolean crashSilenced = mAppsNotReportingCrashes != null 1053 && mAppsNotReportingCrashes.contains(proc.info.packageName); 1054 final long now = SystemClock.uptimeMillis(); 1055 final boolean shouldThottle = crashShowErrorTime != null 1056 && now < crashShowErrorTime + ActivityManagerConstants.MIN_CRASH_INTERVAL; 1057 if ((mService.mAtmInternal.canShowErrorDialogs() || showBackground) 1058 && !crashSilenced && !shouldThottle 1059 && (showFirstCrash || showFirstCrashDevOption || data.repeating)) { 1060 Slog.i(TAG, "Showing crash dialog for package " + packageName + " u" + userId); 1061 errState.getDialogController().showCrashDialogs(data); 1062 if (!proc.isolated) { 1063 mProcessCrashShowDialogTimes.put(proc.processName, proc.uid, now); 1064 } 1065 } else { 1066 // The device is asleep, so just pretend that the user 1067 // saw a crash dialog and hit "force quit". 1068 if (res != null) { 1069 res.set(AppErrorDialog.CANT_SHOW); 1070 } 1071 } 1072 } 1073 } 1074 } 1075 1076 @GuardedBy("mBadProcessLock") 1077 private void stopReportingCrashesLBp(ProcessRecord proc) { 1078 if (mAppsNotReportingCrashes == null) { 1079 mAppsNotReportingCrashes = new ArraySet<>(); 1080 } 1081 mAppsNotReportingCrashes.add(proc.info.packageName); 1082 } 1083 1084 void handleShowAnrUi(Message msg) { 1085 List<VersionedPackage> packageList = null; 1086 boolean doKill = false; 1087 AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj; 1088 final ProcessRecord proc = data.proc; 1089 if (proc == null) { 1090 Slog.e(TAG, "handleShowAnrUi: proc is null"); 1091 return; 1092 } 1093 synchronized (mProcLock) { 1094 final ProcessErrorStateRecord errState = proc.mErrorState; 1095 errState.setAnrData(data); 1096 if (!proc.isPersistent()) { 1097 packageList = proc.getPackageListWithVersionCode(); 1098 } 1099 if (errState.getDialogController().hasAnrDialogs()) { 1100 Slog.e(TAG, "App already has anr dialog: " + proc); 1101 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, 1102 AppNotRespondingDialog.ALREADY_SHOWING); 1103 return; 1104 } 1105 1106 boolean showBackground = Settings.Secure.getIntForUser(mContext.getContentResolver(), 1107 Settings.Secure.ANR_SHOW_BACKGROUND, 0, 1108 mService.mUserController.getCurrentUserId()) != 0; 1109 if (mService.mAtmInternal.canShowErrorDialogs() || showBackground) { 1110 AnrController anrController = errState.getDialogController().getAnrController(); 1111 if (anrController == null) { 1112 errState.getDialogController().showAnrDialogs(data); 1113 } else { 1114 String packageName = proc.info.packageName; 1115 int uid = proc.info.uid; 1116 boolean showDialog = anrController.onAnrDelayCompleted(packageName, uid); 1117 1118 if (showDialog) { 1119 Slog.d(TAG, "ANR delay completed. Showing ANR dialog for package: " 1120 + packageName); 1121 errState.getDialogController().showAnrDialogs(data); 1122 } else { 1123 Slog.d(TAG, "ANR delay completed. Cancelling ANR dialog for package: " 1124 + packageName); 1125 errState.setNotResponding(false); 1126 errState.setNotRespondingReport(null); 1127 errState.getDialogController().clearAnrDialogs(); 1128 } 1129 } 1130 } else { 1131 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, 1132 AppNotRespondingDialog.CANT_SHOW); 1133 // Just kill the app if there is no dialog to be shown. 1134 doKill = true; 1135 } 1136 } 1137 if (doKill) { 1138 mService.killAppAtUsersRequest(proc); 1139 } 1140 // Notify PackageWatchdog without the lock held 1141 if (packageList != null) { 1142 mPackageWatchdog.onPackageFailure(packageList, 1143 PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING); 1144 } 1145 } 1146 1147 void handleDismissAnrDialogs(ProcessRecord proc) { 1148 synchronized (mProcLock) { 1149 final ProcessErrorStateRecord errState = proc.mErrorState; 1150 1151 // Cancel any rescheduled ANR dialogs 1152 mService.mUiHandler.removeMessages( 1153 ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG, errState.getAnrData()); 1154 1155 // Dismiss any ANR dialogs currently visible 1156 if (errState.getDialogController().hasAnrDialogs()) { 1157 errState.setNotResponding(false); 1158 errState.setNotRespondingReport(null); 1159 errState.getDialogController().clearAnrDialogs(); 1160 } 1161 proc.mErrorState.setAnrData(null); 1162 } 1163 } 1164 1165 /** 1166 * Information about a process that is currently marked as bad. 1167 */ 1168 static final class BadProcessInfo { 1169 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 1170 this.time = time; 1171 this.shortMsg = shortMsg; 1172 this.longMsg = longMsg; 1173 this.stack = stack; 1174 } 1175 1176 final long time; 1177 final String shortMsg; 1178 final String longMsg; 1179 final String stack; 1180 } 1181 1182 } 1183