From aeb92c164b4e78258dc3677fc0f470a70ff394ce Mon Sep 17 00:00:00 2001 From: SEED264 Date: Sun, 8 Nov 2026 01:29:32 +0900 Subject: [PATCH] fix(bugreport): prevent the launcher from hanging after a crash (#7499) The bug report file name used the locale-dependent SimpleDateFormat.getDateTimeInstance(), which yields '/' in some locales (e.g. ja_JP: "2026/09/28 12:34:56"). The resulting path had non-existent parent directories, so createNewFile() threw inside the uncaught exception handler and the default handler was never invoked, leaving the process frozen instead of restarting. - Use a fixed, locale-independent format (yyyy-MM-dd_HH-mm-ss, Locale.US) - Always delegate to the default handler via try/finally so the process is killed even if generating the report fails Co-authored-by: Claude Opus 5.5 (1M context) --- .../lawnchair/bugreport/LawnchairBugReporter.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lawnchair/src/app/lawnchair/bugreport/LawnchairBugReporter.kt b/lawnchair/src/app/lawnchair/bugreport/LawnchairBugReporter.kt index d9520f6a8d..6146656b4a 100644 --- a/lawnchair/src/app/lawnchair/bugreport/LawnchairBugReporter.kt +++ b/lawnchair/src/app/lawnchair/bugreport/LawnchairBugReporter.kt @@ -13,6 +13,7 @@ import com.android.launcher3.R import java.io.File import java.text.SimpleDateFormat import java.util.Date +import java.util.Locale class LawnchairBugReporter(private val context: Context) { @@ -38,8 +39,13 @@ class LawnchairBugReporter(private val context: Context) { val defaultHandler = Thread.getDefaultUncaughtExceptionHandler() Thread.setDefaultUncaughtExceptionHandler { thread, throwable -> - sendNotification(throwable) - defaultHandler?.uncaughtException(thread, throwable) + try { + sendNotification(throwable) + } finally { + // Always hand off to the default handler so the process gets killed, + // even if generating the report fails. Otherwise the app would hang. + defaultHandler?.uncaughtException(thread, throwable) + } } removeDismissedLogs() @@ -68,7 +74,9 @@ class LawnchairBugReporter(private val context: Context) { inner class Report(val error: String, val throwable: Throwable? = null) { - private val fileName = "$appName bug report ${SimpleDateFormat.getDateTimeInstance().format(Date())}" + // Use a fixed, locale-independent format: some locales produce characters + // such as '/' that are not valid in a file name. + private val fileName = "$appName bug report ${SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US).format(Date())}" fun generateBugReport(): BugReport? { val contents = writeContents()