Loading app/src/main/java/foundation/e/apps/data/application/ApplicationDataManager.kt +5 −7 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) Loading @@ -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 Loading @@ -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) { Loading app/src/main/java/foundation/e/apps/data/application/utils/AppVisibilityResolver.kt 0 → 100644 +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 } } app/src/main/java/foundation/e/apps/data/playstore/PlayStoreRepository.kt +3 −18 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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> { Loading @@ -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 } } Loading Loading @@ -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") } Loading app/src/test/java/foundation/e/apps/apps/AppsApiTest.kt +9 −7 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) Loading Loading @@ -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 Loading Loading @@ -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( Loading app/src/test/java/foundation/e/apps/category/CategoryApiTest.kt +5 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 Loading
app/src/main/java/foundation/e/apps/data/application/ApplicationDataManager.kt +5 −7 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) Loading @@ -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 Loading @@ -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) { Loading
app/src/main/java/foundation/e/apps/data/application/utils/AppVisibilityResolver.kt 0 → 100644 +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 } }
app/src/main/java/foundation/e/apps/data/playstore/PlayStoreRepository.kt +3 −18 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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> { Loading @@ -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 } } Loading Loading @@ -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") } Loading
app/src/test/java/foundation/e/apps/apps/AppsApiTest.kt +9 −7 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) Loading Loading @@ -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 Loading Loading @@ -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( Loading
app/src/test/java/foundation/e/apps/category/CategoryApiTest.kt +5 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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