Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13900ded authored by dev-12's avatar dev-12 Committed by dev-12
Browse files

fix: removed stalled app entry from database on app start

Fixed an issue where apps could remain stuck in the installing state. Previously, users could not exit this state without clearing app data. This new validation now identifies and removes outdated or stalled installation entries from the database.
parent c1bd30dd
Loading
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ interface AppInstallDAO {
    @Query("SELECT * FROM fuseddownload where id = :id")
    fun getDownloadFlowById(id: String): LiveData<AppInstall?>

    @Query("SELECT * FROM fuseddownload where status = 'INSTALLING'")
    suspend fun getItemInInstallation(): List<AppInstall>

    @Update
    suspend fun updateDownload(appInstall: AppInstall)

+4 −0
Original line number Diff line number Diff line
@@ -63,4 +63,8 @@ class FakeAppInstallDAO : AppInstallDAO {
    override suspend fun deleteDownload(appInstall: AppInstall) {
        appInstallList.remove(appInstall)
    }

    override suspend fun getItemInInstallation(): List<AppInstall> {
        return emptyList()
    }
}