瀏覽代碼

Add more info to debug screen (#9357)

* App version
* WebView version
* ART profile status
* Device model
* Android version
Ivan Iskandar 1 年之前
父節點
當前提交
2c6e025063

+ 1 - 1
app/src/main/java/eu/kanade/presentation/more/settings/screen/AboutScreen.kt

@@ -239,7 +239,7 @@ object AboutScreen : Screen() {
         }
     }
 
-    private fun getFormattedBuildTime(): String {
+    internal fun getFormattedBuildTime(): String {
         return try {
             val inputDf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US)
             inputDf.timeZone = TimeZone.getTimeZone("UTC")

+ 115 - 11
app/src/main/java/eu/kanade/presentation/more/settings/screen/debug/DebugInfoScreen.kt

@@ -1,29 +1,133 @@
 package eu.kanade.presentation.more.settings.screen.debug
 
-import androidx.annotation.StringRes
+import android.os.Build
+import android.webkit.WebView
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.produceState
+import androidx.compose.ui.platform.LocalContext
+import androidx.profileinstaller.ProfileVerifier
 import cafe.adriel.voyager.navigator.LocalNavigator
 import cafe.adriel.voyager.navigator.currentOrThrow
 import eu.kanade.presentation.more.settings.Preference
-import eu.kanade.presentation.more.settings.screen.SearchableSettings
+import eu.kanade.presentation.more.settings.PreferenceScaffold
+import eu.kanade.presentation.more.settings.screen.AboutScreen
+import eu.kanade.presentation.util.Screen
 import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.util.system.DeviceUtil
+import kotlinx.coroutines.guava.await
 
-object DebugInfoScreen : SearchableSettings {
-    @ReadOnlyComposable
+object DebugInfoScreen : Screen() {
     @Composable
-    @StringRes
-    override fun getTitleRes() = R.string.pref_debug_info
+    override fun Content() {
+        val navigator = LocalNavigator.currentOrThrow
+        PreferenceScaffold(
+            titleRes = R.string.pref_debug_info,
+            onBackPressed = navigator::pop,
+            itemsProvider = {
+                listOf(
+                    Preference.PreferenceItem.TextPreference(
+                        title = WorkerInfoScreen.title,
+                        onClick = { navigator.push(WorkerInfoScreen) },
+                    ),
+                    getAppInfoGroup(),
+                    getDeviceInfoGroup(),
+                )
+            },
+        )
+    }
 
     @Composable
-    override fun getPreferences(): List<Preference> {
-        val navigator = LocalNavigator.currentOrThrow
+    private fun getAppInfoGroup(): Preference.PreferenceGroup {
+        return Preference.PreferenceGroup(
+            title = "App info",
+            preferenceItems = listOf(
+                Preference.PreferenceItem.TextPreference(
+                    title = "Version",
+                    subtitle = AboutScreen.getVersionName(false),
+                ),
+                Preference.PreferenceItem.TextPreference(
+                    title = "Build time",
+                    subtitle = AboutScreen.getFormattedBuildTime(),
+                ),
+                getProfileVerifierPreference(),
+                Preference.PreferenceItem.TextPreference(
+                    title = "WebView version",
+                    subtitle = getWebViewVersion(),
+                ),
+            ),
+        )
+    }
 
-        return listOf(
+    @Composable
+    @ReadOnlyComposable
+    private fun getWebViewVersion(): String {
+        val webView = WebView.getCurrentWebViewPackage() ?: return "how did you get here?"
+        val pm = LocalContext.current.packageManager
+        val label = webView.applicationInfo.loadLabel(pm)
+        val version = webView.versionName
+        return "$label $version"
+    }
+
+    @Composable
+    private fun getProfileVerifierPreference(): Preference.PreferenceItem.TextPreference {
+        val status by produceState(initialValue = "-") {
+            val result = ProfileVerifier.getCompilationStatusAsync().await().profileInstallResultCode
+            value = when (result) {
+                ProfileVerifier.CompilationStatus.RESULT_CODE_NO_PROFILE -> "No profile installed"
+                ProfileVerifier.CompilationStatus.RESULT_CODE_COMPILED_WITH_PROFILE -> "Compiled"
+                ProfileVerifier.CompilationStatus.RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING -> "Compiled non-matching"
+                ProfileVerifier.CompilationStatus.RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ,
+                ProfileVerifier.CompilationStatus.RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE,
+                ProfileVerifier.CompilationStatus.RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST,
+                -> "Error $result"
+                ProfileVerifier.CompilationStatus.RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION -> "Not supported"
+                ProfileVerifier.CompilationStatus.RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION -> "Pending compilation"
+                else -> "Unknown code $result"
+            }
+        }
+        return Preference.PreferenceItem.TextPreference(
+            title = "Profile compilation status",
+            subtitle = status,
+        )
+    }
+
+    private fun getDeviceInfoGroup(): Preference.PreferenceGroup {
+        val items = mutableListOf(
             Preference.PreferenceItem.TextPreference(
-                title = WorkerInfoScreen.title,
-                onClick = { navigator.push(WorkerInfoScreen) },
+                title = "Model",
+                subtitle = "${Build.MANUFACTURER} ${Build.MODEL} (${Build.DEVICE})",
             ),
         )
+
+        if (DeviceUtil.oneUiVersion != null) {
+            items += Preference.PreferenceItem.TextPreference(
+                title = "OneUI version",
+                subtitle = "${DeviceUtil.oneUiVersion}",
+            )
+        } else if (DeviceUtil.miuiMajorVersion != null) {
+            items += Preference.PreferenceItem.TextPreference(
+                title = "MIUI version",
+                subtitle = "${DeviceUtil.miuiMajorVersion}",
+            )
+        }
+
+        val androidVersion = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+            Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            Build.VERSION.RELEASE_OR_CODENAME
+        } else {
+            Build.VERSION.RELEASE
+        }
+        items += Preference.PreferenceItem.TextPreference(
+            title = "Android version",
+            subtitle = "$androidVersion (${Build.DISPLAY})",
+        )
+
+        return Preference.PreferenceGroup(
+            title = "Device info",
+            preferenceItems = items,
+        )
     }
 }

+ 17 - 3
core/src/main/java/eu/kanade/tachiyomi/util/system/DeviceUtil.kt

@@ -14,15 +14,15 @@ object DeviceUtil {
     /**
      * Extracts the MIUI major version code from a string like "V12.5.3.0.QFGMIXM".
      *
-     * @return MIUI major version code (e.g., 13) or -1 if can't be parsed.
+     * @return MIUI major version code (e.g., 13) or null if can't be parsed.
      */
     val miuiMajorVersion by lazy {
-        if (!isMiui) return@lazy -1
+        if (!isMiui) return@lazy null
 
         Build.VERSION.INCREMENTAL
             .substringBefore('.')
             .trimStart('V')
-            .toIntOrNull() ?: -1
+            .toIntOrNull()
     }
 
     @SuppressLint("PrivateApi")
@@ -45,6 +45,20 @@ object DeviceUtil {
         Build.MANUFACTURER.equals("samsung", ignoreCase = true)
     }
 
+    val oneUiVersion by lazy {
+        try {
+            val semPlatformIntField = Build.VERSION::class.java.getDeclaredField("SEM_PLATFORM_INT")
+            val version = semPlatformIntField.getInt(null) - 90000
+            if (version < 0) {
+                1.0
+            } else {
+                ((version / 10000).toString() + "." + version % 10000 / 100).toDouble()
+            }
+        } catch (e: Exception) {
+            null
+        }
+    }
+
     val invalidDefaultBrowsers = listOf(
         "android",
         "com.huawei.android.internal.app",

+ 2 - 1
gradle/kotlinx.versions.toml

@@ -10,6 +10,7 @@ gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "
 coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version = "1.6.4" }
 coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core" }
 coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android" }
+coroutines-guava = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-guava" }
 
 serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization_version" }
 serialization-json-okio = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json-okio", version.ref = "serialization_version" }
@@ -19,7 +20,7 @@ serialization-xml-core = { module = "io.github.pdvrieze.xmlutil:core-android", v
 serialization-xml = { module = "io.github.pdvrieze.xmlutil:serialization-android", version.ref = "xml_serialization_version" }
 
 [bundles]
-coroutines = ["coroutines-core", "coroutines-android"]
+coroutines = ["coroutines-core", "coroutines-android", "coroutines-guava"]
 serialization = ["serialization-json", "serialization-json-okio", "serialization-protobuf", "serialization-xml-core", "serialization-xml"]
 
 [plugins]