Bläddra i källkod

Fix installing extensions on MIUI (#8916)

* Fix installing extensions on MIUI

* isShizukuReady -> isShizukuInstalled
stevenyomi 2 år sedan
förälder
incheckning
293b967858

+ 1 - 7
app/src/main/java/eu/kanade/domain/base/BasePreferences.kt

@@ -2,9 +2,6 @@ package eu.kanade.domain.base
 
 import android.content.Context
 import eu.kanade.tachiyomi.core.preference.PreferenceStore
-import eu.kanade.tachiyomi.core.preference.getEnum
-import eu.kanade.tachiyomi.data.preference.PreferenceValues
-import eu.kanade.tachiyomi.util.system.DeviceUtil
 import eu.kanade.tachiyomi.util.system.isPreviewBuildType
 import eu.kanade.tachiyomi.util.system.isReleaseBuildType
 
@@ -21,10 +18,7 @@ class BasePreferences(
 
     fun automaticExtUpdates() = preferenceStore.getBoolean("automatic_ext_updates", true)
 
-    fun extensionInstaller() = preferenceStore.getEnum(
-        "extension_installer",
-        if (DeviceUtil.isMiui) PreferenceValues.ExtensionInstaller.LEGACY else PreferenceValues.ExtensionInstaller.PACKAGEINSTALLER,
-    )
+    fun extensionInstaller() = ExtensionInstallerPreference(context, preferenceStore)
 
     fun acraEnabled() = preferenceStore.getBoolean("acra.enable", isPreviewBuildType || isReleaseBuildType)
 }

+ 68 - 0
app/src/main/java/eu/kanade/domain/base/ExtensionInstallerPreference.kt

@@ -0,0 +1,68 @@
+package eu.kanade.domain.base
+
+import android.content.Context
+import eu.kanade.tachiyomi.core.preference.Preference
+import eu.kanade.tachiyomi.core.preference.PreferenceStore
+import eu.kanade.tachiyomi.core.preference.getEnum
+import eu.kanade.tachiyomi.data.preference.PreferenceValues.ExtensionInstaller
+import eu.kanade.tachiyomi.util.system.hasMiuiPackageInstaller
+import eu.kanade.tachiyomi.util.system.isShizukuInstalled
+import kotlinx.coroutines.CoroutineScope
+
+class ExtensionInstallerPreference(
+    private val context: Context,
+    preferenceStore: PreferenceStore,
+) : Preference<ExtensionInstaller> {
+
+    private val basePref = preferenceStore.getEnum(key(), defaultValue())
+
+    override fun key() = "extension_installer"
+
+    val entries get() = ExtensionInstaller.values().run {
+        if (context.hasMiuiPackageInstaller) {
+            filter { it != ExtensionInstaller.PACKAGEINSTALLER }
+        } else {
+            toList()
+        }
+    }
+
+    override fun defaultValue() = if (context.hasMiuiPackageInstaller) {
+        ExtensionInstaller.LEGACY
+    } else {
+        ExtensionInstaller.PACKAGEINSTALLER
+    }
+
+    private fun check(value: ExtensionInstaller): ExtensionInstaller {
+        when (value) {
+            ExtensionInstaller.PACKAGEINSTALLER -> {
+                if (context.hasMiuiPackageInstaller) return ExtensionInstaller.LEGACY
+            }
+            ExtensionInstaller.SHIZUKU -> {
+                if (!context.isShizukuInstalled) return defaultValue()
+            }
+            else -> {}
+        }
+        return value
+    }
+
+    override fun get(): ExtensionInstaller {
+        val value = basePref.get()
+        val checkedValue = check(value)
+        if (value != checkedValue) {
+            basePref.set(checkedValue)
+        }
+        return checkedValue
+    }
+
+    override fun set(value: ExtensionInstaller) {
+        basePref.set(check(value))
+    }
+
+    override fun isSet() = basePref.isSet()
+
+    override fun delete() = basePref.delete()
+
+    override fun changes() = basePref.changes()
+
+    override fun stateIn(scope: CoroutineScope) = basePref.stateIn(scope)
+}

+ 1 - 24
app/src/main/java/eu/kanade/presentation/browse/ExtensionsScreen.kt

@@ -2,7 +2,6 @@ package eu.kanade.presentation.browse
 
 import androidx.annotation.StringRes
 import androidx.compose.animation.core.animateDpAsState
-import androidx.compose.foundation.clickable
 import androidx.compose.foundation.combinedClickable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -32,7 +31,6 @@ import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalUriHandler
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
@@ -43,7 +41,6 @@ import eu.kanade.presentation.components.EmptyScreen
 import eu.kanade.presentation.components.FastScrollLazyColumn
 import eu.kanade.presentation.components.LoadingScreen
 import eu.kanade.presentation.components.PullRefresh
-import eu.kanade.presentation.components.WarningBanner
 import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
 import eu.kanade.presentation.theme.header
 import eu.kanade.presentation.util.padding
@@ -55,7 +52,6 @@ import eu.kanade.tachiyomi.extension.model.Extension
 import eu.kanade.tachiyomi.extension.model.InstallStep
 import eu.kanade.tachiyomi.ui.browse.extension.ExtensionUiModel
 import eu.kanade.tachiyomi.ui.browse.extension.ExtensionsState
-import eu.kanade.tachiyomi.util.system.DeviceUtil
 import eu.kanade.tachiyomi.util.system.LocaleHelper
 
 @Composable
@@ -123,29 +119,10 @@ private fun ExtensionContent(
     onClickUpdateAll: () -> Unit,
 ) {
     var trustState by remember { mutableStateOf<Extension.Untrusted?>(null) }
-    val showMiuiWarning = DeviceUtil.isMiui && DeviceUtil.miuiMajorVersion >= 13 && !DeviceUtil.isMiuiOptimizationDisabled()
-    val uriHandler = LocalUriHandler.current
 
     FastScrollLazyColumn(
-        contentPadding = if (showMiuiWarning) {
-            contentPadding
-        } else {
-            contentPadding + topSmallPaddingValues
-        },
+        contentPadding = contentPadding + topSmallPaddingValues,
     ) {
-        if (showMiuiWarning) {
-            item {
-                WarningBanner(
-                    textRes = R.string.ext_miui_warning,
-                    modifier = Modifier
-                        .padding(bottom = MaterialTheme.padding.small)
-                        .clickable {
-                            uriHandler.openUri("https://tachiyomi.org/extensions")
-                        },
-                )
-            }
-        }
-
         state.items.forEach { (header, items) ->
             item(
                 contentType = "header",

+ 6 - 13
app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt

@@ -52,10 +52,9 @@ import eu.kanade.tachiyomi.network.PREF_DOH_SHECAN
 import eu.kanade.tachiyomi.util.CrashLogUtil
 import eu.kanade.tachiyomi.util.lang.launchNonCancellable
 import eu.kanade.tachiyomi.util.lang.withUIContext
-import eu.kanade.tachiyomi.util.system.DeviceUtil
-import eu.kanade.tachiyomi.util.system.isPackageInstalled
 import eu.kanade.tachiyomi.util.system.isPreviewBuildType
 import eu.kanade.tachiyomi.util.system.isReleaseBuildType
+import eu.kanade.tachiyomi.util.system.isShizukuInstalled
 import eu.kanade.tachiyomi.util.system.logcat
 import eu.kanade.tachiyomi.util.system.powerManager
 import eu.kanade.tachiyomi.util.system.setDefaultSettings
@@ -63,7 +62,6 @@ import eu.kanade.tachiyomi.util.system.toast
 import kotlinx.coroutines.launch
 import logcat.LogPriority
 import okhttp3.Headers
-import rikka.sui.Sui
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 import java.io.File
@@ -344,6 +342,7 @@ object SettingsAdvancedScreen : SearchableSettings {
     ): Preference.PreferenceGroup {
         val context = LocalContext.current
         val uriHandler = LocalUriHandler.current
+        val extensionInstallerPref = basePreferences.extensionInstaller()
         var shizukuMissing by rememberSaveable { mutableStateOf(false) }
 
         if (shizukuMissing) {
@@ -373,19 +372,13 @@ object SettingsAdvancedScreen : SearchableSettings {
             title = stringResource(R.string.label_extensions),
             preferenceItems = listOf(
                 Preference.PreferenceItem.ListPreference(
-                    pref = basePreferences.extensionInstaller(),
+                    pref = extensionInstallerPref,
                     title = stringResource(R.string.ext_installer_pref),
-                    entries = PreferenceValues.ExtensionInstaller.values()
-                        .run {
-                            if (DeviceUtil.isMiui) {
-                                filter { it != PreferenceValues.ExtensionInstaller.PACKAGEINSTALLER }
-                            } else {
-                                toList()
-                            }
-                        }.associateWith { stringResource(it.titleResId) },
+                    entries = extensionInstallerPref.entries
+                        .associateWith { stringResource(it.titleResId) },
                     onValueChanged = {
                         if (it == PreferenceValues.ExtensionInstaller.SHIZUKU &&
-                            !(context.isPackageInstalled("moe.shizuku.privileged.api") || Sui.isSui())
+                            !context.isShizukuInstalled
                         ) {
                             shizukuMissing = true
                             false

+ 24 - 0
app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallActivity.kt

@@ -5,9 +5,11 @@ import android.content.Intent
 import android.os.Bundle
 import eu.kanade.tachiyomi.extension.ExtensionManager
 import eu.kanade.tachiyomi.extension.model.InstallStep
+import eu.kanade.tachiyomi.util.system.hasMiuiPackageInstaller
 import eu.kanade.tachiyomi.util.system.toast
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
+import kotlin.time.Duration.Companion.seconds
 
 /**
  * Activity used to install extensions, because we can only receive the result of the installation
@@ -15,6 +17,11 @@ import uy.kohesive.injekt.api.get
  */
 class ExtensionInstallActivity : Activity() {
 
+    // MIUI package installer bug workaround
+    private var ignoreUntil = 0L
+    private var ignoreResult = false
+    private var hasIgnoredResult = false
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
@@ -23,6 +30,11 @@ class ExtensionInstallActivity : Activity() {
             .putExtra(Intent.EXTRA_RETURN_RESULT, true)
             .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
 
+        if (hasMiuiPackageInstaller) {
+            ignoreResult = true
+            ignoreUntil = System.nanoTime() + 1.seconds.inWholeNanoseconds
+        }
+
         try {
             startActivityForResult(installIntent, INSTALL_REQUEST_CODE)
         } catch (error: Exception) {
@@ -33,12 +45,24 @@ class ExtensionInstallActivity : Activity() {
     }
 
     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        if (ignoreResult && System.nanoTime() < ignoreUntil) {
+            hasIgnoredResult = true
+            return
+        }
         if (requestCode == INSTALL_REQUEST_CODE) {
             checkInstallationResult(resultCode)
         }
         finish()
     }
 
+    override fun onStart() {
+        super.onStart()
+        if (hasIgnoredResult) {
+            checkInstallationResult(RESULT_CANCELED)
+            finish()
+        }
+    }
+
     private fun checkInstallationResult(resultCode: Int) {
         val downloadId = intent.extras!!.getLong(ExtensionInstaller.EXTRA_DOWNLOAD_ID)
         val extensionManager = Injekt.get<ExtensionManager>()

+ 5 - 0
app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt

@@ -41,6 +41,7 @@ import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
 import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
 import eu.kanade.tachiyomi.util.lang.truncateCenter
 import logcat.LogPriority
+import rikka.sui.Sui
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 import java.io.File
@@ -350,6 +351,10 @@ fun Context.isPackageInstalled(packageName: String): Boolean {
     }
 }
 
+val Context.hasMiuiPackageInstaller get() = isPackageInstalled("com.miui.packageinstaller")
+
+val Context.isShizukuInstalled get() = isPackageInstalled("moe.shizuku.privileged.api") || Sui.isSui()
+
 fun Context.isInstalledFromFDroid(): Boolean {
     val installerPackageName = try {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {

+ 0 - 1
i18n/src/main/res/values/strings.xml

@@ -305,7 +305,6 @@
     <string name="ext_installer_shizuku" translatable="false">Shizuku</string>
     <string name="ext_installer_shizuku_stopped">Shizuku is not running</string>
     <string name="ext_installer_shizuku_unavailable_dialog">Install and start Shizuku to use Shizuku as extension installer.</string>
-    <string name="ext_miui_warning">If installing extensions isn\'t working, try disabling MIUI Optimization or tap here to download from the website instead.</string>
 
       <!-- Reader section -->
     <string name="pref_fullscreen">Fullscreen</string>