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