From 9358232137329ccac49812ab60ec87ebf30f22e7 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Tue, 13 Sep 2022 19:51:47 +0600 Subject: [PATCH 1/8] improved behavior of update process --- .../foundation/e/apps/api/fused/MemoryDao.kt | 26 +++++++ .../e/apps/manager/pkg/PkgManagerModule.kt | 2 + .../e/apps/updates/UpdatesNotifier.kt | 2 +- .../updates/manager/UpdatesManagerImpl.kt | 2 + .../manager/UpdatesManagerRepository.kt | 9 ++- .../updates/manager/UpdatesWorkManager.kt | 11 +-- .../e/apps/updates/manager/UpdatesWorker.kt | 68 ++++++++++++++++--- 7 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt diff --git a/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt b/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt new file mode 100644 index 000000000..43d371801 --- /dev/null +++ b/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2022 ECORP + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package foundation.e.apps.api.fused + +import foundation.e.apps.api.fused.data.FusedApp + +object MemoryDao { + var appsAwaitingForUpdate: List = listOf() + + fun hasAnyAppsForUpdate() = appsAwaitingForUpdate.isNotEmpty() +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt b/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt index ad411ac0a..269491f30 100644 --- a/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt +++ b/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt @@ -231,11 +231,13 @@ class PkgManagerModule @Inject constructor( } fun getAllUserApps(): List { + Timber.d("===> getAllUsersapp START ${System.currentTimeMillis()}") val userPackages = mutableListOf() val allPackages = packageManager.getInstalledApplications(0) allPackages.forEach { if (it.flags and ApplicationInfo.FLAG_SYSTEM == 0) userPackages.add(it) } + Timber.d("===> getAllUsersapp END ${System.currentTimeMillis()}") return userPackages } diff --git a/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt b/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt index 2eaa33257..94202b9ac 100644 --- a/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt +++ b/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt @@ -37,7 +37,7 @@ class UpdatesNotifier { private const val UPDATES_NOTIFICATION_CHANNEL_TITLE = "App updates" } - private fun getNotification( + fun getNotification( context: Context, numberOfApps: Int, installAutomatically: Boolean, diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerImpl.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerImpl.kt index ffd48afa1..2768c9416 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerImpl.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerImpl.kt @@ -81,6 +81,8 @@ class UpdatesManagerImpl @Inject constructor( return Pair(nonFaultyUpdateList, status) } + fun getNumberOfAppsNeedUpdate() = pkgManagerModule.getAllUserApps().size + fun getApplicationCategoryPreference(): String { return fusedAPIRepository.getApplicationCategoryPreference() } diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt index dadc807ca..1ec2d8e09 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt @@ -19,6 +19,7 @@ package foundation.e.apps.updates.manager import com.aurora.gplayapi.data.models.AuthData +import foundation.e.apps.api.fused.MemoryDao import foundation.e.apps.api.fused.data.FusedApp import foundation.e.apps.utils.enums.ResultStatus import javax.inject.Inject @@ -27,13 +28,19 @@ class UpdatesManagerRepository @Inject constructor( private val updatesManagerImpl: UpdatesManagerImpl ) { - suspend fun getUpdates(authData: AuthData): Pair, ResultStatus> { + suspend fun getUpdates(authData: AuthData, isFromUpdateProcess: Boolean = false): Pair, ResultStatus> { + if (isFromUpdateProcess && MemoryDao.hasAnyAppsForUpdate()) { + return Pair(MemoryDao.appsAwaitingForUpdate, ResultStatus.OK) + } return updatesManagerImpl.getUpdates(authData).run { val filteredApps = first.filter { !(!it.isFree && authData.isAnonymous) } + MemoryDao.appsAwaitingForUpdate = filteredApps Pair(filteredApps, this.second) } } + fun getNumberOfAppsNeedUpdate() = updatesManagerImpl.getNumberOfAppsNeedUpdate() + fun getApplicationCategoryPreference(): String { return updatesManagerImpl.getApplicationCategoryPreference() } diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt index c70345a09..164f97766 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt @@ -19,13 +19,7 @@ package foundation.e.apps.updates.manager import android.content.Context import android.util.Log -import androidx.work.Constraints -import androidx.work.ExistingPeriodicWorkPolicy -import androidx.work.ExistingWorkPolicy -import androidx.work.NetworkType -import androidx.work.OneTimeWorkRequest -import androidx.work.PeriodicWorkRequest -import androidx.work.WorkManager +import androidx.work.* import java.util.concurrent.TimeUnit object UpdatesWorkManager { @@ -58,7 +52,8 @@ object UpdatesWorkManager { private fun buildOneTimeWorkRequest(): OneTimeWorkRequest { return OneTimeWorkRequest.Builder(UpdatesWorker::class.java).apply { setConstraints(buildWorkerConstraints()) - }.build() + }.setInputData(Data.Builder().putBoolean(UpdatesWorker.IS_AUTO_UPDATE, false).build()) + .build() } fun enqueueWork( 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 46597fee6..33bd6dfa2 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 @@ -1,16 +1,21 @@ package foundation.e.apps.updates.manager import android.Manifest +import android.app.NotificationChannel +import android.app.NotificationManager import android.content.Context import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.ConnectivityManager import android.net.NetworkCapabilities +import android.os.Build import android.util.Base64 import androidx.hilt.work.HiltWorker import androidx.preference.PreferenceManager import androidx.work.CoroutineWorker +import androidx.work.ForegroundInfo +import androidx.work.WorkManager import androidx.work.WorkerParameters import com.aurora.gplayapi.data.models.AuthData import com.google.gson.Gson @@ -30,24 +35,33 @@ import foundation.e.apps.utils.modules.DataStoreModule import timber.log.Timber import java.io.ByteArrayOutputStream import java.net.URL +import java.util.concurrent.atomic.AtomicInteger @HiltWorker class UpdatesWorker @AssistedInject constructor( @Assisted private val context: Context, - @Assisted params: WorkerParameters, + @Assisted private val params: WorkerParameters, private val updatesManagerRepository: UpdatesManagerRepository, private val fusedAPIRepository: FusedAPIRepository, private val fusedManagerRepository: FusedManagerRepository, private val dataStoreModule: DataStoreModule, private val gson: Gson, ) : CoroutineWorker(context, params) { + + companion object { + const val IS_AUTO_UPDATE = "IS_AUTO_UPDATE" + private val atomicInteger = AtomicInteger(100) + } + val TAG = UpdatesWorker::class.simpleName private var shouldShowNotification = true private var automaticInstallEnabled = true private var onlyOnUnmeteredNetwork = false + private var isAutoUpdate = true override suspend fun doWork(): Result { return try { + isAutoUpdate = params.inputData.getBoolean(IS_AUTO_UPDATE, true) checkForUpdates() Result.success() } catch (e: Throwable) { @@ -57,16 +71,19 @@ class UpdatesWorker @AssistedInject constructor( private suspend fun checkForUpdates() { loadSettings() - val authData = getAuthData() - val appsNeededToUpdate = updatesManagerRepository.getUpdates(authData).first + val numberOfAppNeedUpdate = updatesManagerRepository.getNumberOfAppsNeedUpdate() val isConnectedToUnmeteredNetwork = isConnectedToUnmeteredNetwork(applicationContext) /* * Show notification only if enabled. * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5376 */ - if (shouldShowNotification) { - handleNotification(appsNeededToUpdate, isConnectedToUnmeteredNetwork) + if (shouldShowNotification && !automaticInstallEnabled && isAutoUpdate) { + handleNotification(numberOfAppNeedUpdate, isConnectedToUnmeteredNetwork) + } else if (!isAutoUpdate || automaticInstallEnabled) { + setForeground(createForegroundInfo(numberOfAppNeedUpdate, isConnectedToUnmeteredNetwork)) } + val authData = getAuthData() + val appsNeededToUpdate = updatesManagerRepository.getUpdates(authData, true).first triggerUpdateProcessOnSettings( isConnectedToUnmeteredNetwork, appsNeededToUpdate, @@ -74,12 +91,45 @@ class UpdatesWorker @AssistedInject constructor( ) } + private fun createForegroundInfo( + numberOfApps: Int, + isConnectedToUnmeteredNetwork: Boolean + ): ForegroundInfo { + val title = applicationContext.getString(R.string.app_name) + val cancel = applicationContext.getString(R.string.cancel) + // This PendingIntent can be used to cancel the worker + val intent = WorkManager.getInstance(applicationContext) + .createCancelPendingIntent(getId()) + + val notificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as + NotificationManager + // Create a Notification channel if necessary + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val mChannel = NotificationChannel( + "applounge_notification", + title, + NotificationManager.IMPORTANCE_LOW + ) + notificationManager.createNotificationChannel(mChannel) + } + + val notification = UpdatesNotifier().getNotification( + context, + numberOfApps, + automaticInstallEnabled, + onlyOnUnmeteredNetwork, + isConnectedToUnmeteredNetwork + ) + return ForegroundInfo(atomicInteger.getAndIncrement(), notification) + } + private suspend fun triggerUpdateProcessOnSettings( isConnectedToUnmeteredNetwork: Boolean, appsNeededToUpdate: List, authData: AuthData ) { - if (automaticInstallEnabled && + if ((!isAutoUpdate || automaticInstallEnabled) && applicationContext.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED ) { if (onlyOnUnmeteredNetwork && isConnectedToUnmeteredNetwork) { @@ -91,13 +141,13 @@ class UpdatesWorker @AssistedInject constructor( } private fun handleNotification( - appsNeededToUpdate: List, + numberOfAppsNeedUpdate: Int, isConnectedToUnmeteredNetwork: Boolean ) { - if (appsNeededToUpdate.isNotEmpty()) { + if (numberOfAppsNeedUpdate > 0) { UpdatesNotifier().showNotification( applicationContext, - appsNeededToUpdate.size, + numberOfAppsNeedUpdate, automaticInstallEnabled, onlyOnUnmeteredNetwork, isConnectedToUnmeteredNetwork -- GitLab From be7b7aebdbd294a5ee9ce6eaa5d9cf75d8c1cf21 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Thu, 15 Sep 2022 18:39:11 +0600 Subject: [PATCH 2/8] improved update behavior for all-update click --- .../foundation/e/apps/api/fused/MemoryDao.kt | 6 +-- .../e/apps/manager/pkg/PkgManagerModule.kt | 16 +++++--- .../e/apps/updates/UpdatesNotifier.kt | 37 ++++++++++++------- .../updates/manager/UpdatesManagerImpl.kt | 6 +-- .../manager/UpdatesManagerRepository.kt | 2 - .../updates/manager/UpdatesWorkManager.kt | 11 +++++- .../e/apps/updates/manager/UpdatesWorker.kt | 37 ++++++++++++------- .../e/apps/util/LiveDataTestUtil.kt | 2 - 8 files changed, 72 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt b/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt index 43d371801..fda1143d1 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt @@ -20,7 +20,7 @@ package foundation.e.apps.api.fused import foundation.e.apps.api.fused.data.FusedApp object MemoryDao { - var appsAwaitingForUpdate: List = listOf() + var appsAwaitingForUpdate: List = listOf() - fun hasAnyAppsForUpdate() = appsAwaitingForUpdate.isNotEmpty() -} \ No newline at end of file + fun hasAnyAppsForUpdate() = appsAwaitingForUpdate.isNotEmpty() +} diff --git a/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt b/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt index 269491f30..e3ef5a64b 100644 --- a/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt +++ b/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt @@ -50,6 +50,7 @@ class PkgManagerModule @Inject constructor( companion object { const val ERROR_PACKAGE_INSTALL = "ERROR_PACKAGE_INSTALL" const val PACKAGE_NAME = "packageName" + const val FAKE_STORE_PACKAGE_NAME = "com.android.vending" private const val TAG = "PkgManagerModule" } private val packageManager = context.packageManager @@ -115,12 +116,11 @@ class PkgManagerModule @Inject constructor( return } if (fusedDownload.origin == Origin.GPLAY) { - val fakeStorePackageName = "com.android.vending" - if (fusedDownload.type == Type.NATIVE && isInstalled(fakeStorePackageName)) { + if (fusedDownload.type == Type.NATIVE && isInstalled(FAKE_STORE_PACKAGE_NAME)) { val targetPackage = fusedDownload.packageName try { - packageManager.setInstallerPackageName(targetPackage, fakeStorePackageName) - Timber.d("Changed installer to $fakeStorePackageName for $targetPackage") + packageManager.setInstallerPackageName(targetPackage, FAKE_STORE_PACKAGE_NAME) + Timber.d("Changed installer to $FAKE_STORE_PACKAGE_NAME for $targetPackage") } catch (e: Exception) { e.printStackTrace() } @@ -231,16 +231,20 @@ class PkgManagerModule @Inject constructor( } fun getAllUserApps(): List { - Timber.d("===> getAllUsersapp START ${System.currentTimeMillis()}") val userPackages = mutableListOf() val allPackages = packageManager.getInstalledApplications(0) allPackages.forEach { if (it.flags and ApplicationInfo.FLAG_SYSTEM == 0) userPackages.add(it) } - Timber.d("===> getAllUsersapp END ${System.currentTimeMillis()}") return userPackages } + fun isGplay(packageName: String): Boolean { + val installerPackageName = packageManager.getInstallerPackageName(packageName) + Timber.d("===> installer package name for $packageName : $installerPackageName") + return installerPackageName?.contains(FAKE_STORE_PACKAGE_NAME) == true + } + fun getAllSystemApps(): List { return packageManager.getInstalledApplications(PackageManager.MATCH_SYSTEM_ONLY) } diff --git a/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt b/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt index 94202b9ac..c15927bce 100644 --- a/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt +++ b/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt @@ -48,22 +48,31 @@ class UpdatesNotifier { NotificationCompat.Builder(context, UPDATES_NOTIFICATION_CHANNEL_ID) notificationBuilder.setSmallIcon(R.drawable.ic_app_updated_on) notificationBuilder.priority = NotificationCompat.PRIORITY_DEFAULT - if (numberOfApps == 1) { - notificationBuilder.setContentTitle( - context.resources.getQuantityString( - R.plurals.updates_notification_title, - 1, - numberOfApps + + when (numberOfApps) { + 0 -> { + notificationBuilder.setContentTitle( + "Checking Updates..." ) - ) - } else { - notificationBuilder.setContentTitle( - context.resources.getQuantityString( - R.plurals.updates_notification_title, - numberOfApps, - numberOfApps + } + 1 -> { + notificationBuilder.setContentTitle( + context.resources.getQuantityString( + R.plurals.updates_notification_title, + 1, + numberOfApps + ) ) - ) + } + else -> { + notificationBuilder.setContentTitle( + context.resources.getQuantityString( + R.plurals.updates_notification_title, + numberOfApps, + numberOfApps + ) + ) + } } if (installAutomatically) { notificationBuilder.setContentText(context.getString(R.string.automatically_install_updates_notification_text)) diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerImpl.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerImpl.kt index 2768c9416..5fd534f7a 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerImpl.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerImpl.kt @@ -47,8 +47,10 @@ class UpdatesManagerImpl @Inject constructor( if (pkgList.isNotEmpty()) { // Get updates from CleanAPK + val openSourcePackages = userApplications.filter { !pkgManagerModule.isGplay(it.packageName) }.map { it.packageName } + pkgList.removeAll(openSourcePackages) val cleanAPKResult = fusedAPIRepository.getApplicationDetails( - pkgList, + openSourcePackages, authData, Origin.CLEANAPK ) @@ -81,8 +83,6 @@ class UpdatesManagerImpl @Inject constructor( return Pair(nonFaultyUpdateList, status) } - fun getNumberOfAppsNeedUpdate() = pkgManagerModule.getAllUserApps().size - fun getApplicationCategoryPreference(): String { return fusedAPIRepository.getApplicationCategoryPreference() } diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt index 1ec2d8e09..9bbe46fc3 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt @@ -39,8 +39,6 @@ class UpdatesManagerRepository @Inject constructor( } } - fun getNumberOfAppsNeedUpdate() = updatesManagerImpl.getNumberOfAppsNeedUpdate() - fun getApplicationCategoryPreference(): String { return updatesManagerImpl.getApplicationCategoryPreference() } diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt index 164f97766..fa44293ce 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt @@ -19,7 +19,14 @@ package foundation.e.apps.updates.manager import android.content.Context import android.util.Log -import androidx.work.* +import androidx.work.Constraints +import androidx.work.Data +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.ExistingWorkPolicy +import androidx.work.NetworkType +import androidx.work.OneTimeWorkRequest +import androidx.work.PeriodicWorkRequest +import androidx.work.WorkManager import java.util.concurrent.TimeUnit object UpdatesWorkManager { @@ -43,7 +50,7 @@ object UpdatesWorkManager { return PeriodicWorkRequest.Builder( UpdatesWorker::class.java, interval, - TimeUnit.HOURS + TimeUnit.MINUTES ).apply { setConstraints(buildWorkerConstraints()) }.build() 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 33bd6dfa2..041ffe59f 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 @@ -1,6 +1,7 @@ package foundation.e.apps.updates.manager import android.Manifest +import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context @@ -57,7 +58,7 @@ class UpdatesWorker @AssistedInject constructor( private var shouldShowNotification = true private var automaticInstallEnabled = true private var onlyOnUnmeteredNetwork = false - private var isAutoUpdate = true + private var isAutoUpdate = true // indicates it is auto update or user initiated update override suspend fun doWork(): Result { return try { @@ -71,19 +72,21 @@ class UpdatesWorker @AssistedInject constructor( private suspend fun checkForUpdates() { loadSettings() - val numberOfAppNeedUpdate = updatesManagerRepository.getNumberOfAppsNeedUpdate() val isConnectedToUnmeteredNetwork = isConnectedToUnmeteredNetwork(applicationContext) - /* - * Show notification only if enabled. - * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5376 - */ - if (shouldShowNotification && !automaticInstallEnabled && isAutoUpdate) { - handleNotification(numberOfAppNeedUpdate, isConnectedToUnmeteredNetwork) - } else if (!isAutoUpdate || automaticInstallEnabled) { - setForeground(createForegroundInfo(numberOfAppNeedUpdate, isConnectedToUnmeteredNetwork)) + if (isAutoUpdate) { // running in foreground for autoupdate because we need to fetch update info that will take time + setForeground(createForegroundInfo(0, isConnectedToUnmeteredNetwork)) } + val authData = getAuthData() val appsNeededToUpdate = updatesManagerRepository.getUpdates(authData, true).first + if (shouldShowNotification && !automaticInstallEnabled && isAutoUpdate) { + handleNotification(appsNeededToUpdate.size, isConnectedToUnmeteredNetwork) + return + } + + if (!isAutoUpdate || automaticInstallEnabled) { + setForeground(createForegroundInfo(appsNeededToUpdate.size, isConnectedToUnmeteredNetwork)) + } triggerUpdateProcessOnSettings( isConnectedToUnmeteredNetwork, appsNeededToUpdate, @@ -93,7 +96,7 @@ class UpdatesWorker @AssistedInject constructor( private fun createForegroundInfo( numberOfApps: Int, - isConnectedToUnmeteredNetwork: Boolean + isConnectedToUnmeteredNetwork: Boolean, ): ForegroundInfo { val title = applicationContext.getString(R.string.app_name) val cancel = applicationContext.getString(R.string.cancel) @@ -103,7 +106,7 @@ class UpdatesWorker @AssistedInject constructor( val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as - NotificationManager + NotificationManager // Create a Notification channel if necessary if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val mChannel = NotificationChannel( @@ -114,6 +117,14 @@ class UpdatesWorker @AssistedInject constructor( notificationManager.createNotificationChannel(mChannel) } + val notification = getNotificationForForeground(numberOfApps, isConnectedToUnmeteredNetwork) + return ForegroundInfo(atomicInteger.getAndIncrement(), notification) + } + + private fun getNotificationForForeground( + numberOfApps: Int, + isConnectedToUnmeteredNetwork: Boolean + ): Notification { val notification = UpdatesNotifier().getNotification( context, numberOfApps, @@ -121,7 +132,7 @@ class UpdatesWorker @AssistedInject constructor( onlyOnUnmeteredNetwork, isConnectedToUnmeteredNetwork ) - return ForegroundInfo(atomicInteger.getAndIncrement(), notification) + return notification } private suspend fun triggerUpdateProcessOnSettings( diff --git a/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt b/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt index 679cc04e2..58e478c34 100644 --- a/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt +++ b/app/src/test/java/foundation/e/apps/util/LiveDataTestUtil.kt @@ -20,8 +20,6 @@ package foundation.e.apps.util import androidx.lifecycle.LiveData import androidx.lifecycle.Observer import kotlinx.coroutines.delay -import java.util.concurrent.CountDownLatch -import java.util.concurrent.TimeUnit /** * Gets the value of a [LiveData] or waits for it to have one, with a timeout. -- GitLab From 5dd075c532cd0f33583146d9f34e44386229aabb Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Sat, 17 Sep 2022 10:22:31 +0600 Subject: [PATCH 3/8] Update worker failure case is handled --- .../e/apps/manager/pkg/PkgManagerModule.kt | 1 - .../e/apps/updates/UpdatesFragment.kt | 16 ++++- .../e/apps/updates/UpdatesNotifier.kt | 18 +++-- .../manager/UpdatesManagerRepository.kt | 4 +- .../updates/manager/UpdatesWorkManager.kt | 7 +- .../e/apps/updates/manager/UpdatesWorker.kt | 67 ++----------------- 6 files changed, 41 insertions(+), 72 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt b/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt index e3ef5a64b..7d00c04b4 100644 --- a/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt +++ b/app/src/main/java/foundation/e/apps/manager/pkg/PkgManagerModule.kt @@ -241,7 +241,6 @@ class PkgManagerModule @Inject constructor( fun isGplay(packageName: String): Boolean { val installerPackageName = packageManager.getInstallerPackageName(packageName) - Timber.d("===> installer package name for $packageName : $installerPackageName") return installerPackageName?.contains(FAKE_STORE_PACKAGE_NAME) == true } diff --git a/app/src/main/java/foundation/e/apps/updates/UpdatesFragment.kt b/app/src/main/java/foundation/e/apps/updates/UpdatesFragment.kt index 5e8d1a100..c94ec8b36 100644 --- a/app/src/main/java/foundation/e/apps/updates/UpdatesFragment.kt +++ b/app/src/main/java/foundation/e/apps/updates/UpdatesFragment.kt @@ -28,6 +28,7 @@ import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.work.WorkInfo import androidx.work.WorkManager import com.aurora.gplayapi.data.models.AuthData import dagger.hilt.android.AndroidEntryPoint @@ -199,7 +200,20 @@ class UpdatesFragment : TimeoutFragment(R.layout.fragment_updates), FusedAPIInte showLoadingUI() updatesViewModel.getUpdates(authData) binding.button.setOnClickListener { - UpdatesWorkManager.startUpdateAllWork(requireContext().applicationContext) + val id = UpdatesWorkManager.startUpdateAllWork(requireContext().applicationContext) + WorkManager.getInstance(requireContext()) + .getWorkInfosByTagLiveData(UpdatesWorkManager.UPDATES_WORK_NAME) + .observe(viewLifecycleOwner) { + val errorStates = + listOf( + WorkInfo.State.FAILED, + WorkInfo.State.BLOCKED, + WorkInfo.State.CANCELLED + ) + if (!it.isNullOrEmpty() && errorStates.contains(it.last().state)) { + binding.button.isEnabled = true + } + } binding.button.isEnabled = false } } diff --git a/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt b/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt index c15927bce..61a5116eb 100644 --- a/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt +++ b/app/src/main/java/foundation/e/apps/updates/UpdatesNotifier.kt @@ -29,13 +29,11 @@ import androidx.core.app.NotificationManagerCompat import foundation.e.apps.MainActivity import foundation.e.apps.R -class UpdatesNotifier { - companion object { - const val UPDATES_NOTIFICATION_CLICK_EXTRA = "updates_notification_click_extra" - private const val UPDATES_NOTIFICATION_ID = 76 - private const val UPDATES_NOTIFICATION_CHANNEL_ID = "updates_notification" - private const val UPDATES_NOTIFICATION_CHANNEL_TITLE = "App updates" - } +object UpdatesNotifier { + const val UPDATES_NOTIFICATION_CLICK_EXTRA = "updates_notification_click_extra" + private const val UPDATES_NOTIFICATION_ID = 76 + private const val UPDATES_NOTIFICATION_CHANNEL_ID = "updates_notification" + private const val UPDATES_NOTIFICATION_CHANNEL_TITLE = "App updates" fun getNotification( context: Context, @@ -133,4 +131,10 @@ class UpdatesNotifier { ) } } + + fun cancelNotification(context: Context) { + val notificationManager: NotificationManager = + context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.cancel(UPDATES_NOTIFICATION_ID) + } } diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt index 9bbe46fc3..b16010c05 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt @@ -28,8 +28,8 @@ class UpdatesManagerRepository @Inject constructor( private val updatesManagerImpl: UpdatesManagerImpl ) { - suspend fun getUpdates(authData: AuthData, isFromUpdateProcess: Boolean = false): Pair, ResultStatus> { - if (isFromUpdateProcess && MemoryDao.hasAnyAppsForUpdate()) { + suspend fun getUpdates(authData: AuthData): Pair, ResultStatus> { + if (MemoryDao.hasAnyAppsForUpdate()) { return Pair(MemoryDao.appsAwaitingForUpdate, ResultStatus.OK) } return updatesManagerImpl.getUpdates(authData).run { diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt index fa44293ce..6e650ac39 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt @@ -27,18 +27,21 @@ import androidx.work.NetworkType import androidx.work.OneTimeWorkRequest import androidx.work.PeriodicWorkRequest import androidx.work.WorkManager +import java.util.UUID import java.util.concurrent.TimeUnit object UpdatesWorkManager { const val UPDATES_WORK_NAME = "updates_work" private const val TAG = "UpdatesManager" - fun startUpdateAllWork(context: Context) { + fun startUpdateAllWork(context: Context): UUID { + val oneTimeWorkRequest = buildOneTimeWorkRequest() WorkManager.getInstance(context).enqueueUniqueWork( UPDATES_WORK_NAME, ExistingWorkPolicy.REPLACE, buildOneTimeWorkRequest() ) + return oneTimeWorkRequest.id } private fun buildWorkerConstraints() = Constraints.Builder().apply { @@ -53,12 +56,14 @@ object UpdatesWorkManager { TimeUnit.MINUTES ).apply { setConstraints(buildWorkerConstraints()) + addTag(TAG) }.build() } private fun buildOneTimeWorkRequest(): OneTimeWorkRequest { return OneTimeWorkRequest.Builder(UpdatesWorker::class.java).apply { setConstraints(buildWorkerConstraints()) + addTag(UPDATES_WORK_NAME) }.setInputData(Data.Builder().putBoolean(UpdatesWorker.IS_AUTO_UPDATE, false).build()) .build() } 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 041ffe59f..163a301b5 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 @@ -1,22 +1,16 @@ package foundation.e.apps.updates.manager import android.Manifest -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager import android.content.Context import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.ConnectivityManager import android.net.NetworkCapabilities -import android.os.Build import android.util.Base64 import androidx.hilt.work.HiltWorker import androidx.preference.PreferenceManager import androidx.work.CoroutineWorker -import androidx.work.ForegroundInfo -import androidx.work.WorkManager import androidx.work.WorkerParameters import com.aurora.gplayapi.data.models.AuthData import com.google.gson.Gson @@ -36,7 +30,6 @@ import foundation.e.apps.utils.modules.DataStoreModule import timber.log.Timber import java.io.ByteArrayOutputStream import java.net.URL -import java.util.concurrent.atomic.AtomicInteger @HiltWorker class UpdatesWorker @AssistedInject constructor( @@ -51,7 +44,6 @@ class UpdatesWorker @AssistedInject constructor( companion object { const val IS_AUTO_UPDATE = "IS_AUTO_UPDATE" - private val atomicInteger = AtomicInteger(100) } val TAG = UpdatesWorker::class.simpleName @@ -67,26 +59,22 @@ class UpdatesWorker @AssistedInject constructor( Result.success() } catch (e: Throwable) { Result.failure() + } finally { + if (shouldShowNotification && automaticInstallEnabled) { + UpdatesNotifier.cancelNotification(context) + } } } private suspend fun checkForUpdates() { loadSettings() val isConnectedToUnmeteredNetwork = isConnectedToUnmeteredNetwork(applicationContext) - if (isAutoUpdate) { // running in foreground for autoupdate because we need to fetch update info that will take time - setForeground(createForegroundInfo(0, isConnectedToUnmeteredNetwork)) - } - val authData = getAuthData() - val appsNeededToUpdate = updatesManagerRepository.getUpdates(authData, true).first - if (shouldShowNotification && !automaticInstallEnabled && isAutoUpdate) { + val appsNeededToUpdate = updatesManagerRepository.getUpdates(authData).first + if (shouldShowNotification) { handleNotification(appsNeededToUpdate.size, isConnectedToUnmeteredNetwork) - return } - if (!isAutoUpdate || automaticInstallEnabled) { - setForeground(createForegroundInfo(appsNeededToUpdate.size, isConnectedToUnmeteredNetwork)) - } triggerUpdateProcessOnSettings( isConnectedToUnmeteredNetwork, appsNeededToUpdate, @@ -94,47 +82,6 @@ class UpdatesWorker @AssistedInject constructor( ) } - private fun createForegroundInfo( - numberOfApps: Int, - isConnectedToUnmeteredNetwork: Boolean, - ): ForegroundInfo { - val title = applicationContext.getString(R.string.app_name) - val cancel = applicationContext.getString(R.string.cancel) - // This PendingIntent can be used to cancel the worker - val intent = WorkManager.getInstance(applicationContext) - .createCancelPendingIntent(getId()) - - val notificationManager = - context.getSystemService(Context.NOTIFICATION_SERVICE) as - NotificationManager - // Create a Notification channel if necessary - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val mChannel = NotificationChannel( - "applounge_notification", - title, - NotificationManager.IMPORTANCE_LOW - ) - notificationManager.createNotificationChannel(mChannel) - } - - val notification = getNotificationForForeground(numberOfApps, isConnectedToUnmeteredNetwork) - return ForegroundInfo(atomicInteger.getAndIncrement(), notification) - } - - private fun getNotificationForForeground( - numberOfApps: Int, - isConnectedToUnmeteredNetwork: Boolean - ): Notification { - val notification = UpdatesNotifier().getNotification( - context, - numberOfApps, - automaticInstallEnabled, - onlyOnUnmeteredNetwork, - isConnectedToUnmeteredNetwork - ) - return notification - } - private suspend fun triggerUpdateProcessOnSettings( isConnectedToUnmeteredNetwork: Boolean, appsNeededToUpdate: List, @@ -156,7 +103,7 @@ class UpdatesWorker @AssistedInject constructor( isConnectedToUnmeteredNetwork: Boolean ) { if (numberOfAppsNeedUpdate > 0) { - UpdatesNotifier().showNotification( + UpdatesNotifier.showNotification( applicationContext, numberOfAppsNeedUpdate, automaticInstallEnabled, -- GitLab From f29de8f00fa7deb9bda44f1c2003c484c05b6f59 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Wed, 28 Sep 2022 21:25:08 +0600 Subject: [PATCH 4/8] validation added for already running install process --- .../e/apps/MainActivityViewModel.kt | 1 + .../e/apps/manager/fused/FusedManagerImpl.kt | 4 +++ .../manager/fused/FusedManagerRepository.kt | 12 +++++++ .../e/apps/updates/UpdatesFragment.kt | 32 +++++++++++-------- .../updates/manager/UpdatesWorkManager.kt | 2 +- .../utils/modules/CommonUtilsFunctions.kt | 17 ++++++++++ 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/MainActivityViewModel.kt b/app/src/main/java/foundation/e/apps/MainActivityViewModel.kt index 875997773..373c5903e 100644 --- a/app/src/main/java/foundation/e/apps/MainActivityViewModel.kt +++ b/app/src/main/java/foundation/e/apps/MainActivityViewModel.kt @@ -478,6 +478,7 @@ class MainActivityViewModel @Inject constructor( if (shouldShowPaidAppsSnackBar(app)) { return } + viewModelScope.launch { val fusedDownload: FusedDownload try { diff --git a/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerImpl.kt b/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerImpl.kt index ece25c8b6..ed576ff67 100644 --- a/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerImpl.kt +++ b/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerImpl.kt @@ -74,6 +74,10 @@ class FusedManagerImpl @Inject constructor( databaseRepository.addDownload(fusedDownload) } + suspend fun getDownloadById(fusedDownload: FusedDownload): FusedDownload? { + return databaseRepository.getDownloadById(fusedDownload.id) + } + suspend fun getDownloadList(): List { return databaseRepository.getDownloadList() } diff --git a/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerRepository.kt b/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerRepository.kt index e6ffa4627..1f21ebc37 100644 --- a/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerRepository.kt +++ b/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerRepository.kt @@ -9,7 +9,9 @@ import foundation.e.apps.api.fdroid.FdroidRepository import foundation.e.apps.api.fused.data.FusedApp import foundation.e.apps.manager.database.fusedDownload.FusedDownload import foundation.e.apps.manager.download.data.DownloadProgress +import foundation.e.apps.manager.workmanager.InstallWorkManager import foundation.e.apps.utils.enums.Status +import foundation.e.apps.utils.modules.CommonUtilsFunctions import kotlinx.coroutines.flow.Flow import javax.inject.Inject import javax.inject.Singleton @@ -34,6 +36,16 @@ class FusedManagerRepository @Inject constructor( } suspend fun addDownload(fusedDownload: FusedDownload) { + if (CommonUtilsFunctions.checkWorkIsAlreadyAvailable(InstallWorkManager.context, fusedDownload.id)) { + return + } + + val existingFusedDownload = fusedManagerImpl.getDownloadById(fusedDownload) + // We don't want to add any thing, if it already exists without INSTALLATION_ISSUE + if (existingFusedDownload != null && existingFusedDownload.status != Status.INSTALLATION_ISSUE) { + return + } + return fusedManagerImpl.addDownload(fusedDownload) } diff --git a/app/src/main/java/foundation/e/apps/updates/UpdatesFragment.kt b/app/src/main/java/foundation/e/apps/updates/UpdatesFragment.kt index c94ec8b36..aae5bb2b8 100644 --- a/app/src/main/java/foundation/e/apps/updates/UpdatesFragment.kt +++ b/app/src/main/java/foundation/e/apps/updates/UpdatesFragment.kt @@ -200,24 +200,28 @@ class UpdatesFragment : TimeoutFragment(R.layout.fragment_updates), FusedAPIInte showLoadingUI() updatesViewModel.getUpdates(authData) binding.button.setOnClickListener { - val id = UpdatesWorkManager.startUpdateAllWork(requireContext().applicationContext) - WorkManager.getInstance(requireContext()) - .getWorkInfosByTagLiveData(UpdatesWorkManager.UPDATES_WORK_NAME) - .observe(viewLifecycleOwner) { - val errorStates = - listOf( - WorkInfo.State.FAILED, - WorkInfo.State.BLOCKED, - WorkInfo.State.CANCELLED - ) - if (!it.isNullOrEmpty() && errorStates.contains(it.last().state)) { - binding.button.isEnabled = true - } - } + UpdatesWorkManager.startUpdateAllWork(requireContext().applicationContext) + observeUpdateWork() binding.button.isEnabled = false } } + private fun observeUpdateWork() { + WorkManager.getInstance(requireContext()) + .getWorkInfosByTagLiveData(UpdatesWorkManager.UPDATES_WORK_NAME) + .observe(viewLifecycleOwner) { + val errorStates = + listOf( + WorkInfo.State.FAILED, + WorkInfo.State.BLOCKED, + WorkInfo.State.CANCELLED + ) + if (!it.isNullOrEmpty() && errorStates.contains(it.last().state)) { + binding.button.isEnabled = true + } + } + } + private fun showLoadingUI() { binding.button.isEnabled = false binding.noUpdates.visibility = View.GONE diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt index 6e650ac39..f237e51c6 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesWorkManager.kt @@ -53,7 +53,7 @@ object UpdatesWorkManager { return PeriodicWorkRequest.Builder( UpdatesWorker::class.java, interval, - TimeUnit.MINUTES + TimeUnit.HOURS ).apply { setConstraints(buildWorkerConstraints()) addTag(TAG) diff --git a/app/src/main/java/foundation/e/apps/utils/modules/CommonUtilsFunctions.kt b/app/src/main/java/foundation/e/apps/utils/modules/CommonUtilsFunctions.kt index e31a5efcd..e3f55ccd6 100644 --- a/app/src/main/java/foundation/e/apps/utils/modules/CommonUtilsFunctions.kt +++ b/app/src/main/java/foundation/e/apps/utils/modules/CommonUtilsFunctions.kt @@ -20,6 +20,9 @@ package foundation.e.apps.utils.modules import android.annotation.SuppressLint import android.content.ClipData import android.content.ClipboardManager +import android.content.Context +import androidx.work.WorkManager +import java.lang.Exception object CommonUtilsFunctions { @@ -48,4 +51,18 @@ object CommonUtilsFunctions { } return value } + + fun checkWorkIsAlreadyAvailable(context: Context, tag: String): Boolean { + val works = WorkManager.getInstance(context).getWorkInfosByTag(tag) + try { + works.get().forEach { + if (it.tags.contains(tag) && !it.state.isFinished) { + return true + } + } + } catch (e: Exception) { + e.printStackTrace() + } + return false + } } -- GitLab From a344da7d172f9a9110a598a2c548c6de5da0c6b5 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Sat, 1 Oct 2022 09:12:25 +0600 Subject: [PATCH 5/8] fixed crash in signature validation when download is failed --- .../foundation/e/apps/api/DownloadManager.kt | 23 ++++++++++++- .../apps/api/cleanapk/ApkSignatureManager.kt | 15 ++++++--- .../manager/download/DownloadManagerUtils.kt | 33 +++++++++++++++---- .../e/apps/updates/manager/UpdatesWorker.kt | 2 +- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/api/DownloadManager.kt b/app/src/main/java/foundation/e/apps/api/DownloadManager.kt index 850c0acb1..755219722 100644 --- a/app/src/main/java/foundation/e/apps/api/DownloadManager.kt +++ b/app/src/main/java/foundation/e/apps/api/DownloadManager.kt @@ -127,11 +127,32 @@ class DownloadManager @Inject constructor( } } - private fun tickerFlow(downloadId: Long, period: Duration, initialDelay: Duration = Duration.ZERO) = flow { + private fun tickerFlow( + downloadId: Long, + period: Duration, + initialDelay: Duration = Duration.ZERO + ) = flow { delay(initialDelay) while (downloadsMaps[downloadId]!!) { emit(Unit) delay(period) } } + + fun getDownloadStatus(downloadId: Long): Int { + try { + downloadManager.query(downloadManagerQuery.setFilterById(downloadId)) + .use { cursor -> + if (cursor.moveToFirst()) { + val status = + cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)) + Timber.d("Download Failed: downloadId: $downloadId $status") + return status + } + } + } catch (e: Exception) { + e.printStackTrace() + } + return DownloadManager.STATUS_FAILED + } } diff --git a/app/src/main/java/foundation/e/apps/api/cleanapk/ApkSignatureManager.kt b/app/src/main/java/foundation/e/apps/api/cleanapk/ApkSignatureManager.kt index f9bd54436..78117f03d 100644 --- a/app/src/main/java/foundation/e/apps/api/cleanapk/ApkSignatureManager.kt +++ b/app/src/main/java/foundation/e/apps/api/cleanapk/ApkSignatureManager.kt @@ -35,11 +35,16 @@ import java.security.Security object ApkSignatureManager { fun verifyFdroidSignature(context: Context, apkFilePath: String, signature: String): Boolean { Security.addProvider(BouncyCastleProvider()) - return verifyAPKSignature( - BufferedInputStream(FileInputStream(apkFilePath)), - signature.byteInputStream(Charsets.UTF_8), - context.assets.open("f-droid.org-signing-key.gpg") - ) + try { + return verifyAPKSignature( + BufferedInputStream(FileInputStream(apkFilePath)), + signature.byteInputStream(Charsets.UTF_8), + context.assets.open("f-droid.org-signing-key.gpg") + ) + } catch (e: Exception) { + e.printStackTrace() + } + return false } private fun verifyAPKSignature( diff --git a/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt b/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt index c5a949a87..8d7b2ca4b 100644 --- a/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt +++ b/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt @@ -20,6 +20,7 @@ package foundation.e.apps.manager.download import android.content.Context import dagger.hilt.android.qualifiers.ApplicationContext +import foundation.e.apps.api.DownloadManager import foundation.e.apps.manager.database.fusedDownload.FusedDownload import foundation.e.apps.manager.fused.FusedManagerRepository import foundation.e.apps.utils.enums.Origin @@ -33,11 +34,13 @@ import kotlinx.coroutines.sync.withLock import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton +import android.app.DownloadManager as androidDownloadManager @Singleton class DownloadManagerUtils @Inject constructor( + @ApplicationContext private val context: Context, private val fusedManagerRepository: FusedManagerRepository, - @ApplicationContext private val context: Context + private val downloadManager: DownloadManager ) { private val TAG = DownloadManagerUtils::class.java.simpleName private val mutex = Mutex() @@ -57,11 +60,12 @@ class DownloadManagerUtils @Inject constructor( delay(1500) // Waiting for downloadmanager to publish the progress of last bytes val fusedDownload = fusedManagerRepository.getFusedDownload(downloadId) if (fusedDownload.id.isNotEmpty()) { - fusedDownload.downloadIdMap[downloadId] = true - fusedManagerRepository.updateFusedDownload(fusedDownload) - val downloaded = fusedDownload.downloadIdMap.values.filter { it }.size - Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $downloaded/${fusedDownload.downloadIdMap.size}") - if (downloaded == fusedDownload.downloadIdMap.size && checkCleanApkSignatureOK(fusedDownload)) { + updateDownloadIdMap(fusedDownload, downloadId) + val numberOfDownloadedItems = + fusedDownload.downloadIdMap.values.filter { it }.size + Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $numberOfDownloadedItems/${fusedDownload.downloadIdMap.size}") + if (validateDownload(numberOfDownloadedItems, fusedDownload, downloadId)) { + Timber.d("===> Download is completed for: ${fusedDownload.name}") fusedManagerRepository.moveOBBFileToOBBDirectory(fusedDownload) fusedDownload.status = Status.DOWNLOADED fusedManagerRepository.updateFusedDownload(fusedDownload) @@ -71,6 +75,23 @@ class DownloadManagerUtils @Inject constructor( } } + private suspend fun validateDownload( + numberOfDownloadedItems: Int, + fusedDownload: FusedDownload, + downloadId: Long + ) = downloadManager.getDownloadStatus(downloadId) == androidDownloadManager.STATUS_SUCCESSFUL && + numberOfDownloadedItems == fusedDownload.downloadIdMap.size && checkCleanApkSignatureOK( + fusedDownload + ) + + private suspend fun updateDownloadIdMap( + fusedDownload: FusedDownload, + downloadId: Long + ) { + fusedDownload.downloadIdMap[downloadId] = true + fusedManagerRepository.updateFusedDownload(fusedDownload) + } + private suspend fun checkCleanApkSignatureOK(fusedDownload: FusedDownload): Boolean { if (fusedDownload.origin != Origin.CLEANAPK || fusedManagerRepository.isFdroidApplicationSigned( context, 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 163a301b5..e8965a51d 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 @@ -71,7 +71,7 @@ class UpdatesWorker @AssistedInject constructor( val isConnectedToUnmeteredNetwork = isConnectedToUnmeteredNetwork(applicationContext) val authData = getAuthData() val appsNeededToUpdate = updatesManagerRepository.getUpdates(authData).first - if (shouldShowNotification) { + if (isAutoUpdate && shouldShowNotification) { handleNotification(appsNeededToUpdate.size, isConnectedToUnmeteredNetwork) } -- GitLab From cfea5074517c5546828b9360b9a1617adf11da2a Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Mon, 3 Oct 2022 22:00:34 +0600 Subject: [PATCH 6/8] refactor: moving methods to appropriate class, timber for error logs --- .../foundation/e/apps/api/DownloadManager.kt | 8 ++++++-- .../e/apps/api/cleanapk/ApkSignatureManager.kt | 3 ++- .../manager/download/DownloadManagerUtils.kt | 15 ++++++++++----- .../apps/manager/fused/FusedManagerRepository.kt | 3 +-- .../manager/workmanager/InstallWorkManager.kt | 15 +++++++++++++++ .../e/apps/utils/modules/CommonUtilsFunctions.kt | 16 ---------------- 6 files changed, 34 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/api/DownloadManager.kt b/app/src/main/java/foundation/e/apps/api/DownloadManager.kt index 755219722..3d6f64dbf 100644 --- a/app/src/main/java/foundation/e/apps/api/DownloadManager.kt +++ b/app/src/main/java/foundation/e/apps/api/DownloadManager.kt @@ -139,7 +139,11 @@ class DownloadManager @Inject constructor( } } - fun getDownloadStatus(downloadId: Long): Int { + fun isDownloadSuccessful(downloadId: Long): Boolean { + return getDownloadStatus(downloadId) == DownloadManager.STATUS_SUCCESSFUL + } + + private fun getDownloadStatus(downloadId: Long): Int { try { downloadManager.query(downloadManagerQuery.setFilterById(downloadId)) .use { cursor -> @@ -151,7 +155,7 @@ class DownloadManager @Inject constructor( } } } catch (e: Exception) { - e.printStackTrace() + Timber.e(e) } return DownloadManager.STATUS_FAILED } diff --git a/app/src/main/java/foundation/e/apps/api/cleanapk/ApkSignatureManager.kt b/app/src/main/java/foundation/e/apps/api/cleanapk/ApkSignatureManager.kt index 78117f03d..ea7e58338 100644 --- a/app/src/main/java/foundation/e/apps/api/cleanapk/ApkSignatureManager.kt +++ b/app/src/main/java/foundation/e/apps/api/cleanapk/ApkSignatureManager.kt @@ -27,6 +27,7 @@ import org.bouncycastle.openpgp.PGPUtil import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator +import timber.log.Timber import java.io.BufferedInputStream import java.io.FileInputStream import java.io.InputStream @@ -42,7 +43,7 @@ object ApkSignatureManager { context.assets.open("f-droid.org-signing-key.gpg") ) } catch (e: Exception) { - e.printStackTrace() + Timber.e(e) } return false } diff --git a/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt b/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt index 8d7b2ca4b..c8cb757c8 100644 --- a/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt +++ b/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt @@ -34,7 +34,6 @@ import kotlinx.coroutines.sync.withLock import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton -import android.app.DownloadManager as androidDownloadManager @Singleton class DownloadManagerUtils @Inject constructor( @@ -79,10 +78,16 @@ class DownloadManagerUtils @Inject constructor( numberOfDownloadedItems: Int, fusedDownload: FusedDownload, downloadId: Long - ) = downloadManager.getDownloadStatus(downloadId) == androidDownloadManager.STATUS_SUCCESSFUL && - numberOfDownloadedItems == fusedDownload.downloadIdMap.size && checkCleanApkSignatureOK( - fusedDownload - ) + ) = downloadManager.isDownloadSuccessful(downloadId) && + areAllFilesDownloaded( + numberOfDownloadedItems, + fusedDownload + ) && checkCleanApkSignatureOK(fusedDownload) + + private fun areAllFilesDownloaded( + numberOfDownloadedItems: Int, + fusedDownload: FusedDownload + ) = numberOfDownloadedItems == fusedDownload.downloadIdMap.size private suspend fun updateDownloadIdMap( fusedDownload: FusedDownload, diff --git a/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerRepository.kt b/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerRepository.kt index 1f21ebc37..98c24363b 100644 --- a/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerRepository.kt +++ b/app/src/main/java/foundation/e/apps/manager/fused/FusedManagerRepository.kt @@ -11,7 +11,6 @@ import foundation.e.apps.manager.database.fusedDownload.FusedDownload import foundation.e.apps.manager.download.data.DownloadProgress import foundation.e.apps.manager.workmanager.InstallWorkManager import foundation.e.apps.utils.enums.Status -import foundation.e.apps.utils.modules.CommonUtilsFunctions import kotlinx.coroutines.flow.Flow import javax.inject.Inject import javax.inject.Singleton @@ -36,7 +35,7 @@ class FusedManagerRepository @Inject constructor( } suspend fun addDownload(fusedDownload: FusedDownload) { - if (CommonUtilsFunctions.checkWorkIsAlreadyAvailable(InstallWorkManager.context, fusedDownload.id)) { + if (InstallWorkManager.checkWorkIsAlreadyAvailable(fusedDownload.id)) { return } 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 08edd715f..fd782aea4 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 @@ -6,6 +6,7 @@ import androidx.work.ExistingWorkPolicy import androidx.work.OneTimeWorkRequestBuilder import androidx.work.WorkManager import foundation.e.apps.manager.database.fusedDownload.FusedDownload +import java.lang.Exception object InstallWorkManager { const val INSTALL_WORK_NAME = "APP_LOUNGE_INSTALL_APP" @@ -27,4 +28,18 @@ object InstallWorkManager { fun cancelWork(tag: String) { WorkManager.getInstance(context).cancelAllWorkByTag(tag) } + + fun checkWorkIsAlreadyAvailable(tag: String): Boolean { + val works = WorkManager.getInstance(context).getWorkInfosByTag(tag) + try { + works.get().forEach { + if (it.tags.contains(tag) && !it.state.isFinished) { + return true + } + } + } catch (e: Exception) { + e.printStackTrace() + } + return false + } } diff --git a/app/src/main/java/foundation/e/apps/utils/modules/CommonUtilsFunctions.kt b/app/src/main/java/foundation/e/apps/utils/modules/CommonUtilsFunctions.kt index e3f55ccd6..adf4d1552 100644 --- a/app/src/main/java/foundation/e/apps/utils/modules/CommonUtilsFunctions.kt +++ b/app/src/main/java/foundation/e/apps/utils/modules/CommonUtilsFunctions.kt @@ -20,8 +20,6 @@ package foundation.e.apps.utils.modules import android.annotation.SuppressLint import android.content.ClipData import android.content.ClipboardManager -import android.content.Context -import androidx.work.WorkManager import java.lang.Exception object CommonUtilsFunctions { @@ -51,18 +49,4 @@ object CommonUtilsFunctions { } return value } - - fun checkWorkIsAlreadyAvailable(context: Context, tag: String): Boolean { - val works = WorkManager.getInstance(context).getWorkInfosByTag(tag) - try { - works.get().forEach { - if (it.tags.contains(tag) && !it.state.isFinished) { - return true - } - } - } catch (e: Exception) { - e.printStackTrace() - } - return false - } } -- GitLab From d7f17b53e324081aa1283a21b87435714a9e4a4d Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Mon, 3 Oct 2022 16:15:55 +0000 Subject: [PATCH 7/8] Minor refactoring & copyright updated --- .../foundation/e/apps/api/fused/MemoryDao.kt | 2 +- .../manager/download/DownloadManagerUtils.kt | 229 +++++++++--------- 2 files changed, 116 insertions(+), 115 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt b/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt index fda1143d1..57826cd31 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 ECORP + * Copyright (C) 2022 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt b/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt index c8cb757c8..2661920c3 100644 --- a/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt +++ b/app/src/main/java/foundation/e/apps/manager/download/DownloadManagerUtils.kt @@ -1,114 +1,115 @@ -/* - * Copyright ECORP SAS 2022 - * Apps Quickly and easily install Android apps onto your device! - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package foundation.e.apps.manager.download - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import foundation.e.apps.api.DownloadManager -import foundation.e.apps.manager.database.fusedDownload.FusedDownload -import foundation.e.apps.manager.fused.FusedManagerRepository -import foundation.e.apps.utils.enums.Origin -import foundation.e.apps.utils.enums.Status -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class DownloadManagerUtils @Inject constructor( - @ApplicationContext private val context: Context, - private val fusedManagerRepository: FusedManagerRepository, - private val downloadManager: DownloadManager -) { - private val TAG = DownloadManagerUtils::class.java.simpleName - private val mutex = Mutex() - - @DelicateCoroutinesApi - fun cancelDownload(downloadId: Long) { - GlobalScope.launch { - val fusedDownload = fusedManagerRepository.getFusedDownload(downloadId) - fusedManagerRepository.cancelDownload(fusedDownload) - } - } - - @DelicateCoroutinesApi - fun updateDownloadStatus(downloadId: Long) { - GlobalScope.launch { - mutex.withLock { - delay(1500) // Waiting for downloadmanager to publish the progress of last bytes - val fusedDownload = fusedManagerRepository.getFusedDownload(downloadId) - if (fusedDownload.id.isNotEmpty()) { - updateDownloadIdMap(fusedDownload, downloadId) - val numberOfDownloadedItems = - fusedDownload.downloadIdMap.values.filter { it }.size - Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $numberOfDownloadedItems/${fusedDownload.downloadIdMap.size}") - if (validateDownload(numberOfDownloadedItems, fusedDownload, downloadId)) { - Timber.d("===> Download is completed for: ${fusedDownload.name}") - fusedManagerRepository.moveOBBFileToOBBDirectory(fusedDownload) - fusedDownload.status = Status.DOWNLOADED - fusedManagerRepository.updateFusedDownload(fusedDownload) - } - } - } - } - } - - private suspend fun validateDownload( - numberOfDownloadedItems: Int, - fusedDownload: FusedDownload, - downloadId: Long - ) = downloadManager.isDownloadSuccessful(downloadId) && - areAllFilesDownloaded( - numberOfDownloadedItems, - fusedDownload - ) && checkCleanApkSignatureOK(fusedDownload) - - private fun areAllFilesDownloaded( - numberOfDownloadedItems: Int, - fusedDownload: FusedDownload - ) = numberOfDownloadedItems == fusedDownload.downloadIdMap.size - - private suspend fun updateDownloadIdMap( - fusedDownload: FusedDownload, - downloadId: Long - ) { - fusedDownload.downloadIdMap[downloadId] = true - fusedManagerRepository.updateFusedDownload(fusedDownload) - } - - private suspend fun checkCleanApkSignatureOK(fusedDownload: FusedDownload): Boolean { - if (fusedDownload.origin != Origin.CLEANAPK || fusedManagerRepository.isFdroidApplicationSigned( - context, - fusedDownload - ) - ) { - Timber.d("Apk signature is OK") - return true - } - fusedDownload.status = Status.INSTALLATION_ISSUE - fusedManagerRepository.updateFusedDownload(fusedDownload) - Timber.d("CleanApk signature is Wrong!") - return false - } -} +/* + * Copyright ECORP SAS 2022 + * Apps Quickly and easily install Android apps onto your device! + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package foundation.e.apps.manager.download + +import android.content.Context +import dagger.hilt.android.qualifiers.ApplicationContext +import foundation.e.apps.api.DownloadManager +import foundation.e.apps.manager.database.fusedDownload.FusedDownload +import foundation.e.apps.manager.fused.FusedManagerRepository +import foundation.e.apps.utils.enums.Origin +import foundation.e.apps.utils.enums.Status +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import timber.log.Timber +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class DownloadManagerUtils @Inject constructor( + @ApplicationContext private val context: Context, + private val fusedManagerRepository: FusedManagerRepository, + private val downloadManager: DownloadManager +) { + private val TAG = DownloadManagerUtils::class.java.simpleName + private val mutex = Mutex() + + @DelicateCoroutinesApi + fun cancelDownload(downloadId: Long) { + GlobalScope.launch { + val fusedDownload = fusedManagerRepository.getFusedDownload(downloadId) + fusedManagerRepository.cancelDownload(fusedDownload) + } + } + + @DelicateCoroutinesApi + fun updateDownloadStatus(downloadId: Long) { + GlobalScope.launch { + mutex.withLock { + delay(1500) // Waiting for downloadmanager to publish the progress of last bytes + val fusedDownload = fusedManagerRepository.getFusedDownload(downloadId) + if (fusedDownload.id.isNotEmpty()) { + updateDownloadIdMap(fusedDownload, downloadId) + val numberOfDownloadedItems = + fusedDownload.downloadIdMap.values.filter { it }.size + Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $numberOfDownloadedItems/${fusedDownload.downloadIdMap.size}") + + if (validateDownload(numberOfDownloadedItems, fusedDownload, downloadId)) { + Timber.d("===> Download is completed for: ${fusedDownload.name}") + fusedManagerRepository.moveOBBFileToOBBDirectory(fusedDownload) + fusedDownload.status = Status.DOWNLOADED + fusedManagerRepository.updateFusedDownload(fusedDownload) + } + } + } + } + } + + private suspend fun validateDownload( + numberOfDownloadedItems: Int, + fusedDownload: FusedDownload, + downloadId: Long + ) = downloadManager.isDownloadSuccessful(downloadId) && + areAllFilesDownloaded( + numberOfDownloadedItems, + fusedDownload + ) && checkCleanApkSignatureOK(fusedDownload) + + private fun areAllFilesDownloaded( + numberOfDownloadedItems: Int, + fusedDownload: FusedDownload + ) = numberOfDownloadedItems == fusedDownload.downloadIdMap.size + + private suspend fun updateDownloadIdMap( + fusedDownload: FusedDownload, + downloadId: Long + ) { + fusedDownload.downloadIdMap[downloadId] = true + fusedManagerRepository.updateFusedDownload(fusedDownload) + } + + private suspend fun checkCleanApkSignatureOK(fusedDownload: FusedDownload): Boolean { + if (fusedDownload.origin != Origin.CLEANAPK || fusedManagerRepository.isFdroidApplicationSigned( + context, + fusedDownload + ) + ) { + Timber.d("Apk signature is OK") + return true + } + fusedDownload.status = Status.INSTALLATION_ISSUE + fusedManagerRepository.updateFusedDownload(fusedDownload) + Timber.d("CleanApk signature is Wrong!") + return false + } +} -- GitLab From 9e5f441fbae8c19a370bcb140f16e68815efde28 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Tue, 4 Oct 2022 14:15:59 +0600 Subject: [PATCH 8/8] Refactor:MemoryDao renamed to UpdatesDao --- .../e/apps/api/fused/{MemoryDao.kt => UpdatesDao.kt} | 2 +- .../e/apps/updates/manager/UpdatesManagerRepository.kt | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) rename app/src/main/java/foundation/e/apps/api/fused/{MemoryDao.kt => UpdatesDao.kt} (97%) diff --git a/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt b/app/src/main/java/foundation/e/apps/api/fused/UpdatesDao.kt similarity index 97% rename from app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt rename to app/src/main/java/foundation/e/apps/api/fused/UpdatesDao.kt index fda1143d1..d3cd905d2 100644 --- a/app/src/main/java/foundation/e/apps/api/fused/MemoryDao.kt +++ b/app/src/main/java/foundation/e/apps/api/fused/UpdatesDao.kt @@ -19,7 +19,7 @@ package foundation.e.apps.api.fused import foundation.e.apps.api.fused.data.FusedApp -object MemoryDao { +object UpdatesDao { var appsAwaitingForUpdate: List = listOf() fun hasAnyAppsForUpdate() = appsAwaitingForUpdate.isNotEmpty() diff --git a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt index b16010c05..0805a8a5b 100644 --- a/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt +++ b/app/src/main/java/foundation/e/apps/updates/manager/UpdatesManagerRepository.kt @@ -19,7 +19,7 @@ package foundation.e.apps.updates.manager import com.aurora.gplayapi.data.models.AuthData -import foundation.e.apps.api.fused.MemoryDao +import foundation.e.apps.api.fused.UpdatesDao import foundation.e.apps.api.fused.data.FusedApp import foundation.e.apps.utils.enums.ResultStatus import javax.inject.Inject @@ -29,12 +29,12 @@ class UpdatesManagerRepository @Inject constructor( ) { suspend fun getUpdates(authData: AuthData): Pair, ResultStatus> { - if (MemoryDao.hasAnyAppsForUpdate()) { - return Pair(MemoryDao.appsAwaitingForUpdate, ResultStatus.OK) + if (UpdatesDao.hasAnyAppsForUpdate()) { + return Pair(UpdatesDao.appsAwaitingForUpdate, ResultStatus.OK) } return updatesManagerImpl.getUpdates(authData).run { val filteredApps = first.filter { !(!it.isFree && authData.isAnonymous) } - MemoryDao.appsAwaitingForUpdate = filteredApps + UpdatesDao.appsAwaitingForUpdate = filteredApps Pair(filteredApps, this.second) } } -- GitLab