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.
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user