diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt index f9c3ca9ba3..d072c8b999 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt @@ -13,6 +13,8 @@ import eu.kanade.tachiyomi.util.system.withIOContext import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import timber.log.Timber +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy internal class ExtensionGithubApi { @@ -64,9 +66,12 @@ internal class ExtensionGithubApi { return withIOContext { val extensions = prefetchedExtensions ?: findExtensions() - val installedExtensions = ExtensionLoader.loadExtensions(context) - .filterIsInstance() - .map { it.extension } + val extensionManager: ExtensionManager = Injekt.get() + val installedExtensions = extensionManager.installedExtensionsFlow.value.ifEmpty { + ExtensionLoader.loadExtensionAsync(context) + .filterIsInstance() + .map { it.extension } + } val extensionsWithUpdate = mutableListOf() for (installedExt in installedExtensions) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt index 8b6652703a..1aca9155ff 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt @@ -16,6 +16,7 @@ import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory import eu.kanade.tachiyomi.util.lang.Hash +import eu.kanade.tachiyomi.util.system.withIOContext import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.runBlocking @@ -108,12 +109,7 @@ internal object ExtensionLoader { File(getPrivateExtensionDir(context), "$pkgName.$PRIVATE_EXTENSION_EXTENSION").delete() } - /** - * Return a list of all the installed extensions initialized concurrently. - * - * @param context The application context. - */ - fun loadExtensions(context: Context): List { + private fun getExtensionsPackages(context: Context): List { val pkgManager = context.packageManager val installedPkgs = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { @@ -141,7 +137,7 @@ internal object ExtensionLoader { ?.map { ExtensionInfo(packageInfo = it, isShared = false) } ?: emptySequence() - val extPkgs = (sharedExtPkgs + privateExtPkgs) + return (sharedExtPkgs + privateExtPkgs) // Remove duplicates. Shared takes priority than private by default .distinctBy { it.packageInfo.packageName } // Compare version number @@ -151,9 +147,15 @@ internal object ExtensionLoader { selectExtensionPackage(sharedPkg, privatePkg) } .toList() + } - if (extPkgs.isEmpty()) return emptyList() - + /** + * Return a list of all the installed extensions initialized concurrently. + * + * @param context The application context. + */ + fun loadExtensions(context: Context): List { + val extPkgs = getExtensionsPackages(context) // Load each extension concurrently and wait for completion return runBlocking { val deferred = extPkgs.map { @@ -163,6 +165,17 @@ internal object ExtensionLoader { } } + suspend fun loadExtensionAsync(context: Context): List { + val extPkgs = getExtensionsPackages(context) + // Load each extension concurrently and wait for completion + return withIOContext { + val deferred = extPkgs.map { + async { loadExtension(context, it) } + } + deferred.awaitAll() + } + } + /** * Attempts to load an extension from the given package name. It checks if the extension * contains the required feature flag before trying to load it.