From 7dfe86eea51a16cb86d435c2766a226ef6cda237 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 15 Jan 2026 18:02:31 -0300 Subject: [PATCH] Improve behavior of updating our own app last Now our own app will show as in progress of getting updated. No more 'Update all' button will be shown after it has been pressed already. --- .../org/fdroid/install/AppInstallManager.kt | 17 +++++++++++++++-- .../kotlin/org/fdroid/install/InstallState.kt | 14 ++++++++++++++ .../org/fdroid/ui/details/AppDetailsHeader.kt | 1 + .../kotlin/org/fdroid/updates/UpdatesManager.kt | 16 +++++++++++++++- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/org/fdroid/install/AppInstallManager.kt b/app/src/main/kotlin/org/fdroid/install/AppInstallManager.kt index 2f760d9f6..f301d749d 100644 --- a/app/src/main/kotlin/org/fdroid/install/AppInstallManager.kt +++ b/app/src/main/kotlin/org/fdroid/install/AppInstallManager.kt @@ -67,7 +67,7 @@ class AppInstallManager @Inject constructor( // assign a category to each in progress state val appStateCategory = when (state) { is InstallState.Installing, is InstallState.PreApproved, - is InstallState.Starting -> AppStateCategory.INSTALLING + is InstallState.Waiting, is InstallState.Starting -> AppStateCategory.INSTALLING is InstallState.Downloading -> { numBytesDownloaded += state.downloadedBytes numTotalBytes += state.totalBytes @@ -123,7 +123,7 @@ class AppInstallManager @Inject constructor( ): InstallState { val packageName = appMetadata.packageName val currentState = apps.value[packageName] - if (currentState?.showProgress == true) { + if (currentState?.showProgress == true && currentState !is InstallState.Waiting) { log.warn { "Attempted to install $packageName with install in progress: $currentState" } return currentState } @@ -159,6 +159,19 @@ class AppInstallManager @Inject constructor( return result } + fun setWaitingState( + packageName: String, + name: String, + versionName: String, + currentVersionName: String, + lastUpdated: Long, + ) { + apps.updateApp(packageName) { + InstallState.Waiting(name, versionName, currentVersionName, lastUpdated) + } + onStatesUpdated() + } + @WorkerThread private suspend fun startInstall( appMetadata: AppMetadata, diff --git a/app/src/main/kotlin/org/fdroid/install/InstallState.kt b/app/src/main/kotlin/org/fdroid/install/InstallState.kt index fda917fad..de4f9dc5a 100644 --- a/app/src/main/kotlin/org/fdroid/install/InstallState.kt +++ b/app/src/main/kotlin/org/fdroid/install/InstallState.kt @@ -7,6 +7,20 @@ import org.fdroid.download.DownloadRequest sealed class InstallState(val showProgress: Boolean) { data object Unknown : InstallState(false) + + /** + * Used for our own app which will be updated last, + * so this is waiting for all other updates to complete. + */ + data class Waiting( + override val name: String, + override val versionName: String, + override val currentVersionName: String? = null, + override val lastUpdated: Long, + ) : InstallStateWithInfo(true) { + override val iconDownloadRequest: DownloadRequest? = null + } + data class Starting( override val name: String, override val versionName: String, diff --git a/app/src/main/kotlin/org/fdroid/ui/details/AppDetailsHeader.kt b/app/src/main/kotlin/org/fdroid/ui/details/AppDetailsHeader.kt index 5bb38441f..227d7e6af 100644 --- a/app/src/main/kotlin/org/fdroid/ui/details/AppDetailsHeader.kt +++ b/app/src/main/kotlin/org/fdroid/ui/details/AppDetailsHeader.kt @@ -226,6 +226,7 @@ fun AppDetailsHeader( ) { Column { val strRes = when (item.installState) { + is InstallState.Waiting -> R.string.status_install_preparing is InstallState.Starting -> R.string.status_install_preparing is InstallState.PreApproved -> R.string.status_install_preparing is InstallState.Downloading -> R.string.downloading diff --git a/app/src/main/kotlin/org/fdroid/updates/UpdatesManager.kt b/app/src/main/kotlin/org/fdroid/updates/UpdatesManager.kt index 50f4622bc..9b69d8620 100644 --- a/app/src/main/kotlin/org/fdroid/updates/UpdatesManager.kt +++ b/app/src/main/kotlin/org/fdroid/updates/UpdatesManager.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.withPermit import mu.KotlinLogging +import org.fdroid.LocaleChooser.getBestLocale import org.fdroid.NotificationManager import org.fdroid.database.AppVersion import org.fdroid.database.AvailableAppWithIssue @@ -171,7 +172,20 @@ class UpdatesManager @Inject constructor( val updateLast = appsToUpdate.find { it.packageName == context.packageName } appsToUpdate.mapNotNull { update -> // don't update our own app just yet - if (update.packageName == context.packageName) return@mapNotNull null + if (update.packageName == context.packageName) { + // set app to update last to Starting as well, so it doesn't seem stuck + val app = db.getAppDao().getApp(update.repoId, update.packageName) + ?: return@mapNotNull null + appInstallManager.setWaitingState( + packageName = update.packageName, + name = app.metadata.name.getBestLocale(LocaleListCompat.getDefault()) + ?: "Unknown", + versionName = update.update.versionName, + currentVersionName = update.installedVersionName, + lastUpdated = update.update.added, + ) + return@mapNotNull null + } currentCoroutineContext().ensureActive() // launch a new co-routine for each app to update coroutineScope.launch {