summaryrefslogtreecommitdiff
path: root/app
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
commit53f4a9ce311d612d43fa770cf7e8f8e98fbb43a0 (patch)
tree59c58e58cfef0e370f39bd9c150e36c6dfcb50c0 /app
parent1a77e3924bc78eabca7b859ef62be30bbf2476ad (diff)
2: organise module with clean archi, use Koin for injection.
Diffstat (limited to 'app')
-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/UpdateTrackersWorker.kt59
-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/AppListsRepository.kt281
-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
30 files changed, 311 insertions, 916 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/UpdateTrackersWorker.kt b/app/src/main/java/foundation/e/advancedprivacy/UpdateTrackersWorker.kt
deleted file mode 100644
index 418f75b..0000000
--- a/app/src/main/java/foundation/e/advancedprivacy/UpdateTrackersWorker.kt
+++ /dev/null
@@ -1,59 +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
-
-import android.content.Context
-import androidx.work.Constraints
-import androidx.work.CoroutineWorker
-import androidx.work.ExistingPeriodicWorkPolicy
-import androidx.work.NetworkType
-import androidx.work.PeriodicWorkRequestBuilder
-import androidx.work.WorkManager
-import androidx.work.WorkerParameters
-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
-
- trackersStateUseCase.updateTrackers()
- return Result.success()
- }
-
- companion object {
- private val constraints = Constraints.Builder()
- .setRequiredNetworkType(NetworkType.CONNECTED)
- .build()
-
- fun periodicUpdate(context: Context) {
- val request = PeriodicWorkRequestBuilder<UpdateTrackersWorker>(
- 7, TimeUnit.DAYS
- )
- .setConstraints(constraints).build()
-
- WorkManager.getInstance(context).enqueueUniquePeriodicWork(
- UpdateTrackersWorker::class.qualifiedName ?: "",
- ExistingPeriodicWorkPolicy.KEEP,
- request
- )
- }
- }
-}
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/AppListsRepository.kt b/app/src/main/java/foundation/e/advancedprivacy/data/repositories/AppListsRepository.kt
deleted file mode 100644
index 2d7651d..0000000
--- a/app/src/main/java/foundation/e/advancedprivacy/data/repositories/AppListsRepository.kt
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2022 E FOUNDATION, 2022 - 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.data.repositories
-
-import android.Manifest
-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 kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-
-class AppListsRepository(
- private val permissionsModule: PermissionsPrivacyModule,
- private val context: Context,
- private val coroutineScope: CoroutineScope
-) {
- companion object {
- private const val PNAME_SETTINGS = "com.android.settings"
- private const val PNAME_PWAPLAYER = "foundation.e.pwaplayer"
- private const val PNAME_INTENT_VERIFICATION = "com.android.statementservice"
- private const val PNAME_MICROG_SERVICES_CORE = "com.google.android.gms"
-
- val compatibiltyPNames = setOf(
- PNAME_PWAPLAYER, PNAME_INTENT_VERIFICATION, PNAME_MICROG_SERVICES_CORE
- )
- }
-
- 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) },
- 0
- ).mapNotNull { it.activityInfo?.packageName }
-
- val visibleAppsFilter = { packageInfo: PackageInfo ->
- hasInternetPermission(packageInfo) &&
- isStandardApp(packageInfo.applicationInfo, launcherPackageNames)
- }
-
- val hiddenAppsFilter = { packageInfo: PackageInfo ->
- hasInternetPermission(packageInfo) &&
- isHiddenSystemApp(packageInfo.applicationInfo, launcherPackageNames)
- }
-
- val compatibilityAppsFilter = { packageInfo: PackageInfo ->
- packageInfo.packageName in compatibiltyPNames
- }
-
- val visibleApps = recycleIcons(
- newApps = permissionsModule.getApplications(visibleAppsFilter),
- fetchMissingIcons = fetchMissingIcons
- )
- val hiddenApps = permissionsModule.getApplications(hiddenAppsFilter)
- val compatibilityApps = permissionsModule.getApplications(compatibilityAppsFilter)
-
- updateMaps(visibleApps + hiddenApps + compatibilityApps)
-
- allProfilesAppDescriptions.emit(
- Triple(
- visibleApps + dummySystemApp + dummyCompatibilityApp,
- hiddenApps,
- compatibilityApps
- )
- )
- }
-
- private fun recycleIcons(
- newApps: List<ApplicationDescription>,
- fetchMissingIcons: Boolean
- ): List<ApplicationDescription> {
- val oldVisibleApps = allProfilesAppDescriptions.value.first
- return newApps.map { app ->
- app.copy(
- icon = oldVisibleApps.find { app.apId == it.apId }?.icon
- ?: if (fetchMissingIcons) permissionsModule.getApplicationIcon(app) else null
- )
- }
- }
-
- private fun updateMaps(apps: List<ApplicationDescription>) {
- val byUid = mutableMapOf<Int, ApplicationDescription>()
- val byApId = mutableMapOf<String, ApplicationDescription>()
- apps.forEach { app ->
- byUid[app.uid]?.run { packageName > app.packageName } == true
- if (byUid[app.uid].let { it == null || it.packageName > app.packageName }) {
- byUid[app.uid] = app
- }
-
- byApId[app.apId] = app
- }
- appsByUid = byUid
- appsByAPId = byApId
- }
-
- private var lastFetchApps = 0
- private var refreshAppJob: Job? = null
- private fun refreshAppDescriptions(fetchMissingIcons: Boolean = true, force: Boolean = false): Job? {
- if (refreshAppJob == null || refreshAppJob?.isCompleted == true) {
- refreshAppJob = coroutineScope.launch(Dispatchers.IO) {
- if (appsByUid.isEmpty() || appsByAPId.isEmpty() ||
- force || context.packageManager.getChangedPackages(lastFetchApps) != null
- ) {
- fetchAppDescriptions(fetchMissingIcons = fetchMissingIcons)
- if (fetchMissingIcons) {
- lastFetchApps = context.packageManager.getChangedPackages(lastFetchApps)
- ?.sequenceNumber ?: lastFetchApps
- }
- }
- }
- }
-
- return refreshAppJob
- }
-
- fun mainProfileApps(): Flow<List<ApplicationDescription>> {
- refreshAppDescriptions()
- return allProfilesAppDescriptions.map {
- it.first.filter { app -> app.profileType == ProfileType.MAIN }
- .sortedBy { app -> app.label.toString().lowercase() }
- }
- }
-
- fun getMainProfileHiddenSystemApps(): List<ApplicationDescription> {
- return allProfilesAppDescriptions.value.second.filter { it.profileType == ProfileType.MAIN }
- }
-
- fun apps(): Flow<List<ApplicationDescription>> {
- refreshAppDescriptions()
- return allProfilesAppDescriptions.map {
- it.first.sortedBy { app -> app.label.toString().lowercase() }
- }
- }
-
- fun allApps(): Flow<List<ApplicationDescription>> {
- return allProfilesAppDescriptions.map {
- it.first + it.second + it.third
- }
- }
-
- private fun getHiddenSystemApps(): List<ApplicationDescription> {
- return allProfilesAppDescriptions.value.second
- }
-
- private fun getCompatibilityApps(): List<ApplicationDescription> {
- return allProfilesAppDescriptions.value.third
- }
-
- fun anyForHiddenApps(app: ApplicationDescription, test: (ApplicationDescription) -> Boolean): Boolean {
- return if (app == dummySystemApp) {
- getHiddenSystemApps().any { test(it) }
- } else if (app == dummyCompatibilityApp) {
- getCompatibilityApps().any { test(it) }
- } else test(app)
- }
-
- fun applyForHiddenApps(app: ApplicationDescription, action: (ApplicationDescription) -> Unit) {
- mapReduceForHiddenApps(app = app, map = action, reduce = {})
- }
-
- fun <T, R> mapReduceForHiddenApps(
- app: ApplicationDescription,
- map: (ApplicationDescription) -> T,
- reduce: (List<T>) -> R
- ): R {
- return if (app == dummySystemApp) {
- reduce(getHiddenSystemApps().map(map))
- } else if (app == dummyCompatibilityApp) {
- reduce(getCompatibilityApps().map(map))
- } else reduce(listOf(map(app)))
- }
-
- private var appsByUid = mapOf<Int, ApplicationDescription>()
- private var appsByAPId = mapOf<String, ApplicationDescription>()
-
- fun getApp(appUid: Int): ApplicationDescription? {
- return appsByUid[appUid] ?: run {
- runBlocking { refreshAppDescriptions(fetchMissingIcons = false, force = true)?.join() }
- appsByUid[appUid]
- }
- }
-
- fun getApp(apId: String): ApplicationDescription? {
- if (apId.isBlank()) return null
-
- return appsByAPId[apId] ?: run {
- runBlocking { refreshAppDescriptions(fetchMissingIcons = false, force = true)?.join() }
- appsByAPId[apId]
- }
- }
-
- private val allProfilesAppDescriptions = MutableStateFlow(
- Triple(
- emptyList<ApplicationDescription>(),
- emptyList<ApplicationDescription>(),
- emptyList<ApplicationDescription>()
- )
- )
-
- private fun hasInternetPermission(packageInfo: PackageInfo): Boolean {
- return packageInfo.requestedPermissions?.contains(Manifest.permission.INTERNET) == true
- }
-
- @Suppress("ReturnCount")
- private fun isNotHiddenSystemApp(app: ApplicationInfo, launcherApps: List<String>): Boolean {
- if (app.packageName == PNAME_SETTINGS) {
- return false
- } else if (app.packageName == PNAME_PWAPLAYER) {
- return true
- } else if (app.hasFlag(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) {
- return true
- } else if (!app.hasFlag(ApplicationInfo.FLAG_SYSTEM)) {
- return true
- } else if (launcherApps.contains(app.packageName)) {
- return true
- }
- return false
- }
-
- private fun isStandardApp(app: ApplicationInfo, launcherApps: List<String>): Boolean {
- return when {
- app.packageName == PNAME_SETTINGS -> false
- app.packageName in compatibiltyPNames -> false
- app.hasFlag(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) -> true
- !app.hasFlag(ApplicationInfo.FLAG_SYSTEM) -> true
- launcherApps.contains(app.packageName) -> true
- else -> false
- }
- }
-
- private fun isHiddenSystemApp(app: ApplicationInfo, launcherApps: List<String>): Boolean {
- return when {
- app.packageName in compatibiltyPNames -> false
- else -> !isNotHiddenSystemApp(app, launcherApps)
- }
- }
-
- private fun ApplicationInfo.hasFlag(flag: Int) = (flags and flag) == 1
-}
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 -> {}
}
}