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

Commit a3fdd5a4 authored by Sayantan Roychowdhury's avatar Sayantan Roychowdhury
Browse files

Issue 5136: Show N/A instead of incorrect privacy score.

parent 9c424dd6
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ import foundation.e.apps.api.Result
import foundation.e.apps.api.exodus.models.AppPrivacyInfo
import foundation.e.apps.api.exodus.repositories.IAppPrivacyInfoRepository
import foundation.e.apps.api.fused.data.FusedApp
import foundation.e.apps.utils.modules.CommonUtilsModule.LIST_OF_NULL
import javax.inject.Inject
import kotlin.math.ceil
import kotlin.math.round
@@ -27,8 +28,8 @@ class PrivacyInfoViewModel @Inject constructor(
    private suspend fun fetchEmitAppPrivacyInfo(
        fusedApp: FusedApp
    ): Result<AppPrivacyInfo> {
        if (fusedApp.trackers.isNotEmpty() && fusedApp.perms.isNotEmpty()) {
            val appInfo = AppPrivacyInfo(fusedApp.trackers, fusedApp.perms)
        if (fusedApp.trackers.isNotEmpty() && fusedApp.permsFromExodus.isNotEmpty()) {
            val appInfo = AppPrivacyInfo(fusedApp.trackers, fusedApp.permsFromExodus)
            return Result.success(appInfo)
        }
        val appPrivacyPrivacyInfoResult =
@@ -51,10 +52,14 @@ class PrivacyInfoViewModel @Inject constructor(
        appPrivacyPrivacyInfoResult: Result<AppPrivacyInfo>,
        fusedApp: FusedApp
    ): Result<AppPrivacyInfo> {
        fusedApp.trackers = appPrivacyPrivacyInfoResult.data?.trackerList ?: listOf()
        if (fusedApp.perms.isEmpty()) {

            fusedApp.perms = appPrivacyPrivacyInfoResult.data?.permissionList ?: listOf()
        fusedApp.trackers = appPrivacyPrivacyInfoResult.data?.trackerList ?: LIST_OF_NULL
        fusedApp.permsFromExodus = appPrivacyPrivacyInfoResult.data?.permissionList ?: LIST_OF_NULL
        if (fusedApp.perms.isEmpty() && fusedApp.permsFromExodus != LIST_OF_NULL) {
            /*
             * fusedApp.perms is generally populated from remote source like Play Store.
             * If it is empty then set the value from permissions from exodus api.
             */
            fusedApp.perms = fusedApp.permsFromExodus
        }
        return appPrivacyPrivacyInfoResult
    }
@@ -76,6 +81,9 @@ class PrivacyInfoViewModel @Inject constructor(
    }

    fun calculatePrivacyScore(fusedApp: FusedApp): Int {
        if (fusedApp.permsFromExodus == LIST_OF_NULL) {
            return -1
        }
        val calculateTrackersScore = calculateTrackersScore(fusedApp.trackers.size)
        val calculatePermissionsScore = calculatePermissionsScore(
            countAndroidPermissions(fusedApp)
@@ -88,7 +96,7 @@ class PrivacyInfoViewModel @Inject constructor(
    }

    private fun countAndroidPermissions(fusedApp: FusedApp) =
        fusedApp.perms.filter { it.contains("android.permission") }.size
        fusedApp.permsFromExodus.filter { it.contains("android.permission") }.size

    private fun calculateTrackersScore(numberOfTrackers: Int): Int {
        return if (numberOfTrackers > 5) 0 else 9 - numberOfTrackers
+11 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import foundation.e.apps.api.exodus.Tracker
import foundation.e.apps.api.exodus.TrackerDao
import foundation.e.apps.api.exodus.models.AppPrivacyInfo
import foundation.e.apps.api.getResult
import foundation.e.apps.utils.modules.CommonUtilsModule.LIST_OF_NULL
import javax.inject.Inject
import javax.inject.Singleton

@@ -70,8 +71,17 @@ class AppPrivacyInfoRepositoryImpl @Inject constructor(
    private fun getAppPrivacyInfo(
        appTrackerData: List<Report>,
    ): AppPrivacyInfo {
        /*
         * If the response is empty, that means there is no data on Exodus API about this app,
         * i.e. invalid data.
         * We signal this by list of "null".
         * It is not enough to send just empty lists, as an app can actually have zero trackers
         * and zero permissions. This is not to be confused with invalid data.
         *
         * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5136
         */
        if (appTrackerData.isEmpty()) {
            return AppPrivacyInfo()
            return AppPrivacyInfo(LIST_OF_NULL, LIST_OF_NULL)
        }
        val sortedTrackerData =
            appTrackerData.sortedByDescending { trackerData -> trackerData.versionCode.toLong() }
+12 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ package foundation.e.apps.api.fused.data
import foundation.e.apps.utils.enums.Origin
import foundation.e.apps.utils.enums.Status
import foundation.e.apps.utils.enums.Type
import foundation.e.apps.utils.modules.CommonUtilsModule.LIST_OF_NULL

data class FusedApp(
    val _id: String = String(),
@@ -51,5 +52,15 @@ data class FusedApp(
    var pwaPlayerDbId: Long = -1,
    val url: String = String(),
    var type: Type = Type.NATIVE,
    var privacyScore: Int = -1
    var privacyScore: Int = -1,

    /*
     * List of permissions from Exodus API.
     * This list is now used to calculate the privacy score instead of perms variable above.
     * If the value is LIST_OF_NULL - listOf("null"), it means no data is available in Exodus API for this package,
     * hence display "N/A"
     *
     * Issue: https://gitlab.e.foundation/e/backlog/-/issues/5136
     */
    var permsFromExodus: List<String> = LIST_OF_NULL,
)
+6 −2
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import foundation.e.apps.manager.pkg.PkgManagerModule
import foundation.e.apps.utils.enums.Origin
import foundation.e.apps.utils.enums.Status
import foundation.e.apps.utils.enums.User
import foundation.e.apps.utils.modules.CommonUtilsModule.LIST_OF_NULL
import foundation.e.apps.utils.modules.PWAManagerModule
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -231,10 +232,13 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
                    ).show(childFragmentManager, TAG)
                }
                appTrackers.setOnClickListener {
                    val fusedApp = applicationViewModel.fusedApp.value
                    var trackers =
                        privacyInfoViewModel.getTrackerListText(applicationViewModel.fusedApp.value)
                        privacyInfoViewModel.getTrackerListText(fusedApp)

                    if (trackers.isNotEmpty()) {
                    if (fusedApp?.trackers == LIST_OF_NULL) {
                        trackers = getString(R.string.tracker_information_not_found)
                    } else if (trackers.isNotEmpty()) {
                        trackers += "<br /> <br />" + getString(
                            R.string.privacy_computed_using_text,
                            EXODUS_URL
+3 −2
Original line number Diff line number Diff line
@@ -246,8 +246,9 @@ class ApplicationListRVAdapter(
    ) {
        privacyInfoViewModel.getAppPrivacyInfoLiveData(searchApp).observe(lifecycleOwner) {
            showPrivacyScore()
            if (it.isSuccess()) {
                searchApp.privacyScore = privacyInfoViewModel.calculatePrivacyScore(searchApp)
            val calculatedScore = privacyInfoViewModel.calculatePrivacyScore(searchApp)
            if (it.isSuccess() && calculatedScore != -1) {
                searchApp.privacyScore = calculatedScore
                appPrivacyScore.text = view.context.getString(
                    R.string.privacy_rating_out_of,
                    searchApp.privacyScore.toString()
Loading