diff --git a/app/src/main/java/foundation/e/apps/AppLoungeApplication.kt b/app/src/main/java/foundation/e/apps/AppLoungeApplication.kt index 6adbcb225ebc93346dab76833a7a1f52c79cf2fd..b13c12c69b975f9baabeb89ca43f7f4c2f720181 100644 --- a/app/src/main/java/foundation/e/apps/AppLoungeApplication.kt +++ b/app/src/main/java/foundation/e/apps/AppLoungeApplication.kt @@ -28,8 +28,11 @@ import androidx.work.ExistingPeriodicWorkPolicy import dagger.hilt.android.HiltAndroidApp import foundation.e.apps.data.Constants.TAG_APP_INSTALL_STATE import foundation.e.apps.data.Constants.TAG_AUTHDATA_DUMP +import foundation.e.apps.data.enums.Status +import foundation.e.apps.data.install.AppInstallDAO import foundation.e.apps.data.preference.AppLoungeDataStore import foundation.e.apps.data.preference.AppLoungePreference +import foundation.e.apps.di.qualifiers.IoCoroutineScope import foundation.e.apps.install.pkg.AppLoungePackageManager import foundation.e.apps.install.pkg.PkgManagerBR import foundation.e.apps.install.updates.UpdatesWorkManager @@ -37,6 +40,7 @@ import foundation.e.apps.install.workmanager.InstallWorkManager import foundation.e.apps.ui.setup.tos.TOS_VERSION import foundation.e.apps.utils.CustomUncaughtExceptionHandler import foundation.e.lib.telemetry.Telemetry +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.MainScope import kotlinx.coroutines.flow.first @@ -63,9 +67,16 @@ class AppLoungeApplication : Application(), Configuration.Provider { @Inject lateinit var appLoungePreference: AppLoungePreference + @Inject + lateinit var appInstallDao: AppInstallDAO + @Inject lateinit var uncaughtExceptionHandler: CustomUncaughtExceptionHandler + @Inject + @IoCoroutineScope + lateinit var coroutineScope: CoroutineScope + @RequiresApi(Build.VERSION_CODES.TIRAMISU) override fun onCreate() { super.onCreate() @@ -109,6 +120,35 @@ class AppLoungeApplication : Application(), Configuration.Provider { appLoungePreference.getUpdateInterval(), ExistingPeriodicWorkPolicy.KEEP ) + + removeStalledInstallationFromDb() + } + + private fun removeStalledInstallationFromDb() = coroutineScope.launch { + val existingInstallations = appInstallDao.getItemInInstallation().toMutableList() + if (existingInstallations.isEmpty()) { + return@launch + } + val validPackageSession = packageManager.packageInstaller.allSessions + .filter { !it.isActive } + .mapNotNull { info -> info.appPackageName } + + if (validPackageSession.isNotEmpty()) { + existingInstallations.removeIf { validPackageSession.contains(it.packageName) } + } + + if (existingInstallations.isEmpty()) { + Timber.d("All packages have corresponding sessions;") + return@launch + } + + Timber.e("removing ${existingInstallations.size} app from db stuck at installing") + for (appInstall in existingInstallations) { + Timber.d("removing (${appInstall.packageName}) : (${appInstall.id}) from db") + + appInstall.status = Status.INSTALLATION_ISSUE + appInstallDao.deleteDownload(appInstall) + } } override val workManagerConfiguration: Configuration diff --git a/app/src/main/java/foundation/e/apps/data/install/AppInstallDAO.kt b/app/src/main/java/foundation/e/apps/data/install/AppInstallDAO.kt index a68090c2457c9b7d2c452ba418ddef6f6c3a765e..f008b96b3ef464de9f3487a77ebff99af7982031 100644 --- a/app/src/main/java/foundation/e/apps/data/install/AppInstallDAO.kt +++ b/app/src/main/java/foundation/e/apps/data/install/AppInstallDAO.kt @@ -27,6 +27,9 @@ interface AppInstallDAO { @Query("SELECT * FROM fuseddownload where id = :id") fun getDownloadFlowById(id: String): LiveData + @Query("SELECT * FROM fuseddownload where status = 'INSTALLING'") + suspend fun getItemInInstallation(): List + @Update suspend fun updateDownload(appInstall: AppInstall) diff --git a/app/src/test/java/foundation/e/apps/installProcessor/FakeAppInstallDAO.kt b/app/src/test/java/foundation/e/apps/installProcessor/FakeAppInstallDAO.kt index a592e2688ae7a53073735417d1a25871d2c99e67..93fc563e284bee99d826505c42b0c1d6873a7120 100644 --- a/app/src/test/java/foundation/e/apps/installProcessor/FakeAppInstallDAO.kt +++ b/app/src/test/java/foundation/e/apps/installProcessor/FakeAppInstallDAO.kt @@ -63,4 +63,8 @@ class FakeAppInstallDAO : AppInstallDAO { override suspend fun deleteDownload(appInstall: AppInstall) { appInstallList.remove(appInstall) } + + override suspend fun getItemInInstallation(): List { + return emptyList() + } }