From 03638ca84ce3a07725b1a657412666bab46a337e Mon Sep 17 00:00:00 2001 From: Rahul Patel Date: Sat, 30 May 2026 00:37:05 +0530 Subject: [PATCH] Track the install phase with INSTALLING/INSTALLED download states A download row previously stopped at COMPLETED and never reflected whether the app actually installed. Add INSTALLING/INSTALLED states driven by a central installer-event observer in DownloadHelper: - COMPLETED -> INSTALLING on the installer's first progress event - -> INSTALLED on success (row kept so the APK can still be exported) - a failed install reverts INSTALLING -> COMPLETED so it can be re-installed without re-downloading Consumers that branched on COMPLETED are updated (App Details state, MicroG status mapping, Downloads list icon). downloadStatus is stored as TEXT so no schema migration is needed. --- .../compose/composable/DownloadListItem.kt | 2 +- .../store/data/helper/DownloadHelper.kt | 34 +++++++++++++++++++ .../aurora/store/data/model/DownloadStatus.kt | 6 ++-- .../viewmodel/details/AppDetailsViewModel.kt | 3 +- .../viewmodel/onboarding/MicroGViewModel.kt | 4 ++- app/src/main/res/values/strings.xml | 2 ++ 6 files changed, 46 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/aurora/store/compose/composable/DownloadListItem.kt b/app/src/main/java/com/aurora/store/compose/composable/DownloadListItem.kt index cedf13fb0..203e08af2 100644 --- a/app/src/main/java/com/aurora/store/compose/composable/DownloadListItem.kt +++ b/app/src/main/java/com/aurora/store/compose/composable/DownloadListItem.kt @@ -61,7 +61,7 @@ fun DownloadListItem(modifier: Modifier = Modifier, download: Download, onClick: ) }, trailing = when (download.status) { - DownloadStatus.COMPLETED -> { + DownloadStatus.COMPLETED, DownloadStatus.INSTALLED -> { { Icon( painter = painterResource(R.drawable.ic_check), diff --git a/app/src/main/java/com/aurora/store/data/helper/DownloadHelper.kt b/app/src/main/java/com/aurora/store/data/helper/DownloadHelper.kt index 44f8ade6e..b948a4e25 100644 --- a/app/src/main/java/com/aurora/store/data/helper/DownloadHelper.kt +++ b/app/src/main/java/com/aurora/store/data/helper/DownloadHelper.kt @@ -14,6 +14,7 @@ import androidx.work.WorkRequest import com.aurora.extensions.TAG import com.aurora.gplayapi.data.models.App import com.aurora.store.AuroraApp +import com.aurora.store.data.event.InstallerEvent import com.aurora.store.data.installer.AppInstaller import com.aurora.store.data.model.DownloadStatus import com.aurora.store.data.room.download.Download @@ -75,9 +76,42 @@ class DownloadHelper @Inject constructor( cancelFailedDownloads(downloadDao.downloads().firstOrNull() ?: emptyList()) }.invokeOnCompletion { observeDownloads() + observeInstalls() } } + /** + * Advances a download row through the installer phase so its history reflects whether the + * app actually installed, not just that the bytes finished downloading: + * - [InstallerEvent.Installing] moves a [DownloadStatus.COMPLETED] row to + * [DownloadStatus.INSTALLING]; + * - [InstallerEvent.Installed] marks it [DownloadStatus.INSTALLED] (kept so the user can + * still export the APK); + * - [InstallerEvent.Failed] reverts an in-progress install back to + * [DownloadStatus.COMPLETED] so the downloaded files can be re-installed without + * re-downloading. + */ + private fun observeInstalls() { + AuroraApp.events.installerEvent.onEach { event -> + val existing = getDownload(event.packageName) ?: return@onEach + when (event) { + is InstallerEvent.Installing -> if (existing.status == DownloadStatus.COMPLETED) { + downloadDao.updateStatus(event.packageName, DownloadStatus.INSTALLING) + } + + is InstallerEvent.Installed -> if (existing.status != DownloadStatus.INSTALLED) { + downloadDao.updateStatus(event.packageName, DownloadStatus.INSTALLED) + } + + is InstallerEvent.Failed -> if (existing.status == DownloadStatus.INSTALLING) { + downloadDao.updateStatus(event.packageName, DownloadStatus.COMPLETED) + } + + else -> {} + } + }.launchIn(AuroraApp.scope) + } + private fun observeDownloads() { downloadDao.downloads().onEach { list -> try { diff --git a/app/src/main/java/com/aurora/store/data/model/DownloadStatus.kt b/app/src/main/java/com/aurora/store/data/model/DownloadStatus.kt index 36b34c089..e703d221c 100644 --- a/app/src/main/java/com/aurora/store/data/model/DownloadStatus.kt +++ b/app/src/main/java/com/aurora/store/data/model/DownloadStatus.kt @@ -11,10 +11,12 @@ enum class DownloadStatus(@StringRes val localized: Int) { QUEUED(R.string.status_queued), UNAVAILABLE(R.string.status_unavailable), VERIFYING(R.string.status_verifying), - PURCHASING(R.string.preparing_to_install); + PURCHASING(R.string.preparing_to_install), + INSTALLING(R.string.status_installing), + INSTALLED(R.string.status_installed); companion object { - val finished = listOf(FAILED, CANCELLED, COMPLETED) + val finished = listOf(FAILED, CANCELLED, COMPLETED, INSTALLED) val running = listOf(QUEUED, PURCHASING, DOWNLOADING) /** diff --git a/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt index b9b7aad0a..1ac90d4a3 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt @@ -314,7 +314,8 @@ class AppDetailsViewModel @Inject constructor( DownloadStatus.VERIFYING -> AppState.Verifying - DownloadStatus.COMPLETED -> if (isInstalled) defaultAppState else AppState.Installing(0F) + DownloadStatus.COMPLETED, + DownloadStatus.INSTALLING -> if (isInstalled) defaultAppState else AppState.Installing(0F) else -> defaultAppState } diff --git a/app/src/main/java/com/aurora/store/viewmodel/onboarding/MicroGViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/onboarding/MicroGViewModel.kt index fd4eb2ea8..fca1bcec4 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/onboarding/MicroGViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/onboarding/MicroGViewModel.kt @@ -213,7 +213,9 @@ class MicroGViewModel @Inject constructor( download == null -> InstallStatus.PENDING download.status == DownloadStatus.FAILED -> InstallStatus.FAILED download.status == DownloadStatus.CANCELLED -> InstallStatus.PENDING - download.status == DownloadStatus.COMPLETED -> InstallStatus.INSTALLING + download.status == DownloadStatus.INSTALLED -> InstallStatus.INSTALLED + download.status == DownloadStatus.COMPLETED || + download.status == DownloadStatus.INSTALLING -> InstallStatus.INSTALLING else -> InstallStatus.DOWNLOADING } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a4e2f87ae..c95c36e05 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -520,6 +520,8 @@ Queued Unavailable Verifying + Installing + Installed Authentication required