summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2023-09-12 06:17:39 +0000
committerGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2023-09-12 06:17:39 +0000
commita38472602d259b6c265660bf3b0ba472f20c6a7f (patch)
tree59c58e58cfef0e370f39bd9c150e36c6dfcb50c0
parent1a77e3924bc78eabca7b859ef62be30bbf2476ad (diff)
parent53f4a9ce311d612d43fa770cf7e8f8e98fbb43a0 (diff)
Merge branch '2-privacymodules_to_clean_archi' into 'main'
2: organise module with clean archi, use Koin for injection. See merge request e/os/advanced-privacy!144
-rw-r--r--app/build.gradle8
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt57
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/DependencyContainer.kt210
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt124
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/Notifications.kt6
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/common/ToggleAppsAdapter.kt2
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt5
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/data/repositories/LocalStateRepository.kt2
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/data/repositories/TrackersRepository.kt133
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/entities/AppWithCounts.kt1
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/AppListUseCase.kt2
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/FakeLocationStateUseCase.kt12
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/GetQuickPrivacyStateUseCase.kt4
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/IpScramblingStateUseCase.kt24
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStateUseCase.kt61
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStatisticsUseCase.kt115
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/UpdateWidgetUseCase.kt33
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardFragment.kt12
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyFragment.kt12
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyState.kt2
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyViewModel.kt4
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/location/FakeLocationFragment.kt12
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt11
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersFragment.kt14
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersState.kt4
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersViewModel.kt4
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/ToggleTrackersAdapter.kt2
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/widget/WidgetCommandReceiver.kt11
-rw-r--r--core/.gitignore (renamed from privacymodule-api/.gitignore)0
-rw-r--r--core/build.gradle52
-rw-r--r--core/consumer-rules.pro (renamed from privacymodule-api/consumer-rules.pro)0
-rw-r--r--core/proguard-rules.pro (renamed from privacymodule-api/proguard-rules.pro)0
-rw-r--r--core/src/main/AndroidManifest.xml (renamed from privacymodule-api/src/main/AndroidManifest.xml)3
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/core/KoinModule.kt23
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/core/utils/CoroutinesUtils.kt45
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/data/repositories/AppListsRepository.kt (renamed from app/src/main/java/foundation/e/advancedprivacy/data/repositories/AppListsRepository.kt)29
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/domain/entities/AppOpModes.kt (renamed from privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/AppOpModes.kt)2
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/domain/entities/ApplicationDescription.kt (renamed from privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/ApplicationDescription.kt)2
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/domain/entities/PermissionDescription.kt (renamed from privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/PermissionDescription.kt)2
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/APermissionsPrivacyModule.kt (renamed from privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/APermissionsPrivacyModule.kt)10
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/IPermissionsPrivacyModule.kt (renamed from privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/IPermissionsPrivacyModule.kt)11
-rw-r--r--fakelocation/build.gradle8
-rw-r--r--fakelocation/fakelocationdemo/build.gradle2
-rw-r--r--fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt10
-rw-r--r--fakelocation/src/main/AndroidManifest.xml3
-rw-r--r--fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/KoinModule.kt9
-rw-r--r--fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/domain/usecases/FakeLocationModule.kt (renamed from fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt)11
-rw-r--r--fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/services/FakeLocationService.kt (renamed from fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt)3
-rw-r--r--fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/IFakeLocationModule.kt41
-rw-r--r--gradle/libs.versions.toml5
-rw-r--r--ipscrambling/build.gradle1
m---------ipscrambling/orbotservice0
-rw-r--r--ipscrambling/src/main/AndroidManifest.xml2
-rw-r--r--ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/IpScramblerModule.kt (renamed from ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt)41
-rw-r--r--ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt8
-rw-r--r--ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt54
-rw-r--r--permissionse/build.gradle2
-rw-r--r--permissionse/src/main/AndroidManifest.xml19
-rw-r--r--permissionse/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModule.kt (renamed from permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt)11
-rw-r--r--permissionsstandalone/build.gradle2
-rw-r--r--permissionsstandalone/src/main/AndroidManifest.xml3
-rw-r--r--permissionsstandalone/src/main/java/foundation/e/advancedprivacy/permissions/externalinterfaces/PermissionsPrivacyModule.kt (renamed from permissionsstandalone/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt)7
-rw-r--r--privacymodule-api/build.gradle111
-rw-r--r--privacymodule-api/src/main/java/foundation/e/privacymodules/DependencyInjector.kt31
-rw-r--r--privacymodule-api/src/main/java/foundation/e/privacymodules/trackers/IDNSBlocker.kt26
-rw-r--r--settings.gradle4
-rw-r--r--trackers/build.gradle9
-rw-r--r--trackers/src/main/AndroidManifest.xml5
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/KoinModule.kt72
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/ETrackersResponse.kt10
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/RemoteTrackersListRepository.kt61
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/StatsDatabase.kt (renamed from trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt)22
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/TrackersRepository.kt109
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/WhitelistRepository.kt (renamed from trackers/src/main/java/foundation/e/privacymodules/trackers/data/WhitelistRepository.kt)46
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/entities/Tracker.kt (renamed from trackers/src/main/java/foundation/e/privacymodules/trackers/api/Tracker.kt)2
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/DNSBlocker.kt (renamed from trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerRunnable.kt)68
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/StatisticsUseCase.kt (renamed from trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt)57
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/TrackersLogger.kt (renamed from trackers/src/main/java/foundation/e/privacymodules/trackers/TrackersLogger.kt)49
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/UpdateTrackerListUseCase.kt29
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/services/DNSBlockerService.kt (renamed from trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerService.kt)45
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/services/ForegroundStarter.kt (renamed from trackers/src/main/java/foundation/e/privacymodules/trackers/ForegroundStarter.kt)2
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/services/UpdateTrackersWorker.kt (renamed from app/src/main/java/foundation/e/advancedprivacy/UpdateTrackersWorker.kt)9
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/api/BlockTrackersPrivacyModule.kt98
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/api/IBlockTrackersPrivacyModule.kt98
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt110
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt126
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/data/TrackersRepository.kt57
87 files changed, 975 insertions, 1589 deletions
diff --git a/app/build.gradle b/app/build.gradle
index af05ec0..5ce72f3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -140,7 +140,7 @@ android {
}
dependencies {
- implementation project(':privacymodule-api')
+ implementation project(':core')
standaloneImplementation project(':permissionsstandalone')
eImplementation project(':permissionse')
@@ -160,15 +160,13 @@ dependencies {
libs.androidx.fragment.ktx,
libs.androidx.lifecycle.runtime,
libs.androidx.lifecycle.viewmodel,
- libs.androidx.work.ktx,
+
+ libs.bundles.koin,
libs.google.material,
libs.androidx.navigation.fragment,
libs.androidx.navigation.ui,
- libs.retrofit,
- libs.retrofit.scalars,
-
libs.maplibre,
libs.mpandroidcharts,
diff --git a/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt b/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt
index 9ce0c2b..0af2a0e 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt
@@ -18,17 +18,64 @@
package foundation.e.advancedprivacy
import android.app.Application
+import android.content.Intent
+import foundation.e.advancedprivacy.common.WarningDialog
+import foundation.e.advancedprivacy.domain.usecases.FakeLocationStateUseCase
+import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase
+import foundation.e.advancedprivacy.domain.usecases.IpScramblingStateUseCase
+import foundation.e.advancedprivacy.domain.usecases.ShowFeaturesWarningUseCase
+import foundation.e.advancedprivacy.domain.usecases.TrackersStateUseCase
+import foundation.e.advancedprivacy.domain.usecases.TrackersStatisticsUseCase
+import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
+import foundation.e.advancedprivacy.trackers.services.DNSBlockerService
+import foundation.e.advancedprivacy.trackers.services.UpdateTrackersWorker
import foundation.e.lib.telemetry.Telemetry
+import kotlinx.coroutines.CoroutineScope
+import org.koin.android.ext.koin.androidContext
+import org.koin.core.context.startKoin
+import org.koin.java.KoinJavaComponent.get
class AdvancedPrivacyApplication : Application() {
-
- // Initialize the dependency container.
- val dependencyContainer: DependencyContainer by lazy { DependencyContainer(this) }
-
override fun onCreate() {
super.onCreate()
Telemetry.init(BuildConfig.SENTRY_DSN, this, true)
- dependencyContainer.initBackgroundSingletons()
+ startKoin {
+ androidContext(this@AdvancedPrivacyApplication)
+ modules(appModule)
+ }
+ initBackgroundSingletons()
+ }
+
+ private fun initBackgroundSingletons() {
+ UpdateTrackersWorker.periodicUpdate(this)
+
+ WarningDialog.startListening(
+ get(ShowFeaturesWarningUseCase::class.java),
+ get(CoroutineScope::class.java),
+ this
+ )
+
+ Widget.startListening(
+ this,
+ get(GetQuickPrivacyStateUseCase::class.java),
+ get(TrackersStatisticsUseCase::class.java),
+ )
+
+ Notifications.startListening(
+ this,
+ get(GetQuickPrivacyStateUseCase::class.java),
+ get(IPermissionsPrivacyModule::class.java),
+ get(CoroutineScope::class.java),
+ )
+
+ get<IpScramblingStateUseCase>(IpScramblingStateUseCase::class.java)
+ get<FakeLocationStateUseCase>(FakeLocationStateUseCase::class.java)
+ get<TrackersStateUseCase>(TrackersStateUseCase::class.java)
+
+ val intent = Intent(this, DNSBlockerService::class.java)
+ intent.action = DNSBlockerService.ACTION_START
+ intent.putExtra(DNSBlockerService.EXTRA_ENABLE_NOTIFICATION, false)
+ startService(intent)
}
}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/DependencyContainer.kt b/app/src/main/java/foundation/e/advancedprivacy/DependencyContainer.kt
deleted file mode 100644
index f6f2038..0000000
--- a/app/src/main/java/foundation/e/advancedprivacy/DependencyContainer.kt
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2023 MURENA SAS
- * Copyright (C) 2021 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.advancedprivacy
-
-import android.app.Application
-import android.content.Context
-import android.os.Process
-import androidx.lifecycle.DEFAULT_ARGS_KEY
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
-import androidx.lifecycle.viewmodel.CreationExtras
-import foundation.e.advancedprivacy.common.WarningDialog
-import foundation.e.advancedprivacy.data.repositories.AppListsRepository
-import foundation.e.advancedprivacy.data.repositories.LocalStateRepository
-import foundation.e.advancedprivacy.data.repositories.TrackersRepository
-import foundation.e.advancedprivacy.domain.usecases.AppListUseCase
-import foundation.e.advancedprivacy.domain.usecases.FakeLocationStateUseCase
-import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase
-import foundation.e.advancedprivacy.domain.usecases.IpScramblingStateUseCase
-import foundation.e.advancedprivacy.domain.usecases.ShowFeaturesWarningUseCase
-import foundation.e.advancedprivacy.domain.usecases.TrackersStateUseCase
-import foundation.e.advancedprivacy.domain.usecases.TrackersStatisticsUseCase
-import foundation.e.advancedprivacy.dummy.CityDataSource
-import foundation.e.advancedprivacy.features.dashboard.DashboardViewModel
-import foundation.e.advancedprivacy.features.internetprivacy.InternetPrivacyViewModel
-import foundation.e.advancedprivacy.features.location.FakeLocationViewModel
-import foundation.e.advancedprivacy.features.trackers.TrackersViewModel
-import foundation.e.advancedprivacy.features.trackers.apptrackers.AppTrackersFragmentArgs
-import foundation.e.advancedprivacy.features.trackers.apptrackers.AppTrackersViewModel
-import foundation.e.privacymodules.fakelocation.FakeLocationModule
-import foundation.e.privacymodules.ipscrambler.IIpScramblerModule
-import foundation.e.privacymodules.ipscrambler.IpScramblerModule
-import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.permissions.data.ProfileType
-import foundation.e.privacymodules.trackers.api.BlockTrackersPrivacyModule
-import foundation.e.privacymodules.trackers.api.TrackTrackersPrivacyModule
-import kotlinx.coroutines.DelicateCoroutinesApi
-import kotlinx.coroutines.GlobalScope
-
-/**
- * Simple container to hold application wide dependencies.
- *
- */
-@OptIn(DelicateCoroutinesApi::class)
-class DependencyContainer(val app: Application) {
- val context: Context by lazy { app.applicationContext }
-
- // Drivers
- private val fakeLocationModule: FakeLocationModule by lazy { FakeLocationModule(app.applicationContext) }
- private val permissionsModule by lazy { PermissionsPrivacyModule(app.applicationContext) }
- private val ipScramblerModule: IIpScramblerModule by lazy { IpScramblerModule(app.applicationContext) }
-
- private val appDesc by lazy {
- ApplicationDescription(
- packageName = context.packageName,
- uid = Process.myUid(),
- label = context.resources.getString(R.string.app_name),
- icon = null,
- profileId = -1,
- profileType = ProfileType.MAIN
- )
- }
-
- private val blockTrackersPrivacyModule by lazy { BlockTrackersPrivacyModule.getInstance(context) }
- private val trackTrackersPrivacyModule by lazy { TrackTrackersPrivacyModule.getInstance(context) }
-
- // Repositories
- private val localStateRepository by lazy { LocalStateRepository(context) }
- private val trackersRepository by lazy { TrackersRepository(context) }
- private val appListsRepository by lazy { AppListsRepository(permissionsModule, context, GlobalScope) }
-
- // Usecases
- val getQuickPrivacyStateUseCase by lazy {
- GetQuickPrivacyStateUseCase(localStateRepository)
- }
- private val ipScramblingStateUseCase by lazy {
- IpScramblingStateUseCase(
- ipScramblerModule, permissionsModule, appDesc, localStateRepository,
- appListsRepository, GlobalScope
- )
- }
- private val appListUseCase = AppListUseCase(appListsRepository)
-
- val trackersStatisticsUseCase by lazy {
- TrackersStatisticsUseCase(trackTrackersPrivacyModule, blockTrackersPrivacyModule, appListsRepository, context.resources)
- }
-
- val trackersStateUseCase by lazy {
- TrackersStateUseCase(blockTrackersPrivacyModule, trackTrackersPrivacyModule, localStateRepository, trackersRepository, appListsRepository, GlobalScope)
- }
-
- private val fakeLocationStateUseCase by lazy {
- FakeLocationStateUseCase(
- fakeLocationModule, permissionsModule, localStateRepository, CityDataSource, appDesc, context, GlobalScope
- )
- }
-
- val showFeaturesWarningUseCase by lazy {
- ShowFeaturesWarningUseCase(localStateRepository = localStateRepository)
- }
-
- val viewModelsFactory by lazy {
- ViewModelsFactory(
- getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase,
- trackersStatisticsUseCase = trackersStatisticsUseCase,
- trackersStateUseCase = trackersStateUseCase,
- fakeLocationStateUseCase = fakeLocationStateUseCase,
- ipScramblerModule = ipScramblerModule,
- ipScramblingStateUseCase = ipScramblingStateUseCase,
- appListUseCase = appListUseCase
- )
- }
-
- // Background
- fun initBackgroundSingletons() {
- trackersStateUseCase
- ipScramblingStateUseCase
- fakeLocationStateUseCase
-
- UpdateTrackersWorker.periodicUpdate(context)
-
- WarningDialog.startListening(
- showFeaturesWarningUseCase,
- GlobalScope,
- context
- )
-
- Widget.startListening(
- context,
- getQuickPrivacyStateUseCase,
- trackersStatisticsUseCase,
- )
-
- Notifications.startListening(
- context,
- getQuickPrivacyStateUseCase,
- permissionsModule,
- GlobalScope
- )
- }
-}
-
-@Suppress("LongParameterList")
-class ViewModelsFactory(
- private val getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
- private val trackersStatisticsUseCase: TrackersStatisticsUseCase,
- private val trackersStateUseCase: TrackersStateUseCase,
- private val fakeLocationStateUseCase: FakeLocationStateUseCase,
- private val ipScramblerModule: IIpScramblerModule,
- private val ipScramblingStateUseCase: IpScramblingStateUseCase,
- private val appListUseCase: AppListUseCase
-) : ViewModelProvider.Factory {
-
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
- return when (modelClass) {
- AppTrackersViewModel::class.java -> {
- val app = extras[DEFAULT_ARGS_KEY]?.let {
- appListUseCase.getApp(AppTrackersFragmentArgs.fromBundle(it).appUid)
- } ?: appListUseCase.dummySystemApp
-
- AppTrackersViewModel(
- app = app,
- trackersStateUseCase = trackersStateUseCase,
- trackersStatisticsUseCase = trackersStatisticsUseCase,
- getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase
- )
- }
-
- TrackersViewModel::class.java ->
- TrackersViewModel(
- trackersStatisticsUseCase = trackersStatisticsUseCase
- )
- FakeLocationViewModel::class.java ->
- FakeLocationViewModel(
- fakeLocationStateUseCase = fakeLocationStateUseCase
- )
- InternetPrivacyViewModel::class.java ->
- InternetPrivacyViewModel(
- ipScramblerModule = ipScramblerModule,
- getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase,
- ipScramblingStateUseCase = ipScramblingStateUseCase,
- appListUseCase = appListUseCase
- )
- DashboardViewModel::class.java ->
- DashboardViewModel(
- getPrivacyStateUseCase = getQuickPrivacyStateUseCase,
- trackersStatisticsUseCase = trackersStatisticsUseCase
- )
- else -> throw IllegalArgumentException("Unknown class $modelClass")
- } as T
- }
-}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt b/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt
new file mode 100644
index 0000000..534aa6b
--- /dev/null
+++ b/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt
@@ -0,0 +1,124 @@
+package foundation.e.advancedprivacy
+
+import android.content.res.Resources
+import android.os.Process
+import foundation.e.advancedprivacy.core.coreModule
+import foundation.e.advancedprivacy.data.repositories.LocalStateRepository
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.ProfileType
+import foundation.e.advancedprivacy.domain.usecases.AppListUseCase
+import foundation.e.advancedprivacy.domain.usecases.FakeLocationStateUseCase
+import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase
+import foundation.e.advancedprivacy.domain.usecases.IpScramblingStateUseCase
+import foundation.e.advancedprivacy.domain.usecases.ShowFeaturesWarningUseCase
+import foundation.e.advancedprivacy.domain.usecases.TrackersStateUseCase
+import foundation.e.advancedprivacy.domain.usecases.TrackersStatisticsUseCase
+import foundation.e.advancedprivacy.dummy.CityDataSource
+import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
+import foundation.e.advancedprivacy.fakelocation.fakelocationModule
+import foundation.e.advancedprivacy.features.dashboard.DashboardViewModel
+import foundation.e.advancedprivacy.features.internetprivacy.InternetPrivacyViewModel
+import foundation.e.advancedprivacy.features.location.FakeLocationViewModel
+import foundation.e.advancedprivacy.features.trackers.TrackersViewModel
+import foundation.e.advancedprivacy.features.trackers.apptrackers.AppTrackersViewModel
+import foundation.e.advancedprivacy.ipscrambler.ipScramblerModule
+import foundation.e.advancedprivacy.permissions.externalinterfaces.PermissionsPrivacyModule
+import foundation.e.advancedprivacy.trackers.trackersModule
+import org.koin.android.ext.koin.androidContext
+import org.koin.androidx.viewmodel.dsl.viewModel
+import org.koin.androidx.viewmodel.dsl.viewModelOf
+import org.koin.core.module.dsl.singleOf
+import org.koin.core.qualifier.named
+import org.koin.dsl.module
+
+val appModule = module {
+ includes(coreModule, trackersModule, fakelocationModule, ipScramblerModule)
+
+ factory<Resources> { androidContext().resources }
+ single {
+ LocalStateRepository(context = androidContext())
+ }
+
+ single<ApplicationDescription>(named("AdvancedPrivacy")) {
+ ApplicationDescription(
+ packageName = androidContext().packageName,
+ uid = Process.myUid(),
+ label = androidContext().resources.getString(R.string.app_name),
+ icon = null,
+ profileId = -1,
+ profileType = ProfileType.MAIN
+ )
+ }
+
+ single<ApplicationDescription>(named("DummySystemApp")) {
+ ApplicationDescription(
+ packageName = "foundation.e.dummysystemapp",
+ uid = -1,
+ label = androidContext().getString(R.string.dummy_system_app_label),
+ icon = androidContext().getDrawable(R.drawable.ic_e_app_logo),
+ profileId = -1,
+ profileType = ProfileType.MAIN
+ )
+ }
+
+ single<ApplicationDescription>(named("DummyCompatibilityApp")) {
+ ApplicationDescription(
+ packageName = "foundation.e.dummyappscompatibilityapp",
+ uid = -2,
+ label = androidContext().getString(R.string.dummy_apps_compatibility_app_label),
+ icon = androidContext().getDrawable(R.drawable.ic_apps_compatibility_components),
+ profileId = -1,
+ profileType = ProfileType.MAIN
+ )
+ }
+
+ single { CityDataSource }
+
+ singleOf(::AppListUseCase)
+ single {
+ FakeLocationStateUseCase(
+ fakeLocationModule = get(),
+ permissionsModule = get(),
+ localStateRepository = get(),
+ citiesRepository = get(),
+ appDesc = get(named("AdvancedPrivacy")),
+ appContext = androidContext(),
+ coroutineScope = get()
+ )
+ }
+
+ singleOf(::GetQuickPrivacyStateUseCase)
+ single {
+ IpScramblingStateUseCase(
+ ipScramblerModule = get(),
+ permissionsPrivacyModule = get(),
+ appDesc = get(named("AdvancedPrivacy")),
+ localStateRepository = get(),
+ appListsRepository = get(),
+ coroutineScope = get()
+ )
+ }
+ singleOf(::ShowFeaturesWarningUseCase)
+ singleOf(::TrackersStateUseCase)
+ singleOf(::TrackersStatisticsUseCase)
+
+ single<IPermissionsPrivacyModule> {
+ PermissionsPrivacyModule(context = androidContext())
+ }
+
+ viewModel { parameters ->
+ val appListUseCase: AppListUseCase = get()
+ val app = appListUseCase.getApp(parameters.get())
+
+ AppTrackersViewModel(
+ app = app,
+ trackersStateUseCase = get(),
+ trackersStatisticsUseCase = get(),
+ getQuickPrivacyStateUseCase = get()
+ )
+ }
+ viewModelOf(::TrackersViewModel)
+ viewModelOf(::FakeLocationViewModel)
+ viewModelOf(::InternetPrivacyViewModel)
+ viewModelOf(::DashboardViewModel)
+}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt
index 291f9bc..cd85e9a 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt
@@ -28,8 +28,8 @@ import androidx.core.app.NotificationManagerCompat
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode
import foundation.e.advancedprivacy.domain.entities.MainFeatures
import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase
+import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
import foundation.e.advancedprivacy.main.MainActivity
-import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
@@ -69,7 +69,7 @@ object Notifications {
fun startListening(
appContext: Context,
getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
- permissionsPrivacyModule: PermissionsPrivacyModule,
+ permissionsPrivacyModule: IPermissionsPrivacyModule,
appScope: CoroutineScope
) {
createNotificationFlagChannel(
@@ -118,7 +118,7 @@ object Notifications {
private fun createNotificationFlagChannel(
context: Context,
- permissionsPrivacyModule: PermissionsPrivacyModule,
+ permissionsPrivacyModule: IPermissionsPrivacyModule,
channelId: String,
@StringRes channelName: Int,
@StringRes channelDescription: Int,
diff --git a/app/src/main/java/foundation/e/advancedprivacy/common/ToggleAppsAdapter.kt b/app/src/main/java/foundation/e/advancedprivacy/common/ToggleAppsAdapter.kt
index d8ee8ea..8a0cc83 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/common/ToggleAppsAdapter.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/common/ToggleAppsAdapter.kt
@@ -25,7 +25,7 @@ import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import foundation.e.advancedprivacy.R
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
class ToggleAppsAdapter(
private val itemsLayout: Int,
diff --git a/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt b/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt
index 3f3f66c..1a83692 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt
@@ -27,7 +27,6 @@ import android.util.Log
import android.view.View
import android.widget.CheckBox
import androidx.appcompat.app.AlertDialog
-import foundation.e.advancedprivacy.AdvancedPrivacyApplication
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.domain.entities.MainFeatures
import foundation.e.advancedprivacy.domain.entities.MainFeatures.FAKE_LOCATION
@@ -38,6 +37,7 @@ import foundation.e.advancedprivacy.main.MainActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
+import org.koin.java.KoinJavaComponent.get
class WarningDialog : Activity() {
companion object {
@@ -112,8 +112,7 @@ class WarningDialog : Activity() {
}
) { _, _ ->
if (checkbox.isChecked()) {
- (application as AdvancedPrivacyApplication)
- .dependencyContainer.showFeaturesWarningUseCase
+ get<ShowFeaturesWarningUseCase>(ShowFeaturesWarningUseCase::class.java)
.doNotShowAgain(feature)
}
finish()
diff --git a/app/src/main/java/foundation/e/advancedprivacy/data/repositories/LocalStateRepository.kt b/app/src/main/java/foundation/e/advancedprivacy/data/repositories/LocalStateRepository.kt
index 3f73c78..ba2836f 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/data/repositories/LocalStateRepository.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/data/repositories/LocalStateRepository.kt
@@ -18,9 +18,9 @@
package foundation.e.advancedprivacy.data.repositories
import android.content.Context
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode
import foundation.e.advancedprivacy.domain.entities.LocationMode
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
diff --git a/app/src/main/java/foundation/e/advancedprivacy/data/repositories/TrackersRepository.kt b/app/src/main/java/foundation/e/advancedprivacy/data/repositories/TrackersRepository.kt
deleted file mode 100644
index 568d76b..0000000
--- a/app/src/main/java/foundation/e/advancedprivacy/data/repositories/TrackersRepository.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.advancedprivacy.data.repositories
-
-import android.content.Context
-import com.google.gson.Gson
-import foundation.e.privacymodules.trackers.api.Tracker
-import retrofit2.Retrofit
-import retrofit2.converter.scalars.ScalarsConverterFactory
-import retrofit2.http.GET
-import timber.log.Timber
-import java.io.File
-import java.io.FileInputStream
-import java.io.FileWriter
-import java.io.IOException
-import java.io.InputStreamReader
-import java.io.PrintWriter
-
-class TrackersRepository(private val context: Context) {
-
- private val eTrackerFileName = "e_trackers.json"
- private val eTrackerFile = File(context.filesDir.absolutePath, eTrackerFileName)
-
- var trackers: List<Tracker> = emptyList()
- private set
-
- init {
- initTrackersFile()
- }
-
- suspend fun update() {
- val api = ETrackersApi.build()
- try {
- saveData(eTrackerFile, api.trackers())
- initTrackersFile()
- } catch (e: Exception) {
- Timber.e("While updating trackers", e)
- }
- }
-
- private fun initTrackersFile() {
- try {
- var inputStream = context.assets.open(eTrackerFileName)
- if (eTrackerFile.exists()) {
- inputStream = FileInputStream(eTrackerFile)
- }
- val reader = InputStreamReader(inputStream, "UTF-8")
- val trackerResponse =
- Gson().fromJson(reader, ETrackersApi.ETrackersResponse::class.java)
-
- trackers = mapper(trackerResponse)
-
- reader.close()
- inputStream.close()
- } catch (e: Exception) {
- Timber.e("While parsing trackers in assets", e)
- }
- }
-
- private fun mapper(response: ETrackersApi.ETrackersResponse): List<Tracker> {
- return response.trackers.mapNotNull {
- try {
- it.toTracker()
- } catch (e: Exception) {
- null
- }
- }
- }
-
- private fun ETrackersApi.ETrackersResponse.ETracker.toTracker(): Tracker {
- return Tracker(
- id = id!!,
- hostnames = hostnames!!.toSet(),
- label = name!!,
- exodusId = exodusId
- )
- }
-
- private fun saveData(file: File, data: String): Boolean {
- try {
- val fos = FileWriter(file, false)
- val ps = PrintWriter(fos)
- ps.apply {
- print(data)
- flush()
- close()
- }
- return true
- } catch (e: IOException) {
- e.printStackTrace()
- }
- return false
- }
-}
-
-interface ETrackersApi {
- companion object {
- fun build(): ETrackersApi {
- val retrofit = Retrofit.Builder()
- .baseUrl("https://gitlab.e.foundation/e/os/tracker-list/-/raw/main/")
- .addConverterFactory(ScalarsConverterFactory.create())
- .build()
- return retrofit.create(ETrackersApi::class.java)
- }
- }
-
- @GET("list/e_trackers.json")
- suspend fun trackers(): String
-
- data class ETrackersResponse(val trackers: List<ETracker>) {
- data class ETracker(
- val id: String?,
- val hostnames: List<String>?,
- val name: String?,
- val exodusId: String?
- )
- }
-}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/AppWithCounts.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/entities/AppWithCounts.kt
index 4169ecc..344e689 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/AppWithCounts.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/domain/entities/AppWithCounts.kt
@@ -19,7 +19,6 @@
package foundation.e.advancedprivacy.domain.entities
import android.graphics.drawable.Drawable
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
data class AppWithCounts(
val appDesc: ApplicationDescription,
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/AppListUseCase.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/AppListUseCase.kt
index 8d38ee8..dfd32b6 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/AppListUseCase.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/AppListUseCase.kt
@@ -18,7 +18,7 @@
package foundation.e.advancedprivacy.domain.usecases
import foundation.e.advancedprivacy.data.repositories.AppListsRepository
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import kotlinx.coroutines.flow.Flow
class AppListUseCase(
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/FakeLocationStateUseCase.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/FakeLocationStateUseCase.kt
index 8831fff..30c8e6b 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/FakeLocationStateUseCase.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/FakeLocationStateUseCase.kt
@@ -26,12 +26,12 @@ import android.location.LocationListener
import android.location.LocationManager
import android.os.Bundle
import foundation.e.advancedprivacy.data.repositories.LocalStateRepository
+import foundation.e.advancedprivacy.domain.entities.AppOpModes
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.domain.entities.LocationMode
import foundation.e.advancedprivacy.dummy.CityDataSource
-import foundation.e.privacymodules.fakelocation.IFakeLocationModule
-import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
-import foundation.e.privacymodules.permissions.data.AppOpModes
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
+import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
+import foundation.e.advancedprivacy.fakelocation.domain.usecases.FakeLocationModule
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -41,8 +41,8 @@ import timber.log.Timber
import kotlin.random.Random
class FakeLocationStateUseCase(
- private val fakeLocationModule: IFakeLocationModule,
- private val permissionsModule: PermissionsPrivacyModule,
+ private val fakeLocationModule: FakeLocationModule,
+ private val permissionsModule: IPermissionsPrivacyModule,
private val localStateRepository: LocalStateRepository,
private val citiesRepository: CityDataSource,
private val appDesc: ApplicationDescription,
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/GetQuickPrivacyStateUseCase.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/GetQuickPrivacyStateUseCase.kt
index b82918e..bc4871a 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/GetQuickPrivacyStateUseCase.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/GetQuickPrivacyStateUseCase.kt
@@ -18,11 +18,11 @@
package foundation.e.advancedprivacy.domain.usecases
import foundation.e.advancedprivacy.data.repositories.LocalStateRepository
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode
import foundation.e.advancedprivacy.domain.entities.LocationMode
import foundation.e.advancedprivacy.domain.entities.QuickPrivacyState
import foundation.e.advancedprivacy.domain.entities.TrackerMode
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
@@ -30,7 +30,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
class GetQuickPrivacyStateUseCase(
- private val localStateRepository: LocalStateRepository
+ private val localStateRepository: LocalStateRepository,
) {
val quickPrivacyState: Flow<QuickPrivacyState> = combine(
localStateRepository.blockTrackers,
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/IpScramblingStateUseCase.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/IpScramblingStateUseCase.kt
index 70607cf..a7ed660 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/IpScramblingStateUseCase.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/IpScramblingStateUseCase.kt
@@ -19,14 +19,14 @@ package foundation.e.advancedprivacy.domain.usecases
import foundation.e.advancedprivacy.data.repositories.AppListsRepository
import foundation.e.advancedprivacy.data.repositories.LocalStateRepository
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode.HIDE_IP
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode.HIDE_IP_LOADING
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode.REAL_IP
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode.REAL_IP_LOADING
-import foundation.e.privacymodules.ipscrambler.IIpScramblerModule
-import foundation.e.privacymodules.permissions.IPermissionsPrivacyModule
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
+import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
+import foundation.e.advancedprivacy.ipscrambler.IpScramblerModule
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
@@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
class IpScramblingStateUseCase(
- private val ipScramblerModule: IIpScramblerModule,
+ private val ipScramblerModule: IpScramblerModule,
private val permissionsPrivacyModule: IPermissionsPrivacyModule,
private val appDesc: ApplicationDescription,
private val localStateRepository: LocalStateRepository,
@@ -46,8 +46,8 @@ class IpScramblingStateUseCase(
private val coroutineScope: CoroutineScope
) {
val internetPrivacyMode: StateFlow<InternetPrivacyMode> = callbackFlow {
- val listener = object : IIpScramblerModule.Listener {
- override fun onStatusChanged(newStatus: IIpScramblerModule.Status) {
+ val listener = object : IpScramblerModule.Listener {
+ override fun onStatusChanged(newStatus: IpScramblerModule.Status) {
trySend(map(newStatus))
}
@@ -169,13 +169,13 @@ class IpScramblingStateUseCase(
}
}
- private fun map(status: IIpScramblerModule.Status): InternetPrivacyMode {
+ private fun map(status: IpScramblerModule.Status): InternetPrivacyMode {
return when (status) {
- IIpScramblerModule.Status.OFF -> REAL_IP
- IIpScramblerModule.Status.ON -> HIDE_IP
- IIpScramblerModule.Status.STARTING -> HIDE_IP_LOADING
- IIpScramblerModule.Status.STOPPING,
- IIpScramblerModule.Status.START_DISABLED -> REAL_IP_LOADING
+ IpScramblerModule.Status.OFF -> REAL_IP
+ IpScramblerModule.Status.ON -> HIDE_IP
+ IpScramblerModule.Status.STARTING -> HIDE_IP_LOADING
+ IpScramblerModule.Status.STOPPING,
+ IpScramblerModule.Status.START_DISABLED -> REAL_IP_LOADING
}
}
}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStateUseCase.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStateUseCase.kt
index 882d53f..ed15a41 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStateUseCase.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStateUseCase.kt
@@ -19,87 +19,68 @@ package foundation.e.advancedprivacy.domain.usecases
import foundation.e.advancedprivacy.data.repositories.AppListsRepository
import foundation.e.advancedprivacy.data.repositories.LocalStateRepository
-import foundation.e.advancedprivacy.data.repositories.TrackersRepository
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.trackers.api.IBlockTrackersPrivacyModule
-import foundation.e.privacymodules.trackers.api.ITrackTrackersPrivacyModule
-import foundation.e.privacymodules.trackers.api.Tracker
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.trackers.data.WhitelistRepository
+import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
class TrackersStateUseCase(
- private val blockTrackersPrivacyModule: IBlockTrackersPrivacyModule,
- private val trackersPrivacyModule: ITrackTrackersPrivacyModule,
+ private val whitelistRepository: WhitelistRepository,
private val localStateRepository: LocalStateRepository,
- private val trackersRepository: TrackersRepository,
private val appListsRepository: AppListsRepository,
- private val coroutineScope: CoroutineScope
+ coroutineScope: CoroutineScope
) {
init {
- trackersPrivacyModule.start(
- trackers = trackersRepository.trackers,
- getAppByAPId = appListsRepository::getApp,
- getAppByUid = appListsRepository::getApp,
- enableNotification = false
- )
coroutineScope.launch {
localStateRepository.blockTrackers.collect { enabled ->
- if (enabled) {
- blockTrackersPrivacyModule.enableBlocking()
- } else {
- blockTrackersPrivacyModule.disableBlocking()
- }
+ whitelistRepository.isBlockingEnabled = enabled
updateAllTrackersBlockedState()
}
}
}
private fun updateAllTrackersBlockedState() {
- localStateRepository.areAllTrackersBlocked.value = blockTrackersPrivacyModule.isBlockingEnabled() &&
- blockTrackersPrivacyModule.isWhiteListEmpty()
+ localStateRepository.areAllTrackersBlocked.value = whitelistRepository.isBlockingEnabled &&
+ whitelistRepository.areWhiteListEmpty()
}
fun isWhitelisted(app: ApplicationDescription): Boolean {
- return isWhitelisted(app, appListsRepository, blockTrackersPrivacyModule)
+ return isWhitelisted(app, appListsRepository, whitelistRepository)
}
fun toggleAppWhitelist(app: ApplicationDescription, isWhitelisted: Boolean) {
appListsRepository.applyForHiddenApps(app) {
- blockTrackersPrivacyModule.setWhiteListed(it, isWhitelisted)
+ whitelistRepository.setWhiteListed(it.apId, isWhitelisted)
}
updateAllTrackersBlockedState()
}
fun blockTracker(app: ApplicationDescription, tracker: Tracker, isBlocked: Boolean) {
appListsRepository.applyForHiddenApps(app) {
- blockTrackersPrivacyModule.setWhiteListed(tracker, it, !isBlocked)
+ whitelistRepository.setWhiteListed(tracker, it.apId, !isBlocked)
}
updateAllTrackersBlockedState()
}
fun clearWhitelist(app: ApplicationDescription) {
appListsRepository.applyForHiddenApps(
- app,
- blockTrackersPrivacyModule::clearWhiteList
- )
+ app
+ ) {
+ whitelistRepository.clearWhiteList(it.apId)
+ }
updateAllTrackersBlockedState()
}
-
- fun updateTrackers() = coroutineScope.launch {
- trackersRepository.update()
- trackersPrivacyModule.start(
- trackers = trackersRepository.trackers,
- getAppByAPId = appListsRepository::getApp,
- getAppByUid = appListsRepository::getApp,
- enableNotification = false
- )
- }
}
fun isWhitelisted(
app: ApplicationDescription,
appListsRepository: AppListsRepository,
- blockTrackersPrivacyModule: IBlockTrackersPrivacyModule
+ whitelistRepository: WhitelistRepository
+
): Boolean {
- return appListsRepository.anyForHiddenApps(app, blockTrackersPrivacyModule::isWhitelisted)
+ return appListsRepository.anyForHiddenApps(
+ app,
+ whitelistRepository::isAppWhiteListed
+ )
}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStatisticsUseCase.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStatisticsUseCase.kt
index 43e4496..b0c9f39 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStatisticsUseCase.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStatisticsUseCase.kt
@@ -22,15 +22,14 @@ import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.throttleFirst
import foundation.e.advancedprivacy.data.repositories.AppListsRepository
import foundation.e.advancedprivacy.domain.entities.AppWithCounts
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.domain.entities.TrackersPeriodicStatistics
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.trackers.api.IBlockTrackersPrivacyModule
-import foundation.e.privacymodules.trackers.api.ITrackTrackersPrivacyModule
-import foundation.e.privacymodules.trackers.api.Tracker
+import foundation.e.advancedprivacy.trackers.data.TrackersRepository
+import foundation.e.advancedprivacy.trackers.data.WhitelistRepository
+import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
+import foundation.e.advancedprivacy.trackers.domain.usecases.StatisticsUseCase
import kotlinx.coroutines.FlowPreview
-import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
@@ -41,8 +40,9 @@ import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
class TrackersStatisticsUseCase(
- private val trackTrackersPrivacyModule: ITrackTrackersPrivacyModule,
- private val blockTrackersPrivacyModule: IBlockTrackersPrivacyModule,
+ private val statisticsUseCase: StatisticsUseCase,
+ private val whitelistRepository: WhitelistRepository,
+ private val trackersRepository: TrackersRepository,
private val appListsRepository: AppListsRepository,
private val resources: Resources
) {
@@ -50,54 +50,45 @@ class TrackersStatisticsUseCase(
appListsRepository.apps()
}
- private fun rawUpdates(): Flow<Unit> = callbackFlow {
- val listener = object : ITrackTrackersPrivacyModule.Listener {
- override fun onNewData() {
- trySend(Unit)
- }
- }
- trackTrackersPrivacyModule.addListener(listener)
- awaitClose { trackTrackersPrivacyModule.removeListener(listener) }
- }
-
@OptIn(FlowPreview::class)
- fun listenUpdates(debounce: Duration = 1.seconds) = rawUpdates()
- .throttleFirst(windowDuration = debounce)
- .onStart { emit(Unit) }
+ fun listenUpdates(debounce: Duration = 1.seconds) =
+ statisticsUseCase.newDataAvailable
+ .throttleFirst(windowDuration = debounce)
+ .onStart { emit(Unit) }
fun getDayStatistics(): Pair<TrackersPeriodicStatistics, Int> {
return TrackersPeriodicStatistics(
- callsBlockedNLeaked = trackTrackersPrivacyModule.getPastDayTrackersCalls(),
+ callsBlockedNLeaked = statisticsUseCase.getTrackersCallsOnPeriod(24, ChronoUnit.HOURS),
periods = buildDayLabels(),
- trackersCount = trackTrackersPrivacyModule.getPastDayTrackersCount(),
+ trackersCount = statisticsUseCase.getActiveTrackersByPeriod(24, ChronoUnit.HOURS),
graduations = buildDayGraduations(),
- ) to trackTrackersPrivacyModule.getTrackersCount()
+ ) to statisticsUseCase.getContactedTrackersCount()
}
fun getNonBlockedTrackersCount(): Flow<Int> {
- return if (blockTrackersPrivacyModule.isBlockingEnabled())
+ return if (whitelistRepository.isBlockingEnabled)
appListsRepository.allApps().map { apps ->
val whiteListedTrackers = mutableSetOf<Tracker>()
- val whiteListedApps = blockTrackersPrivacyModule.getWhiteListedApp()
+ val whiteListedApps = whitelistRepository.getWhiteListedApp()
apps.forEach { app ->
if (app in whiteListedApps) {
- whiteListedTrackers.addAll(trackTrackersPrivacyModule.getTrackersForApp(app))
+ whiteListedTrackers.addAll(statisticsUseCase.getTrackers(listOf(app)))
} else {
- whiteListedTrackers.addAll(blockTrackersPrivacyModule.getWhiteList(app))
+ whiteListedTrackers.addAll(getWhiteList(app))
}
}
whiteListedTrackers.size
}
- else flowOf(trackTrackersPrivacyModule.getTrackersCount())
+ else flowOf(statisticsUseCase.getContactedTrackersCount())
}
fun getMostLeakedApp(): ApplicationDescription? {
- return trackTrackersPrivacyModule.getPastDayMostLeakedApp()
+ return statisticsUseCase.getMostLeakedApp(24, ChronoUnit.HOURS)
}
- fun getDayTrackersCalls() = trackTrackersPrivacyModule.getPastDayTrackersCalls()
+ fun getDayTrackersCalls() = statisticsUseCase.getTrackersCallsOnPeriod(24, ChronoUnit.HOURS)
- fun getDayTrackersCount() = trackTrackersPrivacyModule.getPastDayTrackersCount()
+ fun getDayTrackersCount() = statisticsUseCase.getActiveTrackersByPeriod(24, ChronoUnit.HOURS)
private fun buildDayGraduations(): List<String?> {
val formatter = DateTimeFormatter.ofPattern(
@@ -155,25 +146,23 @@ class TrackersStatisticsUseCase(
}
fun getDayMonthYearStatistics(): Triple<TrackersPeriodicStatistics, TrackersPeriodicStatistics, TrackersPeriodicStatistics> {
- return with(trackTrackersPrivacyModule) {
- Triple(
- TrackersPeriodicStatistics(
- callsBlockedNLeaked = getPastDayTrackersCalls(),
- periods = buildDayLabels(),
- trackersCount = getPastDayTrackersCount()
- ),
- TrackersPeriodicStatistics(
- callsBlockedNLeaked = getPastMonthTrackersCalls(),
- periods = buildMonthLabels(),
- trackersCount = getPastMonthTrackersCount()
- ),
- TrackersPeriodicStatistics(
- callsBlockedNLeaked = getPastYearTrackersCalls(),
- periods = buildYearLabels(),
- trackersCount = getPastYearTrackersCount()
- )
+ return Triple(
+ TrackersPeriodicStatistics(
+ callsBlockedNLeaked = statisticsUseCase.getTrackersCallsOnPeriod(24, ChronoUnit.HOURS),
+ periods = buildDayLabels(),
+ trackersCount = statisticsUseCase.getActiveTrackersByPeriod(24, ChronoUnit.HOURS)
+ ),
+ TrackersPeriodicStatistics(
+ callsBlockedNLeaked = statisticsUseCase.getTrackersCallsOnPeriod(30, ChronoUnit.DAYS),
+ periods = buildMonthLabels(),
+ trackersCount = statisticsUseCase.getActiveTrackersByPeriod(30, ChronoUnit.DAYS)
+ ),
+ TrackersPeriodicStatistics(
+ callsBlockedNLeaked = statisticsUseCase.getTrackersCallsOnPeriod(12, ChronoUnit.MONTHS),
+ periods = buildYearLabels(),
+ trackersCount = statisticsUseCase.getActiveTrackersByPeriod(12, ChronoUnit.MONTHS)
)
- }
+ )
}
fun getTrackersWithWhiteList(app: ApplicationDescription): List<Pair<Tracker, Boolean>> {
@@ -181,8 +170,8 @@ class TrackersStatisticsUseCase(
app = app,
map = { appDesc: ApplicationDescription ->
(
- trackTrackersPrivacyModule.getTrackersForApp(appDesc) to
- blockTrackersPrivacyModule.getWhiteList(appDesc)
+ statisticsUseCase.getTrackers(listOf(appDesc)) to
+ getWhiteList(appDesc)
)
},
reduce = { lists ->
@@ -200,7 +189,7 @@ class TrackersStatisticsUseCase(
return appListsRepository.mapReduceForHiddenApps(
app = app,
map = { appDesc: ApplicationDescription ->
- blockTrackersPrivacyModule.getWhiteList(appDesc).isEmpty()
+ getWhiteList(appDesc).isEmpty()
},
reduce = { areEmpty -> areEmpty.all { it } }
)
@@ -209,7 +198,9 @@ class TrackersStatisticsUseCase(
fun getCalls(app: ApplicationDescription): Pair<Int, Int> {
return appListsRepository.mapReduceForHiddenApps(
app = app,
- map = trackTrackersPrivacyModule::getPastDayTrackersCallsForApp,
+ map = {
+ statisticsUseCase.getCalls(it, 24, ChronoUnit.HOURS)
+ },
reduce = { zip ->
zip.unzip().let { (blocked, leaked) ->
blocked.sum() to leaked.sum()
@@ -219,7 +210,7 @@ class TrackersStatisticsUseCase(
}
fun getAppsWithCounts(): Flow<List<AppWithCounts>> {
- val trackersCounts = trackTrackersPrivacyModule.getTrackersCountByApp()
+ val trackersCounts = statisticsUseCase.getContactedTrackersCountByApp()
val hiddenAppsTrackersWithWhiteList =
getTrackersWithWhiteList(appListsRepository.dummySystemApp)
val acAppsTrackersWithWhiteList =
@@ -227,7 +218,7 @@ class TrackersStatisticsUseCase(
return appListsRepository.apps()
.map { apps ->
- val callsByApp = trackTrackersPrivacyModule.getPastDayTrackersCallsByApps()
+ val callsByApp = statisticsUseCase.getCallsByApps(24, ChronoUnit.HOURS)
apps.map { app ->
val calls = appListsRepository.mapReduceForHiddenApps(
app = app,
@@ -241,8 +232,8 @@ class TrackersStatisticsUseCase(
AppWithCounts(
app = app,
- isWhitelisted = !blockTrackersPrivacyModule.isBlockingEnabled() ||
- isWhitelisted(app, appListsRepository, blockTrackersPrivacyModule),
+ isWhitelisted = !whitelistRepository.isBlockingEnabled ||
+ isWhitelisted(app, appListsRepository, whitelistRepository),
trackersCount = when (app) {
appListsRepository.dummySystemApp ->
hiddenAppsTrackersWithWhiteList.size
@@ -256,7 +247,7 @@ class TrackersStatisticsUseCase(
appListsRepository.dummyCompatibilityApp ->
acAppsTrackersWithWhiteList.count { it.second }
else ->
- blockTrackersPrivacyModule.getWhiteList(app).size
+ getWhiteList(app).size
},
blockedLeaks = calls.first,
leaks = calls.second
@@ -266,6 +257,12 @@ class TrackersStatisticsUseCase(
}
}
+ private fun getWhiteList(app: ApplicationDescription): List<Tracker> {
+ return whitelistRepository.getWhiteListForApp(app).mapNotNull {
+ trackersRepository.getTracker(it)
+ }
+ }
+
private val mostLeakedAppsComparator: Comparator<AppWithCounts> = Comparator { o1, o2 ->
val leaks = o2.leaks - o1.leaks
if (leaks != 0) leaks else {
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/UpdateWidgetUseCase.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/UpdateWidgetUseCase.kt
deleted file mode 100644
index 94c734c..0000000
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/UpdateWidgetUseCase.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.advancedprivacy.domain.usecases
-
-import foundation.e.advancedprivacy.data.repositories.LocalStateRepository
-import foundation.e.privacymodules.trackers.api.ITrackTrackersPrivacyModule
-
-class UpdateWidgetUseCase(
- private val localStateRepository: LocalStateRepository,
- private val trackTrackersPrivacyModule: ITrackTrackersPrivacyModule,
-) {
- init {
- trackTrackersPrivacyModule.addListener(object : ITrackTrackersPrivacyModule.Listener {
- override fun onNewData() {
- }
- })
- }
-}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardFragment.kt b/app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardFragment.kt
index 6ca9792..5eb0bb6 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardFragment.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardFragment.kt
@@ -25,14 +25,11 @@ import android.view.View
import android.widget.Toast
import androidx.core.content.ContextCompat.getColor
import androidx.core.view.isVisible
-import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
-import foundation.e.advancedprivacy.AdvancedPrivacyApplication
-import foundation.e.advancedprivacy.DependencyContainer
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.GraphHolder
import foundation.e.advancedprivacy.common.NavToolbarFragment
@@ -44,15 +41,10 @@ import foundation.e.advancedprivacy.domain.entities.TrackerMode
import foundation.e.advancedprivacy.features.dashboard.DashboardViewModel.Action
import foundation.e.advancedprivacy.features.dashboard.DashboardViewModel.SingleEvent
import kotlinx.coroutines.launch
+import org.koin.androidx.viewmodel.ext.android.viewModel
class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
- private val dependencyContainer: DependencyContainer by lazy {
- (this.requireActivity().application as AdvancedPrivacyApplication).dependencyContainer
- }
-
- private val viewModel: DashboardViewModel by viewModels {
- dependencyContainer.viewModelsFactory
- }
+ private val viewModel: DashboardViewModel by viewModel()
private var graphHolder: GraphHolder? = null
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyFragment.kt b/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyFragment.kt
index 35fc1d4..1180af3 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyFragment.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyFragment.kt
@@ -23,13 +23,10 @@ import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Toast
-import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
-import foundation.e.advancedprivacy.AdvancedPrivacyApplication
-import foundation.e.advancedprivacy.DependencyContainer
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.NavToolbarFragment
import foundation.e.advancedprivacy.common.ToggleAppsAdapter
@@ -37,17 +34,12 @@ import foundation.e.advancedprivacy.common.setToolTipForAsterisk
import foundation.e.advancedprivacy.databinding.FragmentInternetActivityPolicyBinding
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode
import kotlinx.coroutines.launch
+import org.koin.androidx.viewmodel.ext.android.viewModel
import java.util.Locale
class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_activity_policy) {
- private val dependencyContainer: DependencyContainer by lazy {
- (this.requireActivity().application as AdvancedPrivacyApplication).dependencyContainer
- }
-
- private val viewModel: InternetPrivacyViewModel by viewModels {
- dependencyContainer.viewModelsFactory
- }
+ private val viewModel: InternetPrivacyViewModel by viewModel()
private var _binding: FragmentInternetActivityPolicyBinding? = null
private val binding get() = _binding!!
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyState.kt b/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyState.kt
index e0df73b..4d0fb38 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyState.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyState.kt
@@ -17,8 +17,8 @@
package foundation.e.advancedprivacy.features.internetprivacy
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
data class InternetPrivacyState(
val mode: InternetPrivacyMode = InternetPrivacyMode.REAL_IP,
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyViewModel.kt b/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyViewModel.kt
index 4c707a2..80e00bc 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyViewModel.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyViewModel.kt
@@ -25,7 +25,7 @@ import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode
import foundation.e.advancedprivacy.domain.usecases.AppListUseCase
import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.advancedprivacy.domain.usecases.IpScramblingStateUseCase
-import foundation.e.privacymodules.ipscrambler.IIpScramblerModule
+import foundation.e.advancedprivacy.ipscrambler.IpScramblerModule
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -40,7 +40,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class InternetPrivacyViewModel(
- private val ipScramblerModule: IIpScramblerModule,
+ private val ipScramblerModule: IpScramblerModule,
private val getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
private val ipScramblingStateUseCase: IpScramblingStateUseCase,
private val appListUseCase: AppListUseCase
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/location/FakeLocationFragment.kt b/app/src/main/java/foundation/e/advancedprivacy/features/location/FakeLocationFragment.kt
index 7d18930..1c629c2 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/location/FakeLocationFragment.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/location/FakeLocationFragment.kt
@@ -31,7 +31,6 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.NonNull
import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
-import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
@@ -50,8 +49,6 @@ import com.mapbox.mapboxsdk.location.modes.CameraMode
import com.mapbox.mapboxsdk.location.modes.RenderMode
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.maps.Style
-import foundation.e.advancedprivacy.AdvancedPrivacyApplication
-import foundation.e.advancedprivacy.DependencyContainer
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.NavToolbarFragment
import foundation.e.advancedprivacy.databinding.FragmentFakeLocationBinding
@@ -60,19 +57,14 @@ import foundation.e.advancedprivacy.features.location.FakeLocationViewModel.Acti
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
+import org.koin.androidx.viewmodel.ext.android.viewModel
import timber.log.Timber
class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location) {
private var isFirstLaunch: Boolean = true
- private val dependencyContainer: DependencyContainer by lazy {
- (this.requireActivity().application as AdvancedPrivacyApplication).dependencyContainer
- }
-
- private val viewModel: FakeLocationViewModel by viewModels {
- dependencyContainer.viewModelsFactory
- }
+ private val viewModel: FakeLocationViewModel by viewModel()
private var _binding: FragmentFakeLocationBinding? = null
private val binding get() = _binding!!
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt
index f486114..132fa3b 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/TrackersFragment.kt
@@ -31,14 +31,11 @@ import android.view.View
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
-import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
-import foundation.e.advancedprivacy.AdvancedPrivacyApplication
-import foundation.e.advancedprivacy.DependencyContainer
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.AppsAdapter
import foundation.e.advancedprivacy.common.GraphHolder
@@ -48,14 +45,10 @@ import foundation.e.advancedprivacy.databinding.FragmentTrackersBinding
import foundation.e.advancedprivacy.databinding.TrackersItemGraphBinding
import foundation.e.advancedprivacy.domain.entities.TrackersPeriodicStatistics
import kotlinx.coroutines.launch
+import org.koin.androidx.viewmodel.ext.android.viewModel
class TrackersFragment : NavToolbarFragment(R.layout.fragment_trackers) {
-
- private val dependencyContainer: DependencyContainer by lazy {
- (this.requireActivity().application as AdvancedPrivacyApplication).dependencyContainer
- }
-
- private val viewModel: TrackersViewModel by viewModels { dependencyContainer.viewModelsFactory }
+ private val viewModel: TrackersViewModel by viewModel()
private var _binding: FragmentTrackersBinding? = null
private val binding get() = _binding!!
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersFragment.kt b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersFragment.kt
index 457a02a..7fb9ca6 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersFragment.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersFragment.kt
@@ -24,27 +24,23 @@ import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.core.view.isVisible
-import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
-import foundation.e.advancedprivacy.AdvancedPrivacyApplication
-import foundation.e.advancedprivacy.DependencyContainer
import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.NavToolbarFragment
import foundation.e.advancedprivacy.databinding.ApptrackersFragmentBinding
import kotlinx.coroutines.launch
+import org.koin.androidx.viewmodel.ext.android.viewModel
+import org.koin.core.parameter.parametersOf
class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
- private val dependencyContainer: DependencyContainer by lazy {
- (this.requireActivity().application as AdvancedPrivacyApplication).dependencyContainer
- }
- private val viewModel: AppTrackersViewModel by viewModels {
- dependencyContainer.viewModelsFactory
- }
+ private val args: AppTrackersFragmentArgs by navArgs()
+ private val viewModel: AppTrackersViewModel by viewModel { parametersOf(args.appUid) }
private var _binding: ApptrackersFragmentBinding? = null
private val binding get() = _binding!!
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersState.kt b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersState.kt
index 2a9e6e8..a597da6 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersState.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersState.kt
@@ -18,8 +18,8 @@
package foundation.e.advancedprivacy.features.trackers.apptrackers
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.trackers.api.Tracker
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
data class AppTrackersState(
val appDesc: ApplicationDescription? = null,
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersViewModel.kt b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersViewModel.kt
index cda4b4b..8740779 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersViewModel.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/AppTrackersViewModel.kt
@@ -22,12 +22,12 @@ import android.net.Uri
import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.domain.entities.TrackerMode
import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.advancedprivacy.domain.usecases.TrackersStateUseCase
import foundation.e.advancedprivacy.domain.usecases.TrackersStatisticsUseCase
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.trackers.api.Tracker
+import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/ToggleTrackersAdapter.kt b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/ToggleTrackersAdapter.kt
index 3696939..ef845b6 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/ToggleTrackersAdapter.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/trackers/apptrackers/ToggleTrackersAdapter.kt
@@ -27,7 +27,7 @@ import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import foundation.e.advancedprivacy.R
-import foundation.e.privacymodules.trackers.api.Tracker
+import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
class ToggleTrackersAdapter(
private val itemsLayout: Int,
diff --git a/app/src/main/java/foundation/e/advancedprivacy/widget/WidgetCommandReceiver.kt b/app/src/main/java/foundation/e/advancedprivacy/widget/WidgetCommandReceiver.kt
index 9021125..917cbda 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/widget/WidgetCommandReceiver.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/widget/WidgetCommandReceiver.kt
@@ -20,11 +20,12 @@ package foundation.e.advancedprivacy.widget
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
-import foundation.e.advancedprivacy.AdvancedPrivacyApplication
+import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase
+import org.koin.java.KoinJavaComponent.get
class WidgetCommandReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
- val getQuickPrivacyStateUseCase = (context?.applicationContext as? AdvancedPrivacyApplication)?.dependencyContainer?.getQuickPrivacyStateUseCase
+ val getQuickPrivacyStateUseCase = get<GetQuickPrivacyStateUseCase>(GetQuickPrivacyStateUseCase::class.java)
val featureEnabled = intent?.extras?.let { bundle ->
if (bundle.containsKey(PARAM_FEATURE_ENABLED))
@@ -32,9 +33,9 @@ class WidgetCommandReceiver : BroadcastReceiver() {
else null
}
when (intent?.action) {
- ACTION_TOGGLE_TRACKERS -> getQuickPrivacyStateUseCase?.toggleTrackers(featureEnabled)
- ACTION_TOGGLE_LOCATION -> getQuickPrivacyStateUseCase?.toggleLocation(featureEnabled)
- ACTION_TOGGLE_IPSCRAMBLING -> getQuickPrivacyStateUseCase?.toggleIpScrambling(featureEnabled)
+ ACTION_TOGGLE_TRACKERS -> getQuickPrivacyStateUseCase.toggleTrackers(featureEnabled)
+ ACTION_TOGGLE_LOCATION -> getQuickPrivacyStateUseCase.toggleLocation(featureEnabled)
+ ACTION_TOGGLE_IPSCRAMBLING -> getQuickPrivacyStateUseCase.toggleIpScrambling(featureEnabled)
else -> {}
}
}
diff --git a/privacymodule-api/.gitignore b/core/.gitignore
index 42afabf..42afabf 100644
--- a/privacymodule-api/.gitignore
+++ b/core/.gitignore
diff --git a/core/build.gradle b/core/build.gradle
new file mode 100644
index 0000000..0e53f22
--- /dev/null
+++ b/core/build.gradle
@@ -0,0 +1,52 @@
+/*
+ * 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/>.
+ */
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+group 'foundation.e'
+
+android {
+ compileSdkVersion buildConfig.compileSdk
+
+ defaultConfig {
+ minSdkVersion buildConfig.minSdk
+ targetSdkVersion buildConfig.targetSdk
+
+ consumerProguardFiles "consumer-rules.pro"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation(
+ libs.androidx.core.ktx,
+ libs.bundles.koin,
+ libs.kotlinx.coroutines
+ )
+}
diff --git a/privacymodule-api/consumer-rules.pro b/core/consumer-rules.pro
index e69de29..e69de29 100644
--- a/privacymodule-api/consumer-rules.pro
+++ b/core/consumer-rules.pro
diff --git a/privacymodule-api/proguard-rules.pro b/core/proguard-rules.pro
index 481bb43..481bb43 100644
--- a/privacymodule-api/proguard-rules.pro
+++ b/core/proguard-rules.pro
diff --git a/privacymodule-api/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml
index 937e285..a29e84c 100644
--- a/privacymodule-api/src/main/AndroidManifest.xml
+++ b/core/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
+ Copyright (C) 2023 MURENA SAS
Copyright (C) 2022 E FOUNDATION
This program is free software: you can redistribute it and/or modify
@@ -16,6 +17,6 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="foundation.e.privacymodules.api"
+ package="foundation.e.advancedprivacy.core"
>
</manifest> \ No newline at end of file
diff --git a/core/src/main/java/foundation/e/advancedprivacy/core/KoinModule.kt b/core/src/main/java/foundation/e/advancedprivacy/core/KoinModule.kt
new file mode 100644
index 0000000..141da86
--- /dev/null
+++ b/core/src/main/java/foundation/e/advancedprivacy/core/KoinModule.kt
@@ -0,0 +1,23 @@
+package foundation.e.advancedprivacy.core
+
+import foundation.e.advancedprivacy.data.repositories.AppListsRepository
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.GlobalScope
+import org.koin.android.ext.koin.androidContext
+import org.koin.core.qualifier.named
+import org.koin.dsl.module
+
+@OptIn(DelicateCoroutinesApi::class)
+val coreModule = module {
+ single<CoroutineScope> { GlobalScope }
+ single {
+ AppListsRepository(
+ permissionsModule = get(),
+ dummySystemApp = get(named("DummySystemApp")),
+ dummyCompatibilityApp = get(named("DummyCompatibilityApp")),
+ context = androidContext(),
+ coroutineScope = get()
+ )
+ }
+}
diff --git a/core/src/main/java/foundation/e/advancedprivacy/core/utils/CoroutinesUtils.kt b/core/src/main/java/foundation/e/advancedprivacy/core/utils/CoroutinesUtils.kt
new file mode 100644
index 0000000..5344c6a
--- /dev/null
+++ b/core/src/main/java/foundation/e/advancedprivacy/core/utils/CoroutinesUtils.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 MURENA SAS
+ *
+ * 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.advancedprivacy.core.utils
+
+import kotlinx.coroutines.CancellationException
+import kotlin.contracts.ExperimentalContracts
+import kotlin.contracts.InvocationKind
+import kotlin.contracts.contract
+
+@OptIn(ExperimentalContracts::class)
+inline fun <T> runSuspendCatching(block: () -> T): Result<T> {
+ contract {
+ callsInPlace(block, InvocationKind.EXACTLY_ONCE)
+ }
+
+ return runCatching(block).onFailure {
+ if (it is CancellationException) {
+ throw it
+ }
+ }
+}
+
+inline fun <R, T : R> Result<T>.recoverSuspendCatching(
+ transform: (exception: Throwable) -> R
+): Result<R> {
+ return when (val exception = exceptionOrNull()) {
+ null -> this
+ else -> runSuspendCatching { transform(exception) }
+ }
+}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/data/repositories/AppListsRepository.kt b/core/src/main/java/foundation/e/advancedprivacy/data/repositories/AppListsRepository.kt
index 2d7651d..f29bb8a 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/data/repositories/AppListsRepository.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/data/repositories/AppListsRepository.kt
@@ -22,10 +22,9 @@ import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
-import foundation.e.advancedprivacy.R
-import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.permissions.data.ProfileType
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.ProfileType
+import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -36,7 +35,9 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
class AppListsRepository(
- private val permissionsModule: PermissionsPrivacyModule,
+ private val permissionsModule: IPermissionsPrivacyModule,
+ val dummySystemApp: ApplicationDescription,
+ val dummyCompatibilityApp: ApplicationDescription,
private val context: Context,
private val coroutineScope: CoroutineScope
) {
@@ -51,24 +52,6 @@ class AppListsRepository(
)
}
- val dummySystemApp = ApplicationDescription(
- packageName = "foundation.e.dummysystemapp",
- uid = -1,
- label = context.getString(R.string.dummy_system_app_label),
- icon = context.getDrawable(R.drawable.ic_e_app_logo),
- profileId = -1,
- profileType = ProfileType.MAIN
- )
-
- val dummyCompatibilityApp = 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),
- profileId = -1,
- profileType = ProfileType.MAIN
- )
-
private suspend fun fetchAppDescriptions(fetchMissingIcons: Boolean = false) {
val launcherPackageNames = context.packageManager.queryIntentActivities(
Intent(Intent.ACTION_MAIN, null).apply { addCategory(Intent.CATEGORY_LAUNCHER) },
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/AppOpModes.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/AppOpModes.kt
index 4764596..3e0a261 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/AppOpModes.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/AppOpModes.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.permissions.data
+package foundation.e.advancedprivacy.domain.entities
import android.app.AppOpsManager.MODE_ALLOWED
import android.app.AppOpsManager.MODE_DEFAULT
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/ApplicationDescription.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ApplicationDescription.kt
index 4fa1bb9..90b637f 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/ApplicationDescription.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ApplicationDescription.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.permissions.data
+package foundation.e.advancedprivacy.domain.entities
import android.graphics.drawable.Drawable
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/PermissionDescription.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/PermissionDescription.kt
index 127192b..c3899a9 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/PermissionDescription.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/PermissionDescription.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.permissions.data
+package foundation.e.advancedprivacy.domain.entities
data class PermissionDescription(
val name: String,
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/APermissionsPrivacyModule.kt b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/APermissionsPrivacyModule.kt
index 64b2292..78f424b 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/APermissionsPrivacyModule.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/APermissionsPrivacyModule.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.permissions
+package foundation.e.advancedprivacy.externalinterfaces.permissions
import android.app.AppOpsManager
import android.content.Context
@@ -27,10 +27,10 @@ import android.content.pm.PermissionInfo.PROTECTION_DANGEROUS
import android.graphics.drawable.Drawable
import android.os.Build
import android.util.Log
-import foundation.e.privacymodules.permissions.data.AppOpModes
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.permissions.data.PermissionDescription
-import foundation.e.privacymodules.permissions.data.ProfileType
+import foundation.e.advancedprivacy.domain.entities.AppOpModes
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.PermissionDescription
+import foundation.e.advancedprivacy.domain.entities.ProfileType
/**
* Implementation of the commons functionality between privileged and standard
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/IPermissionsPrivacyModule.kt b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/IPermissionsPrivacyModule.kt
index 39c726a..da11769 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/IPermissionsPrivacyModule.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/IPermissionsPrivacyModule.kt
@@ -15,17 +15,16 @@
* 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.privacymodules.permissions
+package foundation.e.advancedprivacy.externalinterfaces.permissions
import android.app.NotificationChannel
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.graphics.drawable.Drawable
-import foundation.e.privacymodules.permissions.data.AppOpModes
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.permissions.data.PermissionDescription
-import foundation.e.privacymodules.permissions.data.ProfileType
+import foundation.e.advancedprivacy.domain.entities.AppOpModes
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.PermissionDescription
+import foundation.e.advancedprivacy.domain.entities.ProfileType
/**
* List applications and manage theirs permissions.
diff --git a/fakelocation/build.gradle b/fakelocation/build.gradle
index 91f8031..64fc633 100644
--- a/fakelocation/build.gradle
+++ b/fakelocation/build.gradle
@@ -46,7 +46,11 @@ android {
}
dependencies {
- implementation (libs.bundles.kotlin.android.coroutines)
- implementation project(':privacymodule-api')
+ implementation(
+ libs.bundles.koin,
+ libs.bundles.kotlin.android.coroutines
+ )
+ implementation project(':core')
+
}
diff --git a/fakelocation/fakelocationdemo/build.gradle b/fakelocation/fakelocationdemo/build.gradle
index 0145eca..6cb9af3 100644
--- a/fakelocation/fakelocationdemo/build.gradle
+++ b/fakelocation/fakelocationdemo/build.gradle
@@ -54,7 +54,7 @@ android {
}
dependencies {
- implementation project(':privacymodule-api')
+ implementation project(':core')
implementation project(':fakelocation')
implementation project(':permissionsstandalone')
diff --git a/fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt b/fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt
index b7c9ced..f2e10a4 100644
--- a/fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt
+++ b/fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt
@@ -33,12 +33,12 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
-import foundation.e.privacymodules.fakelocation.FakeLocationModule
+import foundation.e.advancedprivacy.domain.entities.AppOpModes
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.ProfileType
+import foundation.e.advancedprivacy.fakelocation.domain.usecases.FakeLocationModule
+import foundation.e.advancedprivacy.permissions.externalinterfaces.PermissionsPrivacyModule
import foundation.e.privacymodules.fakelocationdemo.databinding.ActivityMainBinding
-import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
-import foundation.e.privacymodules.permissions.data.AppOpModes
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.permissions.data.ProfileType
class MainActivity : AppCompatActivity() {
companion object {
diff --git a/fakelocation/src/main/AndroidManifest.xml b/fakelocation/src/main/AndroidManifest.xml
index 5077c24..fde371c 100644
--- a/fakelocation/src/main/AndroidManifest.xml
+++ b/fakelocation/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
+ ~ Copyright (C) 2023 MURENA SAS
~ Copyright (C) 2022 E FOUNDATION
~
~ This program is free software: you can redistribute it and/or modify
@@ -26,7 +27,7 @@
tools:ignore="MockLocation,ProtectedPermissions" />
<application>
- <service android:name="foundation.e.privacymodules.fakelocation.FakeLocationService"
+ <service android:name="foundation.e.advancedprivacy.fakelocation.services.FakeLocationService"
android:enabled="true" />
</application>
</manifest> \ No newline at end of file
diff --git a/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/KoinModule.kt b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/KoinModule.kt
new file mode 100644
index 0000000..b833181
--- /dev/null
+++ b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/KoinModule.kt
@@ -0,0 +1,9 @@
+package foundation.e.advancedprivacy.fakelocation
+
+import foundation.e.advancedprivacy.fakelocation.domain.usecases.FakeLocationModule
+import org.koin.core.module.dsl.singleOf
+import org.koin.dsl.module
+
+val fakelocationModule = module {
+ singleOf(::FakeLocationModule)
+}
diff --git a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/domain/usecases/FakeLocationModule.kt
index 4245836..c9aac0a 100644
--- a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt
+++ b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/domain/usecases/FakeLocationModule.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.fakelocation
+package foundation.e.advancedprivacy.fakelocation.domain.usecases
import android.content.Context
import android.content.Context.LOCATION_SERVICE
@@ -27,6 +27,7 @@ import android.location.provider.ProviderProperties
import android.os.Build
import android.os.SystemClock
import android.util.Log
+import foundation.e.advancedprivacy.fakelocation.services.FakeLocationService
/**
* Implementation of the functionality of fake location.
@@ -34,7 +35,7 @@ import android.util.Log
*
* @param context an Android context, to retrieve system services for example.
*/
-class FakeLocationModule(private val context: Context) : IFakeLocationModule {
+class FakeLocationModule(private val context: Context) {
companion object {
private const val TAG = "FakeLocationModule"
}
@@ -56,7 +57,7 @@ class FakeLocationModule(private val context: Context) : IFakeLocationModule {
* @see IFakeLocationModule.startFakeLocation
*/
@Synchronized
- override fun startFakeLocation() {
+ fun startFakeLocation() {
providers.forEach { provider ->
try {
locationManager.removeTestProvider(provider)
@@ -84,7 +85,7 @@ class FakeLocationModule(private val context: Context) : IFakeLocationModule {
}
}
- override fun setFakeLocation(latitude: Double, longitude: Double) {
+ fun setFakeLocation(latitude: Double, longitude: Double) {
context.startService(FakeLocationService.buildFakeLocationIntent(context, latitude, longitude))
}
@@ -118,7 +119,7 @@ class FakeLocationModule(private val context: Context) : IFakeLocationModule {
/**
* @see IFakeLocationModule.stopFakeLocation
*/
- override fun stopFakeLocation() {
+ fun stopFakeLocation() {
context.stopService(FakeLocationService.buildStopIntent(context))
providers.forEach { provider ->
try {
diff --git a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/services/FakeLocationService.kt
index 34620fe..6eaae54 100644
--- a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt
+++ b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/services/FakeLocationService.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.fakelocation
+package foundation.e.advancedprivacy.fakelocation.services
import android.app.Service
import android.content.Context
@@ -23,6 +23,7 @@ import android.content.Intent
import android.os.CountDownTimer
import android.os.IBinder
import android.util.Log
+import foundation.e.advancedprivacy.fakelocation.domain.usecases.FakeLocationModule
class FakeLocationService : Service() {
diff --git a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/IFakeLocationModule.kt b/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/IFakeLocationModule.kt
deleted file mode 100644
index 32906f8..0000000
--- a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/IFakeLocationModule.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.privacymodules.fakelocation
-
-/**
- * Manage a fake location on the device.
- */
-interface IFakeLocationModule {
- /**
- * Start to fake the location module. Call [setFakeLocation] after to set the fake
- * position.
- */
- fun startFakeLocation()
-
- /**
- * Set or update the faked position.
- * @param latitude the latitude of the fake position in degrees.
- * @param longitude the longitude of the fake position in degrees.
- */
- fun setFakeLocation(latitude: Double, longitude: Double)
-
- /**
- * Stop the fake location module, giving back hand to the true location modules.
- */
- fun stopFakeLocation()
-}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index e85838d..b9925d4 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,5 +1,6 @@
[versions]
+koin = "3.2.0"
kotlinx-coroutines = "1.6.1"
kotlin = "1.6.10"
androidx-navigation = "2.5.3"
@@ -31,7 +32,10 @@ e-elib = { group = "foundation.e", name = "elib", version = "0.0.1-alpha11" }
e-orbotservice = { group = "foundation.e", name = "orbotservice", version.ref = "orbotservice" }
e-telemetry = { group = "foundation.e.lib", name = "telemetry", version = "0.0.8-alpha" }
google-material = { group = "com.google.android.material", name = "material", version = "1.6.1" }
+google-gson = { group = "com.google.code.gson", name = "gson", version = "2.10.1" }
junit = { group = "junit", name = "junit", version = "4.13.1" }
+koin-core = { group = "io.insert-koin", name = "koin-core", version.ref = "koin" }
+koin-android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin" }
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
leakcanary = { group = "com.squareup.leakcanary", name = "leakcanary-android", version = "2.9.1" }
@@ -44,6 +48,7 @@ timber = { group = "com.jakewharton.timber", name = "timber", version = "5.0.1"
[bundles]
+koin = ["koin-core", "koin-android"]
kotlin-android-coroutines = ["androidx-core-ktx", "kotlinx-coroutines"]
[plugins]
diff --git a/ipscrambling/build.gradle b/ipscrambling/build.gradle
index 0e293df..39efce7 100644
--- a/ipscrambling/build.gradle
+++ b/ipscrambling/build.gradle
@@ -47,6 +47,7 @@ android {
dependencies {
implementation(
+ libs.bundles.koin,
libs.bundles.kotlin.android.coroutines,
libs.androidx.localbroadcast,
)
diff --git a/ipscrambling/orbotservice b/ipscrambling/orbotservice
deleted file mode 160000
-Subproject 1930a046eff2dd37d23ffd83f0064f60334468a
diff --git a/ipscrambling/src/main/AndroidManifest.xml b/ipscrambling/src/main/AndroidManifest.xml
index e948147..d6496f0 100644
--- a/ipscrambling/src/main/AndroidManifest.xml
+++ b/ipscrambling/src/main/AndroidManifest.xml
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="foundation.e.privacymodules.tor"
+ package="foundation.e.advancedprivacy.ipscrambler"
android:installLocation="internalOnly"
>
diff --git a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/IpScramblerModule.kt
index 1c39330..d1f01a0 100644
--- a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IpScramblerModule.kt
+++ b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/IpScramblerModule.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.ipscrambler
+package foundation.e.advancedprivacy.ipscrambler
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
@@ -29,8 +29,6 @@ import android.os.Looper
import android.os.Message
import android.util.Log
import androidx.localbroadcastmanager.content.LocalBroadcastManager
-import foundation.e.privacymodules.ipscrambler.IIpScramblerModule.Listener
-import foundation.e.privacymodules.ipscrambler.IIpScramblerModule.Status
import org.torproject.android.service.OrbotConstants
import org.torproject.android.service.OrbotConstants.ACTION_STOP_FOREGROUND_TASK
import org.torproject.android.service.OrbotService
@@ -38,7 +36,16 @@ import org.torproject.android.service.util.Prefs
import java.security.InvalidParameterException
@SuppressLint("CommitPrefEdits")
-class IpScramblerModule(private val context: Context) : IIpScramblerModule {
+class IpScramblerModule(private val context: Context) {
+ interface Listener {
+ fun onStatusChanged(newStatus: Status)
+ fun log(message: String)
+ fun onTrafficUpdate(upload: Long, download: Long, read: Long, write: Long)
+ }
+
+ enum class Status {
+ OFF, ON, STARTING, STOPPING, START_DISABLED
+ }
companion object {
const val TAG = "IpScramblerModule"
@@ -221,11 +228,11 @@ class IpScramblerModule(private val context: Context) : IIpScramblerModule {
return if (raw.isEmpty()) raw else raw.slice(1..2)
}
- override fun prepareAndroidVpn(): Intent? {
+ fun prepareAndroidVpn(): Intent? {
return VpnService.prepare(context)
}
- override fun start(enableNotification: Boolean) {
+ fun start(enableNotification: Boolean) {
Prefs.enableNotification(enableNotification)
Prefs.putUseVpn(true)
Prefs.putStartOnBoot(true)
@@ -234,7 +241,7 @@ class IpScramblerModule(private val context: Context) : IIpScramblerModule {
sendIntentToService(OrbotConstants.ACTION_START_VPN)
}
- override fun stop() {
+ fun stop() {
updateStatus(Status.STOPPING)
Prefs.putUseVpn(false)
@@ -261,7 +268,7 @@ class IpScramblerModule(private val context: Context) : IIpScramblerModule {
)
}
- override fun requestStatus() {
+ fun requestStatus() {
if (isServiceRunning()) {
sendIntentToService(OrbotConstants.ACTION_STATUS)
} else {
@@ -269,33 +276,33 @@ class IpScramblerModule(private val context: Context) : IIpScramblerModule {
}
}
- override var appList: Set<String>
+ var appList: Set<String>
get() = getTorifiedApps()
set(value) = saveTorifiedApps(value)
- override var exitCountry: String
+ var exitCountry: String
get() = getExitCountryCode()
set(value) = setExitCountryCode(value)
- override fun getAvailablesLocations(): Set<String> = EXIT_COUNTRY_CODES
+ fun getAvailablesLocations(): Set<String> = EXIT_COUNTRY_CODES
- override var httpProxyPort: Int = -1
+ var httpProxyPort: Int = -1
private set
- override var socksProxyPort: Int = -1
+ var socksProxyPort: Int = -1
private set
- override fun addListener(listener: Listener) {
+ fun addListener(listener: Listener) {
listeners.add(listener)
}
- override fun removeListener(listener: Listener) {
+ fun removeListener(listener: Listener) {
listeners.remove(listener)
}
- override fun clearListeners() {
+ fun clearListeners() {
listeners.clear()
}
- override fun onCleared() {
+ fun onCleared() {
LocalBroadcastManager.getInstance(context).unregisterReceiver(localBroadcastReceiver)
}
}
diff --git a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt
new file mode 100644
index 0000000..4f80ef4
--- /dev/null
+++ b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt
@@ -0,0 +1,8 @@
+package foundation.e.advancedprivacy.ipscrambler
+
+import org.koin.core.module.dsl.singleOf
+import org.koin.dsl.module
+
+val ipScramblerModule = module {
+ singleOf(::IpScramblerModule)
+}
diff --git a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt b/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt
deleted file mode 100644
index 859319a..0000000
--- a/ipscrambling/src/main/java/foundation/e/privacymodules/ipscrambler/IIpScramblerModule.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2021 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.privacymodules.ipscrambler
-
-import android.content.Intent
-
-interface IIpScramblerModule {
- fun prepareAndroidVpn(): Intent?
-
- fun start(enableNotification: Boolean = true)
-
- fun stop()
-
- fun requestStatus()
-
- var appList: Set<String>
-
- var exitCountry: String
- fun getAvailablesLocations(): Set<String>
-
- val httpProxyPort: Int
- val socksProxyPort: Int
-
- fun addListener(listener: Listener)
- fun removeListener(listener: Listener)
- fun clearListeners()
-
- fun onCleared()
-
- interface Listener {
- fun onStatusChanged(newStatus: Status)
- fun log(message: String)
- fun onTrafficUpdate(upload: Long, download: Long, read: Long, write: Long)
- }
-
- enum class Status {
- OFF, ON, STARTING, STOPPING, START_DISABLED
- }
-}
diff --git a/permissionse/build.gradle b/permissionse/build.gradle
index 90e0622..7b6ff48 100644
--- a/permissionse/build.gradle
+++ b/permissionse/build.gradle
@@ -27,6 +27,6 @@ dependencies {
compileOnly project(':permissionse:libs:hidden-apis-stub')
implementation(libs.bundles.kotlin.android.coroutines)
+ implementation project(':core')
- implementation project(':privacymodule-api')
}
diff --git a/permissionse/src/main/AndroidManifest.xml b/permissionse/src/main/AndroidManifest.xml
index 3625087..4766007 100644
--- a/permissionse/src/main/AndroidManifest.xml
+++ b/permissionse/src/main/AndroidManifest.xml
@@ -1,6 +1,23 @@
+<!--
+ ~ Copyright (C) 2023 MURENA SAS
+ ~ 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/>.
+ -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- package="foundation.e.privacymodules.e">
+ package="foundation.e.advancedprivacy.permissions.e">
<uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES"
tools:ignore="ProtectedPermissions" />
diff --git a/permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt b/permissionse/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModule.kt
index 6d0a17c..59a20dd 100644
--- a/permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
+++ b/permissionse/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModule.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.permissions
+package foundation.e.advancedprivacy.permissions.externalinterfaces
import android.annotation.TargetApi
import android.app.AppOpsManager
@@ -35,10 +35,11 @@ import android.os.ServiceManager
import android.os.UserHandle
import android.os.UserManager
import android.util.Log
-import foundation.e.privacymodules.permissions.data.AppOpModes
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.permissions.data.ProfileType.MAIN
-import foundation.e.privacymodules.permissions.data.ProfileType.WORK
+import foundation.e.advancedprivacy.domain.entities.AppOpModes
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.ProfileType.MAIN
+import foundation.e.advancedprivacy.domain.entities.ProfileType.WORK
+import foundation.e.advancedprivacy.externalinterfaces.permissions.APermissionsPrivacyModule
/**
* Implements [IPermissionsPrivacyModule] with all privileges of a system app.
diff --git a/permissionsstandalone/build.gradle b/permissionsstandalone/build.gradle
index cf3563e..e330d31 100644
--- a/permissionsstandalone/build.gradle
+++ b/permissionsstandalone/build.gradle
@@ -47,7 +47,7 @@ android {
dependencies {
implementation(libs.bundles.kotlin.android.coroutines)
- implementation project(':privacymodule-api')
+ implementation project(':core')
testImplementation libs.junit
diff --git a/permissionsstandalone/src/main/AndroidManifest.xml b/permissionsstandalone/src/main/AndroidManifest.xml
index 662ea44..60ff274 100644
--- a/permissionsstandalone/src/main/AndroidManifest.xml
+++ b/permissionsstandalone/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
+ ~ Copyright (C) 2023 MURENA SAS
~ Copyright (C) 2022 E FOUNDATION
~
~ This program is free software: you can redistribute it and/or modify
@@ -17,7 +18,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="foundation.e.privacymodules.permissionsstandalone"
+ package="foundation.e.advancedprivacy.permissions.standalone"
>
</manifest> \ No newline at end of file
diff --git a/permissionsstandalone/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt b/permissionsstandalone/src/main/java/foundation/e/advancedprivacy/permissions/externalinterfaces/PermissionsPrivacyModule.kt
index 283b417..95f5ff0 100644
--- a/permissionsstandalone/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
+++ b/permissionsstandalone/src/main/java/foundation/e/advancedprivacy/permissions/externalinterfaces/PermissionsPrivacyModule.kt
@@ -15,15 +15,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.permissions
+package foundation.e.advancedprivacy.permissions.externalinterfaces
import android.app.NotificationChannel
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
-import foundation.e.privacymodules.permissions.data.AppOpModes
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.AppOpModes
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.externalinterfaces.permissions.APermissionsPrivacyModule
/**
* Implements [IPermissionsPrivacyModule] using only API authorized on the PlayStore.
diff --git a/privacymodule-api/build.gradle b/privacymodule-api/build.gradle
deleted file mode 100644
index 259672b..0000000
--- a/privacymodule-api/build.gradle
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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/>.
- */
-
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
-apply plugin: 'maven-publish'
-
-group 'foundation.e'
-
-android {
- compileSdkVersion buildConfig.compileSdk
-
- defaultConfig {
- minSdkVersion buildConfig.minSdk
- targetSdkVersion buildConfig.targetSdk
-
- consumerProguardFiles "consumer-rules.pro"
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-}
-
-dependencies {
- implementation(
- libs.androidx.core.ktx,
- libs.kotlinx.coroutines
- )
-}
-
-//url "https://gitlab.e.foundation/api/v4/groups/e/privacy-central/-/packages/maven"
-
-publishing {
- publications {
- maven(MavenPublication) {
- groupId 'foundation.e'
- //You can either define these here or get them from project conf elsewhere
- artifactId 'privacymodule-api'
- version buildConfig.version.name
- artifact "$buildDir/outputs/aar/privacymodule-api-release.aar"
- //aar artifact you want to publish
-
- //generate pom nodes for dependencies
- pom.withXml {
- def dependenciesNode = asNode().appendNode('dependencies')
- configurations.implementation.allDependencies.each { dependency ->
- if (dependency.name != 'unspecified') {
- def dependencyNode = dependenciesNode.appendNode('dependency')
- dependencyNode.appendNode('groupId', dependency.group)
- dependencyNode.appendNode('artifactId', dependency.name)
- dependencyNode.appendNode('version', dependency.version)
- }
- }
- }
- repositories {
- def ciJobToken = System.getenv("CI_JOB_TOKEN")
- def ciApiV4Url = System.getenv("CI_API_V4_URL")
- if (ciJobToken != null) {
- maven {
- url "${ciApiV4Url}/projects/900/packages/maven"
- credentials(HttpHeaderCredentials) {
- name = 'Job-Token'
- value = ciJobToken
- }
- authentication {
- header(HttpHeaderAuthentication)
- }
- }
- } else {
- maven {
-// url "https://gitlab.e.foundation/api/v4/projects/900/packages/maven"
- // Use privacymodule-e repository (id = 781) for now,
- // because repository not activated on Advanced Privacy (id = 900)
- url "https://gitlab.e.foundation/api/v4/projects/781/packages/maven"
- credentials(HttpHeaderCredentials) {
- name = "Private-Token"
- value = gitLabPrivateToken
- // the variable resides in ~/.gradle/gradle.properties
- }
- authentication {
- header(HttpHeaderAuthentication)
- }
- }
- }
- }
- }
- }
-}
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/DependencyInjector.kt b/privacymodule-api/src/main/java/foundation/e/privacymodules/DependencyInjector.kt
deleted file mode 100644
index 9bf8aba..0000000
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/DependencyInjector.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.privacymodules
-
-import foundation.e.privacymodules.trackers.IDNSBlocker
-
-object DependencyInjector {
- fun initialize(
- dnsBlocker: IDNSBlocker
- ) {
- this.dnsBlocker = dnsBlocker
- }
-
- lateinit var dnsBlocker: IDNSBlocker
- private set
-}
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/trackers/IDNSBlocker.kt b/privacymodule-api/src/main/java/foundation/e/privacymodules/trackers/IDNSBlocker.kt
deleted file mode 100644
index a132aef..0000000
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/trackers/IDNSBlocker.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.privacymodules.trackers
-
-interface IDNSBlocker {
- companion object {
- const val DUMMY_APP_UID = -1
- }
-
- fun shouldBlock(hostname: String, appUid: Int): Boolean
-}
diff --git a/settings.gradle b/settings.gradle
index c9b8f06..1b54f0d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -12,13 +12,13 @@ include ':app'
rootProject.name = "AdvancedPrivacy"
include ':fakelocation'
include ':fakelocation:fakelocationdemo'
-include ':privacymodule-api'
+include ':core'
include ':permissionsstandalone'
include ':trackers'
include ':permissionse'
include ':permissionse:libs:hidden-apis-stub'
include ':ipscrambling'
-include ':ipscrambling:orbotservice'
+//include ':ipscrambling:orbotservice'
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
diff --git a/trackers/build.gradle b/trackers/build.gradle
index bb9489a..737db5a 100644
--- a/trackers/build.gradle
+++ b/trackers/build.gradle
@@ -1,4 +1,5 @@
/*
+ Copyright (C) 2023 MURENA SAS
Copyright (C) 2022 ECORP
This program is free software; you can redistribute it and/or
@@ -42,9 +43,15 @@ android {
}
dependencies {
- implementation project(':privacymodule-api')
+ implementation project(':core')
implementation(
+ libs.androidx.work.ktx,
+ libs.bundles.koin,
libs.bundles.kotlin.android.coroutines,
+ libs.google.gson,
+ libs.retrofit,
+ libs.retrofit.scalars,
+
libs.timber
)
}
diff --git a/trackers/src/main/AndroidManifest.xml b/trackers/src/main/AndroidManifest.xml
index debdf61..615d310 100644
--- a/trackers/src/main/AndroidManifest.xml
+++ b/trackers/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
+ Copyright (C) 2023 MURENA SAS
Copyright (C) 2022 ECORP
This program is free software: you can redistribute it and/or modify
@@ -16,7 +17,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="foundation.e.privacymodules.trackers">
+ package="foundation.e.advancedprivacy.trackers">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@@ -29,7 +30,7 @@
<application>
<service
- android:name="foundation.e.privacymodules.trackers.DNSBlockerService"
+ android:name="foundation.e.advancedprivacy.trackers.services.DNSBlockerService"
android:enabled="true"
android:exported="true" />
</application>
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/KoinModule.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/KoinModule.kt
new file mode 100644
index 0000000..0cfb69c
--- /dev/null
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/KoinModule.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 MURENA SAS
+ *
+ * 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.advancedprivacy.trackers
+
+import foundation.e.advancedprivacy.data.repositories.RemoteTrackersListRepository
+import foundation.e.advancedprivacy.trackers.data.StatsDatabase
+import foundation.e.advancedprivacy.trackers.data.TrackersRepository
+import foundation.e.advancedprivacy.trackers.data.WhitelistRepository
+import foundation.e.advancedprivacy.trackers.domain.usecases.DNSBlocker
+import foundation.e.advancedprivacy.trackers.domain.usecases.StatisticsUseCase
+import foundation.e.advancedprivacy.trackers.domain.usecases.TrackersLogger
+import foundation.e.advancedprivacy.trackers.domain.usecases.UpdateTrackerListUseCase
+import org.koin.android.ext.koin.androidContext
+import org.koin.core.module.dsl.factoryOf
+import org.koin.core.module.dsl.singleOf
+import org.koin.dsl.module
+
+val trackersModule = module {
+
+ factoryOf(::RemoteTrackersListRepository)
+ factoryOf(::UpdateTrackerListUseCase)
+
+ singleOf(::TrackersRepository)
+ single {
+ StatsDatabase(
+ context = androidContext(),
+ trackersRepository = get()
+ )
+ }
+
+ single {
+ StatisticsUseCase(
+ database = get(),
+ appListsRepository = get()
+ )
+ }
+
+ single {
+ WhitelistRepository(
+ context = androidContext(),
+ appListsRepository = get()
+ )
+ }
+
+ factory {
+ DNSBlocker(
+ context = androidContext(),
+ trackersLogger = get(),
+ trackersRepository = get(),
+ whitelistRepository = get()
+ )
+ }
+
+ factory {
+ TrackersLogger(statisticsUseCase = get())
+ }
+}
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/ETrackersResponse.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/ETrackersResponse.kt
new file mode 100644
index 0000000..1b38ecf
--- /dev/null
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/ETrackersResponse.kt
@@ -0,0 +1,10 @@
+package foundation.e.advancedprivacy.trackers.data
+
+data class ETrackersResponse(val trackers: List<ETracker>) {
+ data class ETracker(
+ val id: String?,
+ val hostnames: List<String>?,
+ val name: String?,
+ val exodusId: String?
+ )
+}
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/RemoteTrackersListRepository.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/RemoteTrackersListRepository.kt
new file mode 100644
index 0000000..c2c0768
--- /dev/null
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/RemoteTrackersListRepository.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.advancedprivacy.data.repositories
+
+import retrofit2.Retrofit
+import retrofit2.converter.scalars.ScalarsConverterFactory
+import retrofit2.http.GET
+import timber.log.Timber
+import java.io.File
+import java.io.FileWriter
+import java.io.IOException
+import java.io.PrintWriter
+
+class RemoteTrackersListRepository {
+
+ fun saveData(file: File, data: String): Boolean {
+ try {
+ val fos = FileWriter(file, false)
+ val ps = PrintWriter(fos)
+ ps.apply {
+ print(data)
+ flush()
+ close()
+ }
+ return true
+ } catch (e: IOException) {
+ Timber.e("While saving tracker file.", e)
+ }
+ return false
+ }
+}
+
+interface ETrackersApi {
+ companion object {
+ fun build(): ETrackersApi {
+ val retrofit = Retrofit.Builder()
+ .baseUrl("https://gitlab.e.foundation/e/os/tracker-list/-/raw/main/")
+ .addConverterFactory(ScalarsConverterFactory.create())
+ .build()
+ return retrofit.create(ETrackersApi::class.java)
+ }
+ }
+
+ @GET("list/e_trackers.json")
+ suspend fun trackers(): String
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/StatsDatabase.kt
index 4d287d4..6aa76cf 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/StatsDatabase.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.trackers.data
+package foundation.e.advancedprivacy.trackers.data
import android.content.ContentValues
import android.content.Context
@@ -25,13 +25,13 @@ import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.provider.BaseColumns
import androidx.core.database.getStringOrNull
-import foundation.e.privacymodules.trackers.api.Tracker
-import foundation.e.privacymodules.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_APPID
-import foundation.e.privacymodules.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_NUMBER_BLOCKED
-import foundation.e.privacymodules.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_NUMBER_CONTACTED
-import foundation.e.privacymodules.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_TIMESTAMP
-import foundation.e.privacymodules.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_TRACKER
-import foundation.e.privacymodules.trackers.data.StatsDatabase.AppTrackerEntry.TABLE_NAME
+import foundation.e.advancedprivacy.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_APPID
+import foundation.e.advancedprivacy.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_NUMBER_BLOCKED
+import foundation.e.advancedprivacy.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_NUMBER_CONTACTED
+import foundation.e.advancedprivacy.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_TIMESTAMP
+import foundation.e.advancedprivacy.trackers.data.StatsDatabase.AppTrackerEntry.COLUMN_NAME_TRACKER
+import foundation.e.advancedprivacy.trackers.data.StatsDatabase.AppTrackerEntry.TABLE_NAME
+import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
import timber.log.Timber
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
@@ -39,7 +39,10 @@ import java.time.temporal.ChronoUnit
import java.time.temporal.TemporalUnit
import java.util.concurrent.TimeUnit
-class StatsDatabase(context: Context) :
+class StatsDatabase(
+ context: Context,
+ private val trackersRepository: TrackersRepository
+) :
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
companion object {
@@ -84,7 +87,6 @@ class StatsDatabase(context: Context) :
)
private val lock = Any()
- private val trackersRepository = TrackersRepository.getInstance()
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(SQL_CREATE_TABLE)
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/TrackersRepository.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/TrackersRepository.kt
new file mode 100644
index 0000000..a7d5e49
--- /dev/null
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/TrackersRepository.kt
@@ -0,0 +1,109 @@
+/*
+ * 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.advancedprivacy.trackers.data
+
+import android.content.Context
+import com.google.gson.Gson
+import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import timber.log.Timber
+import java.io.File
+import java.io.FileInputStream
+import java.io.InputStreamReader
+
+class TrackersRepository(
+ private val context: Context,
+ coroutineScope: CoroutineScope
+) {
+
+ private var trackersById: Map<String, Tracker> = HashMap()
+ private var hostnameToId: Map<String, String> = HashMap()
+
+ private val eTrackerFileName = "e_trackers.json"
+ val eTrackerFile = File(context.filesDir.absolutePath, eTrackerFileName)
+
+ init {
+ coroutineScope.launch(Dispatchers.IO) {
+ initTrackersFile()
+ }
+ }
+ fun initTrackersFile() {
+ try {
+ var inputStream = context.assets.open(eTrackerFileName)
+ if (eTrackerFile.exists()) {
+ inputStream = FileInputStream(eTrackerFile)
+ }
+ val reader = InputStreamReader(inputStream, "UTF-8")
+ val trackerResponse =
+ Gson().fromJson(reader, ETrackersResponse::class.java)
+
+ setTrackersList(mapper(trackerResponse))
+
+ reader.close()
+ inputStream.close()
+ } catch (e: Exception) {
+ Timber.e("While parsing trackers in assets", e)
+ }
+ }
+
+ private fun mapper(response: ETrackersResponse): List<Tracker> {
+ return response.trackers.mapNotNull {
+ try {
+ it.toTracker()
+ } catch (e: Exception) {
+ null
+ }
+ }
+ }
+
+ private fun ETrackersResponse.ETracker.toTracker(): Tracker {
+ return Tracker(
+ id = id!!,
+ hostnames = hostnames!!.toSet(),
+ label = name!!,
+ exodusId = exodusId
+ )
+ }
+
+ private fun setTrackersList(list: List<Tracker>) {
+ val trackersById: MutableMap<String, Tracker> = HashMap()
+ val hostnameToId: MutableMap<String, String> = HashMap()
+ list.forEach { tracker ->
+ trackersById[tracker.id] = tracker
+ for (hostname in tracker.hostnames) {
+ hostnameToId[hostname] = tracker.id
+ }
+ }
+ this.trackersById = trackersById
+ this.hostnameToId = hostnameToId
+ }
+
+ fun isTracker(hostname: String?): Boolean {
+ return hostnameToId.containsKey(hostname)
+ }
+
+ fun getTrackerId(hostname: String?): String? {
+ return hostnameToId[hostname]
+ }
+
+ fun getTracker(id: String?): Tracker? {
+ return trackersById[id]
+ }
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/WhitelistRepository.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/WhitelistRepository.kt
index 2763d06..429c5e9 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/WhitelistRepository.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/data/WhitelistRepository.kt
@@ -16,15 +16,19 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.trackers.data
+package foundation.e.advancedprivacy.trackers.data
import android.content.Context
import android.content.SharedPreferences
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.trackers.api.Tracker
+import foundation.e.advancedprivacy.data.repositories.AppListsRepository
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
import java.io.File
-class WhitelistRepository private constructor(context: Context) {
+class WhitelistRepository(
+ context: Context,
+ private val appListsRepository: AppListsRepository
+) {
private var appsWhitelist: Set<String> = HashSet()
private var appUidsWhitelist: Set<Int> = HashSet()
@@ -32,7 +36,6 @@ class WhitelistRepository private constructor(context: Context) {
private var trackersWhitelistByUid: Map<Int, MutableSet<String>> = HashMap()
private val prefs: SharedPreferences
- private var getAppByAPId: ((String) -> ApplicationDescription?)? = null
companion object {
private const val SHARED_PREFS_FILE = "trackers_whitelist_v2"
@@ -41,30 +44,17 @@ class WhitelistRepository private constructor(context: Context) {
private const val KEY_APP_TRACKERS_WHITELIST_PREFIX = "app_trackers_whitelist_"
private const val SHARED_PREFS_FILE_V1 = "trackers_whitelist.prefs"
-
- private var instance: WhitelistRepository? = null
- fun getInstance(context: Context): WhitelistRepository {
- return instance ?: WhitelistRepository(context).apply { instance = this }
- }
}
init {
prefs = context.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE)
reloadCache()
+ migrate(context)
}
- fun setAppGetters(
- context: Context,
- getAppByAPId: (String) -> ApplicationDescription?,
- getAppByUid: (Int) -> ApplicationDescription?
- ) {
- this.getAppByAPId = getAppByAPId
- migrate(context, getAppByUid)
- }
-
- private fun migrate(context: Context, getAppByUid: (Int) -> ApplicationDescription?) {
+ private fun migrate(context: Context) {
if (context.sharedPreferencesExists(SHARED_PREFS_FILE_V1)) {
- migrate1To2(context, getAppByUid)
+ migrate1To2(context)
}
}
@@ -74,7 +64,7 @@ class WhitelistRepository private constructor(context: Context) {
).exists()
}
- private fun migrate1To2(context: Context, getAppByUid: (Int) -> ApplicationDescription?) {
+ private fun migrate1To2(context: Context) {
val prefsV1 = context.getSharedPreferences(SHARED_PREFS_FILE_V1, Context.MODE_PRIVATE)
val editorV2 = prefs.edit()
@@ -83,7 +73,7 @@ class WhitelistRepository private constructor(context: Context) {
val apIds = prefsV1.getStringSet(KEY_APPS_WHITELIST, HashSet())?.mapNotNull {
try {
val uid = it.toInt()
- getAppByUid(uid)?.apId
+ appListsRepository.getApp(uid)?.apId
} catch (e: Exception) { null }
}?.toSet() ?: HashSet()
@@ -93,7 +83,7 @@ class WhitelistRepository private constructor(context: Context) {
if (key.startsWith(KEY_APP_TRACKERS_WHITELIST_PREFIX)) {
try {
val uid = key.substring(KEY_APP_TRACKERS_WHITELIST_PREFIX.length).toInt()
- val apId = getAppByUid(uid)?.apId
+ val apId = appListsRepository.getApp(uid)?.apId
apId?.let {
val trackers = prefsV1.getStringSet(key, emptySet())
editorV2.putStringSet(buildAppTrackersKey(apId), trackers)
@@ -117,13 +107,13 @@ class WhitelistRepository private constructor(context: Context) {
private fun reloadAppsWhiteList() {
appsWhitelist = prefs.getStringSet(KEY_APPS_WHITELIST, HashSet()) ?: HashSet()
appUidsWhitelist = appsWhitelist
- .mapNotNull { apId -> getAppByAPId?.invoke(apId)?.uid }
+ .mapNotNull { apId -> appListsRepository.getApp(apId)?.uid }
.toSet()
}
private fun refreshAppUidTrackersWhiteList() {
trackersWhitelistByUid = trackersWhitelistByApp.mapNotNull { (apId, value) ->
- getAppByAPId?.invoke(apId)?.uid?.let { uid ->
+ appListsRepository.getApp(apId)?.uid?.let { uid ->
uid to value
}
}.toMap()
@@ -190,9 +180,7 @@ class WhitelistRepository private constructor(context: Context) {
}
fun getWhiteListedApp(): List<ApplicationDescription> {
- return getAppByAPId?.let {
- appsWhitelist.mapNotNull(it)
- } ?: emptyList()
+ return appsWhitelist.mapNotNull(appListsRepository::getApp)
}
fun getWhiteListForApp(app: ApplicationDescription): List<String> {
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/Tracker.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/entities/Tracker.kt
index 2da5b16..5c31294 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/Tracker.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/entities/Tracker.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.trackers.api
+package foundation.e.advancedprivacy.trackers.domain.entities
/**
* Describe a tracker.
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerRunnable.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/DNSBlocker.kt
index 44793a4..fb08910 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerRunnable.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/DNSBlocker.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.trackers
+package foundation.e.advancedprivacy.trackers.domain.usecases
import android.content.Context
import android.content.pm.PackageManager
@@ -24,40 +24,38 @@ import android.net.LocalServerSocket
import android.system.ErrnoException
import android.system.Os
import android.system.OsConstants
-import android.util.Log
-import foundation.e.privacymodules.trackers.data.TrackersRepository
-import foundation.e.privacymodules.trackers.data.WhitelistRepository
+import foundation.e.advancedprivacy.core.utils.runSuspendCatching
+import foundation.e.advancedprivacy.trackers.data.TrackersRepository
+import foundation.e.advancedprivacy.trackers.data.WhitelistRepository
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+import timber.log.Timber
import java.io.BufferedReader
-import java.io.IOException
import java.io.InputStreamReader
import java.io.PrintWriter
-class DNSBlockerRunnable(
+class DNSBlocker(
context: Context,
- private val trackersLogger: TrackersLogger,
+ val trackersLogger: TrackersLogger,
private val trackersRepository: TrackersRepository,
private val whitelistRepository: WhitelistRepository
-) : Runnable {
- var resolverReceiver: LocalServerSocket? = null
- var stopped = false
+) {
+ private var resolverReceiver: LocalServerSocket? = null
private var eBrowserAppUid = -1
companion object {
private const val SOCKET_NAME = "foundation.e.advancedprivacy"
private const val E_BROWSER_DOT_SERVER = "chrome.cloudflare-dns.com"
- private const val TAG = "DNSBlockerRunnable"
}
init {
initEBrowserDoTFix(context)
}
- @Synchronized
- fun stop() {
- stopped = true
- closeSocket()
- }
-
private fun closeSocket() {
// Known bug and workaround that LocalServerSocket::close is not working well
// https://issuetracker.google.com/issues/36945762
@@ -68,29 +66,29 @@ class DNSBlockerRunnable(
resolverReceiver = null
} catch (e: ErrnoException) {
if (e.errno != OsConstants.EBADF) {
- Log.w(TAG, "Socket already closed")
+ Timber.w("Socket already closed")
} else {
- Log.e(TAG, "Exception: cannot close DNS port on stop $SOCKET_NAME !", e)
+ Timber.e(e, "Exception: cannot close DNS port on stop $SOCKET_NAME !")
}
} catch (e: Exception) {
- Log.e(TAG, "Exception: cannot close DNS port on stop $SOCKET_NAME !", e)
+ Timber.e(e, "Exception: cannot close DNS port on stop $SOCKET_NAME !")
}
}
}
- override fun run() {
- val resolverReceiver = try {
+ fun listenJob(scope: CoroutineScope): Job = scope.launch(Dispatchers.IO) {
+ val resolverReceiver = runSuspendCatching {
LocalServerSocket(SOCKET_NAME)
- } catch (eio: IOException) {
- Log.e(TAG, "Exception:Cannot open DNS port $SOCKET_NAME !", eio)
- return
+ }.getOrElse {
+ Timber.e(it, "Exception: cannot open DNS port on $SOCKET_NAME")
+ return@launch
}
- this.resolverReceiver = resolverReceiver
- Log.d(TAG, "DNSFilterProxy running on port $SOCKET_NAME !")
+ this@DNSBlocker.resolverReceiver = resolverReceiver
+ Timber.d("DNSFilterProxy running on port $SOCKET_NAME")
- while (!stopped) {
- try {
+ while (isActive) {
+ runSuspendCatching {
val socket = resolverReceiver.accept()
val reader = BufferedReader(InputStreamReader(socket.inputStream))
val line = reader.readLine()
@@ -114,9 +112,13 @@ class DNSBlockerRunnable(
writer.println("pass")
}
socket.close()
- // Printing bufferedreader data
- } catch (e: IOException) {
- Log.w(TAG, "Exception while listening DNS resolver", e)
+ }.onFailure {
+ if (it is CancellationException) {
+ closeSocket()
+ throw it
+ } else {
+ Timber.w(it, "Exception while listening DNS resolver")
+ }
}
}
}
@@ -126,7 +128,7 @@ class DNSBlockerRunnable(
eBrowserAppUid =
context.packageManager.getApplicationInfo("foundation.e.browser", 0).uid
} catch (e: PackageManager.NameNotFoundException) {
- Log.i(TAG, "no E Browser package found.")
+ Timber.i(e, "no E Browser package found.")
}
}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/StatisticsUseCase.kt
index 8f02adb..55efeb9 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/StatisticsUseCase.kt
@@ -16,46 +16,27 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.trackers.data
-
-import android.content.Context
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.trackers.api.Tracker
+package foundation.e.advancedprivacy.trackers.domain.usecases
+
+import foundation.e.advancedprivacy.data.repositories.AppListsRepository
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.trackers.data.StatsDatabase
+import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.SharedFlow
import java.time.temporal.TemporalUnit
-class StatsRepository private constructor(context: Context) {
- private val database: StatsDatabase
- private var newDataCallback: (() -> Unit)? = null
- private var getAppByUid: ((Int) -> ApplicationDescription?)? = null
- private var getAppByAPId: ((String) -> ApplicationDescription?)? = null
-
- companion object {
- private var instance: StatsRepository? = null
- fun getInstance(context: Context): StatsRepository {
- return instance ?: StatsRepository(context).apply { instance = this }
- }
- }
-
- fun setAppGetters(
- getAppByUid: (Int) -> ApplicationDescription?,
- getAppByAPId: (String) -> ApplicationDescription?
- ) {
- this.getAppByUid = getAppByUid
- this.getAppByAPId = getAppByAPId
- }
-
- init {
- database = StatsDatabase(context)
- }
-
- fun setNewDataCallback(callback: () -> Unit) {
- newDataCallback = callback
- }
+class StatisticsUseCase(
+ private val database: StatsDatabase,
+ private val appListsRepository: AppListsRepository
+) {
+ private val _newDataAvailable = MutableSharedFlow<Unit>()
+ val newDataAvailable: SharedFlow<Unit> = _newDataAvailable
- fun logAccess(trackerId: String?, appUid: Int, blocked: Boolean) {
- getAppByUid?.invoke(appUid)?.let { app ->
+ suspend fun logAccess(trackerId: String?, appUid: Int, blocked: Boolean) {
+ appListsRepository.getApp(appUid)?.let { app ->
database.logAccess(trackerId, app.apId, blocked)
- newDataCallback?.invoke()
+ _newDataAvailable.emit(Unit)
}
}
@@ -94,12 +75,12 @@ class StatsRepository private constructor(context: Context) {
}
fun getMostLeakedApp(periodCount: Int, periodUnit: TemporalUnit): ApplicationDescription? {
- return getAppByAPId?.invoke(database.getMostLeakedAppId(periodCount, periodUnit))
+ return appListsRepository.getApp(database.getMostLeakedAppId(periodCount, periodUnit))
}
private fun <K> Map<String, K>.mapByAppIdToApp(): Map<ApplicationDescription, K> {
return entries.mapNotNull { (apId, value) ->
- getAppByAPId?.invoke(apId)?.let { it to value }
+ appListsRepository.getApp(apId)?.let { it to value }
}.toMap()
}
}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/TrackersLogger.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/TrackersLogger.kt
index f3c4745..411b4ab 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/TrackersLogger.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/TrackersLogger.kt
@@ -16,49 +16,40 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.trackers
-
-import android.content.Context
-import android.util.Log
-import foundation.e.privacymodules.trackers.data.StatsRepository
+package foundation.e.advancedprivacy.trackers.domain.usecases
+
+import foundation.e.advancedprivacy.core.utils.runSuspendCatching
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+import timber.log.Timber
import java.util.concurrent.LinkedBlockingQueue
-class TrackersLogger(context: Context) {
- private val statsRepository = StatsRepository.getInstance(context)
+class TrackersLogger(
+ private val statisticsUseCase: StatisticsUseCase,
+) {
private val queue = LinkedBlockingQueue<DetectedTracker>()
- private var stopped = false
-
- companion object {
- private const val TAG = "TrackerModule"
- }
-
- init {
- startWriteLogLoop()
- }
-
- fun stop() {
- stopped = true
- }
fun logAccess(trackerId: String?, appUid: Int, wasBlocked: Boolean) {
queue.offer(DetectedTracker(trackerId, appUid, wasBlocked))
}
- private fun startWriteLogLoop() {
- val writeLogRunner = Runnable {
- while (!stopped) {
- try {
+ fun writeLogJob(scope: CoroutineScope): Job {
+ return scope.launch(Dispatchers.IO) {
+ while (isActive) {
+ runSuspendCatching {
logAccess(queue.take())
- } catch (e: InterruptedException) {
- Log.e(TAG, "writeLogLoop detectedTrackersQueue.take() interrupted: ", e)
+ }.onFailure {
+ Timber.e(it, "writeLogLoop detectedTrackersQueue.take() interrupted: ")
}
}
}
- Thread(writeLogRunner).start()
}
- fun logAccess(detectedTracker: DetectedTracker) {
- statsRepository.logAccess(
+ private suspend fun logAccess(detectedTracker: DetectedTracker) {
+ statisticsUseCase.logAccess(
detectedTracker.trackerId,
detectedTracker.appUid,
detectedTracker.wasBlocked
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/UpdateTrackerListUseCase.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/UpdateTrackerListUseCase.kt
new file mode 100644
index 0000000..3593dbb
--- /dev/null
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/usecases/UpdateTrackerListUseCase.kt
@@ -0,0 +1,29 @@
+package foundation.e.advancedprivacy.trackers.domain.usecases
+
+import foundation.e.advancedprivacy.data.repositories.ETrackersApi
+import foundation.e.advancedprivacy.data.repositories.RemoteTrackersListRepository
+import foundation.e.advancedprivacy.trackers.data.TrackersRepository
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import timber.log.Timber
+
+class UpdateTrackerListUseCase(
+ private val remoteTrackersListRepository: RemoteTrackersListRepository,
+ private val trackersRepository: TrackersRepository,
+ private val coroutineScope: CoroutineScope,
+
+) {
+ fun updateTrackers() = coroutineScope.launch {
+ update()
+ }
+
+ suspend fun update() {
+ val api = ETrackersApi.build()
+ try {
+ remoteTrackersListRepository.saveData(trackersRepository.eTrackerFile, api.trackers())
+ trackersRepository.initTrackersFile()
+ } catch (e: Exception) {
+ Timber.e("While updating trackers", e)
+ }
+ }
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerService.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/services/DNSBlockerService.kt
index c2ad16b..25539e1 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerService.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/services/DNSBlockerService.kt
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2023 MURENA SAS
* Copyright (C) 2021 E FOUNDATION
*
* This program is free software: you can redistribute it and/or modify
@@ -15,28 +16,28 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.trackers
+package foundation.e.advancedprivacy.trackers.services
import android.app.Service
import android.content.Intent
import android.os.IBinder
-import android.util.Log
-import foundation.e.privacymodules.trackers.data.TrackersRepository
-import foundation.e.privacymodules.trackers.data.WhitelistRepository
+import foundation.e.advancedprivacy.trackers.domain.usecases.DNSBlocker
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.cancel
+import org.koin.java.KoinJavaComponent.get
class DNSBlockerService : Service() {
- private var trackersLogger: TrackersLogger? = null
-
companion object {
- private const val TAG = "DNSBlockerService"
- private var sDNSBlocker: DNSBlockerRunnable? = null
const val ACTION_START = "foundation.e.privacymodules.trackers.intent.action.START"
const val EXTRA_ENABLE_NOTIFICATION =
"foundation.e.privacymodules.trackers.intent.extra.ENABLED_NOTIFICATION"
}
+ private var coroutineScope = CoroutineScope(Dispatchers.IO)
+ private var dnsBlocker: DNSBlocker? = null
+
override fun onBind(intent: Intent): IBinder? {
- // TODO: Return the communication channel to the service.
throw UnsupportedOperationException("Not yet implemented")
}
@@ -52,28 +53,16 @@ class DNSBlockerService : Service() {
}
private fun start() {
- try {
- val trackersLogger = TrackersLogger(this)
- this.trackersLogger = trackersLogger
-
- sDNSBlocker = DNSBlockerRunnable(
- this,
- trackersLogger,
- TrackersRepository.getInstance(),
- WhitelistRepository.getInstance(this)
- )
- Thread(sDNSBlocker).start()
- } catch (e: Exception) {
- Log.e(TAG, "Error while starting DNSBlocker service", e)
- stop()
+ coroutineScope = CoroutineScope(Dispatchers.IO)
+ get<DNSBlocker>(DNSBlocker::class.java).apply {
+ this@DNSBlockerService.dnsBlocker = this
+ trackersLogger.writeLogJob(coroutineScope)
+ listenJob(coroutineScope)
}
}
private fun stop() {
- sDNSBlocker?.stop()
- sDNSBlocker = null
-
- trackersLogger?.stop()
- trackersLogger = null
+ kotlin.runCatching { coroutineScope.cancel() }
+ dnsBlocker = null
}
}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/ForegroundStarter.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/services/ForegroundStarter.kt
index 69b4f28..a0cea43 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/ForegroundStarter.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/services/ForegroundStarter.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.privacymodules.trackers
+package foundation.e.advancedprivacy.trackers.services
import android.app.Notification
import android.app.NotificationChannel
diff --git a/app/src/main/java/foundation/e/advancedprivacy/UpdateTrackersWorker.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/services/UpdateTrackersWorker.kt
index 418f75b..50aa082 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/UpdateTrackersWorker.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/services/UpdateTrackersWorker.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package foundation.e.advancedprivacy
+package foundation.e.advancedprivacy.trackers.services
import android.content.Context
import androidx.work.Constraints
@@ -25,16 +25,17 @@ import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
+import foundation.e.advancedprivacy.trackers.domain.usecases.UpdateTrackerListUseCase
+import org.koin.java.KoinJavaComponent.get
import java.util.concurrent.TimeUnit
class UpdateTrackersWorker(appContext: Context, workerParams: WorkerParameters) :
CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result {
- val trackersStateUseCase = (applicationContext as AdvancedPrivacyApplication)
- .dependencyContainer.trackersStateUseCase
+ val updateTrackersUsecase: UpdateTrackerListUseCase = get(UpdateTrackerListUseCase::class.java)
- trackersStateUseCase.updateTrackers()
+ updateTrackersUsecase.updateTrackers()
return Result.success()
}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/BlockTrackersPrivacyModule.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/BlockTrackersPrivacyModule.kt
deleted file mode 100644
index 7463b22..0000000
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/BlockTrackersPrivacyModule.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2023 MURENA SAS
- * 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.privacymodules.trackers.api
-
-import android.content.Context
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.trackers.data.TrackersRepository
-import foundation.e.privacymodules.trackers.data.WhitelistRepository
-
-class BlockTrackersPrivacyModule(context: Context) : IBlockTrackersPrivacyModule {
- private val mListeners = mutableListOf<IBlockTrackersPrivacyModule.Listener>()
- private val trackersRepository = TrackersRepository.getInstance()
- private val whitelistRepository = WhitelistRepository.getInstance(context)
-
- companion object {
- private var instance: BlockTrackersPrivacyModule? = null
-
- fun getInstance(context: Context): BlockTrackersPrivacyModule {
- return instance ?: BlockTrackersPrivacyModule(context).apply { instance = this }
- }
- }
-
- override fun addListener(listener: IBlockTrackersPrivacyModule.Listener) {
- mListeners.add(listener)
- }
-
- override fun clearListeners() {
- mListeners.clear()
- }
-
- override fun disableBlocking() {
- whitelistRepository.isBlockingEnabled = false
- mListeners.forEach { listener -> listener.onBlockingToggle(false) }
- }
-
- override fun enableBlocking() {
- whitelistRepository.isBlockingEnabled = true
- mListeners.forEach { listener -> listener.onBlockingToggle(true) }
- }
-
- override fun getWhiteList(app: ApplicationDescription): List<Tracker> {
- return whitelistRepository.getWhiteListForApp(app).mapNotNull {
- trackersRepository.getTracker(it)
- }
- }
-
- override fun getWhiteListedApp(): List<ApplicationDescription> {
- return whitelistRepository.getWhiteListedApp()
- }
-
- override fun isBlockingEnabled(): Boolean {
- return whitelistRepository.isBlockingEnabled
- }
-
- override fun isWhiteListEmpty(): Boolean {
- return whitelistRepository.areWhiteListEmpty()
- }
-
- override fun isWhitelisted(app: ApplicationDescription): Boolean {
- return whitelistRepository.isAppWhiteListed(app)
- }
-
- override fun removeListener(listener: IBlockTrackersPrivacyModule.Listener) {
- mListeners.remove(listener)
- }
-
- override fun setWhiteListed(
- tracker: Tracker,
- app: ApplicationDescription,
- isWhiteListed: Boolean
- ) {
- whitelistRepository.setWhiteListed(tracker, app.apId, isWhiteListed)
- }
-
- override fun setWhiteListed(app: ApplicationDescription, isWhiteListed: Boolean) {
- whitelistRepository.setWhiteListed(app.apId, isWhiteListed)
- }
-
- override fun clearWhiteList(app: ApplicationDescription) {
- whitelistRepository.clearWhiteList(app.apId)
- }
-}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/IBlockTrackersPrivacyModule.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/IBlockTrackersPrivacyModule.kt
deleted file mode 100644
index 3547b8e..0000000
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/IBlockTrackersPrivacyModule.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2023 MURENA SAS
- * 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.privacymodules.trackers.api
-
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-
-/**
- * Manage trackers blocking and whitelisting.
- */
-interface IBlockTrackersPrivacyModule {
-
- /**
- * Get the state of the blockin module
- * @return true when blocking is enabled, false otherwise.
- */
- fun isBlockingEnabled(): Boolean
-
- /**
- * Enable blocking, using the previously configured whitelists
- */
- fun enableBlocking()
-
- /**
- * Disable blocking
- */
- fun disableBlocking()
-
- /**
- * Set or unset in whitelist the App with the specified uid.
- * @param app the ApplicationDescription of the app
- * @param isWhiteListed true, the app will appears in whitelist, false, it won't
- */
- fun setWhiteListed(app: ApplicationDescription, isWhiteListed: Boolean)
-
- /**
- * Set or unset in whitelist the specifid tracked, for the App specified by its uid.
- * @param tracker the tracker
- * @param app the ApplicationDescription of the app
- * @param isWhiteListed true, the app will appears in whitelist, false, it won't
- */
- fun setWhiteListed(tracker: Tracker, app: ApplicationDescription, isWhiteListed: Boolean)
-
- /**
- * Return true if nothing has been added to the whitelist : everything is blocked.
- */
- fun isWhiteListEmpty(): Boolean
-
- /**
- * Return the white listed App, by their UID
- */
- fun getWhiteListedApp(): List<ApplicationDescription>
-
- /**
- * Return true if the App is whitelisted for trackers blocking.
- */
- fun isWhitelisted(app: ApplicationDescription): Boolean
-
- /**
- * List the white listed trackers for an App specified by it uid
- */
- fun getWhiteList(app: ApplicationDescription): List<Tracker>
-
- fun clearWhiteList(app: ApplicationDescription)
-
- /**
- * Callback interface to get updates about the state of the Block trackers module.
- */
- interface Listener {
-
- /**
- * Called when the trackers blocking is activated or deactivated.
- * @param isBlocking true when activated, false otherwise.
- */
- fun onBlockingToggle(isBlocking: Boolean)
- }
-
- fun addListener(listener: Listener)
-
- fun removeListener(listener: Listener)
-
- fun clearListeners()
-}
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
deleted file mode 100644
index 8aaed4a..0000000
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2023 MURENA SAS
- * 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.privacymodules.trackers.api
-
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-
-/**
- * Get reporting about trackers calls.
- */
-interface ITrackTrackersPrivacyModule {
-
- fun start(
- trackers: List<Tracker>,
- getAppByUid: (Int) -> ApplicationDescription?,
- getAppByAPId: (String) -> ApplicationDescription?,
- enableNotification: Boolean = true
- )
-
- /**
- * List all the trackers encountered for a specific app.
- */
- fun getTrackersForApp(app: ApplicationDescription): List<Tracker>
-
- /**
- * List all the trackers encountere trackers since "ever", for the given [appUids],
- * or all apps if [appUids] is null
- */
- fun getTrackers(apps: List<ApplicationDescription>? = null): List<Tracker>
-
- /**
- * Return the number of encountered trackers since "ever", for the given [appUids],
- * or all apps if [appUids] is null
- */
- fun getTrackersCount(): Int
-
- /**
- * Return the number of encountere trackers since "ever", for each app uid.
- */
- fun getTrackersCountByApp(): Map<ApplicationDescription, Int>
-
- /**
- * Return the number of encountered trackers for the last 24 hours
- */
- fun getPastDayTrackersCount(): Int
-
- /**
- * Return the number of encountered trackers for the last month
- */
- fun getPastMonthTrackersCount(): Int
-
- /**
- * Return the number of encountered trackers for the last year
- */
- fun getPastYearTrackersCount(): Int
-
- /**
- * Return number of trackers calls by hours, for the last 24hours.
- * @return list of 24 numbers of trackers calls by hours
- */
- fun getPastDayTrackersCalls(): List<Pair<Int, Int>>
-
- /**
- * Return number of trackers calls by day, for the last 30 days.
- * @return list of 30 numbers of trackers calls by day
- */
- fun getPastMonthTrackersCalls(): List<Pair<Int, Int>>
-
- /**
- * Return number of trackers calls by month, for the last 12 month.
- * @return list of 12 numbers of trackers calls by month
- */
- fun getPastYearTrackersCalls(): List<Pair<Int, Int>>
-
- fun getPastDayTrackersCallsByApps(): Map<ApplicationDescription, Pair<Int, Int>>
-
- fun getPastDayTrackersCallsForApp(app: ApplicationDescription): Pair<Int, Int>
-
- fun getPastDayMostLeakedApp(): ApplicationDescription?
-
- interface Listener {
-
- /**
- * Called when a new tracker attempt is logged. Consumer may choose to call other methods
- * to refresh the data.
- */
- fun onNewData()
- }
-
- fun addListener(listener: Listener)
-
- fun removeListener(listener: Listener)
-
- fun clearListeners()
-}
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
deleted file mode 100644
index 5fc5b6b..0000000
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2023 MURENA SAS
- * Copyright (C) 2021 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.privacymodules.trackers.api
-
-import android.content.Context
-import android.content.Intent
-import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import foundation.e.privacymodules.trackers.DNSBlockerService
-import foundation.e.privacymodules.trackers.data.StatsRepository
-import foundation.e.privacymodules.trackers.data.TrackersRepository
-import foundation.e.privacymodules.trackers.data.WhitelistRepository
-import java.time.temporal.ChronoUnit
-
-class TrackTrackersPrivacyModule(private val context: Context) : ITrackTrackersPrivacyModule {
- private val statsRepository = StatsRepository.getInstance(context)
- private val listeners: MutableList<ITrackTrackersPrivacyModule.Listener> = mutableListOf()
-
- companion object {
- private var instance: TrackTrackersPrivacyModule? = null
-
- fun getInstance(context: Context): TrackTrackersPrivacyModule {
- return instance ?: TrackTrackersPrivacyModule(context).apply { instance = this }
- }
- }
-
- init {
- statsRepository.setNewDataCallback {
- listeners.forEach { listener -> listener.onNewData() }
- }
- }
-
- override fun start(
- trackers: List<Tracker>,
- getAppByUid: (Int) -> ApplicationDescription?,
- getAppByAPId: (String) -> ApplicationDescription?,
- enableNotification: Boolean
- ) {
- TrackersRepository.getInstance().setTrackersList(trackers)
- StatsRepository.getInstance(context).setAppGetters(getAppByUid, getAppByAPId)
- WhitelistRepository.getInstance(context).setAppGetters(context, getAppByAPId, getAppByUid)
- val intent = Intent(context, DNSBlockerService::class.java)
- intent.action = DNSBlockerService.ACTION_START
- intent.putExtra(DNSBlockerService.EXTRA_ENABLE_NOTIFICATION, enableNotification)
- context.startService(intent)
- }
-
- override fun getPastDayTrackersCalls(): List<Pair<Int, Int>> {
- return statsRepository.getTrackersCallsOnPeriod(24, ChronoUnit.HOURS)
- }
-
- override fun getPastMonthTrackersCalls(): List<Pair<Int, Int>> {
- return statsRepository.getTrackersCallsOnPeriod(30, ChronoUnit.DAYS)
- }
-
- override fun getPastYearTrackersCalls(): List<Pair<Int, Int>> {
- return statsRepository.getTrackersCallsOnPeriod(12, ChronoUnit.MONTHS)
- }
-
- override fun getTrackersCount(): Int {
- return statsRepository.getContactedTrackersCount()
- }
-
- override fun getTrackersCountByApp(): Map<ApplicationDescription, Int> {
- return statsRepository.getContactedTrackersCountByApp()
- }
-
- override fun getTrackersForApp(app: ApplicationDescription): List<Tracker> {
- return statsRepository.getTrackers(listOf(app))
- }
-
- override fun getTrackers(apps: List<ApplicationDescription>?): List<Tracker> {
- return statsRepository.getTrackers(apps)
- }
-
- override fun getPastDayTrackersCount(): Int {
- return statsRepository.getActiveTrackersByPeriod(24, ChronoUnit.HOURS)
- }
-
- override fun getPastMonthTrackersCount(): Int {
- return statsRepository.getActiveTrackersByPeriod(30, ChronoUnit.DAYS)
- }
-
- override fun getPastYearTrackersCount(): Int {
- return statsRepository.getActiveTrackersByPeriod(12, ChronoUnit.MONTHS)
- }
-
- override fun getPastDayMostLeakedApp(): ApplicationDescription? {
- return statsRepository.getMostLeakedApp(24, ChronoUnit.HOURS)
- }
-
- override fun getPastDayTrackersCallsByApps(): Map<ApplicationDescription, Pair<Int, Int>> {
- return statsRepository.getCallsByApps(24, ChronoUnit.HOURS)
- }
-
- override fun getPastDayTrackersCallsForApp(app: ApplicationDescription): Pair<Int, Int> {
- return statsRepository.getCalls(app, 24, ChronoUnit.HOURS)
- }
-
- override fun addListener(listener: ITrackTrackersPrivacyModule.Listener) {
- listeners.add(listener)
- }
-
- override fun removeListener(listener: ITrackTrackersPrivacyModule.Listener) {
- listeners.remove(listener)
- }
-
- override fun clearListeners() {
- listeners.clear()
- }
-}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/TrackersRepository.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/TrackersRepository.kt
deleted file mode 100644
index 994bccf..0000000
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/TrackersRepository.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.privacymodules.trackers.data
-
-import foundation.e.privacymodules.trackers.api.Tracker
-
-class TrackersRepository private constructor() {
- private var trackersById: Map<String, Tracker> = HashMap()
- private var hostnameToId: Map<String, String> = HashMap()
-
- companion object {
- private var instance: TrackersRepository? = null
- fun getInstance(): TrackersRepository {
- return instance ?: TrackersRepository().apply { instance = this }
- }
- }
-
- fun setTrackersList(list: List<Tracker>) {
- val trackersById: MutableMap<String, Tracker> = HashMap()
- val hostnameToId: MutableMap<String, String> = HashMap()
- list.forEach { tracker ->
- trackersById[tracker.id] = tracker
- for (hostname in tracker.hostnames) {
- hostnameToId[hostname] = tracker.id
- }
- }
- this.trackersById = trackersById
- this.hostnameToId = hostnameToId
- }
-
- fun isTracker(hostname: String?): Boolean {
- return hostnameToId.containsKey(hostname)
- }
-
- fun getTrackerId(hostname: String?): String? {
- return hostnameToId[hostname]
- }
-
- fun getTracker(id: String?): Tracker? {
- return trackersById[id]
- }
-}