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

Commit e279045c authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

842: Create dummy-app apps compatibility leaking system components

parent 5aa1f270
Loading
Loading
Loading
Loading
+77 −17
Original line number Diff line number Diff line
@@ -41,6 +41,12 @@ class AppListsRepository(
    companion object {
        private const val PNAME_SETTINGS = "com.android.settings"
        private const val PNAME_PWAPLAYER = "foundation.e.pwaplayer"
        private const val PNAME_INTENT_VERIFICATION = "com.android.statementservice"
        private const val PNAME_MICROG_SERVICES_CORE = "com.google.android.gms"

        val appsCompatibiltyPNames = setOf(
            PNAME_PWAPLAYER, PNAME_INTENT_VERIFICATION, PNAME_MICROG_SERVICES_CORE
        )
    }

    val dummySystemApp = ApplicationDescription(
@@ -50,6 +56,13 @@ class AppListsRepository(
        icon = context.getDrawable(R.drawable.ic_e_app_logo)
    )

    val dummyAppsCompatibilityApp = ApplicationDescription(
        packageName = "foundation.e.dummyappscompatibilityapp",
        uid = -2,
        label = context.getString(R.string.dummy_apps_compatibility_app_label),
        icon = context.getDrawable(R.drawable.ic_apps_compatibility_components)
    )

    private suspend fun fetchAppDescriptions() {
        val launcherPackageNames = pm.queryIntentActivities(
            Intent(Intent.ACTION_MAIN, null).apply { addCategory(Intent.CATEGORY_LAUNCHER) },
@@ -58,25 +71,32 @@ class AppListsRepository(

        val visibleAppsFilter = { packageInfo: PackageInfo ->
            hasInternetPermission(packageInfo) &&
                isNotHiddenSystemApp(packageInfo.applicationInfo, launcherPackageNames)
                isStandardApp(packageInfo.applicationInfo, launcherPackageNames)
        }

        val hiddenAppsFilter = { packageInfo: PackageInfo ->
            hasInternetPermission(packageInfo) &&
                !isNotHiddenSystemApp(packageInfo.applicationInfo, launcherPackageNames)
                isHiddenSystemApp(packageInfo.applicationInfo, launcherPackageNames)
        }

        val aCFilter = { packageInfo: PackageInfo ->
            packageInfo.packageName in appsCompatibiltyPNames
        }

        val visibleApps = permissionsModule.getApplications(visibleAppsFilter, true)
        val hiddenApps = permissionsModule.getApplications(hiddenAppsFilter, false)
        val aCApps = permissionsModule.getApplications(aCFilter, false)

        val workProfileVisibleApps = permissionsModule.getWorkProfileApplications(visibleAppsFilter, true)
        val workProfileHiddenApps = permissionsModule.getWorkProfileApplications(hiddenAppsFilter, false)
        val workProfileACApps = permissionsModule.getApplications(aCFilter, false)

        appDescriptions.emit((visibleApps + dummySystemApp) to hiddenApps)
        allProfilesAppDescriptions.emit(
            (visibleApps + workProfileVisibleApps + dummySystemApp)
                to (hiddenApps + workProfileHiddenApps)
        )
        appDescriptions.emit((visibleApps + dummySystemApp + dummyAppsCompatibilityApp) to hiddenApps)
        allProfilesAppDescriptions.emit(Triple(
            (visibleApps + workProfileVisibleApps + dummySystemApp + dummyAppsCompatibilityApp),
            (hiddenApps + workProfileHiddenApps),
            (aCApps + workProfileACApps)
        ))
    }

    private var refreshAppJob: Job? = null
@@ -109,25 +129,46 @@ class AppListsRepository(
        return allProfilesAppDescriptions.value.second
    }

    fun getAllApps(): Flow<List<ApplicationDescription>> = getAllProfilesVisibleApps()
        .map { it + getAllProfilesHiddenSystemApps() }

    fun getApplicationDescription(packageName: String): ApplicationDescription? {
        return appDescriptions.value.first.find { it.packageName == packageName }
    fun getAllProfilesACApps(): List<ApplicationDescription> {
        return allProfilesAppDescriptions.value.third
    }

    fun getAllApps(): Flow<List<ApplicationDescription>> = getAllProfilesVisibleApps()
        .map { it + getAllProfilesHiddenSystemApps() + getAllProfilesACApps()}

    fun getApplicationDescription(appUid: Int): ApplicationDescription? {
        return appDescriptions.value.first.find { it.uid == appUid }
        return allProfilesAppDescriptions.value.first.find { it.uid == appUid }
    }

    fun foldForHiddenSystemApp(appUid: Int, appValueGetter: (Int) -> Int): Int {
    fun foldForHiddenApp(appUid: Int, appValueGetter: (Int) -> Int): Int {
        return if (appUid == dummySystemApp.uid) {
            getAllProfilesHiddenSystemApps().fold(0) { acc, app ->
                acc + appValueGetter(app.uid)
            }
        } else if (appUid == dummyAppsCompatibilityApp.uid) {
            getAllProfilesACApps().fold(0) { acc, app ->
                acc + appValueGetter(app.uid)
            }
        } else appValueGetter(appUid)
    }

    fun anyForHiddenApps(appUid: Int, test: (Int) -> Boolean): Boolean {
        return if (appUid == dummySystemApp.uid) {
            getAllProfilesHiddenSystemApps().any { test(it.uid) }
        } else if (appUid == dummyAppsCompatibilityApp.uid) {
            getAllProfilesACApps().any { test(it.uid) }
        } else test(appUid)
    }

    fun applyForHiddenApps(appUid: Int, action: (Int) -> Unit) {
        if (appUid == dummySystemApp.uid) {
            getAllProfilesHiddenSystemApps().forEach { action(it.uid) }
        } else if (appUid == dummyAppsCompatibilityApp.uid) {
            getAllProfilesACApps().forEach { action(it.uid) }
        } else action(appUid)
    }


        private val pm get() = context.packageManager

    private val appDescriptions = MutableStateFlow(
@@ -138,7 +179,8 @@ class AppListsRepository(
    )

    private val allProfilesAppDescriptions = MutableStateFlow(
        Pair(
        Triple(
            emptyList<ApplicationDescription>(),
            emptyList<ApplicationDescription>(),
            emptyList<ApplicationDescription>()
        )
@@ -164,5 +206,23 @@ class AppListsRepository(
        return false
    }

    private fun isStandardApp(app: ApplicationInfo, launcherApps: List<String>): Boolean {
        return when {
            app.packageName == PNAME_SETTINGS -> false
            app.packageName in appsCompatibiltyPNames -> false
            app.hasFlag(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) -> true
            !app.hasFlag(ApplicationInfo.FLAG_SYSTEM) -> true
            launcherApps.contains(app.packageName) -> true
            else -> false
        }
    }

    private fun isHiddenSystemApp(app: ApplicationInfo, launcherApps: List<String>): Boolean {
        return when {
            app.packageName in appsCompatibiltyPNames -> false
            else -> !isNotHiddenSystemApp(app, launcherApps)
        }
    }

    private fun ApplicationInfo.hasFlag(flag: Int) = (flags and flag) == 1
}
+9 −0
Original line number Diff line number Diff line
@@ -97,6 +97,11 @@ class IpScramblingStateUseCase(
            mutable.removeAll(getHiddenPackageNames())
            mutable.add(appListsRepository.dummySystemApp.packageName)
            whitelist = mutable
        } else if (AppListsRepository.appsCompatibiltyPNames.any { it in whitelist }) {
            val mutable = whitelist.toMutableSet()
            mutable.removeAll(AppListsRepository.appsCompatibiltyPNames)
            mutable.add(appListsRepository.dummyAppsCompatibilityApp.packageName)
            whitelist = mutable
        }

        return whitelist
@@ -109,12 +114,16 @@ class IpScramblingStateUseCase(
        if (visibleList.contains(packageName)) {
            if (packageName == appListsRepository.dummySystemApp.packageName) {
                rawList.removeAll(getHiddenPackageNames())
            } else if (packageName == appListsRepository.dummyAppsCompatibilityApp.packageName) {
                rawList.removeAll(AppListsRepository.appsCompatibiltyPNames)
            } else {
                rawList.remove(packageName)
            }
        } else {
            if (packageName == appListsRepository.dummySystemApp.packageName) {
                rawList.addAll(getHiddenPackageNames())
            } else if (packageName == appListsRepository.dummyAppsCompatibilityApp.packageName) {
                rawList.addAll(AppListsRepository.appsCompatibiltyPNames)
            } else {
                rawList.add(packageName)
            }
+7 −29
Original line number Diff line number Diff line
@@ -54,10 +54,6 @@ class TrackersStateUseCase(
            blockTrackersPrivacyModule.isWhiteListEmpty()
    }

    fun getApplicationDescription(packageName: String): ApplicationDescription? {
        return appListsRepository.getApplicationDescription(packageName)
    }

    fun getApplicationDescription(appUid: Int): ApplicationDescription? {
        return appListsRepository.getApplicationDescription(appUid)
    }
@@ -66,32 +62,18 @@ class TrackersStateUseCase(
        return isWhitelisted(appUid, appListsRepository, blockTrackersPrivacyModule)
    }

    fun getTrackersWhitelistIds(appUid: Int): List<String> {
        return if (appUid == appListsRepository.dummySystemApp.uid) {
            appListsRepository.getAllProfilesHiddenSystemApps().fold(mutableSetOf<String>()) { acc, app ->
                acc.addAll(blockTrackersPrivacyModule.getWhiteList(app.uid).map { it.id })
                acc
            }.toList()
        } else blockTrackersPrivacyModule.getWhiteList(appUid).map { it.id }
    }

    fun toggleAppWhitelist(appUid: Int, isWhitelisted: Boolean) {
        if (appUid == appListsRepository.dummySystemApp.uid) {
            appListsRepository.getAllProfilesHiddenSystemApps().forEach {
                blockTrackersPrivacyModule.setWhiteListed(it.uid, isWhitelisted)
        appListsRepository.applyForHiddenApps(appUid) { uid ->
            blockTrackersPrivacyModule.setWhiteListed(uid, isWhitelisted)
        }
        } else blockTrackersPrivacyModule.setWhiteListed(appUid, isWhitelisted)

        updateAllTrackersBlockedState()
    }

    fun blockTracker(appUid: Int, tracker: Tracker, isBlocked: Boolean) {
        if (appUid == appListsRepository.dummySystemApp.uid) {
            appListsRepository.getAllProfilesHiddenSystemApps().forEach {
                blockTrackersPrivacyModule.setWhiteListed(tracker, it.uid, !isBlocked)
        appListsRepository.applyForHiddenApps(appUid) { uid ->
            blockTrackersPrivacyModule.setWhiteListed(tracker, uid, !isBlocked)
        }
        } else blockTrackersPrivacyModule.setWhiteListed(tracker, appUid, !isBlocked)

        updateAllTrackersBlockedState()
    }

@@ -106,9 +88,5 @@ fun isWhitelisted(
    appListsRepository: AppListsRepository,
    blockTrackersPrivacyModule: IBlockTrackersPrivacyModule
): Boolean {
    return if (appUid == appListsRepository.dummySystemApp.uid) {
        appListsRepository.getAllProfilesHiddenSystemApps().any {
            blockTrackersPrivacyModule.isWhitelisted(it.uid)
        }
    } else blockTrackersPrivacyModule.isWhitelisted(appUid)
    return appListsRepository.anyForHiddenApps(appUid, blockTrackersPrivacyModule::isWhitelisted)
}
+26 −2
Original line number Diff line number Diff line
@@ -166,6 +166,10 @@ class TrackersStatisticsUseCase(
            appListsRepository.getAllProfilesHiddenSystemApps().map {
                trackTrackersPrivacyModule.getTrackersForApp(it.uid)
            }.flatten().distinctBy { it.id }
        } else if (appUid == appListsRepository.dummyAppsCompatibilityApp.uid) {
            appListsRepository.getAllProfilesACApps().map {
                trackTrackersPrivacyModule.getTrackersForApp(it.uid)
            }.flatten().distinctBy { it.id }
        } else trackTrackersPrivacyModule.getTrackersForApp(appUid)

        return trackers.sortedBy { it.label.lowercase() }
@@ -182,6 +186,14 @@ class TrackersStatisticsUseCase(
                acc.addAll(blockTrackersPrivacyModule.getWhiteList(app.uid).map { it.id })
                acc
            }
        } else if (appUid == appListsRepository.dummyAppsCompatibilityApp.uid) {
            val acApps = appListsRepository.getAllProfilesACApps()
            trackers = trackTrackersPrivacyModule.getTrackers(acApps.map { it.uid })

            whiteListedTrackersIds = acApps.fold(HashSet<String>()) { acc, app ->
                acc.addAll(blockTrackersPrivacyModule.getWhiteList(app.uid).map { it.id })
                acc
            }
        } else {
            trackers = trackTrackersPrivacyModule.getTrackersForApp(appUid)
            whiteListedTrackersIds = blockTrackersPrivacyModule.getWhiteList(appUid)
@@ -198,6 +210,12 @@ class TrackersStatisticsUseCase(
            }.reduce { (accBlocked, accLeaked), (blocked, leaked) ->
                accBlocked + blocked to accLeaked + leaked
            }
        } else if (appUid == appListsRepository.dummyAppsCompatibilityApp.uid) {
            appListsRepository.getAllProfilesACApps().map {
                trackTrackersPrivacyModule.getPastDayTrackersCallsForApp(it.uid)
            }.reduce { (accBlocked, accLeaked), (blocked, leaked) ->
                accBlocked + blocked to accLeaked + leaked
            }
        } else trackTrackersPrivacyModule.getPastDayTrackersCallsForApp(appUid)
    }

@@ -205,6 +223,8 @@ class TrackersStatisticsUseCase(
        val trackersCounts = trackTrackersPrivacyModule.getTrackersCountByApp()
        val hiddenAppsTrackersWithWhiteList =
            getTrackersWithWhiteList(appListsRepository.dummySystemApp.uid)
        val acAppsTrackersWithWhiteList =
            getTrackersWithWhiteList(appListsRepository.dummyAppsCompatibilityApp.uid)

        return appListsRepository.getAllProfilesVisibleApps()
            .map { apps ->
@@ -216,19 +236,23 @@ class TrackersStatisticsUseCase(
                            isWhitelisted(app.uid, appListsRepository, blockTrackersPrivacyModule),
                        trackersCount = if (app.uid == appListsRepository.dummySystemApp.uid) {
                            hiddenAppsTrackersWithWhiteList.size
                        } else if (app.uid == appListsRepository.dummyAppsCompatibilityApp.uid) {
                            acAppsTrackersWithWhiteList.size
                        } else {
                            trackersCounts.getOrDefault(app.uid, 0)
                        },
                        whiteListedTrackersCount = if (app.uid == appListsRepository.dummySystemApp.uid) {
                            hiddenAppsTrackersWithWhiteList.count { it.second }
                        } else if (app.uid == appListsRepository.dummyAppsCompatibilityApp.uid) {
                            acAppsTrackersWithWhiteList.count { it.second }
                        } else {
                            blockTrackersPrivacyModule.getWhiteList(app.uid).size
                        },
                        blockedLeaks = appListsRepository.foldForHiddenSystemApp(app.uid) {
                        blockedLeaks = appListsRepository.foldForHiddenApp(app.uid) {
                            appUid ->
                            callsByApp.getOrDefault(appUid, 0 to 0).first
                        },
                        leaks = appListsRepository.foldForHiddenSystemApp(app.uid) {
                        leaks = appListsRepository.foldForHiddenApp(app.uid) {
                            appUid ->
                            callsByApp.getOrDefault(appUid, 0 to 0).second
                        }
+18 −0
Original line number Diff line number Diff line
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="180dp"
    android:height="180dp"
    android:viewportWidth="180"
    android:viewportHeight="180">
  <path
      android:pathData="M37.43,26.81L77.27,26.81A10.61,10.61 0,0 1,87.88 37.43L87.88,77.26A10.61,10.61 0,0 1,77.27 87.88L37.43,87.88A10.61,10.61 0,0 1,26.82 77.26L26.82,37.43A10.61,10.61 0,0 1,37.43 26.81z"
      android:fillColor="#A1B4BE"/>
  <path
      android:pathData="M37.43,92.12L77.27,92.12A10.61,10.61 0,0 1,87.88 102.74L87.88,142.57A10.61,10.61 0,0 1,77.27 153.19L37.43,153.19A10.61,10.61 0,0 1,26.82 142.57L26.82,102.74A10.61,10.61 0,0 1,37.43 92.12z"
      android:fillColor="#A1B4BE"/>
  <path
      android:pathData="M102.74,26.81L142.57,26.81A10.61,10.61 0,0 1,153.19 37.43L153.19,77.26A10.61,10.61 0,0 1,142.57 87.88L102.74,87.88A10.61,10.61 0,0 1,92.12 77.26L92.12,37.43A10.61,10.61 0,0 1,102.74 26.81z"
      android:fillColor="#A1B4BE"/>
  <path
      android:pathData="M147.81,128.51C144.61,122.96 146.53,115.85 152.11,112.62L146.11,102.23C144.4,103.23 142.4,103.81 140.27,103.81C133.86,103.81 128.66,98.58 128.66,92.12H116.66C116.68,94.12 116.18,96.13 115.11,97.98C111.91,103.53 104.79,105.42 99.2,102.2L93.2,112.59C94.93,113.57 96.42,115.01 97.49,116.86C100.68,122.4 98.77,129.49 93.21,132.73L99.21,143.13C100.92,142.13 102.9,141.56 105.02,141.56C111.41,141.56 116.59,146.76 116.63,153.19H128.63C128.63,151.21 129.12,149.22 130.18,147.39C133.38,141.85 140.49,139.96 146.07,143.15L152.07,132.76C150.35,131.78 148.87,130.35 147.81,128.51ZM122.66,135.02C115.83,135.02 110.29,129.49 110.29,122.65C110.29,115.82 115.83,110.29 122.66,110.29C129.49,110.29 135.02,115.82 135.02,122.65C135.02,129.49 129.49,135.02 122.66,135.02Z"
      android:fillColor="#A1B4BE"/>
</vector>
Loading