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

Commit 99eb645c authored by dev-12's avatar dev-12
Browse files

refactor: sequential start installation jobs

now the update worker will start installation jobs sequentially instead of enqueuing every app at once, and will wait for job results before marking job as completed
parent 029179ca
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ package foundation.e.apps.install.workmanager

import android.content.Context
import androidx.annotation.VisibleForTesting
import androidx.work.WorkInfo
import androidx.work.WorkManager
import com.aurora.gplayapi.exceptions.InternalException
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.R
@@ -50,10 +52,16 @@ import foundation.e.apps.utils.getFormattedString
import foundation.e.apps.utils.isNetworkAvailable
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.transformWhile
import kotlinx.coroutines.time.withTimeout
import timber.log.Timber
import java.text.NumberFormat
import java.time.Duration
import java.util.Date
import java.util.UUID
import javax.inject.Inject

class AppInstallProcessor @Inject constructor(
@@ -75,6 +83,7 @@ class AppInstallProcessor @Inject constructor(
    companion object {
        private const val TAG = "AppInstallProcessor"
        private const val DATE_FORMAT = "dd/MM/yyyy-HH:mm"
        private val INSTALL_TASK_TIMEOUT = Duration.ofMinutes(30)
    }

    /**
@@ -141,8 +150,8 @@ class AppInstallProcessor @Inject constructor(
            if (!canEnqueue(appInstall)) return false

            appInstallComponents.appManagerWrapper.updateAwaiting(appInstall)
            InstallWorkManager.enqueueWork(appInstall, isAnUpdate)
            true
            val id = InstallWorkManager.enqueueWork(appInstall, isAnUpdate)
            waitForTaskCompletionOrCancelOnTimeout(workId = id)
        } catch (e: Exception) {
            Timber.e(
                e,
@@ -153,6 +162,25 @@ class AppInstallProcessor @Inject constructor(
        }
    }

    private suspend fun waitForTaskCompletionOrCancelOnTimeout(
        workManager: WorkManager = WorkManager.getInstance(context),
        timeout: Duration = INSTALL_TASK_TIMEOUT,
        workId: UUID
    ): Boolean {
        return try {
            withTimeout(timeout) {
                workManager.getWorkInfoByIdFlow(workId)
                    .filterNotNull()
                    .first { it.state.isFinished }
                    .state == WorkInfo.State.SUCCEEDED
            }
        } catch (e: TimeoutCancellationException) {
            Timber.e(e, "install work timed-out")
            workManager.cancelWorkById(workId)
            false
        }
    }

    @VisibleForTesting
    suspend fun canEnqueue(appInstall: AppInstall): Boolean {
        if (appInstall.type != Type.PWA && !updateDownloadUrls(appInstall)) {