ExtensionInstaller: Fix mistakenly canceling unrelated waitingInstall & avoid adding duplicate entry to installing queue (#1649)
* ExtensionInstaller: Fix mistakenly canceling unrelated `waitingInstall` & avoid adding duplicate entry to installing `queue` - Changes the installer queue from a synchronized list to a synchronized set to prevent duplicate entries. - Updates queue removal logic to remove specific entries instead of using index-based removal. - Refines `cancelQueue` logic to ensure the active installation is only cancelled if its download ID matches the requested ID. * Ensure thread-safe access to the installation queue when canceling downloads
This commit is contained in:
parent
dc7dd8045e
commit
94eac94ce7
3 changed files with 16 additions and 10 deletions
|
|
@ -24,7 +24,9 @@ abstract class Installer(private val service: Service) {
|
|||
private val extensionManager: ExtensionManager by injectLazy()
|
||||
|
||||
private var waitingInstall = AtomicReference<Entry?>(null)
|
||||
private val queue = Collections.synchronizedList(mutableListOf<Entry>())
|
||||
// KMK -->
|
||||
private val queue = Collections.synchronizedSet(mutableSetOf<Entry>())
|
||||
// KMK <--
|
||||
|
||||
private val cancelReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
|
|
@ -104,7 +106,9 @@ abstract class Installer(private val service: Service) {
|
|||
}
|
||||
val nextEntry = queue.first()
|
||||
if (waitingInstall.compareAndSet(null, nextEntry)) {
|
||||
queue.removeAt(0)
|
||||
// KMK -->
|
||||
queue.remove(nextEntry)
|
||||
// KMK <--
|
||||
processEntry(nextEntry)
|
||||
}
|
||||
}
|
||||
|
|
@ -129,7 +133,11 @@ abstract class Installer(private val service: Service) {
|
|||
*/
|
||||
private fun cancelQueue(downloadId: Long) {
|
||||
val waitingInstall = this.waitingInstall.load()
|
||||
val toCancel = queue.find { it.downloadId == downloadId } ?: waitingInstall ?: return
|
||||
// KMK -->
|
||||
val toCancel = synchronized(queue) { queue.find { it.downloadId == downloadId } }
|
||||
?: waitingInstall?.takeIf { it.downloadId == downloadId }
|
||||
// KMK <--
|
||||
?: return
|
||||
if (cancelEntry(toCancel)) {
|
||||
queue.remove(toCancel)
|
||||
if (waitingInstall == toCancel) {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ import eu.kanade.tachiyomi.extension.model.InstallStep
|
|||
import eu.kanade.tachiyomi.util.lang.use
|
||||
import eu.kanade.tachiyomi.util.system.getParcelableExtraCompat
|
||||
import eu.kanade.tachiyomi.util.system.getUriSize
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
import exh.log.xLogE
|
||||
|
||||
class PackageInstallerInstaller(private val service: Service) : Installer(service) {
|
||||
|
||||
|
|
@ -42,7 +41,7 @@ class PackageInstallerInstaller(private val service: Service) : Installer(servic
|
|||
.sanitizeByFiltering(this)
|
||||
}
|
||||
if (userAction == null) {
|
||||
logcat(LogPriority.ERROR) { "Fatal error for $intent" }
|
||||
xLogE("Fatal error for $intent")
|
||||
continueQueue(InstallStep.Error)
|
||||
return
|
||||
}
|
||||
|
|
@ -95,7 +94,7 @@ class PackageInstallerInstaller(private val service: Service) : Installer(servic
|
|||
session.commit(intentSender)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e) { "Failed to install extension ${entry.downloadId} ${entry.uri}" }
|
||||
xLogE("Failed to install extension ${entry.downloadId} ${entry.uri}", e)
|
||||
activeSession?.let { (_, sessionId) ->
|
||||
packageInstaller.abandonSession(sessionId)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,8 @@ import eu.kanade.tachiyomi.extension.installer.ShizukuInstaller
|
|||
import eu.kanade.tachiyomi.extension.util.ExtensionInstaller.Companion.EXTRA_DOWNLOAD_ID
|
||||
import eu.kanade.tachiyomi.util.system.getSerializableExtraCompat
|
||||
import eu.kanade.tachiyomi.util.system.notificationBuilder
|
||||
import logcat.LogPriority
|
||||
import exh.log.xLogE
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.i18n.MR
|
||||
|
||||
class ExtensionInstallService : Service() {
|
||||
|
|
@ -53,7 +52,7 @@ class ExtensionInstallService : Service() {
|
|||
BasePreferences.ExtensionInstaller.PACKAGEINSTALLER -> PackageInstallerInstaller(this)
|
||||
BasePreferences.ExtensionInstaller.SHIZUKU -> ShizukuInstaller(this)
|
||||
else -> {
|
||||
logcat(LogPriority.ERROR) { "Not implemented for installer $installerUsed" }
|
||||
xLogE("Not implemented for installer $installerUsed")
|
||||
stopSelf()
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue