Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42aeb0a4 authored by Fahim M. Choudhury's avatar Fahim M. Choudhury
Browse files

Merge branch '4235-serialize-update-one-at-a-time' into 'main'

feat(update): serialize update processing and fix ConcurrentModificationException

See merge request !785
parents 2ce05edd 4c7de56f
Loading
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -22,12 +22,14 @@ import foundation.e.apps.data.installation.model.AppInstall

object UpdatesDao {
    private val _appsAwaitingForUpdate: MutableList<Application> = mutableListOf()
    val appsAwaitingForUpdate: List<Application> = _appsAwaitingForUpdate
    val appsAwaitingForUpdate: List<Application>
        get() = _appsAwaitingForUpdate.toList()
    var appsAwaitingForUpdateIncludesOtherStores: Boolean = false
        private set

    private val _successfulUpdatedApps = mutableListOf<AppInstall>()
    val successfulUpdatedApps: List<AppInstall> = _successfulUpdatedApps
    val successfulUpdatedApps: List<AppInstall>
        get() = _successfulUpdatedApps.toList()

    fun addItemsForUpdate(
        appsNeedUpdate: List<Application>,
+2 −2
Original line number Diff line number Diff line
@@ -42,10 +42,10 @@ class DownloadProgressTracker @Inject constructor(
        application?.let { app ->
            val appDownload = appManager.getDownloadList()
                .singleOrNull { it.id.contentEquals(app._id) && it.packageName.contentEquals(app.package_name) }
                ?: return 0
                ?: return -1
            return calculateProgress(appDownload, progress)
        }
        return 0
        return -1
    }

    suspend fun calculateProgress(
+2 −5
Original line number Diff line number Diff line
@@ -46,7 +46,8 @@ class AppInstallationFacade @Inject constructor(
        application: Application,
        isAnUpdate: Boolean = false
    ): Boolean {
        val appInstall = installationRequest.create(application)
        val isUpdate = isAnUpdate || application.status == Status.UPDATABLE
        val appInstall = installationRequest.create(application, isUpdateRequest = isUpdate)

        if (application.source == Source.PLAY_STORE) {
            val libs = application.dependentLibraries.ifEmpty {
@@ -66,10 +67,6 @@ class AppInstallationFacade @Inject constructor(
            appInstall.sharedLibs = libs
        }

        val isUpdate = isAnUpdate ||
            application.status == Status.UPDATABLE ||
            appManager.isAppInstalled(appInstall)

        return enqueueAppForInstallation(appInstall, isUpdate, application.isSystemApp)
    }

+1 −15
Original line number Diff line number Diff line
@@ -18,13 +18,10 @@

package foundation.e.apps.data.install.core

import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.R
import foundation.e.apps.data.application.AppManager
import foundation.e.apps.data.event.AppEvent
import foundation.e.apps.data.install.core.helper.PreEnqueueChecker
import foundation.e.apps.data.install.workmanager.InstallWorkManager
import foundation.e.apps.data.install.wrapper.AppEventDispatcher
import foundation.e.apps.data.installation.model.AppInstall
import foundation.e.apps.data.preference.PlayStoreAuthStore
@@ -34,7 +31,6 @@ import kotlinx.coroutines.CancellationException
import timber.log.Timber
import javax.inject.Inject
class InstallationEnqueuer @Inject constructor(
    @ApplicationContext private val context: Context,
    private val preEnqueueChecker: PreEnqueueChecker,
    private val appManager: AppManager,
    private val sessionRepository: SessionRepository,
@@ -55,11 +51,7 @@ class InstallationEnqueuer @Inject constructor(

                canEnqueue(appInstall, isAnUpdate) -> {
                    appManager.updateAwaiting(appInstall)
                    // Enqueueing installation work is managed by InstallOrchestrator#observeDownloads().
                    // This method only handles update work.
                    if (isAnUpdate) {
                        enqueueUpdate(appInstall)
                    }
                    // InstallOrchestrator owns WorkManager dispatch for queued installs and updates.
                    true
                }

@@ -101,12 +93,6 @@ class InstallationEnqueuer @Inject constructor(
        }
    }

    private fun enqueueUpdate(appInstall: AppInstall) {
        val uniqueWorkName = InstallWorkManager.getUniqueWorkName(appInstall.packageName)
        InstallWorkManager.enqueueWork(context, appInstall, true)
        Timber.d("UPDATE: Successfully enqueued unique work: $uniqueWorkName")
    }

    suspend fun canEnqueue(appInstall: AppInstall, isAnUpdate: Boolean = false): Boolean {
        return preEnqueueChecker.canEnqueue(appInstall, isAnUpdate)
    }
+3 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import foundation.e.apps.data.installation.model.AppInstall
import foundation.e.apps.data.installation.model.InstallationType
import javax.inject.Inject
class InstallationRequest @Inject constructor() {
    fun create(application: Application): AppInstall {
    fun create(application: Application, isUpdateRequest: Boolean = false): AppInstall {
        val appInstall = AppInstall(
            application._id,
            application.source.toInstallationSource(),
@@ -41,7 +41,8 @@ class InstallationRequest @Inject constructor() {
            application.latest_version_code,
            application.offer_type,
            application.isFree,
            application.originalSize
            application.originalSize,
            isUpdateRequest = isUpdateRequest
        ).also {
            it.contentRating = application.contentRating
        }
Loading