From e73ab3e91b125f9f868c9ffe3ed8042d4f338673 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Fri, 30 Sep 2022 06:23:47 +0000 Subject: 5907: Hide deprecated trackers from trackers counts. --- .../domain/usecases/TrackersStatisticsUseCase.kt | 43 +++++++++++++--------- .../trackers/apptrackers/AppTrackersFragment.kt | 3 +- .../trackers/apptrackers/AppTrackersState.kt | 16 +++----- .../trackers/apptrackers/AppTrackersViewModel.kt | 14 +++---- .../trackers/api/ITrackTrackersPrivacyModule.kt | 6 +++ .../trackers/api/TrackTrackersPrivacyModule.kt | 6 ++- .../privacymodules/trackers/data/StatsDatabase.kt | 43 ++++++++++------------ .../trackers/data/StatsRepository.kt | 4 +- 8 files changed, 73 insertions(+), 62 deletions(-) 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 52e0bad..0a47bc5 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 @@ -18,7 +18,6 @@ package foundation.e.privacycentralapp.domain.usecases import android.content.res.Resources -import android.util.Log import foundation.e.privacycentralapp.R import foundation.e.privacycentralapp.common.throttleFirst import foundation.e.privacycentralapp.data.repositories.AppListsRepository @@ -156,6 +155,28 @@ class TrackersStatisticsUseCase( return trackers.sortedBy { it.label.lowercase() } } + fun getTrackersWithWhiteList(appUid: Int): List> { + val trackers: List + val whiteListedTrackersIds: Set + if (appUid == appListsRepository.dummySystemApp.uid) { + val hiddenApps = appListsRepository.getHiddenSystemApps() + trackers = trackTrackersPrivacyModule.getTrackers(hiddenApps.map { it.uid }) + + whiteListedTrackersIds = hiddenApps.fold(HashSet()) { acc, app -> + acc.addAll(blockTrackersPrivacyModule.getWhiteList(app.uid).map { it.id }) + acc + } + + } else { + trackers = trackTrackersPrivacyModule.getTrackersForApp(appUid) + whiteListedTrackersIds = blockTrackersPrivacyModule.getWhiteList(appUid) + .map { it.id }.toSet() + } + + return trackers.sortedBy { it.label.lowercase() }.map { tracker -> tracker to whiteListedTrackersIds.any { tracker.id == it }} + } + + fun getCalls(appUid: Int): Pair { return if (appUid == appListsRepository.dummySystemApp.uid) { appListsRepository.getHiddenSystemApps().map { @@ -168,6 +189,8 @@ class TrackersStatisticsUseCase( fun getAppsWithCounts(): Flow> { val trackersCounts = trackTrackersPrivacyModule.getTrackersCountByApp() + val hiddenAppsTrackersWithWhiteList = + getTrackersWithWhiteList(appListsRepository.dummySystemApp.uid) return appListsRepository.getVisibleApps() .map { apps -> @@ -178,12 +201,12 @@ class TrackersStatisticsUseCase( isWhitelisted = !blockTrackersPrivacyModule.isBlockingEnabled() || isWhitelisted(app.uid, appListsRepository, blockTrackersPrivacyModule), trackersCount = if (app.uid == appListsRepository.dummySystemApp.uid) { - getHiddenSystemAppsTrackersCount() + hiddenAppsTrackersWithWhiteList.size } else { trackersCounts.getOrDefault(app.uid, 0) }, whiteListedTrackersCount = if (app.uid == appListsRepository.dummySystemApp.uid) { - getHiddenSystemAppWhitelistedTrackersCount() + hiddenAppsTrackersWithWhiteList.count { it.second } } else { blockTrackersPrivacyModule.getWhiteList(app.uid).size }, @@ -198,20 +221,6 @@ class TrackersStatisticsUseCase( } } - private fun getHiddenSystemAppsTrackersCount(): Int { - return trackTrackersPrivacyModule.getTrackersCount( - appListsRepository.getHiddenSystemApps().map { it.uid } - ) - } - - private fun getHiddenSystemAppWhitelistedTrackersCount(): Int { - return appListsRepository.getHiddenSystemApps().fold(HashSet()) { acc, app -> - acc.addAll(blockTrackersPrivacyModule.getWhiteList(app.uid).map { it.id }) - acc - }.size - } - - private val mostLeakedAppsComparator: Comparator = Comparator { o1, o2 -> val leaks = o2.leaks - o1.leaks if (leaks != 0) leaks else { diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt index 3d8f809..ae169b4 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt @@ -151,10 +151,10 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) { binding.blockAllToggle.isChecked = state.isBlockingActivated - binding.trackersListTitle.isVisible = state.isBlockingActivated val trackersStatus = state.getTrackersStatus() if (!trackersStatus.isNullOrEmpty()) { + binding.trackersListTitle.isVisible = state.isBlockingActivated binding.trackers.isVisible = true binding.trackers.post { (binding.trackers.adapter as ToggleTrackersAdapter?)?.updateDataSet( @@ -164,6 +164,7 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) { } binding.noTrackersYet.isVisible = false } else { + binding.trackersListTitle.isVisible = false binding.trackers.isVisible = false binding.noTrackersYet.isVisible = true binding.noTrackersYet.text = getString( diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt index 230f872..ffa1f36 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt @@ -23,23 +23,17 @@ import foundation.e.privacymodules.trackers.api.Tracker data class AppTrackersState( val appDesc: ApplicationDescription? = null, val isBlockingActivated: Boolean = false, - val trackers: List? = null, - val whitelist: List? = null, + val trackersWithWhiteList: List>? = null, val leaked: Int = 0, val blocked: Int = 0, val isQuickPrivacyEnabled: Boolean = false, val showQuickPrivacyDisabledMessage: Boolean = false, ) { - fun getTrackersStatus(): List>? { - if (trackers != null && whitelist != null) { - return trackers.map { it to (it.id !in whitelist) } - } else { - return null - } - } + fun getTrackersStatus(): List>? + = trackersWithWhiteList?.map { it.first to !it.second } - fun getTrackersCount() = trackers?.size ?: 0 + fun getTrackersCount() = trackersWithWhiteList?.size ?: 0 fun getBlockedTrackersCount(): Int = if (isQuickPrivacyEnabled && isBlockingActivated) - getTrackersCount() - (whitelist?.size ?: 0) + trackersWithWhiteList?.count { !it.second }?: 0 else 0 } \ No newline at end of file diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt index c20ec7c..faa4e6b 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt @@ -54,9 +54,9 @@ class AppTrackersViewModel( init { viewModelScope.launch(Dispatchers.IO) { _state.update { it.copy( - appDesc = trackersStateUseCase.getApplicationDescription(appUid), - isBlockingActivated = !trackersStateUseCase.isWhitelisted(appUid), - whitelist = trackersStateUseCase.getTrackersWhitelistIds(appUid), + appDesc = trackersStateUseCase.getApplicationDescription(appUid), + isBlockingActivated = !trackersStateUseCase.isWhitelisted(appUid), + trackersWithWhiteList = trackersStatisticsUseCase.getTrackersWithWhiteList(appUid), ) } } } @@ -96,7 +96,7 @@ class AppTrackersViewModel( if (state.value.isBlockingActivated) { trackersStateUseCase.blockTracker(appUid, action.tracker, action.isBlocked) _state.update { it.copy( - whitelist = trackersStateUseCase.getTrackersWhitelistIds(appUid) + trackersWithWhiteList = trackersStatisticsUseCase.getTrackersWithWhiteList(appUid) ) } } } @@ -115,9 +115,9 @@ class AppTrackersViewModel( private fun fetchStatistics() { val (blocked, leaked) = trackersStatisticsUseCase.getCalls(appUid) return _state.update { s -> s.copy( - trackers = trackersStatisticsUseCase.getTrackers(appUid), - leaked = leaked, - blocked = blocked, + trackersWithWhiteList = trackersStatisticsUseCase.getTrackersWithWhiteList(appUid), + leaked = leaked, + blocked = blocked, ) } } diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt index f7beebd..5f1fa92 100644 --- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt +++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt @@ -29,6 +29,12 @@ interface ITrackTrackersPrivacyModule { */ fun getTrackersForApp(appUid: Int): List + /** + * List all the trackers encountere trackers since "ever", for the given [appUids], + * or all apps if [appUids] is null + */ + fun getTrackers(appUids: List? = null): List + /** * Return the number of encountered trackers since "ever", for the given [appUids], * or all apps if [appUids] is null diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt index e0672cc..d8f75aa 100644 --- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt +++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt @@ -72,7 +72,11 @@ class TrackTrackersPrivacyModule(private val context: Context) : ITrackTrackersP } override fun getTrackersForApp(appUid: Int): List { - return statsRepository.getAllTrackersOfApp(appUid) + return statsRepository.getTrackers(listOf(appUid)) + } + + override fun getTrackers(appUids: List?): List { + return statsRepository.getTrackers(appUids) } override fun getPastDayTrackersCount(): Int { diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt index 86208ad..c93fe90 100644 --- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt +++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt @@ -184,10 +184,7 @@ class StatsDatabase(context: Context) : fun getContactedTrackersCount(appUids: List?): Int { synchronized(lock) { val db = readableDatabase - val projection = - "COUNT(DISTINCT $COLUMN_NAME_TRACKER) $PROJECTION_NAME_TRACKERS_COUNT" - - var query = "SELECT $projection FROM $TABLE_NAME" + var query = "SELECT DISTINCT $COLUMN_NAME_TRACKER FROM $TABLE_NAME" appUids?.let { query += " WHERE $COLUMN_NAME_APP_UID IN (${it.joinToString(", ")})" @@ -195,8 +192,10 @@ class StatsDatabase(context: Context) : val cursor = db.rawQuery(query, arrayOf()) var count = 0 - if (cursor.moveToNext()) { - count = cursor.getInt(0) + while (cursor.moveToNext()) { + trackersRepository.getTracker(cursor.getString(COLUMN_NAME_TRACKER))?.let { + count++ + } } cursor.close() db.close() @@ -207,17 +206,17 @@ class StatsDatabase(context: Context) : fun getContactedTrackersCountByApp(): Map { synchronized(lock) { val db = readableDatabase - val projection = "$COLUMN_NAME_APP_UID, " + - "COUNT(DISTINCT $COLUMN_NAME_TRACKER) $PROJECTION_NAME_TRACKERS_COUNT" + val projection = "$COLUMN_NAME_APP_UID, $COLUMN_NAME_TRACKER" val cursor = db.rawQuery( - "SELECT $projection FROM $TABLE_NAME" + - " GROUP BY $COLUMN_NAME_APP_UID", + "SELECT DISTINCT $projection FROM $TABLE_NAME", //+ arrayOf() ) val countByApp = mutableMapOf() while (cursor.moveToNext()) { - countByApp[cursor.getInt(COLUMN_NAME_APP_UID)] = - cursor.getInt(PROJECTION_NAME_TRACKERS_COUNT) + trackersRepository.getTracker(cursor.getString(COLUMN_NAME_TRACKER))?.let { + val appUid = cursor.getInt(COLUMN_NAME_APP_UID) + countByApp[appUid] = countByApp.getOrDefault(appUid, 0) + 1 + } } cursor.close() db.close() @@ -364,16 +363,18 @@ class StatsDatabase(context: Context) : return entry } - fun getAllTrackersOfApp(appUid: Int): List { + + fun getTrackers(appUids: List?): List { synchronized(lock) { - val columns = - arrayOf(COLUMN_NAME_TRACKER, COLUMN_NAME_APP_UID) + val columns = arrayOf(COLUMN_NAME_TRACKER, COLUMN_NAME_APP_UID) var selection: String? = null + var selectionArg: Array? = null - if (appUid >= 0) { - selection = "$COLUMN_NAME_APP_UID = ?" - selectionArg = arrayOf("" + appUid) + appUids?.let { + selection = "$COLUMN_NAME_APP_UID IN (${it.joinToString(", ")})" + selectionArg = arrayOf() } + val db = readableDatabase val cursor = db.query( true, @@ -388,8 +389,7 @@ class StatsDatabase(context: Context) : ) val trackers: MutableList = ArrayList() while (cursor.moveToNext()) { - val trackerId = - cursor.getString(COLUMN_NAME_TRACKER) + val trackerId = cursor.getString(COLUMN_NAME_TRACKER) val tracker = trackersRepository.getTracker(trackerId) if (tracker != null) { trackers.add(tracker) @@ -401,9 +401,6 @@ class StatsDatabase(context: Context) : } } - val allTrackers: List - get() = getAllTrackersOfApp(-1) - class StatEntry { var app_uid = 0 var sum_contacted = 0 diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt index 0e88102..f5d217a 100644 --- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt +++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt @@ -65,8 +65,8 @@ class StatsRepository private constructor(context: Context) { return database.getContactedTrackersCount(appUids) } - fun getAllTrackersOfApp(app_uid: Int): List { - return database.getAllTrackersOfApp(app_uid) + fun getTrackers(appUids: List?): List { + return database.getTrackers(appUids) } fun getCallsByApps(periodCount: Int, periodUnit: TemporalUnit): Map> { -- cgit v1.2.1