summaryrefslogtreecommitdiff
path: root/trackers/src/main/java/foundation/e/advancedprivacy
diff options
context:
space:
mode:
authorGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2023-12-05 08:17:01 +0000
committerGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2023-12-05 08:17:01 +0000
commit2e897cc8af4234abc4e3f5c3448e1fd7b2b8a1bd (patch)
tree8f72170bee6247db6743521675d0ac0822b2ef65 /trackers/src/main/java/foundation/e/advancedprivacy
parent0db4d25038823369f320e0cd291968e66ed51e0c (diff)
1203 trackers oriented view
Diffstat (limited to 'trackers/src/main/java/foundation/e/advancedprivacy')
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/StatsDatabase.kt165
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/WhitelistRepository.kt225
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/FilterHostnameUseCase.kt10
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/StatisticsUseCase.kt13
4 files changed, 320 insertions, 93 deletions
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/StatsDatabase.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/StatsDatabase.kt
index 15ff813..a80d4dc 100644
--- a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/StatsDatabase.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/StatsDatabase.kt
@@ -224,61 +224,112 @@ class StatsDatabase(
}
}
- fun getContactedTrackersCountByAppId(): Map<String, Int> {
+ fun getCalls(appId: String, periodCount: Int, periodUnit: TemporalUnit): Pair<Int, Int> {
synchronized(lock) {
+ val minTimestamp = getPeriodStartTs(periodCount, periodUnit)
val db = readableDatabase
- val projection = "$COLUMN_NAME_APPID, $COLUMN_NAME_TRACKER"
+ val selection = "$COLUMN_NAME_APPID = ? AND " +
+ "$COLUMN_NAME_TIMESTAMP >= ?"
+ val selectionArg = arrayOf("" + appId, "" + minTimestamp)
+ val projection =
+ "SUM($COLUMN_NAME_NUMBER_CONTACTED) $PROJECTION_NAME_CONTACTED_SUM," +
+ "SUM($COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_BLOCKED_SUM"
val cursor = db.rawQuery(
- "SELECT DISTINCT $projection FROM $TABLE_NAME", // +
- arrayOf()
+ "SELECT $projection FROM $TABLE_NAME WHERE $selection",
+ selectionArg
)
- val countByApp = mutableMapOf<String, Int>()
- while (cursor.moveToNext()) {
- trackersRepository.getTracker(cursor.getString(COLUMN_NAME_TRACKER))?.let {
- val appId = cursor.getString(COLUMN_NAME_APPID)
- countByApp[appId] = countByApp.getOrDefault(appId, 0) + 1
- }
+ var calls: Pair<Int, Int> = 0 to 0
+ if (cursor.moveToNext()) {
+ val contacted = cursor.getInt(PROJECTION_NAME_CONTACTED_SUM)
+ val blocked = cursor.getInt(PROJECTION_NAME_BLOCKED_SUM)
+ calls = blocked to contacted - blocked
}
cursor.close()
db.close()
- return countByApp
+ return calls
}
}
- fun getCallsByAppIds(periodCount: Int, periodUnit: TemporalUnit): Map<String, Pair<Int, Int>> {
+ fun getMostLeakedAppId(periodCount: Int, periodUnit: TemporalUnit): String {
synchronized(lock) {
val minTimestamp = getPeriodStartTs(periodCount, periodUnit)
val db = readableDatabase
val selection = "$COLUMN_NAME_TIMESTAMP >= ?"
val selectionArg = arrayOf("" + minTimestamp)
val projection = "$COLUMN_NAME_APPID, " +
- "SUM($COLUMN_NAME_NUMBER_CONTACTED) $PROJECTION_NAME_CONTACTED_SUM," +
- "SUM($COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_BLOCKED_SUM"
+ "SUM($COLUMN_NAME_NUMBER_CONTACTED - $COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_LEAKED_SUM"
val cursor = db.rawQuery(
"SELECT $projection FROM $TABLE_NAME" +
" WHERE $selection" +
- " GROUP BY $COLUMN_NAME_APPID",
+ " GROUP BY $COLUMN_NAME_APPID" +
+ " ORDER BY $PROJECTION_NAME_LEAKED_SUM DESC LIMIT 1",
selectionArg
)
- val callsByApp = HashMap<String, Pair<Int, Int>>()
+ var appId = ""
+ if (cursor.moveToNext()) {
+ appId = cursor.getString(COLUMN_NAME_APPID)
+ }
+ cursor.close()
+ db.close()
+ return appId
+ }
+ }
+
+ fun getDistinctTrackerAndApp(): List<Pair<String, String>> {
+ synchronized(lock) {
+ val db = readableDatabase
+ val projection = "$COLUMN_NAME_APPID, $COLUMN_NAME_TRACKER"
+ val cursor = db.rawQuery(
+ "SELECT DISTINCT $projection FROM $TABLE_NAME", // +
+ arrayOf()
+ )
+
+ val res = mutableListOf<Pair<String, String>>()
while (cursor.moveToNext()) {
- val contacted = cursor.getInt(PROJECTION_NAME_CONTACTED_SUM)
- val blocked = cursor.getInt(PROJECTION_NAME_BLOCKED_SUM)
- callsByApp[cursor.getString(COLUMN_NAME_APPID)] = blocked to contacted - blocked
+ res.add(
+ cursor.getString(COLUMN_NAME_TRACKER) to cursor.getString(COLUMN_NAME_APPID)
+ )
}
cursor.close()
db.close()
- return callsByApp
+ return res
}
}
- fun getCalls(appId: String, periodCount: Int, periodUnit: TemporalUnit): Pair<Int, Int> {
+ suspend fun getApIds(trackerId: String): List<String> = withContext(Dispatchers.IO) {
synchronized(lock) {
- val minTimestamp = getPeriodStartTs(periodCount, periodUnit)
val db = readableDatabase
- val selection = "$COLUMN_NAME_APPID = ? AND " +
- "$COLUMN_NAME_TIMESTAMP >= ?"
- val selectionArg = arrayOf("" + appId, "" + minTimestamp)
+ val columns = arrayOf(COLUMN_NAME_APPID, COLUMN_NAME_TRACKER)
+ val selection = "$COLUMN_NAME_TRACKER = ?"
+ val selectionArg = arrayOf(trackerId)
+ val cursor = db.query(
+ true,
+ TABLE_NAME,
+ columns,
+ selection,
+ selectionArg,
+ null,
+ null,
+ null,
+ null
+ )
+
+ val apIds: MutableList<String> = ArrayList()
+ while (cursor.moveToNext()) {
+ apIds.add(cursor.getString(COLUMN_NAME_APPID))
+ }
+ cursor.close()
+ db.close()
+
+ apIds
+ }
+ }
+
+ suspend fun getCallsForApp(apId: String): Pair<Int, Int> = withContext(Dispatchers.IO) {
+ synchronized(lock) {
+ val db = readableDatabase
+ val selection = "$COLUMN_NAME_APPID = ?"
+ val selectionArg = arrayOf(apId)
val projection =
"SUM($COLUMN_NAME_NUMBER_CONTACTED) $PROJECTION_NAME_CONTACTED_SUM," +
"SUM($COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_BLOCKED_SUM"
@@ -294,32 +345,31 @@ class StatsDatabase(
}
cursor.close()
db.close()
- return calls
+ calls
}
}
- fun getMostLeakedAppId(periodCount: Int, periodUnit: TemporalUnit): String {
+ suspend fun getCallsForTracker(trackerId: String): Pair<Int, Int> = withContext(Dispatchers.IO) {
synchronized(lock) {
- val minTimestamp = getPeriodStartTs(periodCount, periodUnit)
val db = readableDatabase
- val selection = "$COLUMN_NAME_TIMESTAMP >= ?"
- val selectionArg = arrayOf("" + minTimestamp)
- val projection = "$COLUMN_NAME_APPID, " +
- "SUM($COLUMN_NAME_NUMBER_CONTACTED - $COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_LEAKED_SUM"
+ val selection = "$COLUMN_NAME_TRACKER = ?"
+ val selectionArg = arrayOf(trackerId)
+ val projection =
+ "SUM($COLUMN_NAME_NUMBER_CONTACTED) $PROJECTION_NAME_CONTACTED_SUM," +
+ "SUM($COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_BLOCKED_SUM"
val cursor = db.rawQuery(
- "SELECT $projection FROM $TABLE_NAME" +
- " WHERE $selection" +
- " GROUP BY $COLUMN_NAME_APPID" +
- " ORDER BY $PROJECTION_NAME_LEAKED_SUM DESC LIMIT 1",
+ "SELECT $projection FROM $TABLE_NAME WHERE $selection",
selectionArg
)
- var appId = ""
+ var calls: Pair<Int, Int> = 0 to 0
if (cursor.moveToNext()) {
- appId = cursor.getString(COLUMN_NAME_APPID)
+ val contacted = cursor.getInt(PROJECTION_NAME_CONTACTED_SUM)
+ val blocked = cursor.getInt(PROJECTION_NAME_BLOCKED_SUM)
+ calls = blocked to contacted - blocked
}
cursor.close()
db.close()
- return appId
+ calls
}
}
@@ -386,7 +436,40 @@ class StatsDatabase(
return entry
}
- fun getTrackers(appIds: List<String>?): List<Tracker> {
+ suspend fun getTrackerIds(appIds: List<String>?): List<String> = withContext(Dispatchers.IO) {
+ synchronized(lock) {
+ val columns = arrayOf(COLUMN_NAME_TRACKER, COLUMN_NAME_APPID)
+ var selection: String? = null
+
+ var selectionArg: Array<String>? = null
+ appIds?.let { appIds ->
+ selection = "$COLUMN_NAME_APPID IN (${appIds.joinToString(", ") { "'$it'" }})"
+ selectionArg = arrayOf()
+ }
+
+ val db = readableDatabase
+ val cursor = db.query(
+ true,
+ TABLE_NAME,
+ columns,
+ selection,
+ selectionArg,
+ null,
+ null,
+ null,
+ null
+ )
+ val trackerIds: MutableList<String> = mutableListOf()
+ while (cursor.moveToNext()) {
+ trackerIds.add(cursor.getString(COLUMN_NAME_TRACKER))
+ }
+ cursor.close()
+ db.close()
+ trackerIds
+ }
+ }
+
+ suspend fun getTrackers(appIds: List<String>?): List<Tracker> = withContext(Dispatchers.IO) {
synchronized(lock) {
val columns = arrayOf(COLUMN_NAME_TRACKER, COLUMN_NAME_APPID)
var selection: String? = null
@@ -419,7 +502,7 @@ class StatsDatabase(
}
cursor.close()
db.close()
- return trackers
+ trackers
}
}
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/WhitelistRepository.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/WhitelistRepository.kt
index 429c5e9..9f37a1d 100644
--- a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/WhitelistRepository.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/WhitelistRepository.kt
@@ -23,6 +23,9 @@ import android.content.SharedPreferences
import foundation.e.advancedprivacy.data.repositories.AppListsRepository
import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
import java.io.File
class WhitelistRepository(
@@ -32,18 +35,25 @@ class WhitelistRepository(
private var appsWhitelist: Set<String> = HashSet()
private var appUidsWhitelist: Set<Int> = HashSet()
- private var trackersWhitelistByApp: MutableMap<String, MutableSet<String>> = HashMap()
- private var trackersWhitelistByUid: Map<Int, MutableSet<String>> = HashMap()
+ private var trackersWhitelist: Set<String> = HashSet()
+
+ private var apIdTrackersWhitelist: Map<String, Boolean> = emptyMap()
+ private var appUidTrackersWhitelist: Map<String, Boolean> = emptyMap()
private val prefs: SharedPreferences
companion object {
- private const val SHARED_PREFS_FILE = "trackers_whitelist_v2"
+ private const val SHARED_PREFS_FILE = "trackers_whitelist_v3"
private const val KEY_BLOCKING_ENABLED = "blocking_enabled"
private const val KEY_APPS_WHITELIST = "apps_whitelist"
- private const val KEY_APP_TRACKERS_WHITELIST_PREFIX = "app_trackers_whitelist_"
+ private const val KEY_TRACKERS_WHITELIST = "trackers_whitelist"
+ private const val KEY_APP_TRACKER_WHITELIST = "app_tracker_whitelist"
+ private const val KEY_APP_TRACKER_BLACKLIST = "app_tracker_blacklist"
+ // Deprecated keys.
private const val SHARED_PREFS_FILE_V1 = "trackers_whitelist.prefs"
+ private const val SHARED_PREFS_FILE_V2 = "trackers_whitelist_v2"
+ private const val KEY_APP_TRACKERS_WHITELIST_PREFIX = "app_trackers_whitelist_"
}
init {
@@ -56,6 +66,9 @@ class WhitelistRepository(
if (context.sharedPreferencesExists(SHARED_PREFS_FILE_V1)) {
migrate1To2(context)
}
+ if (context.sharedPreferencesExists(SHARED_PREFS_FILE_V2)) {
+ migrate2To3(context)
+ }
}
private fun Context.sharedPreferencesExists(fileName: String): Boolean {
@@ -86,7 +99,7 @@ class WhitelistRepository(
val apId = appListsRepository.getApp(uid)?.apId
apId?.let {
val trackers = prefsV1.getStringSet(key, emptySet())
- editorV2.putStringSet(buildAppTrackersKey(apId), trackers)
+ editorV2.putStringSet(KEY_APP_TRACKERS_WHITELIST_PREFIX + apId, trackers)
}
} catch (e: Exception) { }
}
@@ -98,10 +111,39 @@ class WhitelistRepository(
reloadCache()
}
+ private fun migrate2To3(context: Context) {
+ val prefsV2 = context.getSharedPreferences(SHARED_PREFS_FILE_V1, Context.MODE_PRIVATE)
+ val editorV3 = prefs.edit()
+
+ editorV3.putBoolean(KEY_BLOCKING_ENABLED, prefsV2.getBoolean(KEY_BLOCKING_ENABLED, false))
+
+ prefsV2.getStringSet(KEY_APPS_WHITELIST, null)?.let {
+ editorV3.putStringSet(KEY_APPS_WHITELIST, it)
+ }
+ editorV3.commit()
+
+ runBlocking {
+ prefsV2.all.keys.forEach { key ->
+ if (key.startsWith(KEY_APP_TRACKERS_WHITELIST_PREFIX)) {
+ runCatching {
+ val apId = key.substring(KEY_APP_TRACKERS_WHITELIST_PREFIX.length)
+ prefsV2.getStringSet(key, null)
+ ?.map { trackerId -> buildApIdTrackerKey(apId, trackerId) }
+ ?.let { setWhitelisted(it, true) }
+ }
+ }
+ }
+ }
+
+ context.deleteSharedPreferences(SHARED_PREFS_FILE_V2)
+
+ reloadCache()
+ }
+
private fun reloadCache() {
isBlockingEnabled = prefs.getBoolean(KEY_BLOCKING_ENABLED, false)
reloadAppsWhiteList()
- reloadAllAppTrackersWhiteList()
+ reloadAppTrackersWhitelist()
}
private fun reloadAppsWhiteList() {
@@ -111,24 +153,28 @@ class WhitelistRepository(
.toSet()
}
- private fun refreshAppUidTrackersWhiteList() {
- trackersWhitelistByUid = trackersWhitelistByApp.mapNotNull { (apId, value) ->
+ private fun reloadTrackersWhiteList() {
+ trackersWhitelist = prefs.getStringSet(KEY_TRACKERS_WHITELIST, HashSet()) ?: HashSet()
+ }
+
+ private fun reloadAppTrackersWhitelist() {
+ val whitelist = mutableMapOf<String, Boolean>()
+ prefs.getStringSet(KEY_APP_TRACKER_WHITELIST, HashSet())?.forEach { key ->
+ whitelist[key] = true
+ }
+
+ prefs.getStringSet(KEY_APP_TRACKER_BLACKLIST, HashSet())?.forEach { key ->
+ whitelist[key] = false
+ }
+
+ apIdTrackersWhitelist = whitelist
+ appUidTrackersWhitelist = whitelist.mapNotNull { (apIdTrackerId, isWhitelisted) ->
+ val (apId, tracker) = parseApIdTrackerKey(apIdTrackerId)
appListsRepository.getApp(apId)?.uid?.let { uid ->
- uid to value
+ buildAppUidTrackerKey(uid, tracker) to isWhitelisted
}
}.toMap()
}
- private fun reloadAllAppTrackersWhiteList() {
- val map: MutableMap<String, MutableSet<String>> = HashMap()
- prefs.all.keys.forEach { key ->
- if (key.startsWith(KEY_APP_TRACKERS_WHITELIST_PREFIX)) {
- map[key.substring(KEY_APP_TRACKERS_WHITELIST_PREFIX.length)] = (
- prefs.getStringSet(key, HashSet()) ?: HashSet()
- )
- }
- }
- trackersWhitelistByApp = map
- }
var isBlockingEnabled: Boolean = false
get() = field
@@ -149,34 +195,83 @@ class WhitelistRepository(
reloadAppsWhiteList()
}
- private fun buildAppTrackersKey(apId: String): String {
- return KEY_APP_TRACKERS_WHITELIST_PREFIX + apId
- }
+ private suspend fun setWhitelisted(keys: List<String>, isWhitelisted: Boolean) = withContext(Dispatchers.IO) {
+ val whitelist = HashSet<String>().apply {
+ prefs.getStringSet(KEY_APP_TRACKER_WHITELIST, HashSet())?.let { addAll(it) }
+ }
- fun setWhiteListed(tracker: Tracker, apId: String, isWhiteListed: Boolean) {
- val trackers = trackersWhitelistByApp.getOrDefault(apId, HashSet())
- trackersWhitelistByApp[apId] = trackers
+ val blacklist = HashSet<String>().apply {
+ prefs.getStringSet(KEY_APP_TRACKER_BLACKLIST, HashSet())?.let { addAll(it) }
+ }
- if (isWhiteListed) {
- trackers.add(tracker.id)
+ if (isWhitelisted) {
+ blacklist.removeAll(keys)
+ whitelist.addAll(keys)
} else {
- trackers.remove(tracker.id)
+ whitelist.removeAll(keys)
+ blacklist.addAll(keys)
}
- refreshAppUidTrackersWhiteList()
- prefs.edit().putStringSet(buildAppTrackersKey(apId), trackers).commit()
+
+ prefs.edit().apply {
+ putStringSet(KEY_APP_TRACKER_BLACKLIST, blacklist)
+ putStringSet(KEY_APP_TRACKER_WHITELIST, whitelist)
+ commit()
+ }
+ reloadAppTrackersWhitelist()
+ }
+
+ suspend fun setWhiteListed(tracker: Tracker, apId: String, isWhitelisted: Boolean) {
+ setWhitelisted(listOf(buildApIdTrackerKey(apId, tracker.id)), isWhitelisted)
+ }
+
+ suspend fun setWhitelistedTrackersForApp(apId: String, trackerIds: List<String>, isWhitelisted: Boolean) = withContext(
+ Dispatchers.IO
+ ) {
+ setWhitelisted(
+ trackerIds.map { trackerId -> buildApIdTrackerKey(apId, trackerId) }, isWhitelisted
+ )
+ }
+
+ suspend fun setWhitelistedAppsForTracker(apIds: List<String>, trackerId: String, isWhitelisted: Boolean) = withContext(
+ Dispatchers.IO
+ ) {
+ setWhitelisted(
+ apIds.map { apId -> buildApIdTrackerKey(apId, trackerId) },
+ isWhitelisted
+ )
}
fun isAppWhiteListed(app: ApplicationDescription): Boolean {
return appsWhitelist.contains(app.apId)
}
- fun isWhiteListed(appUid: Int, trackerId: String?): Boolean {
- return appUidsWhitelist.contains(appUid) ||
- trackersWhitelistByUid.getOrDefault(appUid, HashSet()).contains(trackerId)
+ fun isAppWhiteListed(appUid: Int): Boolean {
+ return appUidsWhitelist.contains(appUid)
+ }
+
+ fun isWhiteListed(appUid: Int, trackerId: String?): Boolean? {
+ trackerId ?: return null
+
+ val key = buildAppUidTrackerKey(appUid, trackerId)
+ return appUidTrackersWhitelist.get(key)
+ }
+
+ private fun buildApIdTrackerKey(apId: String, trackerId: String): String {
+ return "$apId|$trackerId"
+ }
+
+ private fun parseApIdTrackerKey(key: String): Pair<String, String> {
+ return key.split("|").let { it[0] to it[1] }
+ }
+
+ private fun buildAppUidTrackerKey(appUid: Int, trackerId: String): String {
+ return "$appUid-$trackerId"
}
fun areWhiteListEmpty(): Boolean {
- return appsWhitelist.isEmpty() && trackersWhitelistByApp.all { (_, trackers) -> trackers.isEmpty() }
+ return appsWhitelist.isEmpty() &&
+ trackersWhitelist.isEmpty() &&
+ apIdTrackersWhitelist.values.none { it }
}
fun getWhiteListedApp(): List<ApplicationDescription> {
@@ -184,12 +279,64 @@ class WhitelistRepository(
}
fun getWhiteListForApp(app: ApplicationDescription): List<String> {
- return trackersWhitelistByApp[app.apId]?.toList() ?: emptyList()
+ return apIdTrackersWhitelist.entries.mapNotNull { (key, isWhitelisted) ->
+ if (!isWhitelisted) {
+ null
+ } else {
+ val (apId, tracker) = parseApIdTrackerKey(key)
+ if (apId == app.apId) {
+ tracker
+ } else {
+ null
+ }
+ }
+ }
}
fun clearWhiteList(apId: String) {
- trackersWhitelistByApp.remove(apId)
- refreshAppUidTrackersWhiteList()
- prefs.edit().remove(buildAppTrackersKey(apId)).commit()
+ val (whitelistToRemove, blacklistToRemove) = apIdTrackersWhitelist.entries
+ .filter { (key, _) -> key.startsWith(apId) }
+ .partition { (_, whitelisted) -> whitelisted }.let { (whitelistEntries, blacklistEntries) ->
+ whitelistEntries.map { it.key }.toSet() to
+ blacklistEntries.map { it.key }.toSet()
+ }
+
+ val whitelist = HashSet<String>().apply {
+ prefs.getStringSet(KEY_APP_TRACKER_WHITELIST, HashSet())?.let { addAll(it) }
+ }
+
+ val blacklist = HashSet<String>().apply {
+ prefs.getStringSet(KEY_APP_TRACKER_BLACKLIST, HashSet())?.let { addAll(it) }
+ }
+
+ whitelist.removeAll(whitelistToRemove)
+ blacklist.removeAll(blacklistToRemove)
+
+ prefs.edit().apply {
+ putStringSet(KEY_APP_TRACKER_WHITELIST, whitelist)
+ putStringSet(KEY_APP_TRACKER_BLACKLIST, blacklist)
+ commit()
+ }
+ reloadAppTrackersWhitelist()
+ }
+
+ fun setWhiteListed(tracker: Tracker, isWhiteListed: Boolean) {
+ val current = prefs.getStringSet(KEY_TRACKERS_WHITELIST, HashSet())?.toHashSet() ?: HashSet()
+
+ if (isWhiteListed) {
+ current.add(tracker.id)
+ } else {
+ current.remove(tracker.id)
+ }
+ prefs.edit().putStringSet(KEY_TRACKERS_WHITELIST, current).commit()
+ reloadTrackersWhiteList()
+ }
+
+ fun isWhiteListed(tracker: Tracker): Boolean {
+ return trackersWhitelist.contains(tracker.id)
+ }
+
+ fun isTrackerWhiteListed(trackerId: String): Boolean {
+ return trackersWhitelist.contains(trackerId)
}
}
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/FilterHostnameUseCase.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/FilterHostnameUseCase.kt
index e229cab..e0fae43 100644
--- a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/FilterHostnameUseCase.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/FilterHostnameUseCase.kt
@@ -81,7 +81,15 @@ class FilterHostnameUseCase(
private fun shouldBlock(appUid: Int, trackerId: String?): Boolean {
return whitelistRepository.isBlockingEnabled &&
- !whitelistRepository.isWhiteListed(appUid, trackerId)
+ trackerId != null &&
+ !isWhitelisted(appUid, trackerId)
+ }
+
+ fun isWhitelisted(appUid: Int, trackerId: String): Boolean {
+ return whitelistRepository.isWhiteListed(appUid, trackerId) ?: (
+ whitelistRepository.isTrackerWhiteListed(trackerId) ||
+ whitelistRepository.isAppWhiteListed(appUid)
+ )
}
private val queue = LinkedBlockingQueue<DetectedTracker>()
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/StatisticsUseCase.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/StatisticsUseCase.kt
index e7a84b8..22bd8fc 100644
--- a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/StatisticsUseCase.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/StatisticsUseCase.kt
@@ -39,25 +39,14 @@ class StatisticsUseCase(
return database.getActiveTrackersByPeriod(periodsCount, periodUnit)
}
- fun getContactedTrackersCountByApp(): Map<ApplicationDescription, Int> {
- return database.getContactedTrackersCountByAppId().mapByAppIdToApp()
- }
-
fun getContactedTrackersCount(): Int {
return database.getContactedTrackersCount()
}
- fun getTrackers(apps: List<ApplicationDescription>?): List<Tracker> {
+ suspend fun getTrackers(apps: List<ApplicationDescription>?): List<Tracker> {
return database.getTrackers(apps?.map { it.apId })
}
- fun getCallsByApps(
- periodCount: Int,
- periodUnit: TemporalUnit
- ): Map<ApplicationDescription, Pair<Int, Int>> {
- return database.getCallsByAppIds(periodCount, periodUnit).mapByAppIdToApp()
- }
-
fun getCalls(app: ApplicationDescription, periodCount: Int, periodUnit: TemporalUnit): Pair<Int, Int> {
return database.getCalls(app.apId, periodCount, periodUnit)
}