diff options
author | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2023-03-06 10:41:06 +0000 |
---|---|---|
committer | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2023-03-06 10:41:06 +0000 |
commit | e279045cfe02dd4a571df98f596b8a9af9b9d24c (patch) | |
tree | 36c76f3addaa94a56025ce15d753f609978ac8e5 /app/src | |
parent | 5aa1f270323bf36a2797cef3f486a1c22e76c308 (diff) |
842: Create dummy-app apps compatibility leaking system components
Diffstat (limited to 'app/src')
6 files changed, 138 insertions, 48 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/AppListsRepository.kt b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/AppListsRepository.kt index 65ae478..a97888f 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/AppListsRepository.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/AppListsRepository.kt @@ -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) - - appDescriptions.emit((visibleApps + dummySystemApp) to hiddenApps) - allProfilesAppDescriptions.emit( - (visibleApps + workProfileVisibleApps + dummySystemApp) - to (hiddenApps + workProfileHiddenApps) - ) + val workProfileACApps = permissionsModule.getApplications(aCFilter, false) + + appDescriptions.emit((visibleApps + dummySystemApp + dummyAppsCompatibilityApp) to hiddenApps) + allProfilesAppDescriptions.emit(Triple( + (visibleApps + workProfileVisibleApps + dummySystemApp + dummyAppsCompatibilityApp), + (hiddenApps + workProfileHiddenApps), + (aCApps + workProfileACApps) + )) } private var refreshAppJob: Job? = null @@ -109,26 +129,47 @@ 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) } - private val pm get() = context.packageManager + 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( Pair( @@ -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 } diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt index 9216233..e753d7b 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt @@ -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) } diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt index 11f0466..820073b 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt @@ -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) - } - } else blockTrackersPrivacyModule.setWhiteListed(appUid, isWhitelisted) + appListsRepository.applyForHiddenApps(appUid) { uid -> + blockTrackersPrivacyModule.setWhiteListed(uid, isWhitelisted) + } updateAllTrackersBlockedState() } fun blockTracker(appUid: Int, tracker: Tracker, isBlocked: Boolean) { - if (appUid == appListsRepository.dummySystemApp.uid) { - appListsRepository.getAllProfilesHiddenSystemApps().forEach { - blockTrackersPrivacyModule.setWhiteListed(tracker, it.uid, !isBlocked) - } - } else blockTrackersPrivacyModule.setWhiteListed(tracker, appUid, !isBlocked) - + appListsRepository.applyForHiddenApps(appUid) { uid -> + blockTrackersPrivacyModule.setWhiteListed(tracker, uid, !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) } diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt index 404032b..cc6ec45 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt @@ -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 } diff --git a/app/src/main/res/drawable/ic_apps_compatibility_components.xml b/app/src/main/res/drawable/ic_apps_compatibility_components.xml new file mode 100644 index 0000000..6ca9cec --- /dev/null +++ b/app/src/main/res/drawable/ic_apps_compatibility_components.xml @@ -0,0 +1,18 @@ +<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> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6cb0b5b..38cd38b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,6 +7,7 @@ <string name="ok">OK</string> <string name="dummy_system_app_label">System</string> + <string name="dummy_apps_compatibility_app_label">Applications compatibility</string> <string name="graph_empty_message">Congratulations! No trackers are profiling you.</string> <string name="graph_legend_blocked">Blocked leaks</string> <string name="graph_legend_allowed">Allowed leaks</string> |