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

Commit 92cb5f0a authored by Jonathan Klee's avatar Jonathan Klee
Browse files

Remove circular dependency

between ApplicationDataManager & PlayStoreRepository
parent bd26fa8e
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -21,12 +21,13 @@ package foundation.e.apps.data.application
import com.aurora.gplayapi.Constants
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.application.data.Home
import foundation.e.apps.data.application.utils.AppVisibilityResolver
import foundation.e.apps.data.enums.FilterLevel
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.enums.Status
import foundation.e.apps.data.playstore.PlayStoreRepository
import foundation.e.apps.install.pkg.AppLoungePackageManager
import foundation.e.apps.install.pkg.PwaManager
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton

@@ -34,7 +35,7 @@ import javax.inject.Singleton
class ApplicationDataManager @Inject constructor(
    private val appLoungePackageManager: AppLoungePackageManager,
    private val pwaManager: PwaManager,
    private val playStoreRepository: PlayStoreRepository
    private val visibilityFetcher: AppVisibilityResolver,
) {
    suspend fun updateFilterLevel(application: Application) {
        application.filterLevel = getAppFilterLevel(application)
@@ -56,6 +57,7 @@ class ApplicationDataManager @Inject constructor(
    }

    suspend fun getAppFilterLevel(application: Application): FilterLevel {
        Timber.i("getAppFilterLevel: $application")
        return when {
            application.package_name.isBlank() -> FilterLevel.UNKNOWN
            !application.isFree && application.price.isBlank() -> FilterLevel.UI
@@ -72,12 +74,8 @@ class ApplicationDataManager @Inject constructor(
        return application.restriction != Constants.Restriction.NOT_RESTRICTED
    }

    /*
    * Some apps are not visible because of geo-restriction, banning, etc.
    */
    private suspend fun isApplicationVisible(application: Application): Boolean {
        val appDetails = playStoreRepository.getAppDetailsWeb(application.package_name)
        return appDetails != null
        return visibilityFetcher.isApplicationVisible(application)
    }

    fun updateStatus(application: Application) {
+31 −0
Original line number Diff line number Diff line
package foundation.e.apps.data.application.utils

import android.content.Context
import com.aurora.gplayapi.helpers.web.WebAppDetailsHelper
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.handleNetworkResult
import foundation.e.apps.data.playstore.utils.GPlayHttpClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class AppVisibilityResolver @Inject constructor(
    private val gPlayHttpClient: GPlayHttpClient,
    @ApplicationContext private val context: Context
) {
    suspend fun isApplicationVisible(application: Application): Boolean {
        val webAppDetailsHelper = WebAppDetailsHelper().using(gPlayHttpClient)

        val appDetails = withContext(Dispatchers.IO) {
            val result =
                handleNetworkResult { webAppDetailsHelper.getAppByPackageName(application.package_name) }
            val app = result.data ?: return@withContext null

            app.toApplication(context)
        }
        return appDetails != null
    }
}
+3 −18
Original line number Diff line number Diff line
@@ -29,12 +29,10 @@ import com.aurora.gplayapi.helpers.ContentRatingHelper
import com.aurora.gplayapi.helpers.PurchaseHelper
import com.aurora.gplayapi.helpers.contracts.TopChartsContract.Chart
import com.aurora.gplayapi.helpers.contracts.TopChartsContract.Type
import com.aurora.gplayapi.helpers.web.WebAppDetailsHelper
import com.aurora.gplayapi.helpers.web.WebCategoryHelper
import com.aurora.gplayapi.helpers.web.WebCategoryStreamHelper
import com.aurora.gplayapi.helpers.web.WebSearchHelper
import com.aurora.gplayapi.helpers.web.WebTopChartsHelper
import dagger.Lazy
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.R
import foundation.e.apps.data.StoreRepository
@@ -44,7 +42,6 @@ import foundation.e.apps.data.application.data.Home
import foundation.e.apps.data.application.utils.CategoryType
import foundation.e.apps.data.application.utils.toApplication
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.handleNetworkResult
import foundation.e.apps.data.login.AuthenticatorRepository
import foundation.e.apps.data.login.PlayStoreAuthenticator
import foundation.e.apps.data.playstore.utils.GPlayHttpClient
@@ -60,7 +57,7 @@ class PlayStoreRepository @Inject constructor(
    @ApplicationContext private val context: Context,
    private val gPlayHttpClient: GPlayHttpClient,
    private val authenticatorRepository: AuthenticatorRepository,
    private val applicationDataManager: Lazy<ApplicationDataManager> // Used Lazy to break circular dependency
    private val applicationDataManager: ApplicationDataManager
) : StoreRepository {

    override suspend fun getHomeScreenData(list: MutableList<Home>): List<Home> {
@@ -79,8 +76,8 @@ class PlayStoreRepository @Inject constructor(
        homeScreenData.map {
            val fusedApps = it.value.map { app ->
                app.apply {
                    applicationDataManager.get().updateStatus(this)
                    applicationDataManager.get().updateFilterLevel(this)
                    applicationDataManager.updateStatus(this)
                    applicationDataManager.updateFilterLevel(this)
                    source = Source.PLAY_STORE
                }
            }
@@ -180,18 +177,6 @@ class PlayStoreRepository @Inject constructor(
        authenticatorRepository.getAuthObjects(listOf(PlayStoreAuthenticator::class.java.simpleName))
    }

    suspend fun getAppDetailsWeb(packageName: String): Application? {
        val webAppDetailsHelper = WebAppDetailsHelper().using(gPlayHttpClient)

        return withContext(Dispatchers.IO) {
            val result =
                handleNetworkResult { webAppDetailsHelper.getAppByPackageName(packageName) }
            val app = result.data ?: return@withContext null

            app.toApplication(context)
        }
    }

    private fun isEmulator(): Boolean {
        return SystemInfoProvider.getSystemProperty("ro.boot.qemu").equals("1")
    }
+9 −7
Original line number Diff line number Diff line
@@ -22,12 +22,12 @@ import android.content.Context
import android.text.format.Formatter
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.aurora.gplayapi.Constants
import foundation.e.apps.FakeAppLoungePreference
import foundation.e.apps.data.Stores
import foundation.e.apps.data.application.ApplicationDataManager
import foundation.e.apps.data.application.apps.AppsApi
import foundation.e.apps.data.application.apps.AppsApiImpl
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.application.utils.AppVisibilityResolver
import foundation.e.apps.data.enums.FilterLevel
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.enums.Status
@@ -48,6 +48,7 @@ import org.mockito.Mock
import org.mockito.MockedStatic
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.eq

@OptIn(ExperimentalCoroutinesApi::class)
@@ -78,21 +79,21 @@ class AppsApiTest {
    @Mock
    private lateinit var stores: Stores

    @Mock
    private lateinit var visibilityFetcher: AppVisibilityResolver

    private lateinit var appsApi: AppsApi

    private lateinit var applicationDataManager: ApplicationDataManager

    private lateinit var preferenceManagerModule: FakeAppLoungePreference

    private lateinit var formatterMocked: MockedStatic<Formatter>

    @Before
    fun setup() {
        MockitoAnnotations.openMocks(this)
        formatterMocked = Mockito.mockStatic(Formatter::class.java)
        preferenceManagerModule = FakeAppLoungePreference(context)
        applicationDataManager =
            ApplicationDataManager(appLoungePackageManager, pwaManager, playStoreRepository)
            ApplicationDataManager(appLoungePackageManager, pwaManager, visibilityFetcher)
        appsApi = AppsApiImpl(
            stores,
            applicationDataManager
@@ -462,13 +463,14 @@ class AppsApiTest {
    @Test
    fun `getAppFilterLevel when app is restricted and getAppDetails and getDownloadDetails returns success`() =
        runTest {

            val fusedApp = getFusedAppForFilterLevelTest().apply {
                this.source = Source.PLAY_STORE
                this.restriction = Constants.Restriction.UNKNOWN
            }

            Mockito.`when`(playStoreRepository.getAppDetailsWeb(fusedApp.package_name))
                .thenReturn(Application(fusedApp.package_name))
            Mockito.`when`(visibilityFetcher.isApplicationVisible(any()))
                .thenReturn(true)

            Mockito.`when`(
                playStoreRepository.getDownloadInfo(
+5 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import foundation.e.apps.data.Stores
import foundation.e.apps.data.application.ApplicationDataManager
import foundation.e.apps.data.application.category.CategoryApi
import foundation.e.apps.data.application.category.CategoryApiImpl
import foundation.e.apps.data.application.utils.AppVisibilityResolver
import foundation.e.apps.data.application.utils.CategoryType
import foundation.e.apps.data.cleanapk.data.categories.Categories
import foundation.e.apps.data.cleanapk.repositories.CleanApkAppsRepository
@@ -85,6 +86,9 @@ class CategoryApiTest {
    @Mock
    private lateinit var appLoungePreference: AppLoungePreference

    @Mock
    private lateinit var visibilityFetcher: AppVisibilityResolver

    private lateinit var fakeStores: Stores

    private lateinit var categoryApi: CategoryApi
@@ -93,7 +97,7 @@ class CategoryApiTest {
    fun setup() {
        MockitoAnnotations.openMocks(this)
        val applicationDataManager =
            ApplicationDataManager(appLoungePackageManager, pwaManager, playStoreRepository)
            ApplicationDataManager(appLoungePackageManager, pwaManager, visibilityFetcher)

        fakeStores = Stores(playStoreRepository, cleanApkAppsRepository, cleanApkPWARepository, appLoungePreference)

Loading