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

Commit 473092da authored by Abhishek Aggarwal's avatar Abhishek Aggarwal
Browse files

refactor(login): move auth flows behind domain and app services

parent 51e8add0
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2026 e Foundation
 *
 * 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 <https://www.gnu.org/licenses/>.
 */

package foundation.e.apps.data.di.bindings

import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import foundation.e.apps.data.login.microg.MicrogLoginManager
import foundation.e.apps.data.login.repository.AppLoginRepository
import foundation.e.apps.data.login.repository.AuthenticatorRepository
import foundation.e.apps.domain.login.LoginRepository
import foundation.e.apps.login.MicrogAccountFetcher
import foundation.e.apps.login.PlayStoreAuthManager
import foundation.e.apps.login.StoreAuthCoordinator
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
interface LoginBindingModule {

    @Binds
    @Singleton
    fun bindLoginRepository(
        appLoginRepository: AppLoginRepository,
    ): LoginRepository

    @Binds
    @Singleton
    fun bindPlayStoreAuthManager(
        authenticatorRepository: AuthenticatorRepository,
    ): PlayStoreAuthManager

    @Binds
    @Singleton
    fun bindStoreAuthCoordinator(
        authenticatorRepository: AuthenticatorRepository,
    ): StoreAuthCoordinator

    @Binds
    @Singleton
    fun bindMicrogAccountFetcher(
        microgLoginManager: MicrogLoginManager,
    ): MicrogAccountFetcher
}
+20 −35
Original line number Diff line number Diff line
@@ -21,28 +21,28 @@ import foundation.e.apps.data.event.AppEvent
import foundation.e.apps.data.event.EventBus
import foundation.e.apps.data.gitlab.SystemAppsUpdatesRepository
import foundation.e.apps.data.install.workmanager.AppInstallProcessor
import foundation.e.apps.data.login.repository.AuthenticatorRepository
import foundation.e.apps.data.updates.UpdatesManagerRepository
import foundation.e.apps.domain.model.User
import foundation.e.apps.domain.preferences.AppPreferencesRepository
import foundation.e.apps.domain.preferences.SessionRepository
import foundation.e.apps.login.PlayStoreAuthManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import timber.log.Timber

@Suppress("LongParameterList")
@HiltWorker
@Suppress("LongParameterList")
class UpdatesWorker @AssistedInject constructor(
    @Assisted private val context: Context,
    @Assisted private val params: WorkerParameters,
    private val updatesManagerRepository: UpdatesManagerRepository,
    private val blockedAppRepository: BlockedAppRepository,
    private val systemAppsUpdatesRepository: SystemAppsUpdatesRepository,
    private val sessionRepository: SessionRepository,
    private val appPreferencesRepository: AppPreferencesRepository,
    private val authenticatorRepository: AuthenticatorRepository,
    private val playStoreAuthManager: PlayStoreAuthManager,
    private val appInstallProcessor: AppInstallProcessor,
    private val blockedAppRepository: BlockedAppRepository,
    private val systemAppsUpdatesRepository: SystemAppsUpdatesRepository,
) : CoroutineWorker(context, params) {

    companion object {
@@ -154,36 +154,19 @@ class UpdatesWorker @AssistedInject constructor(
    @VisibleForTesting
    suspend fun getAvailableUpdates(): Pair<List<Application>, ResultStatus> {
        loadSettings()
        val appsNeededToUpdate = mutableListOf<Application>()
        val user = getUser()
        val authData = authenticatorRepository.getValidatedAuthData().data
        val resultStatus: ResultStatus

        if (user in listOf(User.ANONYMOUS, User.GOOGLE) && authData != null) {
            /*
             * Signifies valid Google user and valid auth data to update
             * apps from Google Play store.
             * The user check will be more useful in No-Google mode.
             */
            val (apps, status) = updatesManagerRepository.getUpdates()
            appsNeededToUpdate.addAll(apps)
            resultStatus = status
        } else if (user == User.NO_GOOGLE) {
            /*
             * If authData is null, update apps from cleanapk only.
             */
            val (apps, status) = updatesManagerRepository.getUpdatesOSS()
            appsNeededToUpdate.addAll(apps)
            resultStatus = status
        } else {
            /*
             * If user in UNAVAILABLE, don't do anything.
             */
        val authData = playStoreAuthManager.getValidatedAuthData().data
        val canUsePlayStoreUpdates =
            (user == User.ANONYMOUS || user == User.GOOGLE) && authData != null

        return when {
            canUsePlayStoreUpdates -> updatesManagerRepository.getUpdates()
            user == User.NO_GOOGLE -> updatesManagerRepository.getUpdatesOSS()
            else -> {
                Timber.e("Update is aborted for unavailable user!")
            resultStatus = ResultStatus.UNKNOWN
                Pair(emptyList(), ResultStatus.UNKNOWN)
            }
        }

        return Pair(appsNeededToUpdate, resultStatus)
    }

    @VisibleForTesting
@@ -224,9 +207,11 @@ class UpdatesWorker @AssistedInject constructor(

    // returns list of Pair(app, status(success|failed))
    @VisibleForTesting
    suspend fun startUpdateProcess(appsNeededToUpdate: List<Application>): List<Pair<Application, Boolean>> {
    suspend fun startUpdateProcess(
        appsNeededToUpdate: List<Application>
    ): List<Pair<Application, Boolean>> {
        val response = mutableListOf<Pair<Application, Boolean>>()
        val authData = authenticatorRepository.getValidatedAuthData()
        val authData = playStoreAuthManager.getValidatedAuthData()
        val isNotLoggedIntoPersonalAccount =
            !authData.isValidData() || authData.data?.isAnonymous == true
        for (fusedApp in appsNeededToUpdate) {
+0 −4
Original line number Diff line number Diff line
@@ -37,10 +37,6 @@ object InstallWorkManager {
        return operation
    }

    fun cancelWork(context: Context, tag: String) {
        WorkManager.getInstance(context).cancelAllWorkByTag(tag)
    }

    fun checkWorkIsAlreadyAvailable(context: Context, tag: String): Boolean {
        val works = WorkManager.getInstance(context).getWorkInfosByTag(tag)
        try {
+3 −7
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import foundation.e.apps.data.login.core.StoreAuthResult
import foundation.e.apps.data.login.core.StoreAuthenticator
import foundation.e.apps.data.login.core.StoreType
import foundation.e.apps.domain.model.LoginState
import foundation.e.apps.domain.model.User
import foundation.e.apps.domain.preferences.AppPreferencesRepository
import foundation.e.apps.domain.preferences.SessionRepository
import javax.inject.Inject
@@ -40,11 +39,8 @@ class CleanApkAuthenticator @Inject constructor(
) : StoreAuthenticator {
    override val storeType: StoreType = StoreType.CLEAN_APK

    private val user: User
        get() = sessionRepository.getUser()

    override fun isStoreActive(): Boolean {
        if (sessionRepository.getLoginState() == LoginState.UNAVAILABLE) {
    override suspend fun isStoreActive(): Boolean {
        if (sessionRepository.awaitLoginState() == LoginState.UNAVAILABLE) {
            /*
             * UNAVAILABLE login state means first login is not completed.
             */
@@ -57,7 +53,7 @@ class CleanApkAuthenticator @Inject constructor(
        return StoreAuthResult(
            authObject = AuthObject.CleanApk(
                ResultSupreme.Success(Unit),
                user,
                sessionRepository.awaitUser(),
            )
        )
    }
+1 −1
Original line number Diff line number Diff line
@@ -24,5 +24,5 @@ interface StoreAuthenticator {
    val storeType: StoreType
    suspend fun login(): StoreAuthResult
    suspend fun logout()
    fun isStoreActive(): Boolean
    suspend fun isStoreActive(): Boolean
}
Loading