From f294c8a6551b9c2dad65d59c6fc09e17148c9c77 Mon Sep 17 00:00:00 2001 From: Jing Ji Date: Thu, 5 Dec 2019 09:59:04 -0800 Subject: [PATCH] Throttle the error dialog for continuous crashing processes Bug: 145745693 Test: repeat "adb shell am crash" an app and launch it again Change-Id: If49276999d37886852605bb63ad222b8bc1ca5e1 --- .../java/com/android/server/am/AppErrors.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index c38072661cee2..5e48dcf916766 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -87,6 +87,11 @@ class AppErrors { */ private final ProcessMap mProcessCrashTimesPersistent = new ProcessMap<>(); + /** + * The last time that various processes have crashed and shown an error dialog. + */ + private final ProcessMap mProcessCrashShowDialogTimes = new ProcessMap<>(); + /** * Set of applications that we consider to be bad, and will reject * incoming broadcasts from (which the user has no control over). @@ -820,6 +825,11 @@ class AppErrors { } return; } + Long crashShowErrorTime = null; + if (!proc.isolated) { + crashShowErrorTime = mProcessCrashShowDialogTimes.get(proc.info.processName, + proc.uid); + } final boolean showFirstCrash = Settings.Global.getInt( mContext.getContentResolver(), Settings.Global.SHOW_FIRST_CRASH_DIALOG, 0) != 0; @@ -830,10 +840,16 @@ class AppErrors { mService.mUserController.getCurrentUserId()) != 0; final boolean crashSilenced = mAppsNotReportingCrashes != null && mAppsNotReportingCrashes.contains(proc.info.packageName); + final long now = SystemClock.uptimeMillis(); + final boolean shouldThottle = crashShowErrorTime != null + && now < crashShowErrorTime + ProcessList.MIN_CRASH_INTERVAL; if ((mService.mAtmInternal.canShowErrorDialogs() || showBackground) - && !crashSilenced + && !crashSilenced && !shouldThottle && (showFirstCrash || showFirstCrashDevOption || data.repeating)) { proc.getDialogController().showCrashDialogs(data); + if (!proc.isolated) { + mProcessCrashShowDialogTimes.put(proc.info.processName, proc.uid, now); + } } else { // The device is asleep, so just pretend that the user // saw a crash dialog and hit "force quit".