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

Commit 519c6370 authored by Hasib Prince's avatar Hasib Prince
Browse files

Merge branch '1709-homeapi' into 'main'

HomeApi is introduced

See merge request !398
parents f3b2e44c 9f7845b1
Loading
Loading
Loading
Loading
Loading
+0 −8
Original line number Original line Diff line number Diff line
@@ -28,7 +28,6 @@
    <ID>MagicNumber:ApkSignatureManager.kt$ApkSignatureManager$1024</ID>
    <ID>MagicNumber:ApkSignatureManager.kt$ApkSignatureManager$1024</ID>
    <ID>MagicNumber:AppDatabase.kt$AppDatabase.Companion.&lt;no name provided&gt;$3</ID>
    <ID>MagicNumber:AppDatabase.kt$AppDatabase.Companion.&lt;no name provided&gt;$3</ID>
    <ID>MagicNumber:AppDatabase.kt$AppDatabase.Companion.&lt;no name provided&gt;$4</ID>
    <ID>MagicNumber:AppDatabase.kt$AppDatabase.Companion.&lt;no name provided&gt;$4</ID>
    <ID>MagicNumber:ApplicationApiImpl.kt$ApplicationApiImpl$3</ID>
    <ID>MagicNumber:ApplicationFragment.kt$ApplicationFragment$100f</ID>
    <ID>MagicNumber:ApplicationFragment.kt$ApplicationFragment$100f</ID>
    <ID>MagicNumber:ApplicationFragment.kt$ApplicationFragment$15</ID>
    <ID>MagicNumber:ApplicationFragment.kt$ApplicationFragment$15</ID>
    <ID>MagicNumber:ApplicationFragment.kt$ApplicationFragment$3</ID>
    <ID>MagicNumber:ApplicationFragment.kt$ApplicationFragment$3</ID>
@@ -74,8 +73,6 @@
    <ID>MaxLineLength:AppPrivacyInfo.kt$AppPrivacyInfo</ID>
    <ID>MaxLineLength:AppPrivacyInfo.kt$AppPrivacyInfo</ID>
    <ID>MaxLineLength:ApplicationApi.kt$ApplicationApi$suspend fun getGplayAppsByCategory(authData: AuthData, category: String, pageUrl: String?): ResultSupreme&lt;Pair&lt;List&lt;Application&gt;, String&gt;&gt;</ID>
    <ID>MaxLineLength:ApplicationApi.kt$ApplicationApi$suspend fun getGplayAppsByCategory(authData: AuthData, category: String, pageUrl: String?): ResultSupreme&lt;Pair&lt;List&lt;Application&gt;, String&gt;&gt;</ID>
    <ID>MaxLineLength:ApplicationApiImpl.kt$ApplicationApiImpl$(cleanApkAppsRepository.getAppDetails(result.apps[0]._id) as Response&lt;CleanApkApplication&gt;).body()?.app</ID>
    <ID>MaxLineLength:ApplicationApiImpl.kt$ApplicationApiImpl$(cleanApkAppsRepository.getAppDetails(result.apps[0]._id) as Response&lt;CleanApkApplication&gt;).body()?.app</ID>
    <ID>MaxLineLength:ApplicationApiImpl.kt$ApplicationApiImpl$val hasGplayLimitedResult = gplayHomes.any { fusedHome -&gt; fusedHome.list.size &lt; THRESHOLD_LIMITED_RESULT_HOME_PAGE }</ID>
    <ID>MaxLineLength:ApplicationDiffUtil.kt$ApplicationDiffUtil$((oldItem.trackers == LIST_OF_NULL &amp;&amp; newItem.trackers.isEmpty()) || oldItem.trackers == newItem.trackers)</ID>
    <ID>MaxLineLength:ApplicationFragment.kt$ApplicationFragment.Companion$"https://gitlab.e.foundation/e/os/apps/-/blob/main/app/src/main/java/foundation/e/apps/data/exodus/repositories/PrivacyScoreRepositoryImpl.kt"</ID>
    <ID>MaxLineLength:ApplicationFragment.kt$ApplicationFragment.Companion$"https://gitlab.e.foundation/e/os/apps/-/blob/main/app/src/main/java/foundation/e/apps/data/exodus/repositories/PrivacyScoreRepositoryImpl.kt"</ID>
    <ID>MaxLineLength:CommonUtilsModule.kt$CommonUtilsModule$*</ID>
    <ID>MaxLineLength:CommonUtilsModule.kt$CommonUtilsModule$*</ID>
    <ID>MaxLineLength:DownloadManager.kt$DownloadManager$Timber.e("Download Issue: $downloadId : DownloadManager returns status: $status but the failed because: reason: $reason")</ID>
    <ID>MaxLineLength:DownloadManager.kt$DownloadManager$Timber.e("Download Issue: $downloadId : DownloadManager returns status: $status but the failed because: reason: $reason")</ID>
@@ -83,9 +80,6 @@
    <ID>MaxLineLength:DownloadManagerUtils.kt$DownloadManagerUtils$Timber.d("===&gt; updateDownloadStatus: ${fusedDownload.name}: $downloadId: $numberOfDownloadedItems/${fusedDownload.downloadIdMap.size}")</ID>
    <ID>MaxLineLength:DownloadManagerUtils.kt$DownloadManagerUtils$Timber.d("===&gt; updateDownloadStatus: ${fusedDownload.name}: $downloadId: $numberOfDownloadedItems/${fusedDownload.downloadIdMap.size}")</ID>
    <ID>MaxLineLength:DownloadManagerUtils.kt$DownloadManagerUtils$if</ID>
    <ID>MaxLineLength:DownloadManagerUtils.kt$DownloadManagerUtils$if</ID>
    <ID>MaxLineLength:DownloadManagerUtils.kt$DownloadManagerUtils$numberOfDownloadedItems == fusedDownload.downloadIdMap.size &amp;&amp; numberOfDownloadedItems == fusedDownload.downloadURLList.size</ID>
    <ID>MaxLineLength:DownloadManagerUtils.kt$DownloadManagerUtils$numberOfDownloadedItems == fusedDownload.downloadIdMap.size &amp;&amp; numberOfDownloadedItems == fusedDownload.downloadURLList.size</ID>
    <ID>MaxLineLength:DownloadProgressLD.kt$DownloadProgressLD$cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))</ID>
    <ID>MaxLineLength:DownloadProgressLD.kt$DownloadProgressLD$cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))</ID>
    <ID>MaxLineLength:DownloadProgressLD.kt$DownloadProgressLD$status == DownloadManager.STATUS_SUCCESSFUL || status == DownloadManager.STATUS_FAILED</ID>
    <ID>MaxLineLength:FdroidRepository.kt$FdroidRepository$override suspend</ID>
    <ID>MaxLineLength:FdroidRepository.kt$FdroidRepository$override suspend</ID>
    <ID>MaxLineLength:FusedManagerImpl.kt$FusedManagerImpl$.</ID>
    <ID>MaxLineLength:FusedManagerImpl.kt$FusedManagerImpl$.</ID>
    <ID>MaxLineLength:FusedManagerImpl.kt$FusedManagerImpl$return</ID>
    <ID>MaxLineLength:FusedManagerImpl.kt$FusedManagerImpl$return</ID>
@@ -120,8 +114,6 @@
    <ID>ReturnCount:AppPrivacyInfoRepositoryImpl.kt$AppPrivacyInfoRepositoryImpl$override suspend fun getAppPrivacyInfo( application: Application, appHandle: String ): Result&lt;AppPrivacyInfo&gt;</ID>
    <ID>ReturnCount:AppPrivacyInfoRepositoryImpl.kt$AppPrivacyInfoRepositoryImpl$override suspend fun getAppPrivacyInfo( application: Application, appHandle: String ): Result&lt;AppPrivacyInfo&gt;</ID>
    <ID>ReturnCount:AppPrivacyInfoRepositoryImpl.kt$AppPrivacyInfoRepositoryImpl$private fun getAppPrivacyInfo( application: Application, appTrackerData: List&lt;Report&gt;, ): AppPrivacyInfo</ID>
    <ID>ReturnCount:AppPrivacyInfoRepositoryImpl.kt$AppPrivacyInfoRepositoryImpl$private fun getAppPrivacyInfo( application: Application, appTrackerData: List&lt;Report&gt;, ): AppPrivacyInfo</ID>
    <ID>ReturnCount:ApplicationApiImpl.kt$ApplicationApiImpl$override fun isAnyFusedAppUpdated( newApplications: List&lt;Application&gt;, oldApplications: List&lt;Application&gt; ): Boolean</ID>
    <ID>ReturnCount:ApplicationApiImpl.kt$ApplicationApiImpl$override fun isAnyFusedAppUpdated( newApplications: List&lt;Application&gt;, oldApplications: List&lt;Application&gt; ): Boolean</ID>
    <ID>ReturnCount:ApplicationApiImpl.kt$ApplicationApiImpl$override fun isHomeDataUpdated( newHomeData: List&lt;Home&gt;, oldHomeData: List&lt;Home&gt; ): Boolean</ID>
    <ID>ReturnCount:ApplicationApiImpl.kt$ApplicationApiImpl$private fun areFusedAppsUpdated( oldHome: Home, newHome: Home, ): Boolean</ID>
    <ID>ReturnCount:DownloadManager.kt$DownloadManager$fun getSizeRequired(downloadId: Long): Long</ID>
    <ID>ReturnCount:DownloadManager.kt$DownloadManager$fun getSizeRequired(downloadId: Long): Long</ID>
    <ID>ReturnCount:DownloadManager.kt$DownloadManager$private fun sanitizeStatus(downloadId: Long, status: Int, reason: Int): Int</ID>
    <ID>ReturnCount:DownloadManager.kt$DownloadManager$private fun sanitizeStatus(downloadId: Long, status: Int, reason: Int): Int</ID>
    <ID>ReturnCount:Extensions.kt$fun Context.isNetworkAvailable(): Boolean</ID>
    <ID>ReturnCount:Extensions.kt$fun Context.isNetworkAvailable(): Boolean</ID>
+0 −4
Original line number Original line Diff line number Diff line
@@ -29,10 +29,6 @@ interface ApplicationApi {


    fun getApplicationCategoryPreference(): List<String>
    fun getApplicationCategoryPreference(): List<String>


    suspend fun getHomeScreenData(
        authData: AuthData,
    ): LiveData<ResultSupreme<List<Home>>>

    /*
    /*
        * Return three elements from the function.
        * Return three elements from the function.
        * - List<FusedCategory> : List of categories.
        * - List<FusedCategory> : List of categories.
+10 −214
Original line number Original line Diff line number Diff line
@@ -20,8 +20,6 @@ package foundation.e.apps.data.application


import android.content.Context
import android.content.Context
import android.text.format.Formatter
import android.text.format.Formatter
import androidx.lifecycle.LiveData
import androidx.lifecycle.liveData
import com.aurora.gplayapi.Constants
import com.aurora.gplayapi.Constants
import com.aurora.gplayapi.SearchSuggestEntry
import com.aurora.gplayapi.SearchSuggestEntry
import com.aurora.gplayapi.data.models.App
import com.aurora.gplayapi.data.models.App
@@ -32,28 +30,26 @@ import com.aurora.gplayapi.data.models.StreamCluster
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.R
import foundation.e.apps.R
import foundation.e.apps.data.ResultSupreme
import foundation.e.apps.data.ResultSupreme
import foundation.e.apps.data.application.ApplicationApi.Companion.APP_TYPE_ANY
import foundation.e.apps.data.application.ApplicationApi.Companion.APP_TYPE_OPEN
import foundation.e.apps.data.application.ApplicationApi.Companion.APP_TYPE_PWA
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.application.data.Category
import foundation.e.apps.data.application.data.Home
import foundation.e.apps.data.application.data.Ratings
import foundation.e.apps.data.application.utils.CategoryType
import foundation.e.apps.data.application.utils.CategoryUtils
import foundation.e.apps.data.cleanapk.CleanApkDownloadInfoFetcher
import foundation.e.apps.data.cleanapk.CleanApkDownloadInfoFetcher
import foundation.e.apps.data.cleanapk.data.categories.Categories
import foundation.e.apps.data.cleanapk.data.categories.Categories
import foundation.e.apps.data.cleanapk.data.home.HomeScreen
import foundation.e.apps.data.cleanapk.data.search.Search
import foundation.e.apps.data.cleanapk.data.search.Search
import foundation.e.apps.data.cleanapk.repositories.CleanApkRepository
import foundation.e.apps.data.cleanapk.repositories.CleanApkRepository
import foundation.e.apps.data.enums.AppTag
import foundation.e.apps.data.enums.AppTag
import foundation.e.apps.data.enums.FilterLevel
import foundation.e.apps.data.enums.FilterLevel
import foundation.e.apps.data.enums.Origin
import foundation.e.apps.data.enums.Origin
import foundation.e.apps.data.enums.ResultStatus
import foundation.e.apps.data.enums.ResultStatus
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.enums.Status
import foundation.e.apps.data.enums.Status
import foundation.e.apps.data.enums.Type
import foundation.e.apps.data.enums.Type
import foundation.e.apps.data.enums.isUnFiltered
import foundation.e.apps.data.enums.isUnFiltered
import foundation.e.apps.data.application.ApplicationApi.Companion.APP_TYPE_ANY
import foundation.e.apps.data.application.ApplicationApi.Companion.APP_TYPE_OPEN
import foundation.e.apps.data.application.ApplicationApi.Companion.APP_TYPE_PWA
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.application.data.Category
import foundation.e.apps.data.application.data.Home
import foundation.e.apps.data.application.data.Ratings
import foundation.e.apps.data.application.utils.CategoryType
import foundation.e.apps.data.application.utils.CategoryUtils
import foundation.e.apps.data.fusedDownload.models.FusedDownload
import foundation.e.apps.data.fusedDownload.models.FusedDownload
import foundation.e.apps.data.handleNetworkResult
import foundation.e.apps.data.handleNetworkResult
import foundation.e.apps.data.login.AuthObject
import foundation.e.apps.data.login.AuthObject
@@ -66,8 +62,6 @@ import foundation.e.apps.utils.eventBus.AppEvent
import foundation.e.apps.utils.eventBus.EventBus
import foundation.e.apps.utils.eventBus.EventBus
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.launch
import retrofit2.Response
import retrofit2.Response
import timber.log.Timber
import timber.log.Timber
@@ -76,7 +70,6 @@ import javax.inject.Named
import javax.inject.Singleton
import javax.inject.Singleton
import com.aurora.gplayapi.data.models.Category as GplayapiCategory
import com.aurora.gplayapi.data.models.Category as GplayapiCategory
import foundation.e.apps.data.cleanapk.data.app.Application as CleanApkApplication
import foundation.e.apps.data.cleanapk.data.app.Application as CleanApkApplication
import foundation.e.apps.data.cleanapk.data.home.Home as CleanApkHome


typealias FusedHomeDeferred = Deferred<ResultSupreme<List<Home>>>
typealias FusedHomeDeferred = Deferred<ResultSupreme<List<Home>>>


@@ -95,7 +88,6 @@ class ApplicationApiImpl @Inject constructor(
        private const val CATEGORY_TITLE_REPLACEABLE_CONJUNCTION = "&"
        private const val CATEGORY_TITLE_REPLACEABLE_CONJUNCTION = "&"
        private const val CATEGORY_OPEN_GAMES_ID = "game_open_games"
        private const val CATEGORY_OPEN_GAMES_ID = "game_open_games"
        private const val CATEGORY_OPEN_GAMES_TITLE = "Open games"
        private const val CATEGORY_OPEN_GAMES_TITLE = "Open games"
        private const val THRESHOLD_LIMITED_RESULT_HOME_PAGE = 4
        private const val KEYWORD_TEST_SEARCH = "facebook"
        private const val KEYWORD_TEST_SEARCH = "facebook"
    }
    }


@@ -107,97 +99,6 @@ class ApplicationApiImpl @Inject constructor(
        return prefs
        return prefs
    }
    }


    override suspend fun getHomeScreenData(
        authData: AuthData,
    ): LiveData<ResultSupreme<List<Home>>> {

        val list = mutableListOf<Home>()
        var resultGplay: FusedHomeDeferred? = null
        var resultOpenSource: FusedHomeDeferred? = null
        var resultPWA: FusedHomeDeferred? = null

        return liveData {
            coroutineScope {

                if (preferenceManagerModule.isGplaySelected()) {
                    resultGplay = async { loadHomeData(list, Source.GPLAY, authData) }
                }

                if (preferenceManagerModule.isOpenSourceSelected()) {
                    resultOpenSource = async { loadHomeData(list, Source.OPEN, authData) }
                }

                if (preferenceManagerModule.isPWASelected()) {
                    resultPWA = async { loadHomeData(list, Source.PWA, authData) }
                }

                resultGplay?.await()?.let {
                    emit(it)
                }

                resultOpenSource?.await()?.let {
                    emit(it)
                }

                resultPWA?.await()?.let {
                    emit(it)
                }
            }
        }
    }

    private suspend fun loadHomeData(
        priorList: MutableList<Home>,
        source: Source,
        authData: AuthData,
    ): ResultSupreme<List<Home>> {

        val result = when (source) {
            Source.GPLAY -> handleNetworkResult<List<Home>> {
                priorList.addAll(fetchGPlayHome(authData))
                priorList
            }

            Source.OPEN -> handleNetworkResult {
                val response =
                    (cleanApkAppsRepository.getHomeScreenData() as Response<HomeScreen>).body()
                response?.home?.let {
                    priorList.addAll(generateCleanAPKHome(it, APP_TYPE_OPEN))
                }
                priorList
            }

            Source.PWA -> handleNetworkResult {
                val response =
                    (cleanApkPWARepository.getHomeScreenData() as Response<HomeScreen>).body()
                response?.home?.let {
                    priorList.addAll(generateCleanAPKHome(it, APP_TYPE_PWA))
                }
                priorList
            }
        }

        setHomeErrorMessage(result.getResultStatus(), source)
        priorList.sortByDescending {
            when (it.source) {
                APP_TYPE_OPEN -> 2
                APP_TYPE_PWA -> 1
                else -> 3
            }
        }
        return ResultSupreme.create(result.getResultStatus(), priorList)
    }

    private fun setHomeErrorMessage(apiStatus: ResultStatus, source: Source) {
        if (apiStatus != ResultStatus.OK) {
            apiStatus.message = when (source) {
                Source.GPLAY -> ("GPlay home loading error\n" + apiStatus.message).trim()
                Source.OPEN -> ("Open Source home loading error\n" + apiStatus.message).trim()
                Source.PWA -> ("PWA home loading error\n" + apiStatus.message).trim()
            }
        }
    }

    /*
    /*
     * Return three elements from the function.
     * Return three elements from the function.
     * - List<FusedCategory> : List of categories.
     * - List<FusedCategory> : List of categories.
@@ -756,7 +657,7 @@ class ApplicationApiImpl @Inject constructor(
    /*
    /*
     * Handy method to run on an instance of FusedApp to update its filter level.
     * Handy method to run on an instance of FusedApp to update its filter level.
     */
     */
    private suspend fun Application.updateFilterLevel(authData: AuthData?) {
    suspend fun Application.updateFilterLevel(authData: AuthData?) {
        this.filterLevel = getAppFilterLevel(this, authData)
        this.filterLevel = getAppFilterLevel(this, authData)
    }
    }


@@ -1065,111 +966,6 @@ class ApplicationApiImpl @Inject constructor(
        return gPlayFusedApp
        return gPlayFusedApp
    }
    }


    /*
     * Home screen-related internal functions
     */

    private suspend fun generateCleanAPKHome(home: CleanApkHome, appType: String): List<Home> {
        val list = mutableListOf<Home>()
        val headings = if (appType == APP_TYPE_OPEN) {
            getOpenSourceHomeCategories()
        } else {
            getPWAHomeCategories()
        }
        headings.forEach { (key, value) ->
            when (key) {
                "top_updated_apps" -> {
                    prepareApps(home.top_updated_apps, list, value)
                }

                "top_updated_games" -> {
                    prepareApps(home.top_updated_games, list, value)
                }

                "popular_apps" -> {
                    prepareApps(home.popular_apps, list, value)
                }

                "popular_games" -> {
                    prepareApps(home.popular_games, list, value)
                }

                "popular_apps_in_last_24_hours" -> {
                    prepareApps(home.popular_apps_in_last_24_hours, list, value)
                }

                "popular_games_in_last_24_hours" -> {
                    prepareApps(home.popular_games_in_last_24_hours, list, value)
                }

                "discover" -> {
                    prepareApps(home.discover, list, value)
                }
            }
        }

        return list.map {
            it.source = appType
            it
        }
    }

    private suspend fun prepareApps(
        appList: List<Application>,
        list: MutableList<Home>,
        value: String
    ) {
        if (appList.isNotEmpty()) {
            appList.forEach {
                it.updateStatus()
                it.updateType()
                it.updateFilterLevel(null)
            }
            list.add(Home(value, appList))
        }
    }

    private fun getPWAHomeCategories() = mapOf(
        "popular_apps" to context.getString(R.string.popular_apps),
        "popular_games" to context.getString(R.string.popular_games),
        "discover" to context.getString(R.string.discover_pwa)
    )

    private fun getOpenSourceHomeCategories() = mapOf(
        "top_updated_apps" to context.getString(R.string.top_updated_apps),
        "top_updated_games" to context.getString(R.string.top_updated_games),
        "popular_apps_in_last_24_hours" to context.getString(R.string.popular_apps_in_last_24_hours),
        "popular_games_in_last_24_hours" to context.getString(R.string.popular_games_in_last_24_hours),
        "discover" to context.getString(R.string.discover)
    )

    private suspend fun fetchGPlayHome(authData: AuthData): List<Home> {
        val list = mutableListOf<Home>()
        val gplayHomeData = gplayRepository.getHomeScreenData() as Map<String, List<App>>
        gplayHomeData.map {
            val fusedApps = it.value.map { app ->
                app.transformToFusedApp().apply {
                    updateFilterLevel(authData)
                }
            }
            list.add(Home(it.key, fusedApps))
        }

        handleLimitedResult(list)
        Timber.d("HomePageData: $list")

        return list
    }

    private fun handleLimitedResult(homeList: List<Home>) {
        val gplayHomes = homeList.filter { fusedHome -> fusedHome.source.isEmpty() }
        val hasGplayLimitedResult = gplayHomes.any { fusedHome -> fusedHome.list.size < THRESHOLD_LIMITED_RESULT_HOME_PAGE }
        if (hasGplayLimitedResult) {
            Timber.w("Limited result is found for homepage...")
            refreshToken()
        }
    }

    private fun refreshToken() {
    private fun refreshToken() {
        MainScope().launch {
        MainScope().launch {
            EventBus.invokeEvent(
            EventBus.invokeEvent(
+120 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright MURENA SAS 2023
 * Apps  Quickly and easily install Android apps onto your device!
 *
 * 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.application

import com.aurora.gplayapi.Constants
import com.aurora.gplayapi.data.models.AuthData
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.application.data.Home
import foundation.e.apps.data.enums.FilterLevel
import foundation.e.apps.data.enums.Origin
import foundation.e.apps.data.enums.Status
import foundation.e.apps.data.playstore.PlayStoreRepository
import foundation.e.apps.install.pkg.PWAManagerModule
import foundation.e.apps.install.pkg.PkgManagerModule
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton

@Singleton
class ApplicationDataManager @Inject constructor(
    @Named("gplayRepository") private val gplayRepository: PlayStoreRepository,
    private val pkgManagerModule: PkgManagerModule,
    private val pwaManagerModule: PWAManagerModule
) {
    suspend fun updateFilterLevel(authData: AuthData?, application: Application) {
        application.filterLevel = getAppFilterLevel(application, authData)
    }

    suspend fun prepareApps(
        appList: List<Application>,
        list: MutableList<Home>,
        value: String
    ) {
        if (appList.isNotEmpty()) {
            appList.forEach {
                it.updateType()
                updateStatus(it)
                updateFilterLevel(null, it)
            }
            list.add(Home(value, appList))
        }
    }

    private suspend fun getAppFilterLevel(application: Application, authData: AuthData?): FilterLevel {
        return when {
            application.package_name.isBlank() -> FilterLevel.UNKNOWN
            !application.isFree && application.price.isBlank() -> FilterLevel.UI
            application.origin == Origin.CLEANAPK -> FilterLevel.NONE
            !isRestricted(application) -> FilterLevel.NONE
            authData == null -> FilterLevel.UNKNOWN // cannot determine for gplay app
            !isApplicationVisible(application) -> FilterLevel.DATA
            application.originalSize == 0L -> FilterLevel.UI
            !isDownloadable(application) -> FilterLevel.UI
            else -> FilterLevel.NONE
        }
    }

    private fun isRestricted(application: Application): Boolean {
        return application.restriction != Constants.Restriction.NOT_RESTRICTED
    }

    /*
     * Some apps are simply not visible.
     * Example: com.skype.m2
     */
    private suspend fun isApplicationVisible(application: Application): Boolean {
        return kotlin.runCatching { gplayRepository.getAppDetails(application.package_name) }.isSuccess
    }

    /*
     * Some apps are visible but not downloadable.
     * Example: com.riotgames.league.wildrift
     */
    private suspend fun isDownloadable(application: Application): Boolean {
        return kotlin.runCatching {
            gplayRepository.getDownloadInfo(
                application.package_name,
                application.latest_version_code,
                application.offer_type,
            )
        }.isSuccess
    }

    fun updateStatus(application: Application) {
        if (application.status != Status.INSTALLATION_ISSUE) {
            application.status = getFusedAppInstallationStatus(application)
        }
    }

    /*
     * Get fused app installation status.
     * Applicable for both native apps and PWAs.
     *
     * Recommended to use this instead of [PkgManagerModule.getPackageStatus].
     */
    fun getFusedAppInstallationStatus(application: Application): Status {
        return if (application.is_pwa) {
            pwaManagerModule.getPwaStatus(application)
        } else {
            pkgManagerModule.getPackageStatus(application.package_name, application.latest_version_code)
        }
    }

}
+5 −2
Original line number Original line Diff line number Diff line
@@ -37,10 +37,13 @@ import javax.inject.Inject
import javax.inject.Singleton
import javax.inject.Singleton


@Singleton
@Singleton
class ApplicationRepository @Inject constructor(private val applicationAPIImpl: ApplicationApi) {
class ApplicationRepository @Inject constructor(
    private val applicationAPIImpl: ApplicationApi,
    private val homeApi: HomeApi
) {


    suspend fun getHomeScreenData(authData: AuthData): LiveData<ResultSupreme<List<Home>>> {
    suspend fun getHomeScreenData(authData: AuthData): LiveData<ResultSupreme<List<Home>>> {
        return applicationAPIImpl.getHomeScreenData(authData)
        return homeApi.fetchHomeScreenData(authData)
    }
    }


    fun getApplicationCategoryPreference(): List<String> {
    fun getApplicationCategoryPreference(): List<String> {
Loading