diff --git a/app/src/main/java/foundation/e/apps/api/fused/UpdatesDao.kt b/app/src/main/java/foundation/e/apps/api/fused/UpdatesDao.kt index f5b24243f2459e2794c63cf306c5668f1b0efaf9..30e989c2da776c121d3f80fdd7ba63034b4489ce 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/UpdatesDao.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/UpdatesDao.kt @@ -18,11 +18,15 @@ package foundation.e.apps.api.fused import foundation.e.apps.api.fused.data.FusedApp +import foundation.e.apps.manager.database.fusedDownload.FusedDownload object UpdatesDao { private val _appsAwaitingForUpdate: MutableList = mutableListOf() val appsAwaitingForUpdate: List = _appsAwaitingForUpdate + private val _successfulUpdatedApps = mutableListOf() + val successfulUpdatedApps: List = _successfulUpdatedApps + fun addItemsForUpdate(appsNeedUpdate: List) { _appsAwaitingForUpdate.clear() _appsAwaitingForUpdate.addAll(appsNeedUpdate) @@ -31,4 +35,12 @@ object UpdatesDao { fun hasAnyAppsForUpdate() = _appsAwaitingForUpdate.isNotEmpty() fun removeUpdateIfExists(packageName: String) = _appsAwaitingForUpdate.removeIf { it.package_name == packageName } + + fun addSuccessfullyUpdatedApp(fusedDownload: FusedDownload) { + _successfulUpdatedApps.add(fusedDownload) + } + + fun clearSuccessfullyUpdatedApps() { + _successfulUpdatedApps.clear() + } } diff --git a/app/src/main/java/foundation/e/apps/manager/workmanager/InstallAppWorker.kt b/app/src/main/java/foundation/e/apps/manager/workmanager/InstallAppWorker.kt index ed37094a773b5773a27838c820cccf89a60ce97e..6dca817c3ecbdfd48094464f7f02fedb51538703 100644 --- a/app/src/main/java/foundation/e/apps/manager/workmanager/InstallAppWorker.kt +++ b/app/src/main/java/foundation/e/apps/manager/workmanager/InstallAppWorker.kt @@ -33,6 +33,7 @@ import androidx.work.WorkerParameters import dagger.assisted.Assisted import dagger.assisted.AssistedInject import foundation.e.apps.R +import foundation.e.apps.api.fused.UpdatesDao import foundation.e.apps.manager.database.DatabaseRepository import foundation.e.apps.manager.database.fusedDownload.FusedDownload import foundation.e.apps.manager.fused.FusedManagerRepository @@ -49,6 +50,7 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.sync.Mutex import timber.log.Timber +import java.text.NumberFormat import java.text.SimpleDateFormat import java.util.Date import java.util.concurrent.atomic.AtomicInteger @@ -73,6 +75,7 @@ class InstallAppWorker @AssistedInject constructor( companion object { private const val TAG = "InstallWorker" const val INPUT_DATA_FUSED_DOWNLOAD = "input_data_fused_download" + const val IS_UPDATE_WORK = "is_update_work" /* * If this is not "static" then each notification has the same ID. @@ -97,7 +100,8 @@ class InstallAppWorker @AssistedInject constructor( fusedDownload = databaseRepository.getDownloadById(fusedDownloadString) Timber.d(">>> dowork started for Fused download name " + fusedDownload?.name + " " + fusedDownloadString) fusedDownload?.let { - isItUpdateWork = packageManagerModule.isInstalled(it.packageName) + isItUpdateWork = params.inputData.getBoolean(IS_UPDATE_WORK, false) + && packageManagerModule.isInstalled(it.packageName) if (fusedDownload.status != Status.AWAITING) { return Result.success() @@ -122,32 +126,50 @@ class InstallAppWorker @AssistedInject constructor( fusedManagerRepository.installationIssue(it) } } finally { - if (isItUpdateWork && isUpdateCompleted()) { // show notification for ended update - showNotificationOnUpdateEnded() - } - Timber.d("doWork: RESULT SUCCESS: ${fusedDownload?.name}") return Result.success() } } + private suspend fun InstallAppWorker.checkUpdateWork( + fusedDownload: FusedDownload? + ) { + if (isItUpdateWork) { + fusedDownload?.let { + val actualFusedDownload = databaseRepository.getDownloadById(it.id) + if (actualFusedDownload?.status == Status.INSTALLED) { + UpdatesDao.addSuccessfullyUpdatedApp(it) + } + + if (isUpdateCompleted()) { // show notification for ended update + showNotificationOnUpdateEnded() + UpdatesDao.clearSuccessfullyUpdatedApps() + } + } + } + } + private suspend fun isUpdateCompleted(): Boolean { val downloadListWithoutAnyIssue = databaseRepository.getDownloadList() .filter { !listOf(Status.INSTALLATION_ISSUE, Status.PURCHASE_NEEDED).contains(it.status) } - return downloadListWithoutAnyIssue.isEmpty() + return UpdatesDao.successfulUpdatedApps.isNotEmpty() && downloadListWithoutAnyIssue.isEmpty() } private fun showNotificationOnUpdateEnded() { val date = Date(System.currentTimeMillis()) + val locale = dataStoreManager.getAuthData().locale val dateFormat = - SimpleDateFormat("dd/MM/yyyy-HH:mm", dataStoreManager.getAuthData().locale) + SimpleDateFormat("dd/MM/yyyy-HH:mm", locale) + val numberOfUpdatedApps = NumberFormat.getNumberInstance(locale) + .format(UpdatesDao.successfulUpdatedApps.size) + .toString() UpdatesNotifier.showNotification( context, context.getString(R.string.update), context.getString( - R.string.message_last_update_triggered, dateFormat.format(date) + R.string.message_last_update_triggered, numberOfUpdatedApps, dateFormat.format(date) ) ) } @@ -161,8 +183,9 @@ class InstallAppWorker @AssistedInject constructor( tickerFlow(3.seconds) .onEach { val download = databaseRepository.getDownloadById(fusedDownload.id) + if (download == null) { - finishInstallation() + finishInstallation(fusedDownload) } else { handleFusedDownloadStatusCheckingException(download) if (isAppDownloading(download)) { @@ -184,7 +207,7 @@ class InstallAppWorker @AssistedInject constructor( handleFusedDownloadStatus(download) } catch (e: Exception) { Log.e(TAG, "observeDownload: ", e) - finishInstallation() + finishInstallation(download) } } @@ -225,11 +248,11 @@ class InstallAppWorker @AssistedInject constructor( Timber.d("===> doWork: Installing ${fusedDownload.name} ${fusedDownload.status}") } Status.INSTALLED, Status.INSTALLATION_ISSUE -> { - finishInstallation() + finishInstallation(fusedDownload) Timber.d("===> doWork: Installed/Failed: ${fusedDownload.name} ${fusedDownload.status}") } else -> { - finishInstallation() + finishInstallation(fusedDownload) Log.wtf( TAG, "===> ${fusedDownload.name} is in wrong state ${fusedDownload.status}" @@ -238,7 +261,8 @@ class InstallAppWorker @AssistedInject constructor( } } - private fun finishInstallation() { + private suspend fun finishInstallation(fusedDownload: FusedDownload) { + checkUpdateWork(fusedDownload) isDownloading = false unlockMutex() } diff --git a/app/src/main/java/foundation/e/apps/manager/workmanager/InstallWorkManager.kt b/app/src/main/java/foundation/e/apps/manager/workmanager/InstallWorkManager.kt index fd782aea4cee10d8763fe358aced297daf469e8a..e9a10152b134608efd43bccfe30dde15f396083f 100644 --- a/app/src/main/java/foundation/e/apps/manager/workmanager/InstallWorkManager.kt +++ b/app/src/main/java/foundation/e/apps/manager/workmanager/InstallWorkManager.kt @@ -12,13 +12,14 @@ object InstallWorkManager { const val INSTALL_WORK_NAME = "APP_LOUNGE_INSTALL_APP" lateinit var context: Application - fun enqueueWork(fusedDownload: FusedDownload) { + fun enqueueWork(fusedDownload: FusedDownload, isUpdateWork:Boolean = false) { WorkManager.getInstance(context).enqueueUniqueWork( INSTALL_WORK_NAME, ExistingWorkPolicy.APPEND_OR_REPLACE, OneTimeWorkRequestBuilder().setInputData( Data.Builder() .putString(InstallAppWorker.INPUT_DATA_FUSED_DOWNLOAD, fusedDownload.id) + .putBoolean(InstallAppWorker.IS_UPDATE_WORK, isUpdateWork) .build() ).addTag(fusedDownload.id) .build() diff --git a/app/src/main/java/foundation/e/apps/settings/SettingsFragment.kt b/app/src/main/java/foundation/e/apps/settings/SettingsFragment.kt index 5c56f9b97e692c7e5bdc0d93d9f766a7d335b826..a39a043fc99e91aa13d182758e2f130717f3da10 100644 --- a/app/src/main/java/foundation/e/apps/settings/SettingsFragment.kt +++ b/app/src/main/java/foundation/e/apps/settings/SettingsFragment.kt @@ -90,7 +90,7 @@ class SettingsFragment : PreferenceFragmentCompat() { UpdatesWorkManager.enqueueWork( it, newValue.toString().toLong(), - ExistingPeriodicWorkPolicy.REPLACE + ExistingPeriodicWorkPolicy.KEEP ) } true diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorker.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorker.kt index c9c1076d3a29a583971d31d52e404032fa6c09eb..7ddd47bcda896129d6c187de6a8322fc5b131ed4 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorker.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorker.kt @@ -236,7 +236,7 @@ class UpdatesWorker @AssistedInject constructor( fusedManagerRepository.addDownload(fusedDownload) fusedManagerRepository.updateAwaiting(fusedDownload) Timber.d("startUpdateProcess: Enqueued for update: ${fusedDownload.name} ${fusedDownload.id} ${fusedDownload.status}") - InstallWorkManager.enqueueWork(fusedDownload) + InstallWorkManager.enqueueWork(fusedDownload, true) Timber.d(">>> startUpdateProcess: " + fusedDownload.name) } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 94e9026e73e4f2a883ea2a56a50850be8f2dbaf8..ef12776e3969a58bb95e22ddcf92346333e52efe 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -151,5 +151,4 @@ Die Aktualisierung von %1$s ist aufgrund einer Unterstützungs-Vorschrift (Standort, Betriebssystemversion …) fehlgeschlagen. Aufgrund eines vorübergehenden Fehlers können nicht alle Ihre Anwendungen aktualisiert werden. Bitte versuchen Sie es später noch einmal. Aktualisierungen fehlgeschlagen. Automatische Wiederholungsversuche sind im Gange. - Neueste Aktualisierung ausgelöst %1$s \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index dd4b85a76327dd898634571c10145a8848bed355..bf8b000bc388ff35558e4d98d0004678e63d7a95 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -148,7 +148,6 @@ Mensuelle Hebdomadaire Quotidienne - Dernière mise à jour déclenchée le %1$s La mise à jour de %1$s a échoué à cause d\'une règle de support (localisation, version de l\'OS...). Des échecs temporaires empêchent la mise à jour de certaines applications. Merci de réessayer plus tard. \"Tout mettre à jour\" a échoué. Nouvelles tentatives automatiques en cours. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index ce9fc43414df4d2aedfab8c876bc35fabfeedeab..eab8926bfcb84c9320bf54cf8aae1f826b1f5987 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -148,7 +148,6 @@ Mensile Settimanale Giornaliero - Ultimo aggiornamento effettuato %1$s L\'aggiornamento di %1$s e fallito a causa di una problema di supporto (luogo in cui ti trovi, versione del SO, ...). A causa di problemi temporanei, le tue app non possono essere aggiornate tutte. Riprova più tardi. Aggiorna tutto non ha funzionato. Ulteriori tentativi di aggiornamento in corso. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 44b0740706f7059cdd594b38d95382fc7cf4e946..cef4be51259a6877cd00e193b0d03f45313fa0f2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -153,7 +153,7 @@ App updates will be installed automatically App updates will not be installed automatically Waiting for un-metered network - Last update triggered %1$s + Update of %1$s apps completed on %2$s. No runtime android permission found!