diff --git a/app/src/main/kotlin/com/fox2code/mmm/MainActivity.kt b/app/src/main/kotlin/com/fox2code/mmm/MainActivity.kt index 9156c1d..872a62b 100644 --- a/app/src/main/kotlin/com/fox2code/mmm/MainActivity.kt +++ b/app/src/main/kotlin/com/fox2code/mmm/MainActivity.kt @@ -21,7 +21,6 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup.MarginLayoutParams import android.view.WindowManager -import android.view.animation.AccelerateInterpolator import android.view.animation.DecelerateInterpolator import android.view.inputmethod.EditorInfo import android.widget.Toast diff --git a/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewListBuilder.kt b/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewListBuilder.kt index c9d0be2..57e9f69 100644 --- a/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewListBuilder.kt +++ b/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewListBuilder.kt @@ -6,6 +6,8 @@ package com.fox2code.mmm.module import android.app.Activity import android.os.Build +import android.os.Handler +import android.os.Looper import android.view.View import androidx.recyclerview.widget.RecyclerView import com.fox2code.mmm.AppUpdateManager @@ -32,6 +34,7 @@ class ModuleViewListBuilder(private val activity: Activity) { private var updating = false private var headerPx = 0 private var footerPx = 0 + private var tries = 0 private var moduleSorter: ModuleSorter = ModuleSorter.UPDATE private var updateInsets = RUNNABLE fun addNotification(notificationType: NotificationType?) { @@ -85,46 +88,62 @@ class ModuleViewListBuilder(private val activity: Activity) { repoManager?.runAfterUpdate { Timber.i("A2: %s", repoManager.modules.size) val no32bitSupport = Build.SUPPORTED_32_BIT_ABIS.isEmpty() - for (repoModule in repoManager.modules.values) { - // add the remote module to the list in MainActivity - MainActivity.onlineModuleInfoList += repoModule - // if repoData is null, something is wrong - @Suppress("SENSELESS_COMPARISON") - if (repoModule.repoData == null) { - Timber.w("RepoData is null for module %s", repoModule.id) - continue - } - if (!repoModule.repoData.isEnabled) { - Timber.i( - "Repo %s is disabled, skipping module %s", - repoModule.repoData.preferenceId, - repoModule.id - ) - continue - } - val moduleInfo = repoModule.moduleInfo - if (!showIncompatible && (moduleInfo.minApi > Build.VERSION.SDK_INT || moduleInfo.maxApi != 0 && moduleInfo.maxApi < Build.VERSION.SDK_INT || peekMagiskPath() != null) && repoModule.moduleInfo.minMagisk > peekMagiskVersion() || no32bitSupport && (AppUpdateManager.getFlagsForModule( - repoModule.id - ) - and AppUpdateManager.FLAG_COMPAT_NEED_32BIT) != 0 || repoModule.moduleInfo.needRamdisk && !peekHasRamdisk() - ) continue // Skip adding incompatible modules - var moduleHolder = mappedModuleHolders[repoModule.id] - if (moduleHolder == null) { - mappedModuleHolders[repoModule.id] = ModuleHolder(repoModule.id).also { - moduleHolder = it + try { + for (repoModule in repoManager.modules.values) { + // add the remote module to the list in MainActivity + MainActivity.onlineModuleInfoList += repoModule + // if repoData is null, something is wrong + @Suppress("SENSELESS_COMPARISON") if (repoModule.repoData == null) { + Timber.w("RepoData is null for module %s", repoModule.id) + continue } - } - moduleHolder!!.repoModule = repoModule - // check if local module is installed - // iterate over MainActivity.localModuleInfoList until we hit the module with the same id - for (localModuleInfo in MainActivity.localModuleInfoList) { - if (localModuleInfo.id == repoModule.id) { - moduleHolder!!.moduleInfo = localModuleInfo - break + if (!repoModule.repoData.isEnabled) { + Timber.i( + "Repo %s is disabled, skipping module %s", + repoModule.repoData.preferenceId, + repoModule.id + ) + continue + } + val moduleInfo = repoModule.moduleInfo + if (!showIncompatible && (moduleInfo.minApi > Build.VERSION.SDK_INT || moduleInfo.maxApi != 0 && moduleInfo.maxApi < Build.VERSION.SDK_INT || peekMagiskPath() != null) && repoModule.moduleInfo.minMagisk > peekMagiskVersion() || no32bitSupport && (AppUpdateManager.getFlagsForModule( + repoModule.id + ) and AppUpdateManager.FLAG_COMPAT_NEED_32BIT) != 0 || repoModule.moduleInfo.needRamdisk && !peekHasRamdisk() + ) continue // Skip adding incompatible modules + var moduleHolder = mappedModuleHolders[repoModule.id] + if (moduleHolder == null) { + mappedModuleHolders[repoModule.id] = ModuleHolder(repoModule.id).also { + moduleHolder = it + } } + moduleHolder!!.repoModule = repoModule + // check if local module is installed + // iterate over MainActivity.localModuleInfoList until we hit the module with the same id + for (localModuleInfo in MainActivity.localModuleInfoList) { + if (localModuleInfo.id == repoModule.id) { + moduleHolder!!.moduleInfo = localModuleInfo + break + } + } + } + } catch (e: Exception) { + Timber.e(e, "appendRemoteModules() failed") + // retry up to five times, waiting i * 100ms between each try + if (tries < 5) { + tries++ + Timber.i("appendRemoteModules() retrying in %dms", tries * 100) + Handler(Looper.getMainLooper()).postDelayed({ + appendRemoteModules() + }, tries * 100.toLong()) + } else { + Timber.e(e, "appendRemoteModules() failed after %d tries", tries) + tries = 0 } } - Timber.i("appendRemoteModules() finished in %dms", System.currentTimeMillis() - startTime) + Timber.i( + "appendRemoteModules() finished in %dms", + System.currentTimeMillis() - startTime + ) } } } @@ -132,8 +151,7 @@ class ModuleViewListBuilder(private val activity: Activity) { fun refreshNotificationsUI(moduleViewAdapter: ModuleViewAdapter) { val notificationCount = notifications.size notifySizeChanged( - moduleViewAdapter, 0, - notificationCount, notificationCount + moduleViewAdapter, 0, notificationCount, notificationCount ) } @@ -195,7 +213,8 @@ class ModuleViewListBuilder(private val activity: Activity) { newNotificationsLen = notifications.size + 1 - special val headerTypes = EnumSet.of( ModuleHolder.Type.SEPARATOR, - ModuleHolder.Type.NOTIFICATION, ModuleHolder.Type.FOOTER + ModuleHolder.Type.NOTIFICATION, + ModuleHolder.Type.FOOTER ) val moduleHolderIterator = mappedModuleHolders.values.iterator() synchronized(queryLock) { @@ -218,8 +237,7 @@ class ModuleViewListBuilder(private val activity: Activity) { Thread( { // Apply async applyTo(moduleList, moduleViewAdapter) - }, - "Sorter apply Thread" + }, "Sorter apply Thread" ).start() } } @@ -256,9 +274,7 @@ class ModuleViewListBuilder(private val activity: Activity) { if (notificationType != null) { oldNotifications.add(notificationType) if (!notificationType.special) oldNotificationsLen++ - } else if (moduleHolder.footerPx != -1 && - moduleHolder.filterLevel == 1 - ) oldNotificationsLen++ // Fix header + } else if (moduleHolder.footerPx != -1 && moduleHolder.filterLevel == 1) oldNotificationsLen++ // Fix header if (moduleHolder.separator === ModuleHolder.Type.INSTALLABLE) break oldOfflineModulesLen++ } @@ -274,25 +290,23 @@ class ModuleViewListBuilder(private val activity: Activity) { val oldLen = moduleViewAdapter.moduleHolders.size moduleViewAdapter.moduleHolders.clear() moduleViewAdapter.moduleHolders.addAll(moduleHolders) - if (oldNotificationsLen != newNotificationsLen || - oldNotifications != notifications - ) { + if (oldNotificationsLen != newNotificationsLen || oldNotifications != notifications) { notifySizeChanged( - moduleViewAdapter, 0, - oldNotificationsLen, newNotificationsLen + moduleViewAdapter, 0, oldNotificationsLen, newNotificationsLen ) } else { notifySizeChanged(moduleViewAdapter, 0, 1, 1) } if (newLen - newNotificationsLen == 0) { notifySizeChanged( - moduleViewAdapter, newNotificationsLen, - oldLen - oldNotificationsLen, 0 + moduleViewAdapter, newNotificationsLen, oldLen - oldNotificationsLen, 0 ) } else { notifySizeChanged( - moduleViewAdapter, newNotificationsLen, - oldOfflineModulesLen, newOfflineModulesLen + moduleViewAdapter, + newNotificationsLen, + oldOfflineModulesLen, + newOfflineModulesLen ) notifySizeChanged( moduleViewAdapter, @@ -306,8 +320,7 @@ class ModuleViewListBuilder(private val activity: Activity) { updateInsets = Runnable { notifySizeChanged(moduleViewAdapter, 0, 1, 1) notifySizeChanged( - moduleViewAdapter, - moduleHolders.size, 1, 1 + moduleViewAdapter, moduleHolders.size, 1, 1 ) } } @@ -350,8 +363,7 @@ class ModuleViewListBuilder(private val activity: Activity) { companion object { private val RUNNABLE = Runnable {} private fun notifySizeChanged( - moduleViewAdapter: ModuleViewAdapter, - index: Int, oldLen: Int, newLen: Int + moduleViewAdapter: ModuleViewAdapter, index: Int, oldLen: Int, newLen: Int ) { // Timber.i("A: " + index + " " + oldLen + " " + newLen); if (oldLen == newLen) { diff --git a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoManager.kt b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoManager.kt index e642e59..f179ae5 100644 --- a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoManager.kt +++ b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoManager.kt @@ -32,7 +32,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import timber.log.Timber import java.io.File import java.nio.charset.StandardCharsets -import java.util.concurrent.Executors @Suppress("NAME_SHADOWING", "unused") class RepoManager private constructor(mainApplication: MainApplication) : SyncManager() { @@ -173,44 +172,19 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa val repoModules = repoUpdaters[i]!!.toUpdate() val repoData = repoDatas[i] if (BuildConfig.DEBUG) Timber.d("Registering %s", repoData.name) - // max threads is equal to the number of cores - val executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()) for (repoModule in repoModules!!) { try { if (repoModule.propUrl != null && repoModule.propUrl!!.isNotEmpty()) { - executor.execute { - repoData.storeMetadata( - repoModule, doHttpGet( - repoModule.propUrl!!, false - ) + repoData.storeMetadata( + repoModule, doHttpGet( + repoModule.propUrl!!, false ) - write( - File(repoData.cacheRoot, repoModule.id + ".prop"), doHttpGet( - repoModule.propUrl!!, false - ) + ) + write( + File(repoData.cacheRoot, repoModule.id + ".prop"), doHttpGet( + repoModule.propUrl!!, false ) - - if (repoData.tryLoadMetadata(repoModule) && (allowLowQualityModules || !isLowQualityModule( - repoModule.moduleInfo - )) - ) { - // Note: registeredRepoModule may not be null if registered by multiple repos - val registeredRepoModule = modules[repoModule.id] - if (registeredRepoModule == null) { - modules[repoModule.id] = repoModule - } else if (instance.isEnabled && registeredRepoModule.repoData === androidacyRepoData) { - // empty - } else if (instance.isEnabled && repoModule.repoData === androidacyRepoData) { - modules[repoModule.id] = repoModule - } else if (repoModule.moduleInfo.versionCode > registeredRepoModule.moduleInfo.versionCode) { - modules[repoModule.id] = repoModule - } - } else { - repoModule.moduleInfo.flags = - repoModule.moduleInfo.flags or ModuleInfo.FLAG_METADATA_INVALID - } - return@execute - } + ) } if (repoData.tryLoadMetadata(repoModule) && (allowLowQualityModules || !isLowQualityModule( repoModule.moduleInfo @@ -253,6 +227,7 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa } } } + MainApplication.INSTANCE!!.repoModules.putAll(modules) } if (BuildConfig.DEBUG) Timber.d("Finishing update") if (hasConnectivity()) { diff --git a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoUpdater.kt b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoUpdater.kt index f7190fa..dfcbc55 100644 --- a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoUpdater.kt +++ b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoUpdater.kt @@ -37,7 +37,7 @@ class RepoUpdater(repoData2: RepoData) { return 0 } // if MainApplication.repoModules is not empty, return it - if (MainApplication.INSTANCE!!.repoModules.isNotEmpty()) { + /*if (MainApplication.INSTANCE!!.repoModules.isNotEmpty()) { Timber.d("Returning MainApplication.repoModules for %s", repoData.preferenceId) // convert to list for toUpdate val toUpdateList = ArrayList() @@ -48,7 +48,7 @@ class RepoUpdater(repoData2: RepoData) { // toapply is a collection of RepoModule, so we need to convert the list to a set toApply = HashSet(MainApplication.INSTANCE!!.repoModules.values) return toUpdate!!.size - } + }*/ // if we shouldn't update, get the values from the ModuleListCache realm if (!repoData.shouldUpdate() && repoData.preferenceId == "androidacy_repo") { // for now, only enable cache reading for androidacy repo, until we handle storing module prop file values in cache Timber.d("Fetching index from cache for %s", repoData.preferenceId)