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 bd902e1e4..b08f680e8 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 @@ -116,6 +116,14 @@ class DownloadHelper @Inject constructor( downloadDao.updateStatus(packageName, DownloadStatus.CANCELLED) } + /** + * Removes the download record from the database without deleting downloaded files. + * @param packageName Name of the package + */ + suspend fun removeDownload(packageName: String) { + downloadDao.delete(packageName) + } + /** * Clears the entry & downloaded files for the given package * @param packageName Name of the package of the app 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 5ec664f7d..16e24ecf9 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 @@ -16,7 +16,6 @@ import com.aurora.extensions.TAG import com.aurora.extensions.requiresGMS import com.aurora.gplayapi.data.models.App import com.aurora.gplayapi.data.models.Review -import com.aurora.gplayapi.data.models.datasafety.Report as DataSafetyReport import com.aurora.gplayapi.data.models.details.TestingProgramStatus import com.aurora.gplayapi.helpers.AppDetailsHelper import com.aurora.gplayapi.helpers.ReviewsHelper @@ -42,7 +41,6 @@ import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_EXTENDED import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext -import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -56,6 +54,8 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.serialization.json.Json import org.json.JSONObject +import javax.inject.Inject +import com.aurora.gplayapi.data.models.datasafety.Report as DataSafetyReport @HiltViewModel class AppDetailsViewModel @Inject constructor( @@ -155,12 +155,22 @@ class AppDetailsViewModel @Inject constructor( _app.value = appDetailsHelper.getAppByPackageName(packageName).copy( isInstalled = PackageUtil.isInstalled(context, packageName) ) - // Seed state from any in-flight download for this package so reopening - // the screen doesn't briefly flash the default install action while the - // download flow catches up. - _state.value = downloadHelper.getDownload(packageName) - ?.let { stateFromDownload(it) } - ?: defaultAppState + val existingDownload = downloadHelper.getDownload(packageName) + + // A COMPLETED record for an app that is no longer installed means the app was + // installed then removed while Aurora held a stale record. + // Remove it so the live download observer doesn't lock the UI in Installing state + // indefinitely. + if (existingDownload?.status == DownloadStatus.COMPLETED && !isInstalled) { + downloadHelper.removeDownload(packageName) + _state.value = defaultAppState + } else { + // Seed state from any in-flight download for this package so reopening + // the screen doesn't briefly flash the default install action while the + // download flow catches up. + _state.value = + existingDownload?.let { stateFromDownload(it) } ?: defaultAppState + } } catch (exception: Exception) { Log.e(TAG, "Failed to fetch app details", exception) _app.value = null