summaryrefslogtreecommitdiff
path: root/app/src/main/java/foundation
diff options
context:
space:
mode:
authorGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2022-03-03 07:36:57 +0000
committerGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2022-03-03 07:36:57 +0000
commit00620b4b24482c67541106b6b4584b3ff4f383ca (patch)
treee58b397c478d8d61cfedc541ff3361692b917883 /app/src/main/java/foundation
parent72a66e8640c21683e99e4e7d866253fe205d14f0 (diff)
Update trackers list each week #4595
Diffstat (limited to 'app/src/main/java/foundation')
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt7
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/UpdateTrackersWorker.kt53
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/data/repositories/AppListsRepository.kt29
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/data/repositories/TrackersRepository.kt23
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt8
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt8
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/ToggleTrackersAdapter.kt2
7 files changed, 90 insertions, 40 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
index 6b4035e..639e7b4 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
@@ -50,8 +50,7 @@ import kotlinx.coroutines.GlobalScope
*
* TODO: Test if this implementation is leaky.
*/
-class DependencyContainer constructor(val app: Application) {
-
+class DependencyContainer(val app: Application) {
val context: Context by lazy { app.applicationContext }
// Drivers
@@ -92,7 +91,7 @@ class DependencyContainer constructor(val app: Application) {
TrackersStatisticsUseCase(trackTrackersPrivacyModule, blockTrackersPrivacyModule, appListsRepository, context.resources)
}
- private val trackersStateUseCase by lazy {
+ val trackersStateUseCase by lazy {
TrackersStateUseCase(blockTrackersPrivacyModule, trackTrackersPrivacyModule, permissionsModule, localStateRepository, trackersRepository, appListsRepository, GlobalScope)
}
@@ -131,5 +130,7 @@ class DependencyContainer constructor(val app: Application) {
trackersStateUseCase
ipScramblingStateUseCase
fakeLocationStateUseCase
+
+ UpdateTrackersWorker.periodicUpdate(context)
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/UpdateTrackersWorker.kt b/app/src/main/java/foundation/e/privacycentralapp/UpdateTrackersWorker.kt
new file mode 100644
index 0000000..ba6bae9
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/UpdateTrackersWorker.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp
+
+import android.content.Context
+import androidx.work.CoroutineWorker
+import androidx.work.ExistingPeriodicWorkPolicy
+import androidx.work.PeriodicWorkRequestBuilder
+import androidx.work.WorkManager
+import androidx.work.WorkerParameters
+import java.time.temporal.ChronoUnit
+
+class UpdateTrackersWorker(appContext: Context, workerParams: WorkerParameters) :
+ CoroutineWorker(appContext, workerParams) {
+
+ override suspend fun doWork(): Result {
+ val trackersStateUseCase = (applicationContext as PrivacyCentralApplication)
+ .dependencyContainer.trackersStateUseCase
+
+ trackersStateUseCase.updateTrackers()
+ return Result.success()
+ }
+
+ companion object {
+ fun periodicUpdate(context: Context) {
+ val request = PeriodicWorkRequestBuilder<UpdateTrackersWorker>(
+ ChronoUnit.WEEKS.duration,
+ ChronoUnit.DAYS.duration
+ ).build()
+
+ WorkManager.getInstance(context).enqueueUniquePeriodicWork(
+ UpdateTrackersWorker::class.qualifiedName ?: "",
+ ExistingPeriodicWorkPolicy.REPLACE,
+ request
+ )
+ }
+ }
+}
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 958a536..3573d4f 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
@@ -21,6 +21,7 @@ import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.CoroutineScope
@@ -40,8 +41,10 @@ class AppListsRepository(
coroutineScope.launch {
val (visible, hidden) = splitVisibleToHidden(getAppsUsingInternet())
appDescriptions.emit(
- visible.map { it.toApplicationDescription(withIcon = true) }
- to hidden.map { it.toApplicationDescription() }
+ Pair(
+ visible.map { permissionsModule.buildApplicationDescription(it, withIcon = true) },
+ hidden.map { permissionsModule.buildApplicationDescription(it, withIcon = false) },
+ )
)
}
return appDescriptions.map { it.first.sortedBy { app -> app.label.toString().lowercase() } }
@@ -61,15 +64,18 @@ class AppListsRepository(
private val pm get() = context.packageManager
private val appDescriptions = MutableStateFlow(
- emptyList<ApplicationDescription>() to emptyList<ApplicationDescription>()
+ Pair(
+ emptyList<ApplicationDescription>(),
+ emptyList<ApplicationDescription>()
+ )
)
private fun getAppsUsingInternet(): List<ApplicationInfo> {
- return pm.getInstalledApplications(0)
- .filter {
- permissionsModule.getPermissions(it.packageName)
- .contains(Manifest.permission.INTERNET)
- }
+ return pm.getInstalledPackages(PackageManager.GET_PERMISSIONS).filter {
+ it.requestedPermissions?.contains(Manifest.permission.INTERNET) == true
+ }.map {
+ it.applicationInfo
+ }
}
private fun isNotHiddenSystemApp(app: ApplicationInfo, launcherApps: List<String>): Boolean {
@@ -102,11 +108,4 @@ class AppListsRepository(
acc
}
}
-
- private fun ApplicationInfo.toApplicationDescription(withIcon: Boolean = true) = ApplicationDescription(
- packageName = packageName,
- uid = uid,
- label = pm.getApplicationLabel(this),
- icon = if (withIcon) pm.getApplicationIcon(packageName) else null
- )
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/TrackersRepository.kt b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/TrackersRepository.kt
index c7efa84..8216a19 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/TrackersRepository.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/TrackersRepository.kt
@@ -20,13 +20,11 @@ package foundation.e.privacycentralapp.data.repositories
import android.content.Context
import android.util.Log
import com.google.gson.Gson
-import com.google.gson.annotations.SerializedName
import foundation.e.privacymodules.trackers.Tracker
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import java.io.InputStreamReader
-import java.lang.Exception
class TrackersRepository(private val context: Context) {
@@ -37,6 +35,12 @@ class TrackersRepository(private val context: Context) {
initFromAssets()
}
+ suspend fun update() {
+ val api = ETrackersApi.build()
+ val response = api.trackers()
+ trackers = mapper(response)
+ }
+
private fun initFromAssets() {
try {
val reader = InputStreamReader(context.getAssets().open("e_trackers.json"), "UTF-8")
@@ -65,8 +69,7 @@ class TrackersRepository(private val context: Context) {
id = id!!,
hostnames = hostnames!!.toSet(),
label = name!!,
- description = description,
- website = website,
+ exodusId = exodusId
)
}
}
@@ -75,14 +78,14 @@ interface ETrackersApi {
companion object {
fun build(): ETrackersApi {
val retrofit = Retrofit.Builder()
- .baseUrl("TODO")
+ .baseUrl("https://gitlab.e.foundation/e/apps/tracker-list/-/raw/main/")
.addConverterFactory(GsonConverterFactory.create())
.build()
return retrofit.create(ETrackersApi::class.java)
}
}
- @GET("TODO")
+ @GET("list/e_trackers.json")
suspend fun trackers(): ETrackersResponse
data class ETrackersResponse(val trackers: List<ETracker>) {
@@ -90,13 +93,7 @@ interface ETrackersApi {
val id: String?,
val hostnames: List<String>?,
val name: String?,
-
- val description: String?,
- @SerializedName("creation_date") val creationDate: String?,
- @SerializedName("code_signature") val codeSignature: String?,
- @SerializedName("network_signature") val networkSignature: String?,
- val website: String?,
- val categories: List<String>?,
+ val exodusId: String?
)
}
}
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 16a1a82..ecf2e7b 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
@@ -26,6 +26,7 @@ import foundation.e.privacymodules.trackers.IBlockTrackersPrivacyModule
import foundation.e.privacymodules.trackers.ITrackTrackersPrivacyModule
import foundation.e.privacymodules.trackers.Tracker
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
@@ -38,7 +39,7 @@ class TrackersStateUseCase(
private val localStateRepository: LocalStateRepository,
private val trackersRepository: TrackersRepository,
private val appListsRepository: AppListsRepository,
- coroutineScope: CoroutineScope
+ private val coroutineScope: CoroutineScope
) {
private val _areAllTrackersBlocked = MutableStateFlow(
@@ -106,4 +107,9 @@ class TrackersStateUseCase(
updateAllTrackersBlockedState()
}
+
+ fun updateTrackers() = coroutineScope.launch {
+ trackersRepository.update()
+ trackersPrivacyModule.start(trackersRepository.trackers, enableNotification = false)
+ }
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt
index b35fbca..790a5a0 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt
@@ -192,7 +192,7 @@ class AppTrackersFeature(
}
is Action.ClickTracker -> {
flowOf(
- action.tracker.getExodusId()?.let {
+ action.tracker.exodusId?.let {
try {
Effect.OpenUrlEffect(Uri.parse(exodusBaseUrl + it))
} catch (e: Exception) {
@@ -226,9 +226,3 @@ class AppTrackersFeature(
)
}
}
-
-fun Tracker.getExodusId(): String? {
- return if (id.startsWith("exodus_")) {
- id.substringAfter("exodus_")
- } else null
-}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/ToggleTrackersAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/ToggleTrackersAdapter.kt
index 82f2d2c..e77b61f 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/ToggleTrackersAdapter.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/ToggleTrackersAdapter.kt
@@ -46,7 +46,7 @@ class ToggleTrackersAdapter(
fun bind(item: Pair<Tracker, Boolean>, isEnabled: Boolean) {
val text = item.first.label
- if (item.first.website != null) {
+ if (item.first.exodusId != null) {
title.setTextColor(ContextCompat.getColor(title.context, R.color.accent))
val spannable = SpannableString(text)
spannable.setSpan(UnderlineSpan(), 0, spannable.length, 0)