Loading app/build.gradle +2 −2 Original line number Diff line number Diff line Loading @@ -110,8 +110,8 @@ dependencies { //googleImplementation project(":privacymodulesgoogle") // include the e specific version of the modules, just for the e flavor implementation 'foundation.e:privacymodule.trackerfilter:0.6.1' implementation 'foundation.e:privacymodule.api:1.0.0' implementation 'foundation.e:privacymodule.trackerfilter:0.7.0' implementation 'foundation.e:privacymodule.api:1.1.0' e29Implementation 'foundation.e:privacymodule.e-29:0.4.2' e30Implementation 'foundation.e:privacymodule.e-30:0.4.2' implementation 'foundation.e:privacymodule.tor:0.2.2' Loading app/src/main/java/foundation/e/privacycentralapp/common/AppsAdapter.kt +2 −1 Original line number Diff line number Diff line Loading @@ -41,7 +41,8 @@ class AppsAdapter( counts.text = itemView.context.getString( R.string.trackers_app_trackers_counts, item.blockedTrackersCount, item.trackersCount item.trackersCount, item.leaks ) icon.setImageDrawable(item.icon) Loading app/src/main/java/foundation/e/privacycentralapp/data/repositories/AppListsRepository.kt +4 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,10 @@ class AppListsRepository( return appDescriptions.value.first.find { it.packageName == packageName } } fun getApplicationDescription(appUid: Int): ApplicationDescription? { return appDescriptions.value.first.find { it.uid == appUid } } fun foldForHiddenSystemApp(appUid: Int, appValueGetter: (Int) -> Int): Int { return if (appUid == dummySystemApp.uid) { getHiddenSystemApps().fold(0) { acc, app -> Loading app/src/main/java/foundation/e/privacycentralapp/domain/entities/AppWithCounts.kt +9 −3 Original line number Diff line number Diff line Loading @@ -27,13 +27,17 @@ data class AppWithCounts( var icon: Drawable?, val isWhitelisted: Boolean = false, val trackersCount: Int = 0, val whiteListedTrackersCount: Int = 0 val whiteListedTrackersCount: Int = 0, val blockedLeaks: Int = 0, val leaks: Int = 0, ) { constructor( app: ApplicationDescription, isWhitelisted: Boolean, trackersCount: Int, whiteListedTrackersCount: Int whiteListedTrackersCount: Int, blockedLeaks: Int, leaks: Int, ) : this( packageName = app.packageName, Loading @@ -42,7 +46,9 @@ data class AppWithCounts( icon = app.icon, isWhitelisted = isWhitelisted, trackersCount = trackersCount, whiteListedTrackersCount = whiteListedTrackersCount whiteListedTrackersCount = whiteListedTrackersCount, blockedLeaks = blockedLeaks, leaks = leaks ) val blockedTrackersCount get() = if (isWhitelisted) 0 Loading app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt +42 −8 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import foundation.e.privacycentralapp.R import foundation.e.privacycentralapp.data.repositories.AppListsRepository import foundation.e.privacycentralapp.domain.entities.AppWithCounts import foundation.e.privacycentralapp.domain.entities.TrackersPeriodicStatistics import foundation.e.privacymodules.permissions.data.ApplicationDescription import foundation.e.privacymodules.trackers.IBlockTrackersPrivacyModule import foundation.e.privacymodules.trackers.ITrackTrackersPrivacyModule import foundation.e.privacymodules.trackers.Tracker Loading @@ -35,12 +36,14 @@ import java.time.format.DateTimeFormatter import java.time.temporal.ChronoUnit class TrackersStatisticsUseCase( // TODO private val trackTrackersPrivacyModule: ITrackTrackersPrivacyModule, private val trackTrackersPrivacyModule: ITrackTrackersPrivacyModule, private val blockTrackersPrivacyModule: IBlockTrackersPrivacyModule, private val appListsRepository: AppListsRepository, private val resources: Resources ) { fun initAppList() { appListsRepository.getVisibleApps() } fun listenUpdates(): Flow<Unit> = callbackFlow { val listener = object : ITrackTrackersPrivacyModule.Listener { Loading @@ -60,6 +63,12 @@ class TrackersStatisticsUseCase( ) to trackTrackersPrivacyModule.getTrackersCount() } fun getMostLeakedApp(): ApplicationDescription? { return appListsRepository.getApplicationDescription( trackTrackersPrivacyModule.getPastDayMostLeakedApp() ) } fun getDayTrackersCalls() = trackTrackersPrivacyModule.getPastDayTrackersCalls() fun getDayTrackersCount() = trackTrackersPrivacyModule.getPastDayTrackersCount() Loading Loading @@ -136,22 +145,47 @@ class TrackersStatisticsUseCase( return trackers.sortedBy { it.label.lowercase() } } fun getCalls(appUid: Int): Pair<Int, Int> { return if (appUid == appListsRepository.dummySystemApp.uid) { appListsRepository.getHiddenSystemApps().map { trackTrackersPrivacyModule.getPastDayTrackersCallsForApp(it.uid) }.reduce { (accBlocked, accLeaked), (blocked, leaked) -> accBlocked + blocked to accLeaked + leaked } } else trackTrackersPrivacyModule.getPastDayTrackersCallsForApp(appUid) } fun getAppsWithCounts(): Flow<List<AppWithCounts>> { val trackersCounts = trackTrackersPrivacyModule.getTrackersCountByApp() return appListsRepository.getVisibleApps() .map { apps -> val callsByApp = trackTrackersPrivacyModule.getPastDayTrackersCallsByApps() apps.map { app -> val (blockedLeaks, leaks) = callsByApp.getOrDefault(app.uid, 0 to 0) AppWithCounts( app, !blockTrackersPrivacyModule.isBlockingEnabled() || app = app, isWhitelisted = !blockTrackersPrivacyModule.isBlockingEnabled() || blockTrackersPrivacyModule.isWhitelisted(app.uid), appListsRepository.foldForHiddenSystemApp(app.uid) { trackersCount = appListsRepository.foldForHiddenSystemApp(app.uid) { trackersCounts.getOrDefault(it, 0) }, appListsRepository.foldForHiddenSystemApp(app.uid) { whiteListedTrackersCount = appListsRepository.foldForHiddenSystemApp(app.uid) { blockTrackersPrivacyModule.getWhiteList(it).size } }, blockedLeaks = blockedLeaks, leaks = leaks ) }.sortedWith(mostLeakedAppsComparator) } } private val mostLeakedAppsComparator: Comparator<AppWithCounts> = Comparator { o1, o2 -> val leaks = o2.leaks - o1.leaks if (leaks != 0) leaks else { val whitelisted = o2.whiteListedTrackersCount - o1.whiteListedTrackersCount if (whitelisted != 0) whitelisted else { o2.trackersCount - o1.trackersCount } } } Loading Loading
app/build.gradle +2 −2 Original line number Diff line number Diff line Loading @@ -110,8 +110,8 @@ dependencies { //googleImplementation project(":privacymodulesgoogle") // include the e specific version of the modules, just for the e flavor implementation 'foundation.e:privacymodule.trackerfilter:0.6.1' implementation 'foundation.e:privacymodule.api:1.0.0' implementation 'foundation.e:privacymodule.trackerfilter:0.7.0' implementation 'foundation.e:privacymodule.api:1.1.0' e29Implementation 'foundation.e:privacymodule.e-29:0.4.2' e30Implementation 'foundation.e:privacymodule.e-30:0.4.2' implementation 'foundation.e:privacymodule.tor:0.2.2' Loading
app/src/main/java/foundation/e/privacycentralapp/common/AppsAdapter.kt +2 −1 Original line number Diff line number Diff line Loading @@ -41,7 +41,8 @@ class AppsAdapter( counts.text = itemView.context.getString( R.string.trackers_app_trackers_counts, item.blockedTrackersCount, item.trackersCount item.trackersCount, item.leaks ) icon.setImageDrawable(item.icon) Loading
app/src/main/java/foundation/e/privacycentralapp/data/repositories/AppListsRepository.kt +4 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,10 @@ class AppListsRepository( return appDescriptions.value.first.find { it.packageName == packageName } } fun getApplicationDescription(appUid: Int): ApplicationDescription? { return appDescriptions.value.first.find { it.uid == appUid } } fun foldForHiddenSystemApp(appUid: Int, appValueGetter: (Int) -> Int): Int { return if (appUid == dummySystemApp.uid) { getHiddenSystemApps().fold(0) { acc, app -> Loading
app/src/main/java/foundation/e/privacycentralapp/domain/entities/AppWithCounts.kt +9 −3 Original line number Diff line number Diff line Loading @@ -27,13 +27,17 @@ data class AppWithCounts( var icon: Drawable?, val isWhitelisted: Boolean = false, val trackersCount: Int = 0, val whiteListedTrackersCount: Int = 0 val whiteListedTrackersCount: Int = 0, val blockedLeaks: Int = 0, val leaks: Int = 0, ) { constructor( app: ApplicationDescription, isWhitelisted: Boolean, trackersCount: Int, whiteListedTrackersCount: Int whiteListedTrackersCount: Int, blockedLeaks: Int, leaks: Int, ) : this( packageName = app.packageName, Loading @@ -42,7 +46,9 @@ data class AppWithCounts( icon = app.icon, isWhitelisted = isWhitelisted, trackersCount = trackersCount, whiteListedTrackersCount = whiteListedTrackersCount whiteListedTrackersCount = whiteListedTrackersCount, blockedLeaks = blockedLeaks, leaks = leaks ) val blockedTrackersCount get() = if (isWhitelisted) 0 Loading
app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt +42 −8 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import foundation.e.privacycentralapp.R import foundation.e.privacycentralapp.data.repositories.AppListsRepository import foundation.e.privacycentralapp.domain.entities.AppWithCounts import foundation.e.privacycentralapp.domain.entities.TrackersPeriodicStatistics import foundation.e.privacymodules.permissions.data.ApplicationDescription import foundation.e.privacymodules.trackers.IBlockTrackersPrivacyModule import foundation.e.privacymodules.trackers.ITrackTrackersPrivacyModule import foundation.e.privacymodules.trackers.Tracker Loading @@ -35,12 +36,14 @@ import java.time.format.DateTimeFormatter import java.time.temporal.ChronoUnit class TrackersStatisticsUseCase( // TODO private val trackTrackersPrivacyModule: ITrackTrackersPrivacyModule, private val trackTrackersPrivacyModule: ITrackTrackersPrivacyModule, private val blockTrackersPrivacyModule: IBlockTrackersPrivacyModule, private val appListsRepository: AppListsRepository, private val resources: Resources ) { fun initAppList() { appListsRepository.getVisibleApps() } fun listenUpdates(): Flow<Unit> = callbackFlow { val listener = object : ITrackTrackersPrivacyModule.Listener { Loading @@ -60,6 +63,12 @@ class TrackersStatisticsUseCase( ) to trackTrackersPrivacyModule.getTrackersCount() } fun getMostLeakedApp(): ApplicationDescription? { return appListsRepository.getApplicationDescription( trackTrackersPrivacyModule.getPastDayMostLeakedApp() ) } fun getDayTrackersCalls() = trackTrackersPrivacyModule.getPastDayTrackersCalls() fun getDayTrackersCount() = trackTrackersPrivacyModule.getPastDayTrackersCount() Loading Loading @@ -136,22 +145,47 @@ class TrackersStatisticsUseCase( return trackers.sortedBy { it.label.lowercase() } } fun getCalls(appUid: Int): Pair<Int, Int> { return if (appUid == appListsRepository.dummySystemApp.uid) { appListsRepository.getHiddenSystemApps().map { trackTrackersPrivacyModule.getPastDayTrackersCallsForApp(it.uid) }.reduce { (accBlocked, accLeaked), (blocked, leaked) -> accBlocked + blocked to accLeaked + leaked } } else trackTrackersPrivacyModule.getPastDayTrackersCallsForApp(appUid) } fun getAppsWithCounts(): Flow<List<AppWithCounts>> { val trackersCounts = trackTrackersPrivacyModule.getTrackersCountByApp() return appListsRepository.getVisibleApps() .map { apps -> val callsByApp = trackTrackersPrivacyModule.getPastDayTrackersCallsByApps() apps.map { app -> val (blockedLeaks, leaks) = callsByApp.getOrDefault(app.uid, 0 to 0) AppWithCounts( app, !blockTrackersPrivacyModule.isBlockingEnabled() || app = app, isWhitelisted = !blockTrackersPrivacyModule.isBlockingEnabled() || blockTrackersPrivacyModule.isWhitelisted(app.uid), appListsRepository.foldForHiddenSystemApp(app.uid) { trackersCount = appListsRepository.foldForHiddenSystemApp(app.uid) { trackersCounts.getOrDefault(it, 0) }, appListsRepository.foldForHiddenSystemApp(app.uid) { whiteListedTrackersCount = appListsRepository.foldForHiddenSystemApp(app.uid) { blockTrackersPrivacyModule.getWhiteList(it).size } }, blockedLeaks = blockedLeaks, leaks = leaks ) }.sortedWith(mostLeakedAppsComparator) } } private val mostLeakedAppsComparator: Comparator<AppWithCounts> = Comparator { o1, o2 -> val leaks = o2.leaks - o1.leaks if (leaks != 0) leaks else { val whitelisted = o2.whiteListedTrackersCount - o1.whiteListedTrackersCount if (whitelisted != 0) whitelisted else { o2.trackersCount - o1.trackersCount } } } Loading