diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/CrashLogUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/CrashLogUtil.kt index 536fb724f3..7f39823e71 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/CrashLogUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/CrashLogUtil.kt @@ -14,13 +14,18 @@ import tachiyomi.core.util.lang.withUIContext import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -class CrashLogUtil(private val context: Context) { +class CrashLogUtil( + private val context: Context, + private val extensionManager: ExtensionManager = Injekt.get(), +) { suspend fun dumpLogs() = withNonCancellableContext { try { val file = context.createFileInCacheDir("tachiyomi_crash_logs.txt") + file.appendText(getDebugInfo() + "\n\n") - file.appendText(getExtensionsInfo() + "\n\n") + getExtensionsInfo()?.let { file.appendText("$it\n\n") } + Runtime.getRuntime().exec("logcat *:E -d -f ${file.absolutePath}").waitFor() val uri = file.getUriCompat(context) @@ -30,42 +35,41 @@ class CrashLogUtil(private val context: Context) { } } - private fun getExtensionsInfo(): String { - val extensionManager: ExtensionManager = Injekt.get() - val installedExtensions = extensionManager.installedExtensionsFlow.value - val availableExtensions = extensionManager.availableExtensionsFlow.value - val extensionInfoList = mutableListOf() - - for (installedExtension in installedExtensions) { - val availableExtension = availableExtensions.find { it.pkgName == installedExtension.pkgName } - val hasUpdate = (availableExtension?.versionCode ?: 0) > installedExtension.versionCode - if (hasUpdate || installedExtension.isObsolete || installedExtension.isUnofficial) { - val extensionInfo = - "Extension Name: ${installedExtension.name}\n" + - "Installed Version: ${installedExtension.versionName}\n" + - "Available Version: ${availableExtension?.versionName ?: "N/A"}\n" + - "Obsolete: ${installedExtension.isObsolete}\n" + - "Unofficial: ${installedExtension.isUnofficial}\n" - extensionInfoList.add(extensionInfo) - } - } - if (extensionInfoList.isNotEmpty()) { - extensionInfoList.add(0, "Extensions that are outdated, obsolete, or unofficial") - } - return extensionInfoList.joinToString("\n") - } - fun getDebugInfo(): String { return """ App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE}, ${BuildConfig.BUILD_TIME}) - Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT}) - Android build ID: ${Build.DISPLAY} + Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT}; build ${Build.DISPLAY}) Device brand: ${Build.BRAND} Device manufacturer: ${Build.MANUFACTURER} - Device name: ${Build.DEVICE} + Device name: ${Build.DEVICE} (${Build.PRODUCT}) Device model: ${Build.MODEL} - Device product name: ${Build.PRODUCT} WebView: ${WebViewUtil.getVersion(context)} """.trimIndent() } + + private fun getExtensionsInfo(): String? { + val availableExtensions = extensionManager.availableExtensionsFlow.value.associateBy { it.pkgName } + + val extensionInfoList = extensionManager.installedExtensionsFlow.value + .sortedBy { it.name } + .mapNotNull { + val availableExtension = availableExtensions[it.pkgName] + val hasUpdate = (availableExtension?.versionCode ?: 0) > it.versionCode + + if (!hasUpdate && !it.isObsolete && !it.isUnofficial) return@mapNotNull null + + """ + - ${it.name} + Installed: ${it.versionName} / Available: ${availableExtension?.versionName ?: "?"} + Obsolete: ${it.isObsolete} / Unofficial: ${it.isUnofficial} + """.trimIndent() + } + + return if (extensionInfoList.isNotEmpty()) { + (listOf("Problematic extensions:") + extensionInfoList) + .joinToString("\n") + } else { + null + } + } }