summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--app/build.gradle13
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt5
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt13
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/Notifications.kt28
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/common/BootCompletedReceiver.kt8
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt43
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/data/repositories/LocalStateRepository.kt54
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/FakeLocationStateUseCase.kt9
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/GetQuickPrivacyStateUseCase.kt13
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/IpScramblingStateUseCase.kt95
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/ShowFeaturesWarningUseCase.kt25
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/domain/usecases/TrackersStateUseCase.kt9
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardFragment.kt10
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardState.kt4
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyFragment.kt8
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyState.kt4
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyViewModel.kt4
-rw-r--r--app/src/main/java/foundation/e/advancedprivacy/widget/WidgetUI.kt6
-rw-r--r--core/build.gradle9
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureState.kt (renamed from core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureServiceState.kt)2
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt (renamed from app/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt)0
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt (renamed from app/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt)8
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt59
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnSupervisorUseCase.kt (renamed from app/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt)13
-rw-r--r--core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureSupervisor.kt27
-rw-r--r--gradle/libs.versions.toml6
-rw-r--r--ipscrambling/README.md4
-rw-r--r--ipscrambling/build.gradle2
m---------ipscrambling/orbotservice0
-rw-r--r--ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt2
-rw-r--r--ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotSupervisor.kt (renamed from ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt)32
-rw-r--r--permissionseos/.gitignore (renamed from permissionse/.gitignore)0
-rw-r--r--permissionseos/build.gradle (renamed from permissionse/build.gradle)2
-rw-r--r--permissionseos/consumer-rules.pro (renamed from permissionse/consumer-rules.pro)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/.gitignore (renamed from permissionse/libs/hidden-apis-stub/.gitignore)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/build.gradle (renamed from permissionse/libs/hidden-apis-stub/build.gradle)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/AndroidManifest.xml (renamed from permissionse/libs/hidden-apis-stub/src/main/AndroidManifest.xml)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/java/android/app/AppOpsManager.java (renamed from permissionse/libs/hidden-apis-stub/src/main/java/android/app/AppOpsManager.java)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/java/android/app/NotificationChannel.java (renamed from permissionse/libs/hidden-apis-stub/src/main/java/android/app/NotificationChannel.java)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/java/android/content/pm/PackageManager.java (renamed from permissionse/libs/hidden-apis-stub/src/main/java/android/content/pm/PackageManager.java)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/java/android/content/pm/UserInfo.java (renamed from permissionse/libs/hidden-apis-stub/src/main/java/android/content/pm/UserInfo.java)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java (renamed from permissionse/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java (renamed from permissionse/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/java/android/os/ServiceManager.java (renamed from permissionse/libs/hidden-apis-stub/src/main/java/android/os/ServiceManager.java)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/java/android/os/UserHandle.java (renamed from permissionse/libs/hidden-apis-stub/src/main/java/android/os/UserHandle.java)0
-rw-r--r--permissionseos/libs/hidden-apis-stub/src/main/java/android/os/UserManager.java (renamed from permissionse/libs/hidden-apis-stub/src/main/java/android/os/UserManager.java)0
-rw-r--r--permissionseos/proguard-rules.pro (renamed from permissionse/proguard-rules.pro)0
-rw-r--r--permissionseos/src/main/AndroidManifest.xml (renamed from permissionse/src/main/AndroidManifest.xml)2
-rw-r--r--permissionseos/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleImpl.kt (renamed from permissionse/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleImpl.kt)0
-rw-r--r--settings.gradle6
-rw-r--r--trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersSupervisor.kt (renamed from trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersServiceSupervisor.kt)5
-rw-r--r--trackersserviceeos/.gitignore (renamed from trackersservicee/.gitignore)0
-rw-r--r--trackersserviceeos/build.gradle (renamed from trackersservicee/build.gradle)1
-rw-r--r--trackersserviceeos/consumer-rules.pro (renamed from trackersservicee/consumer-rules.pro)0
-rw-r--r--trackersserviceeos/proguard-rules.pro (renamed from trackersservicee/proguard-rules.pro)0
-rw-r--r--trackersserviceeos/src/main/AndroidManifest.xml (renamed from trackersservicee/src/main/AndroidManifest.xml)0
-rw-r--r--trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/DNSBlocker.kt (renamed from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/DNSBlocker.kt)0
-rw-r--r--trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt (renamed from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt)0
-rw-r--r--trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorEos.kt (renamed from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt)25
-rw-r--r--trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt108
-rw-r--r--trackersservicestandalone/build.gradle1
-rw-r--r--trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt21
-rw-r--r--trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorStandalone.kt (renamed from trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt)30
-rw-r--r--trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TunLooper.kt1
-rw-r--r--trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt154
66 files changed, 595 insertions, 278 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 89a6f78..9f3d1f0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -93,7 +93,7 @@ test-debug:
build-e-release:
stage: build
script:
- - ./gradlew :app:assembleERelease
+ - ./gradlew :app:assembleEosRelease
rules:
- if: '$CI_COMMIT_REF_PROTECTED == "true" && $CI_COMMIT_TAG =~ /^eOS-/'
variables:
diff --git a/app/build.gradle b/app/build.gradle
index 216b81a..95bbee6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -20,7 +20,6 @@ plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
- id 'kotlin-parcelize'
id 'androidx.navigation.safeargs.kotlin'
}
@@ -82,7 +81,7 @@ android {
// expected by the android gradle plugin.
flavorDimensions 'os'
productFlavors {
- e {
+ eos {
dimension 'os'
minSdkVersion 29
targetSdkVersion 32
@@ -144,20 +143,20 @@ android {
dependencies {
implementation project(':core')
standaloneImplementation project(':permissionsstandalone')
- eImplementation project(':permissionse')
+ eosImplementation project(':permissionseos')
implementation project(':fakelocation')
- eImplementation files('libs/lineage-sdk.jar')
+ eosImplementation files('libs/lineage-sdk.jar')
implementation project(':trackers')
implementation project(':ipscrambling')
- eImplementation project(':trackersservicee')
+ eosImplementation project(':trackersserviceeos')
standaloneImplementation project(':trackersservicestandalone')
implementation (
- libs.e.elib,
+ libs.eos.elib,
libs.androidx.core.ktx,
libs.androidx.appcompat,
@@ -174,7 +173,7 @@ dependencies {
libs.maplibre,
libs.mpandroidcharts,
- libs.e.telemetry,
+ libs.eos.telemetry,
libs.timber
)
diff --git a/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt b/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt
index 71fef00..0fc1d67 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2021 E FOUNDATION, 2022 - 2023 MURENA SAS
+ * Copyright (C) 2022 - 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
@@ -25,6 +26,7 @@ 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.domain.usecases.VpnSupervisorUseCase
import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
import foundation.e.advancedprivacy.trackers.services.UpdateTrackersWorker
import foundation.e.lib.telemetry.Telemetry
@@ -70,5 +72,6 @@ class AdvancedPrivacyApplication : Application() {
get<IpScramblingStateUseCase>(IpScramblingStateUseCase::class.java)
get<TrackersStateUseCase>(TrackersStateUseCase::class.java)
get<FakeLocationStateUseCase>(FakeLocationStateUseCase::class.java)
+ get<VpnSupervisorUseCase>(VpnSupervisorUseCase::class.java).listenSettings()
}
}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt b/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt
index fbf1252..efcd096 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt
@@ -20,11 +20,12 @@ 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.data.repositories.LocalStateRepositoryImpl
import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
import foundation.e.advancedprivacy.domain.entities.CHANNEL_TRACKER_FLAG
import foundation.e.advancedprivacy.domain.entities.NotificationContent
import foundation.e.advancedprivacy.domain.entities.ProfileType
+import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository
import foundation.e.advancedprivacy.domain.usecases.AppListUseCase
import foundation.e.advancedprivacy.domain.usecases.FakeLocationStateUseCase
import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase
@@ -55,8 +56,8 @@ val appModule = module {
includes(coreModule, trackersModule, fakelocationModule, ipScramblerModule, trackerServiceModule)
factory<Resources> { androidContext().resources }
- single {
- LocalStateRepository(context = androidContext())
+ single<LocalStateRepository> {
+ LocalStateRepositoryImpl(context = androidContext())
}
single<ApplicationDescription>(named("AdvancedPrivacy")) {
@@ -120,15 +121,13 @@ val appModule = module {
singleOf(::GetQuickPrivacyStateUseCase)
single {
IpScramblingStateUseCase(
- orbotServiceSupervisor = get(),
- permissionsPrivacyModule = get(),
- appDesc = get(named("AdvancedPrivacy")),
+ orbotSupervisor = get(),
localStateRepository = get(),
appListsRepository = get(),
- trackersServiceSupervisor = get(),
coroutineScope = get()
)
}
+
singleOf(::ShowFeaturesWarningUseCase)
singleOf(::TrackersStateUseCase)
singleOf(::TrackersStatisticsUseCase)
diff --git a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt
index 639ede4..430e9d5 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt
@@ -29,8 +29,7 @@ import foundation.e.advancedprivacy.domain.entities.CHANNEL_FAKE_LOCATION_FLAG
import foundation.e.advancedprivacy.domain.entities.CHANNEL_FIRST_BOOT
import foundation.e.advancedprivacy.domain.entities.CHANNEL_IPSCRAMBLING_FLAG
import foundation.e.advancedprivacy.domain.entities.CHANNEL_TRACKER_FLAG
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
-import foundation.e.advancedprivacy.domain.entities.MainFeatures
+import foundation.e.advancedprivacy.domain.entities.FeatureState
import foundation.e.advancedprivacy.domain.entities.NOTIFICATION_FAKE_LOCATION_FLAG
import foundation.e.advancedprivacy.domain.entities.NOTIFICATION_FIRST_BOOT
import foundation.e.advancedprivacy.domain.entities.NOTIFICATION_IPSCRAMBLING_FLAG
@@ -98,19 +97,19 @@ object Notifications {
getQuickPrivacyStateUseCase.isLocationHidden.onEach {
if (it) {
- showFlagNotification(appContext, MainFeatures.FAKE_LOCATION)
+ showFlagNotification(appContext, NOTIFICATION_FAKE_LOCATION_FLAG)
} else {
- hideFlagNotification(appContext, MainFeatures.FAKE_LOCATION)
+ hideFlagNotification(appContext, NOTIFICATION_FAKE_LOCATION_FLAG)
}
}.launchIn(appScope)
getQuickPrivacyStateUseCase.ipScramblingMode.map {
- it != FeatureServiceState.OFF
+ it != FeatureState.OFF
}.distinctUntilChanged().onEach {
if (it) {
- showFlagNotification(appContext, MainFeatures.IP_SCRAMBLING)
+ showFlagNotification(appContext, NOTIFICATION_IPSCRAMBLING_FLAG)
} else {
- hideFlagNotification(appContext, MainFeatures.IP_SCRAMBLING)
+ hideFlagNotification(appContext, NOTIFICATION_IPSCRAMBLING_FLAG)
}
}.launchIn(appScope)
}
@@ -139,9 +138,9 @@ object Notifications {
NotificationManagerCompat.from(context).createNotificationChannel(channel)
}
- private fun showFlagNotification(context: Context, feature: MainFeatures) {
- when (feature) {
- MainFeatures.FAKE_LOCATION -> showFlagNotification(
+ private fun showFlagNotification(context: Context, id: Int) {
+ when (id) {
+ NOTIFICATION_FAKE_LOCATION_FLAG -> showFlagNotification(
context = context,
id = NOTIFICATION_FAKE_LOCATION_FLAG,
content = NotificationContent(
@@ -154,7 +153,7 @@ object Notifications {
.createPendingIntent()
)
)
- MainFeatures.IP_SCRAMBLING -> showFlagNotification(
+ NOTIFICATION_IPSCRAMBLING_FLAG -> showFlagNotification(
context = context,
id = NOTIFICATION_IPSCRAMBLING_FLAG,
content = NotificationContent(
@@ -183,12 +182,7 @@ object Notifications {
NotificationManagerCompat.from(context).notify(id, builder.build())
}
- private fun hideFlagNotification(context: Context, feature: MainFeatures) {
- val id = when (feature) {
- MainFeatures.FAKE_LOCATION -> NOTIFICATION_FAKE_LOCATION_FLAG
- MainFeatures.IP_SCRAMBLING -> NOTIFICATION_IPSCRAMBLING_FLAG
- else -> return
- }
+ private fun hideFlagNotification(context: Context, id: Int) {
NotificationManagerCompat.from(context).cancel(id)
}
}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/common/BootCompletedReceiver.kt b/app/src/main/java/foundation/e/advancedprivacy/common/BootCompletedReceiver.kt
index d73f770..562144d 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/common/BootCompletedReceiver.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/common/BootCompletedReceiver.kt
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2023 MURENA SAS
* Copyright (C) 2022 E FOUNDATION
*
* This program is free software: you can redistribute it and/or modify
@@ -21,12 +22,15 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import foundation.e.advancedprivacy.Notifications
-import foundation.e.advancedprivacy.data.repositories.LocalStateRepository
+import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository
+import org.koin.java.KoinJavaComponent.inject
class BootCompletedReceiver : BroadcastReceiver() {
+
+ private val localStateRepository by inject<LocalStateRepository>(LocalStateRepository::class.java)
+
override fun onReceive(context: Context, intent: Intent?) {
if (intent?.action == Intent.ACTION_BOOT_COMPLETED) {
- val localStateRepository = LocalStateRepository(context)
if (localStateRepository.firstBoot) {
Notifications.showFirstBootNotification(context)
localStateRepository.firstBoot = false
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 589aa74..9dbfea9 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt
@@ -29,9 +29,12 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import foundation.e.advancedprivacy.R
-import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning
-import foundation.e.advancedprivacy.domain.usecases.IpScramblingStateUseCase
+import foundation.e.advancedprivacy.domain.entities.MainFeatures
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.FakeLocation
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.IpScrambling
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.TrackersControl
import foundation.e.advancedprivacy.domain.usecases.ShowFeaturesWarningUseCase
+import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase
import foundation.e.advancedprivacy.main.MainActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
@@ -57,7 +60,7 @@ class WarningDialog : AppCompatActivity() {
private fun createIntent(
context: Context,
- feature: ShowFeaturesWarning,
+ feature: MainFeatures,
): Intent {
val intent = Intent(context, WarningDialog::class.java)
intent.putExtra(PARAM_FEATURE, feature)
@@ -67,13 +70,14 @@ class WarningDialog : AppCompatActivity() {
}
private var isWaitingForResult = false
+ private lateinit var feature: MainFeatures
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.setBackgroundDrawable(ColorDrawable(0))
- val feature = try {
- intent.getParcelableExtra<ShowFeaturesWarning>(PARAM_FEATURE)!!
+ feature = try {
+ intent.getParcelableExtra<MainFeatures>(PARAM_FEATURE)!!
} catch (e: Exception) {
Timber.e(e, "Missing mandatory activity parameter")
finish()
@@ -82,7 +86,7 @@ class WarningDialog : AppCompatActivity() {
showWarningDialog(feature)
}
- private fun showWarningDialog(feature: ShowFeaturesWarning) {
+ private fun showWarningDialog(feature: MainFeatures) {
val builder = AlertDialog.Builder(this)
builder.setOnDismissListener { if (!isWaitingForResult) finish() }
@@ -92,23 +96,23 @@ class WarningDialog : AppCompatActivity() {
builder.setMessage(
when (feature) {
- ShowFeaturesWarning.TrackersControl -> R.string.warningdialog_trackers_message
- ShowFeaturesWarning.FakeLocation -> R.string.warningdialog_location_message
- is ShowFeaturesWarning.IpScrambling -> R.string.warningdialog_ipscrambling_message
+ is TrackersControl -> R.string.warningdialog_trackers_message
+ is FakeLocation -> R.string.warningdialog_location_message
+ is IpScrambling -> R.string.warningdialog_ipscrambling_message
}
)
builder.setTitle(
when (feature) {
- ShowFeaturesWarning.TrackersControl -> R.string.warningdialog_trackers_title
- ShowFeaturesWarning.FakeLocation -> R.string.warningdialog_location_title
- is ShowFeaturesWarning.IpScrambling -> R.string.warningdialog_ipscrambling_title
+ is TrackersControl -> R.string.warningdialog_trackers_title
+ is FakeLocation -> R.string.warningdialog_location_title
+ is IpScrambling -> R.string.warningdialog_ipscrambling_title
}
)
builder.setPositiveButton(
when (feature) {
- is ShowFeaturesWarning.IpScrambling -> R.string.warningdialog_ipscrambling_cta
+ is IpScrambling -> R.string.warningdialog_ipscrambling_cta
else -> R.string.ok
}
) { _, _ ->
@@ -117,7 +121,7 @@ class WarningDialog : AppCompatActivity() {
.doNotShowAgain(feature)
}
- val vpnDisclaimerIntent = (feature as? ShowFeaturesWarning.IpScrambling)
+ val vpnDisclaimerIntent = (feature as? MainFeatures.IpScrambling)
?.startVpnDisclaimer
if (vpnDisclaimerIntent != null) {
@@ -126,7 +130,7 @@ class WarningDialog : AppCompatActivity() {
} else finish()
}
- if (feature == ShowFeaturesWarning.TrackersControl) {
+ if (feature is MainFeatures.TrackersControl) {
builder.setNeutralButton(R.string.warningdialog_trackers_secondary_cta) { _, _ ->
MainActivity.deepLinkBuilder(this)
.setDestination(R.id.trackersFragment)
@@ -135,16 +139,17 @@ class WarningDialog : AppCompatActivity() {
finish()
}
}
-
builder.show()
}
private val launchAndroidVpnDisclaimer = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
- val ipScramblingStateUseCase = get<IpScramblingStateUseCase>(IpScramblingStateUseCase::class.java)
+ val vpnSupervisorUseCase = get<VpnSupervisorUseCase>(
+ VpnSupervisorUseCase::class.java
+ )
if (result.resultCode == Activity.RESULT_OK) {
- ipScramblingStateUseCase.startIpScrambling()
+ vpnSupervisorUseCase.startVpnService(feature)
} else {
- ipScramblingStateUseCase.toggle(false)
+ vpnSupervisorUseCase.cancelStartVpnService(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 c7d4a27..2afd6ee 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
@@ -19,18 +19,18 @@
package foundation.e.advancedprivacy.data.repositories
import android.content.Context
-import android.content.Intent
import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
import foundation.e.advancedprivacy.domain.entities.LocationMode
-import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning
+import foundation.e.advancedprivacy.domain.entities.MainFeatures
+import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
-class LocalStateRepository(context: Context) {
+class LocalStateRepositoryImpl(context: Context) : LocalStateRepository {
companion object {
private const val SHARED_PREFS_FILE = "localState"
private const val KEY_BLOCK_TRACKERS = "blockTrackers"
@@ -47,25 +47,26 @@ class LocalStateRepository(context: Context) {
private val sharedPref = context.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE)
private val _blockTrackers = MutableStateFlow(sharedPref.getBoolean(KEY_BLOCK_TRACKERS, true))
- val blockTrackers = _blockTrackers.asStateFlow()
- fun setBlockTrackers(enabled: Boolean) {
+ override val blockTrackers = _blockTrackers.asStateFlow()
+
+ override fun setBlockTrackers(enabled: Boolean) {
set(KEY_BLOCK_TRACKERS, enabled)
_blockTrackers.update { enabled }
}
- val areAllTrackersBlocked: MutableStateFlow<Boolean> = MutableStateFlow(false)
+ override val areAllTrackersBlocked: MutableStateFlow<Boolean> = MutableStateFlow(false)
private val _fakeLocationEnabled = MutableStateFlow(sharedPref.getBoolean(KEY_FAKE_LOCATION, false))
- val fakeLocationEnabled = _fakeLocationEnabled.asStateFlow()
+ override val fakeLocationEnabled = _fakeLocationEnabled.asStateFlow()
- fun setFakeLocationEnabled(enabled: Boolean) {
+ override fun setFakeLocationEnabled(enabled: Boolean) {
set(KEY_FAKE_LOCATION, enabled)
_fakeLocationEnabled.update { enabled }
}
- var fakeLocation: Pair<Float, Float>
+ override var fakeLocation: Pair<Float, Float>
get() = Pair(
// Initial default value is Quezon City
sharedPref.getFloat(KEY_FAKE_LATITUDE, 14.6760f),
@@ -79,43 +80,48 @@ class LocalStateRepository(context: Context) {
.apply()
}
- val locationMode: MutableStateFlow<LocationMode> = MutableStateFlow(LocationMode.REAL_LOCATION)
+ override val locationMode: MutableStateFlow<LocationMode> = MutableStateFlow(LocationMode.REAL_LOCATION)
private val _ipScramblingSetting = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, false))
- val ipScramblingSetting = _ipScramblingSetting.asStateFlow()
- fun setIpScramblingSetting(enabled: Boolean) {
+ override val ipScramblingSetting = _ipScramblingSetting.asStateFlow()
+
+ override fun setIpScramblingSetting(enabled: Boolean) {
set(KEY_IP_SCRAMBLING, enabled)
_ipScramblingSetting.update { enabled }
}
- val internetPrivacyMode: MutableStateFlow<FeatureServiceState> = MutableStateFlow(FeatureServiceState.OFF)
+ override val internetPrivacyMode: MutableStateFlow<FeatureState> = MutableStateFlow(FeatureState.OFF)
+
+ private val _startVpnDisclaimer = MutableSharedFlow<MainFeatures>()
- private val _startVpnDisclaimer = MutableSharedFlow<ShowFeaturesWarning.IpScrambling>()
- suspend fun emitStartVpnDisclaimer(intent: Intent?) {
- _startVpnDisclaimer.emit(ShowFeaturesWarning.IpScrambling(startVpnDisclaimer = intent))
+ override suspend fun emitStartVpnDisclaimer(feature: MainFeatures) {
+ _startVpnDisclaimer.emit(feature)
}
- val startVpnDisclaimer: SharedFlow<ShowFeaturesWarning.IpScrambling> = _startVpnDisclaimer
+
+ override val startVpnDisclaimer: SharedFlow<MainFeatures> = _startVpnDisclaimer
private val _otherVpnRunning = MutableSharedFlow<ApplicationDescription>()
- suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) {
+
+ override suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) {
_otherVpnRunning.emit(appDesc)
}
- val otherVpnRunning: SharedFlow<ApplicationDescription> = _otherVpnRunning
- var firstBoot: Boolean
+ override val otherVpnRunning: SharedFlow<ApplicationDescription> = _otherVpnRunning
+
+ override var firstBoot: Boolean
get() = sharedPref.getBoolean(KEY_FIRST_BOOT, true)
set(value) = set(KEY_FIRST_BOOT, value)
- var hideWarningTrackers: Boolean
+ override var hideWarningTrackers: Boolean
get() = sharedPref.getBoolean(KEY_HIDE_WARNING_TRACKERS, false)
set(value) = set(KEY_HIDE_WARNING_TRACKERS, value)
- var hideWarningLocation: Boolean
+ override var hideWarningLocation: Boolean
get() = sharedPref.getBoolean(KEY_HIDE_WARNING_LOCATION, false)
set(value) = set(KEY_HIDE_WARNING_LOCATION, value)
- var hideWarningIpScrambling: Boolean
+ override var hideWarningIpScrambling: Boolean
get() = sharedPref.getBoolean(KEY_HIDE_WARNING_IPSCRAMBLING, false)
set(value) = set(KEY_HIDE_WARNING_IPSCRAMBLING, value)
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 983ba71..282116e 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
@@ -25,10 +25,10 @@ import android.location.Location
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.domain.repositories.LocalStateRepository
import foundation.e.advancedprivacy.dummy.CityDataSource
import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
import foundation.e.advancedprivacy.fakelocation.domain.usecases.FakeLocationModule
@@ -49,11 +49,10 @@ class FakeLocationStateUseCase(
private val appContext: Context,
coroutineScope: CoroutineScope
) {
- companion object {
- private const val TAG = "FakeLocationStateUseCase"
- }
+ private val _configuredLocationMode = MutableStateFlow<Triple<LocationMode, Float?, Float?>>(
+ Triple(LocationMode.REAL_LOCATION, null, null)
+ )
- private val _configuredLocationMode = MutableStateFlow<Triple<LocationMode, Float?, Float?>>(Triple(LocationMode.REAL_LOCATION, null, null))
val configuredLocationMode: StateFlow<Triple<LocationMode, Float?, Float?>> = _configuredLocationMode
init {
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 1b8f62c..480d3b3 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
@@ -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
@@ -17,12 +18,12 @@
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.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
import foundation.e.advancedprivacy.domain.entities.LocationMode
import foundation.e.advancedprivacy.domain.entities.QuickPrivacyState
import foundation.e.advancedprivacy.domain.entities.TrackerMode
+import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
@@ -41,13 +42,13 @@ class GetQuickPrivacyStateUseCase(
when {
!isBlockTrackers &&
locationMode == LocationMode.REAL_LOCATION &&
- internetPrivacyMode == FeatureServiceState.OFF -> QuickPrivacyState.DISABLED
+ internetPrivacyMode == FeatureState.OFF -> QuickPrivacyState.DISABLED
isAllTrackersBlocked &&
locationMode != LocationMode.REAL_LOCATION &&
internetPrivacyMode in listOf(
- FeatureServiceState.ON,
- FeatureServiceState.STARTING
+ FeatureState.ON,
+ FeatureState.STARTING
) -> QuickPrivacyState.FULL_ENABLED
else -> QuickPrivacyState.ENABLED
@@ -71,7 +72,7 @@ class GetQuickPrivacyStateUseCase(
val locationMode: StateFlow<LocationMode> = localStateRepository.locationMode
- val ipScramblingMode: Flow<FeatureServiceState> =
+ val ipScramblingMode: Flow<FeatureState> =
localStateRepository.internetPrivacyMode
fun toggleTrackers(enabled: Boolean?) {
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 79c79f7..00613dd 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
@@ -18,43 +18,27 @@
package foundation.e.advancedprivacy.domain.usecases
-import android.content.Intent
-import foundation.e.advancedprivacy.common.isStandaloneBuild
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.FeatureServiceState
-import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
-import foundation.e.advancedprivacy.ipscrambler.OrbotServiceSupervisor
-import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor
+import foundation.e.advancedprivacy.domain.entities.FeatureState
+import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository
+import foundation.e.advancedprivacy.ipscrambler.OrbotSupervisor
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.launch
class IpScramblingStateUseCase(
- private val orbotServiceSupervisor: OrbotServiceSupervisor,
- private val permissionsPrivacyModule: IPermissionsPrivacyModule,
- private val appDesc: ApplicationDescription,
+ private val orbotSupervisor: OrbotSupervisor,
private val localStateRepository: LocalStateRepository,
private val appListsRepository: AppListsRepository,
- private val trackersServiceSupervisor: TrackersServiceSupervisor,
private val coroutineScope: CoroutineScope
) {
- val internetPrivacyMode: StateFlow<FeatureServiceState> = orbotServiceSupervisor.state
+ val internetPrivacyMode: StateFlow<FeatureState> = orbotSupervisor.state
init {
- orbotServiceSupervisor.requestStatus()
+ orbotSupervisor.requestStatus()
- coroutineScope.launch(Dispatchers.Default) {
- localStateRepository.ipScramblingSetting.collect {
- applySettings(it)
- }
- }
-
- orbotServiceSupervisor.state.map {
+ orbotSupervisor.state.map {
localStateRepository.internetPrivacyMode.value = it
}.launchIn(coroutineScope)
}
@@ -68,7 +52,7 @@ class IpScramblingStateUseCase(
}
val bypassTorApps: Set<String> get() {
- var whitelist = orbotServiceSupervisor.appList
+ var whitelist = orbotSupervisor.appList
if (getHiddenPackageNames().any { it in whitelist }) {
val mutable = whitelist.toMutableSet()
mutable.removeAll(getHiddenPackageNames())
@@ -86,7 +70,7 @@ class IpScramblingStateUseCase(
fun toggleBypassTor(packageName: String) {
val visibleList = bypassTorApps.toMutableSet()
- val rawList = orbotServiceSupervisor.appList.toMutableSet()
+ val rawList = orbotSupervisor.appList.toMutableSet()
if (visibleList.contains(packageName)) {
if (packageName == appListsRepository.dummySystemApp.packageName) {
@@ -105,69 +89,16 @@ class IpScramblingStateUseCase(
rawList.add(packageName)
}
}
- orbotServiceSupervisor.appList = rawList
+ orbotSupervisor.appList = rawList
}
- val availablesLocations: List<String> = orbotServiceSupervisor.getAvailablesLocations().sorted()
+ val availablesLocations: List<String> = orbotSupervisor.getAvailablesLocations().sorted()
- val exitCountry: String get() = orbotServiceSupervisor.getExitCountryCode()
+ val exitCountry: String get() = orbotSupervisor.getExitCountryCode()
suspend fun setExitCountry(locationId: String) {
if (locationId != exitCountry) {
- orbotServiceSupervisor.setExitCountryCode(locationId)
+ orbotSupervisor.setExitCountryCode(locationId)
}
}
-
- private suspend fun applySettings(isIpScramblingEnabled: Boolean) {
- val currentMode = localStateRepository.internetPrivacyMode.value
- when {
- isIpScramblingEnabled && currentMode in setOf(FeatureServiceState.OFF, FeatureServiceState.STOPPING) ->
- applyStartIpScrambling()
-
- !isIpScramblingEnabled && currentMode in setOf(FeatureServiceState.ON, FeatureServiceState.STARTING) ->
- orbotServiceSupervisor.stop()
-
- else -> {}
- }
- }
-
- private suspend fun applyStartIpScrambling() {
- val authorizeVpnIntent = orbotServiceSupervisor.prepareAndroidVpn()
- if (authorizeVpnIntent == null) {
- localStateRepository.emitStartVpnDisclaimer(null)
-
- startIpScrambling()
- return
- }
-
- acquireVpnAuthorization(authorizeVpnIntent)
- }
-
- private suspend fun acquireVpnAuthorization(authorizeVpnIntent: Intent) {
- val authorized = permissionsPrivacyModule.setVpnPackageAuthorization(appDesc.packageName)
- val alwaysOnVpnPackage = permissionsPrivacyModule.getAlwaysOnVpnPackage()
-
- when {
- authorized && alwaysOnVpnPackage == null -> {
- localStateRepository.emitStartVpnDisclaimer(null)
- startIpScrambling()
- }
- authorized && alwaysOnVpnPackage != null -> {
- localStateRepository.emitOtherVpnRunning(
- permissionsPrivacyModule.getApplicationDescription(
- packageName = alwaysOnVpnPackage,
- withIcon = false
- )
- )
- localStateRepository.setIpScramblingSetting(enabled = false)
- }
- else -> localStateRepository.emitStartVpnDisclaimer(authorizeVpnIntent)
- }
- }
-
- fun startIpScrambling() {
- localStateRepository.internetPrivacyMode.value = FeatureServiceState.STARTING
- orbotServiceSupervisor.setDNSFilter((trackersServiceSupervisor.dnsFilterForIpScrambling))
- orbotServiceSupervisor.start(enableNotification = isStandaloneBuild)
- }
}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/ShowFeaturesWarningUseCase.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/ShowFeaturesWarningUseCase.kt
index c99d5f1..f8a0986 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/ShowFeaturesWarningUseCase.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/ShowFeaturesWarningUseCase.kt
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2023 MURENA SAS
* Copyright (C) 2022 E FOUNDATION
*
* This program is free software: you can redistribute it and/or modify
@@ -17,11 +18,11 @@
package foundation.e.advancedprivacy.domain.usecases
-import foundation.e.advancedprivacy.data.repositories.LocalStateRepository
-import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning
-import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning.FakeLocation
-import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning.IpScrambling
-import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning.TrackersControl
+import foundation.e.advancedprivacy.domain.entities.MainFeatures
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.FakeLocation
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.IpScrambling
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.TrackersControl
+import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.dropWhile
@@ -33,24 +34,22 @@ class ShowFeaturesWarningUseCase(
private val localStateRepository: LocalStateRepository
) {
- fun showWarning(): Flow<ShowFeaturesWarning> {
+ fun showWarning(): Flow<MainFeatures> {
return merge(
- localStateRepository.blockTrackers.drop(1).dropWhile { !it }
- .filter { it && !localStateRepository.hideWarningTrackers }
- .map { TrackersControl },
localStateRepository.fakeLocationEnabled.drop(1).dropWhile { !it }
.filter { it && !localStateRepository.hideWarningLocation }
.map { FakeLocation },
localStateRepository.startVpnDisclaimer.filter {
- it.startVpnDisclaimer != null || !localStateRepository.hideWarningIpScrambling
+ (it is IpScrambling && !localStateRepository.hideWarningIpScrambling) ||
+ (it is TrackersControl && !localStateRepository.hideWarningTrackers)
}
)
}
- fun doNotShowAgain(feature: ShowFeaturesWarning) {
+ fun doNotShowAgain(feature: MainFeatures) {
when (feature) {
- TrackersControl -> localStateRepository.hideWarningTrackers = true
- FakeLocation -> localStateRepository.hideWarningLocation = true
+ is TrackersControl -> localStateRepository.hideWarningTrackers = true
+ is FakeLocation -> localStateRepository.hideWarningLocation = true
is IpScrambling -> localStateRepository.hideWarningIpScrambling = true
}
}
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 9b79dcc..2c47d70 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
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2021 E FOUNDATION, 2022 - 2023 MURENA SAS
+ * Copyright (C) 2022 - 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
@@ -18,11 +19,10 @@
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.repositories.LocalStateRepository
import foundation.e.advancedprivacy.trackers.data.WhitelistRepository
import foundation.e.advancedprivacy.trackers.domain.entities.Tracker
-import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -30,7 +30,6 @@ class TrackersStateUseCase(
private val whitelistRepository: WhitelistRepository,
private val localStateRepository: LocalStateRepository,
private val appListsRepository: AppListsRepository,
- private val trackersServiceSupervisor: TrackersServiceSupervisor,
coroutineScope: CoroutineScope,
) {
init {
@@ -40,8 +39,6 @@ class TrackersStateUseCase(
updateAllTrackersBlockedState()
}
}
-
- trackersServiceSupervisor.start()
}
private fun updateAllTrackersBlockedState() {
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 0a53c6c..56cf81f 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
@@ -34,7 +34,7 @@ import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.common.GraphHolder
import foundation.e.advancedprivacy.common.NavToolbarFragment
import foundation.e.advancedprivacy.databinding.FragmentDashboardBinding
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
import foundation.e.advancedprivacy.domain.entities.LocationMode
import foundation.e.advancedprivacy.domain.entities.QuickPrivacyState
import foundation.e.advancedprivacy.domain.entities.TrackerMode
@@ -186,11 +186,11 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
binding.toggleIpscrambling.isChecked = state.ipScramblingMode.isChecked
val isLoading = state.ipScramblingMode.isLoading
binding.toggleIpscrambling.isEnabled = (
- state.ipScramblingMode != FeatureServiceState.STOPPING
+ state.ipScramblingMode != FeatureState.STOPPING
)
binding.stateIpAddress.text = getString(
- if (state.ipScramblingMode == FeatureServiceState.ON) R.string.dashboard_state_ipaddress_on
+ if (state.ipScramblingMode == FeatureState.ON) R.string.dashboard_state_ipaddress_on
else R.string.dashboard_state_ipaddress_off
)
@@ -200,7 +200,7 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
binding.stateIpAddress.setTextColor(
getColor(
requireContext(),
- if (state.ipScramblingMode == FeatureServiceState.ON) R.color.green_valid
+ if (state.ipScramblingMode == FeatureState.ON) R.color.green_valid
else R.color.red_off
)
)
@@ -250,7 +250,7 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
)
binding.internetActivityPrivacy.subTitle = getString(
- if (state.ipScramblingMode == FeatureServiceState.ON) R.string.dashboard_internet_activity_privacy_subtitle_on
+ if (state.ipScramblingMode == FeatureState.ON) R.string.dashboard_internet_activity_privacy_subtitle_on
else R.string.dashboard_internet_activity_privacy_subtitle_off
)
diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardState.kt b/app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardState.kt
index 069ff04..d26c53d 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardState.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/features/dashboard/DashboardState.kt
@@ -17,7 +17,7 @@
package foundation.e.advancedprivacy.features.dashboard
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
import foundation.e.advancedprivacy.domain.entities.LocationMode
import foundation.e.advancedprivacy.domain.entities.QuickPrivacyState
import foundation.e.advancedprivacy.domain.entities.TrackerMode
@@ -26,7 +26,7 @@ data class DashboardState(
val quickPrivacyState: QuickPrivacyState = QuickPrivacyState.DISABLED,
val trackerMode: TrackerMode = TrackerMode.VULNERABLE,
val isLocationHidden: Boolean = false,
- val ipScramblingMode: FeatureServiceState = FeatureServiceState.STOPPING,
+ val ipScramblingMode: FeatureState = FeatureState.STOPPING,
val locationMode: LocationMode = LocationMode.REAL_LOCATION,
val leakedTrackersCount: Int? = null,
val trackersCount: Int? = 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 b4fc8a1..482a773 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
@@ -32,7 +32,7 @@ import foundation.e.advancedprivacy.common.NavToolbarFragment
import foundation.e.advancedprivacy.common.ToggleAppsAdapter
import foundation.e.advancedprivacy.common.setToolTipForAsterisk
import foundation.e.advancedprivacy.databinding.FragmentInternetActivityPolicyBinding
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
import kotlinx.coroutines.launch
import org.koin.androidx.viewmodel.ext.android.viewModel
import java.util.Locale
@@ -137,11 +137,11 @@ class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_ac
private fun render(state: InternetPrivacyState) {
binding.radioUseHiddenIp.radiobutton.apply {
isChecked = state.mode.isChecked
- isEnabled = state.mode != FeatureServiceState.STARTING
+ isEnabled = state.mode != FeatureState.STARTING
}
binding.radioUseRealIp.radiobutton.apply {
isChecked = !state.mode.isChecked
- isEnabled = state.mode != FeatureServiceState.STOPPING
+ isEnabled = state.mode != FeatureState.STOPPING
}
binding.ipscramblingSelectLocation.setSelection(state.selectedLocationPosition)
@@ -150,7 +150,7 @@ class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_ac
binding.apps.post {
(binding.apps.adapter as ToggleAppsAdapter?)?.setData(
list = state.getApps(),
- isEnabled = state.mode == FeatureServiceState.ON
+ isEnabled = state.mode == FeatureState.ON
)
}
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 e607d6c..9ba716f 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
@@ -18,10 +18,10 @@
package foundation.e.advancedprivacy.features.internetprivacy
import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
data class InternetPrivacyState(
- val mode: FeatureServiceState = FeatureServiceState.OFF,
+ val mode: FeatureState = FeatureState.OFF,
val availableApps: List<ApplicationDescription> = emptyList(),
val bypassTorApps: Collection<String> = emptyList(),
val selectedLocation: String = "",
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 10530e1..b2f93c2 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
@@ -22,7 +22,7 @@ import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import foundation.e.advancedprivacy.R
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
import foundation.e.advancedprivacy.domain.usecases.AppListUseCase
import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.advancedprivacy.domain.usecases.IpScramblingStateUseCase
@@ -88,7 +88,7 @@ class InternetPrivacyViewModel(
launch {
ipScramblingStateUseCase.internetPrivacyMode
- .map { it == FeatureServiceState.STARTING }
+ .map { it == FeatureState.STARTING }
.debounce(WARNING_LOADING_LONG_DELAY)
.collect {
if (it) _singleEvents.emit(
diff --git a/app/src/main/java/foundation/e/advancedprivacy/widget/WidgetUI.kt b/app/src/main/java/foundation/e/advancedprivacy/widget/WidgetUI.kt
index 1bd8693..e3454b9 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/widget/WidgetUI.kt
+++ b/app/src/main/java/foundation/e/advancedprivacy/widget/WidgetUI.kt
@@ -31,7 +31,7 @@ import foundation.e.advancedprivacy.R
import foundation.e.advancedprivacy.Widget
import foundation.e.advancedprivacy.Widget.Companion.isDarkText
import foundation.e.advancedprivacy.common.extensions.dpToPxF
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
import foundation.e.advancedprivacy.domain.entities.QuickPrivacyState
import foundation.e.advancedprivacy.domain.entities.TrackerMode
import foundation.e.advancedprivacy.features.dashboard.DashboardFragmentArgs
@@ -45,7 +45,7 @@ data class State(
val quickPrivacyState: QuickPrivacyState = QuickPrivacyState.DISABLED,
val trackerMode: TrackerMode = TrackerMode.VULNERABLE,
val isLocationHidden: Boolean = false,
- val ipScramblingMode: FeatureServiceState = FeatureServiceState.STOPPING,
+ val ipScramblingMode: FeatureState = FeatureState.STOPPING,
val dayStatistics: List<Pair<Int, Int>> = emptyList(),
val activeTrackersCount: Int = 0,
)
@@ -157,7 +157,7 @@ fun render(
setTextViewText(
R.id.state_ip_address,
context.getString(
- if (state.ipScramblingMode == FeatureServiceState.ON) R.string.widget_state_ipaddress_on
+ if (state.ipScramblingMode == FeatureState.ON) R.string.widget_state_ipaddress_on
else R.string.widget_state_ipaddress_off
)
)
diff --git a/core/build.gradle b/core/build.gradle
index 0e53f22..3b5234d 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2023 MURENA SAS
* Copyright (C) 2022 E FOUNDATION
*
* This program is free software: you can redistribute it and/or modify
@@ -15,8 +16,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
+plugins {
+ id 'com.android.library'
+ id 'kotlin-android'
+ id 'kotlin-kapt'
+ id 'kotlin-parcelize'
+}
group 'foundation.e'
diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureServiceState.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureState.kt
index f079c56..c756f4a 100644
--- a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureServiceState.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureState.kt
@@ -16,7 +16,7 @@
*/
package foundation.e.advancedprivacy.domain.entities
-enum class FeatureServiceState {
+enum class FeatureState {
OFF, ON, STARTING, STOPPING;
val isChecked get() = this == ON || this == STARTING
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt
index 62581eb..62581eb 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt
index 0d8e0e8..1af2ae0 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt
@@ -21,11 +21,11 @@ import android.content.Intent
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-sealed class ShowFeaturesWarning : Parcelable {
+sealed class MainFeatures : Parcelable {
@Parcelize
- object TrackersControl : ShowFeaturesWarning()
+ data class TrackersControl(val startVpnDisclaimer: Intent? = null) : MainFeatures()
@Parcelize
- object FakeLocation : ShowFeaturesWarning()
+ object FakeLocation : MainFeatures()
@Parcelize
- data class IpScrambling(val startVpnDisclaimer: Intent? = null) : ShowFeaturesWarning()
+ data class IpScrambling(val startVpnDisclaimer: Intent? = null) : MainFeatures()
}
diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt
new file mode 100644
index 0000000..0266f85
--- /dev/null
+++ b/core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.domain.repositories
+
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.FeatureState
+import foundation.e.advancedprivacy.domain.entities.LocationMode
+import foundation.e.advancedprivacy.domain.entities.MainFeatures
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.StateFlow
+
+interface LocalStateRepository {
+ val blockTrackers: StateFlow<Boolean>
+ fun setBlockTrackers(enabled: Boolean)
+
+ val areAllTrackersBlocked: MutableStateFlow<Boolean>
+
+ val fakeLocationEnabled: StateFlow<Boolean>
+ fun setFakeLocationEnabled(enabled: Boolean)
+
+ var fakeLocation: Pair<Float, Float>
+
+ val locationMode: MutableStateFlow<LocationMode>
+
+ fun setIpScramblingSetting(enabled: Boolean)
+ val ipScramblingSetting: StateFlow<Boolean>
+
+ val internetPrivacyMode: MutableStateFlow<FeatureState>
+
+ suspend fun emitStartVpnDisclaimer(feature: MainFeatures)
+
+ val startVpnDisclaimer: SharedFlow<MainFeatures>
+
+ suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription)
+ val otherVpnRunning: SharedFlow<ApplicationDescription>
+
+ var firstBoot: Boolean
+
+ var hideWarningTrackers: Boolean
+
+ var hideWarningLocation: Boolean
+
+ var hideWarningIpScrambling: Boolean
+}
diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnSupervisorUseCase.kt
index c63d3ab..fce9fd0 100644
--- a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt
+++ b/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnSupervisorUseCase.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 E FOUNDATION
+ * 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
@@ -14,9 +14,14 @@
* 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
-package foundation.e.advancedprivacy.domain.entities
+import foundation.e.advancedprivacy.domain.entities.MainFeatures
-enum class MainFeatures {
- TRACKERS_CONTROL, FAKE_LOCATION, IP_SCRAMBLING
+interface VpnSupervisorUseCase {
+ fun listenSettings()
+
+ fun startVpnService(feature: MainFeatures)
+
+ fun cancelStartVpnService(feature: MainFeatures)
}
diff --git a/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureSupervisor.kt b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureSupervisor.kt
new file mode 100644
index 0000000..632172d
--- /dev/null
+++ b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureSupervisor.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.externalinterfaces.servicesupervisors
+
+import foundation.e.advancedprivacy.domain.entities.FeatureState
+import kotlinx.coroutines.flow.StateFlow
+
+interface FeatureSupervisor {
+ fun start(): Boolean
+ fun stop(): Boolean
+
+ val state: StateFlow<FeatureState>
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ec4122e..5c945fa 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -29,9 +29,9 @@ androidx-room-compiler = { group = "androidx.room", name = "room-compiler", vers
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "androidx-room" }
androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "androidx-room" }
androidx-work-ktx = { group = "androidx.work", name = "work-runtime-ktx", version = "2.7.1" }
-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" }
+eos-elib = { group = "foundation.e", name = "elib", version = "0.0.1-alpha11" }
+eos-orbotservice = { group = "foundation.e", name = "orbotservice", version.ref = "orbotservice" }
+eos-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" }
diff --git a/ipscrambling/README.md b/ipscrambling/README.md
index be51828..104060a 100644
--- a/ipscrambling/README.md
+++ b/ipscrambling/README.md
@@ -8,8 +8,8 @@ Ipscrambling includes a git repo submodules of OrbotService, the module used by
Be sure that you have all of the git submodules up-to-date:
- git submodule update --init --recursive
-
+` git submodule update --init --recursive
+`
You can build the AAR modules :
./gradlew :ipscrambling:orbotservice:assembleRelease
diff --git a/ipscrambling/build.gradle b/ipscrambling/build.gradle
index 29fed4f..9ff3f8c 100644
--- a/ipscrambling/build.gradle
+++ b/ipscrambling/build.gradle
@@ -53,6 +53,6 @@ dependencies {
libs.pcap4j,
libs.timber
)
- implementation libs.e.orbotservice
+ implementation libs.eos.orbotservice
implementation project(':core')
}
diff --git a/ipscrambling/orbotservice b/ipscrambling/orbotservice
new file mode 160000
+Subproject 16c61e2f6fcb78c664aa23b9fed24048b52d943
diff --git a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt
index 79aeb05..d9ef0be 100644
--- a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt
+++ b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/KoinModule.kt
@@ -21,5 +21,5 @@ import org.koin.core.module.dsl.singleOf
import org.koin.dsl.module
val ipScramblerModule = module {
- singleOf(::OrbotServiceSupervisor)
+ singleOf(::OrbotSupervisor)
}
diff --git a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotSupervisor.kt
index 8813948..6e0e205 100644
--- a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt
+++ b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotSupervisor.kt
@@ -29,7 +29,8 @@ import android.os.Handler
import android.os.Looper
import android.os.Message
import androidx.localbroadcastmanager.content.LocalBroadcastManager
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
+import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureSupervisor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@@ -48,12 +49,12 @@ import java.security.InvalidParameterException
import java.util.function.Function
@SuppressLint("CommitPrefEdits")
-class OrbotServiceSupervisor(
+class OrbotSupervisor(
private val context: Context,
private val coroutineScope: CoroutineScope,
-) {
- private val _state = MutableStateFlow(FeatureServiceState.OFF)
- val state: StateFlow<FeatureServiceState> = _state
+) : FeatureSupervisor {
+ private val _state = MutableStateFlow(FeatureState.OFF)
+ override val state: StateFlow<FeatureState> = _state
enum class Status {
OFF, ON, STARTING, STOPPING, START_DISABLED
@@ -150,17 +151,17 @@ class OrbotServiceSupervisor(
private fun updateStatus(status: Status, force: Boolean = false) {
if (force || status != currentStatus) {
val newState = when (status) {
- Status.OFF -> FeatureServiceState.OFF
- Status.ON -> FeatureServiceState.ON
- Status.STARTING -> FeatureServiceState.STARTING
+ Status.OFF -> FeatureState.OFF
+ Status.ON -> FeatureState.ON
+ Status.STARTING -> FeatureState.STARTING
Status.STOPPING,
- Status.START_DISABLED -> FeatureServiceState.STOPPING
+ Status.START_DISABLED -> FeatureState.STOPPING
}
coroutineScope.launch(Dispatchers.IO) {
_state.update { currentState ->
- if (newState == FeatureServiceState.OFF &&
- currentState == FeatureServiceState.STOPPING
+ if (newState == FeatureState.OFF &&
+ currentState == FeatureState.STOPPING
) {
// Wait for orbot to relax before allowing user to reactivate it.
delay(1000)
@@ -244,17 +245,19 @@ class OrbotServiceSupervisor(
OrbotService.shouldBlock = shouldBlock
}
- fun start(enableNotification: Boolean) {
+ override fun start(): Boolean {
+ val enableNotification = OrbotService.shouldBlock != null
Prefs.enableNotification(enableNotification)
Prefs.putUseVpn(true)
Prefs.putStartOnBoot(true)
sendIntentToService(OrbotConstants.ACTION_START)
sendIntentToService(OrbotConstants.ACTION_START_VPN)
+ return true
}
- fun stop() {
- if (!isServiceRunning()) return
+ override fun stop(): Boolean {
+ if (!isServiceRunning()) return false
updateStatus(Status.STOPPING)
@@ -267,6 +270,7 @@ class OrbotServiceSupervisor(
extra = Bundle().apply { putBoolean(ACTION_STOP_FOREGROUND_TASK, true) }
)
stoppingWatchdog(5)
+ return true
}
private fun stoppingWatchdog(countDown: Int) {
diff --git a/permissionse/.gitignore b/permissionseos/.gitignore
index 42afabf..42afabf 100644
--- a/permissionse/.gitignore
+++ b/permissionseos/.gitignore
diff --git a/permissionse/build.gradle b/permissionseos/build.gradle
index 7b6ff48..d57ea9c 100644
--- a/permissionse/build.gradle
+++ b/permissionseos/build.gradle
@@ -24,7 +24,7 @@ android {
}
dependencies {
- compileOnly project(':permissionse:libs:hidden-apis-stub')
+ compileOnly project(':permissionseos:libs:hidden-apis-stub')
implementation(libs.bundles.kotlin.android.coroutines)
implementation project(':core')
diff --git a/permissionse/consumer-rules.pro b/permissionseos/consumer-rules.pro
index e69de29..e69de29 100644
--- a/permissionse/consumer-rules.pro
+++ b/permissionseos/consumer-rules.pro
diff --git a/permissionse/libs/hidden-apis-stub/.gitignore b/permissionseos/libs/hidden-apis-stub/.gitignore
index 42afabf..42afabf 100644
--- a/permissionse/libs/hidden-apis-stub/.gitignore
+++ b/permissionseos/libs/hidden-apis-stub/.gitignore
diff --git a/permissionse/libs/hidden-apis-stub/build.gradle b/permissionseos/libs/hidden-apis-stub/build.gradle
index 2043edc..2043edc 100644
--- a/permissionse/libs/hidden-apis-stub/build.gradle
+++ b/permissionseos/libs/hidden-apis-stub/build.gradle
diff --git a/permissionse/libs/hidden-apis-stub/src/main/AndroidManifest.xml b/permissionseos/libs/hidden-apis-stub/src/main/AndroidManifest.xml
index 61f315a..61f315a 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/AndroidManifest.xml
+++ b/permissionseos/libs/hidden-apis-stub/src/main/AndroidManifest.xml
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/app/AppOpsManager.java b/permissionseos/libs/hidden-apis-stub/src/main/java/android/app/AppOpsManager.java
index 753b456..753b456 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/app/AppOpsManager.java
+++ b/permissionseos/libs/hidden-apis-stub/src/main/java/android/app/AppOpsManager.java
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/app/NotificationChannel.java b/permissionseos/libs/hidden-apis-stub/src/main/java/android/app/NotificationChannel.java
index 9e8d65a..9e8d65a 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/app/NotificationChannel.java
+++ b/permissionseos/libs/hidden-apis-stub/src/main/java/android/app/NotificationChannel.java
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/content/pm/PackageManager.java b/permissionseos/libs/hidden-apis-stub/src/main/java/android/content/pm/PackageManager.java
index c6232ce..c6232ce 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/content/pm/PackageManager.java
+++ b/permissionseos/libs/hidden-apis-stub/src/main/java/android/content/pm/PackageManager.java
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/content/pm/UserInfo.java b/permissionseos/libs/hidden-apis-stub/src/main/java/android/content/pm/UserInfo.java
index 28a3732..28a3732 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/content/pm/UserInfo.java
+++ b/permissionseos/libs/hidden-apis-stub/src/main/java/android/content/pm/UserInfo.java
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java b/permissionseos/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java
index 53440e0..53440e0 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java
+++ b/permissionseos/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java b/permissionseos/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java
index dab2173..dab2173 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java
+++ b/permissionseos/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/os/ServiceManager.java b/permissionseos/libs/hidden-apis-stub/src/main/java/android/os/ServiceManager.java
index 4696b79..4696b79 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/os/ServiceManager.java
+++ b/permissionseos/libs/hidden-apis-stub/src/main/java/android/os/ServiceManager.java
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/os/UserHandle.java b/permissionseos/libs/hidden-apis-stub/src/main/java/android/os/UserHandle.java
index df56daf..df56daf 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/os/UserHandle.java
+++ b/permissionseos/libs/hidden-apis-stub/src/main/java/android/os/UserHandle.java
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/os/UserManager.java b/permissionseos/libs/hidden-apis-stub/src/main/java/android/os/UserManager.java
index be6797e..be6797e 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/os/UserManager.java
+++ b/permissionseos/libs/hidden-apis-stub/src/main/java/android/os/UserManager.java
diff --git a/permissionse/proguard-rules.pro b/permissionseos/proguard-rules.pro
index 481bb43..481bb43 100644
--- a/permissionse/proguard-rules.pro
+++ b/permissionseos/proguard-rules.pro
diff --git a/permissionse/src/main/AndroidManifest.xml b/permissionseos/src/main/AndroidManifest.xml
index 4766007..ed25c1c 100644
--- a/permissionse/src/main/AndroidManifest.xml
+++ b/permissionseos/src/main/AndroidManifest.xml
@@ -17,7 +17,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- package="foundation.e.advancedprivacy.permissions.e">
+ package="foundation.e.advancedprivacy.permissions.eos">
<uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES"
tools:ignore="ProtectedPermissions" />
diff --git a/permissionse/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleImpl.kt b/permissionseos/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleImpl.kt
index 0d32bce..0d32bce 100644
--- a/permissionse/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleImpl.kt
+++ b/permissionseos/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleImpl.kt
diff --git a/settings.gradle b/settings.gradle
index a25c6a8..7eadbc9 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -15,12 +15,12 @@ include ':fakelocation:fakelocationdemo'
include ':core'
include ':permissionsstandalone'
include ':trackers'
-include ':permissionse'
-include ':permissionse:libs:hidden-apis-stub'
+include ':permissionseos'
+include ':permissionseos:libs:hidden-apis-stub'
include ':ipscrambling'
include ':ipscrambling:orbotservice'
include ':trackersservicestandalone'
-include ':trackersservicee'
+include ':trackersserviceeos'
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
diff --git a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersServiceSupervisor.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersSupervisor.kt
index 79f721b..a0c7935 100644
--- a/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersServiceSupervisor.kt
+++ b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersSupervisor.kt
@@ -16,12 +16,11 @@
*/
package foundation.e.advancedprivacy.trackers.domain.externalinterfaces
+import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureSupervisor
import org.pcap4j.packet.DnsPacket
import java.util.function.Function
-interface TrackersServiceSupervisor {
- fun start(): Boolean
- fun stop(): Boolean
+interface TrackersSupervisor : FeatureSupervisor {
fun isRunning(): Boolean
val dnsFilterForIpScrambling: Function<DnsPacket?, DnsPacket?>?
diff --git a/trackersservicee/.gitignore b/trackersserviceeos/.gitignore
index 42afabf..42afabf 100644
--- a/trackersservicee/.gitignore
+++ b/trackersserviceeos/.gitignore
diff --git a/trackersservicee/build.gradle b/trackersserviceeos/build.gradle
index e93d5d6..d9f80af 100644
--- a/trackersservicee/build.gradle
+++ b/trackersserviceeos/build.gradle
@@ -30,6 +30,7 @@ android {
dependencies {
implementation project(":core")
implementation project(":trackers")
+ implementation project(":ipscrambling")
implementation(
libs.androidx.core.ktx,
diff --git a/trackersservicee/consumer-rules.pro b/trackersserviceeos/consumer-rules.pro
index e69de29..e69de29 100644
--- a/trackersservicee/consumer-rules.pro
+++ b/trackersserviceeos/consumer-rules.pro
diff --git a/trackersservicee/proguard-rules.pro b/trackersserviceeos/proguard-rules.pro
index 481bb43..481bb43 100644
--- a/trackersservicee/proguard-rules.pro
+++ b/trackersserviceeos/proguard-rules.pro
diff --git a/trackersservicee/src/main/AndroidManifest.xml b/trackersserviceeos/src/main/AndroidManifest.xml
index 2290432..2290432 100644
--- a/trackersservicee/src/main/AndroidManifest.xml
+++ b/trackersserviceeos/src/main/AndroidManifest.xml
diff --git a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/DNSBlocker.kt b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/DNSBlocker.kt
index 6a2b218..6a2b218 100644
--- a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/DNSBlocker.kt
+++ b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/DNSBlocker.kt
diff --git a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt
index 5f573b0..5f573b0 100644
--- a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt
+++ b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt
diff --git a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorEos.kt
index dcdf0d4..71a4fc4 100644
--- a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt
+++ b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorEos.kt
@@ -18,15 +18,22 @@ package foundation.e.advancedprivacy.trackers.service
import android.content.Context
import android.content.Intent
-import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor
+import foundation.e.advancedprivacy.domain.entities.FeatureState
+import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase
+import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersSupervisor
import foundation.e.advancedprivacy.trackers.service.TrackersService.Companion.ACTION_START
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.isActive
import org.koin.core.module.dsl.bind
import org.koin.core.module.dsl.factoryOf
import org.koin.core.module.dsl.singleOf
+import org.koin.core.qualifier.named
import org.koin.dsl.module
-class TrackersServiceSupervisorImpl(private val context: Context) : TrackersServiceSupervisor {
+class TrackersSupervisorEos(private val context: Context) : TrackersSupervisor {
+
+ override val state: StateFlow<FeatureState> = MutableStateFlow(FeatureState.ON)
override fun start(): Boolean {
val intent = Intent(context, TrackersService::class.java)
@@ -47,7 +54,17 @@ class TrackersServiceSupervisorImpl(private val context: Context) : TrackersServ
val trackerServiceModule = module {
factoryOf(::DNSBlocker)
- singleOf(::TrackersServiceSupervisorImpl) {
- bind<TrackersServiceSupervisor>()
+ singleOf(::TrackersSupervisorEos) {
+ bind<TrackersSupervisor>()
+ }
+ single<VpnSupervisorUseCase> {
+ VpnSupervisorUseCaseEos(
+ localStateRepository = get(),
+ orbotSupervisor = get(),
+ trackersSupervisor = get(),
+ appDesc = get(named("AdvancedPrivacy")),
+ permissionsPrivacyModule = get(),
+ scope = get(),
+ )
}
}
diff --git a/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt
new file mode 100644
index 0000000..976a2b7
--- /dev/null
+++ b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt
@@ -0,0 +1,108 @@
+/*
+ * 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.service
+
+import foundation.e.advancedprivacy.domain.entities.ApplicationDescription
+import foundation.e.advancedprivacy.domain.entities.FeatureState
+import foundation.e.advancedprivacy.domain.entities.MainFeatures
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.IpScrambling
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.TrackersControl
+import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository
+import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase
+import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule
+import foundation.e.advancedprivacy.ipscrambler.OrbotSupervisor
+import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersSupervisor
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.drop
+import kotlinx.coroutines.flow.dropWhile
+import kotlinx.coroutines.launch
+
+class VpnSupervisorUseCaseEos(
+ private val localStateRepository: LocalStateRepository,
+ private val orbotSupervisor: OrbotSupervisor,
+ private val trackersSupervisor: TrackersSupervisor,
+ private val appDesc: ApplicationDescription,
+ private val permissionsPrivacyModule: IPermissionsPrivacyModule,
+ private val scope: CoroutineScope,
+) : VpnSupervisorUseCase {
+
+ override fun listenSettings() {
+ trackersSupervisor.start()
+
+ scope.launch(Dispatchers.IO) {
+ localStateRepository.ipScramblingSetting.collect {
+ applySettings(it)
+ }
+ }
+
+ scope.launch(Dispatchers.IO) {
+ localStateRepository.blockTrackers.drop(1).dropWhile { !it }.collect {
+ localStateRepository.emitStartVpnDisclaimer(TrackersControl())
+ }
+ }
+ }
+
+ private suspend fun applySettings(isIpScramblingEnabled: Boolean) {
+ val currentMode = localStateRepository.internetPrivacyMode.value
+ when {
+ (
+ isIpScramblingEnabled &&
+ currentMode in setOf(FeatureState.OFF, FeatureState.STOPPING)
+ ) -> {
+ applyStartIpScrambling()
+ }
+ (
+ !isIpScramblingEnabled &&
+ currentMode in setOf(FeatureState.ON, FeatureState.STARTING)
+ ) -> {
+ orbotSupervisor.stop()
+ }
+ else -> {}
+ }
+ }
+
+ private suspend fun applyStartIpScrambling() {
+ if (orbotSupervisor.prepareAndroidVpn() != null) {
+ permissionsPrivacyModule.setVpnPackageAuthorization(appDesc.packageName)
+ val alwaysOnVpnPackage = permissionsPrivacyModule.getAlwaysOnVpnPackage()
+ if (alwaysOnVpnPackage != null) {
+ localStateRepository.emitOtherVpnRunning(
+ permissionsPrivacyModule.getApplicationDescription(
+ packageName = alwaysOnVpnPackage,
+ withIcon = false
+ )
+ )
+ localStateRepository.setIpScramblingSetting(enabled = false)
+ return
+ }
+ }
+
+ localStateRepository.emitStartVpnDisclaimer(IpScrambling())
+ startVpnService(IpScrambling())
+ }
+
+ override fun startVpnService(feature: MainFeatures) {
+ localStateRepository.internetPrivacyMode.value = FeatureState.STARTING
+ orbotSupervisor.setDNSFilter(null)
+ orbotSupervisor.start()
+ }
+
+ override fun cancelStartVpnService(feature: MainFeatures) {
+ localStateRepository.setIpScramblingSetting(enabled = false)
+ }
+}
diff --git a/trackersservicestandalone/build.gradle b/trackersservicestandalone/build.gradle
index ead9dbd..5b574cd 100644
--- a/trackersservicestandalone/build.gradle
+++ b/trackersservicestandalone/build.gradle
@@ -29,6 +29,7 @@ android {
dependencies {
implementation project(":core")
implementation project(":trackers")
+ implementation project(":ipscrambling")
implementation(
libs.androidx.core.ktx,
diff --git a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt
index 918977f..152a3e9 100644
--- a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt
+++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt
@@ -16,16 +16,15 @@
*/
package foundation.e.advancedprivacy.trackers.service
-import android.content.Context
import android.content.Intent
import android.net.VpnService
import android.os.Build
import android.os.ParcelFileDescriptor
import foundation.e.advancedprivacy.core.utils.notificationBuilder
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
+import foundation.e.advancedprivacy.domain.entities.FeatureState
import foundation.e.advancedprivacy.domain.entities.NOTIFICATION_TRACKER_FLAG
import foundation.e.advancedprivacy.domain.entities.NotificationContent
-import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor
+import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersSupervisor
import foundation.e.advancedprivacy.trackers.service.Config.DNS_SERVER_TO_CATCH_IPV4
import foundation.e.advancedprivacy.trackers.service.Config.DNS_SERVER_TO_CATCH_IPV6
import foundation.e.advancedprivacy.trackers.service.Config.SESSION_NAME
@@ -39,18 +38,12 @@ import timber.log.Timber
class TrackersService : VpnService() {
companion object {
var coroutineScope = CoroutineScope(Dispatchers.IO)
-
- fun start(context: Context) {
- prepare(context)
- val intent = Intent(context, TrackersService::class.java)
- context.startService(intent)
- }
}
private val networkDNSAddressRepository: NetworkDNSAddressRepository = get(NetworkDNSAddressRepository::class.java)
- private val trackersServiceSupervisor: TrackersServiceSupervisorImpl = get(
- TrackersServiceSupervisor::class.java
- ) as TrackersServiceSupervisorImpl
+ private val trackersSupervisor: TrackersSupervisorStandalone = get(
+ TrackersSupervisor::class.java
+ ) as TrackersSupervisorStandalone
private val notificationTrackerFlag: NotificationContent = get(NotificationContent::class.java, named("notificationTrackerFlag"))
@@ -64,14 +57,14 @@ class TrackersService : VpnService() {
content = notificationTrackerFlag
).build()
)
- trackersServiceSupervisor.state.value = FeatureServiceState.ON
+ trackersSupervisor.mutableState.value = FeatureState.ON
return START_STICKY
}
override fun onDestroy() {
networkDNSAddressRepository.stop()
- trackersServiceSupervisor.state.value = FeatureServiceState.OFF
+ trackersSupervisor.mutableState.value = FeatureState.OFF
super.onDestroy()
}
diff --git a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorStandalone.kt
index e2a6692..ac06ced 100644
--- a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt
+++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorStandalone.kt
@@ -18,37 +18,42 @@ package foundation.e.advancedprivacy.trackers.service
import android.content.Context
import android.content.Intent
-import foundation.e.advancedprivacy.domain.entities.FeatureServiceState
-import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor
+import foundation.e.advancedprivacy.domain.entities.FeatureState
+import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase
+import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersSupervisor
import foundation.e.advancedprivacy.trackers.service.data.NetworkDNSAddressRepository
import foundation.e.advancedprivacy.trackers.service.data.RequestDNSRepository
import foundation.e.advancedprivacy.trackers.service.usecases.ResolveDNSUseCase
+import foundation.e.advancedprivacy.trackers.service.usecases.VpnSupervisorUseCaseStandalone
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
import org.koin.core.module.dsl.bind
import org.koin.core.module.dsl.singleOf
import org.koin.dsl.module
import org.pcap4j.packet.DnsPacket
import java.util.function.Function
-class TrackersServiceSupervisorImpl(
+class TrackersSupervisorStandalone(
private val context: Context,
private val resolveDNSUseCase: ResolveDNSUseCase
-) : TrackersServiceSupervisor {
- internal val state: MutableStateFlow<FeatureServiceState> = MutableStateFlow(FeatureServiceState.OFF)
+) : TrackersSupervisor {
+ internal val mutableState: MutableStateFlow<FeatureState> = MutableStateFlow(FeatureState.OFF)
+ override val state: StateFlow<FeatureState> = mutableState
override fun start(): Boolean {
return if (!isRunning()) {
- state.value = FeatureServiceState.STARTING
- TrackersService.start(context)
+ mutableState.value = FeatureState.STARTING
+ val intent = Intent(context, TrackersService::class.java)
+ context.startService(intent)
true
} else false
}
override fun stop(): Boolean {
- return when (state.value) {
- FeatureServiceState.ON -> {
- state.value = FeatureServiceState.STOPPING
+ return when (mutableState.value) {
+ FeatureState.ON -> {
+ mutableState.value = FeatureState.STOPPING
kotlin.runCatching { TrackersService.coroutineScope.cancel() }
context.stopService(Intent(context, TrackersService::class.java))
true
@@ -58,7 +63,7 @@ class TrackersServiceSupervisorImpl(
}
override fun isRunning(): Boolean {
- return state.value != FeatureServiceState.OFF
+ return state.value != FeatureState.OFF
}
override val dnsFilterForIpScrambling = Function<DnsPacket?, DnsPacket?> { dnsRequest -> resolveDNSUseCase.shouldBlock(dnsRequest) }
@@ -69,5 +74,6 @@ val trackerServiceModule = module {
singleOf(::RequestDNSRepository)
singleOf(::ResolveDNSUseCase)
singleOf(::TunLooper)
- singleOf(::TrackersServiceSupervisorImpl) { bind<TrackersServiceSupervisor>() }
+ singleOf(::TrackersSupervisorStandalone) { bind<TrackersSupervisor>() }
+ singleOf(::VpnSupervisorUseCaseStandalone) { bind<VpnSupervisorUseCase>() }
}
diff --git a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TunLooper.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TunLooper.kt
index 7813c67..bb349eb 100644
--- a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TunLooper.kt
+++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TunLooper.kt
@@ -84,6 +84,7 @@ class TunLooper(
}
}
}
+ closeStreams()
}
private suspend fun handleIpPacket(buffer: ByteArray, pLen: Int) {
diff --git a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt
new file mode 100644
index 0000000..683f886
--- /dev/null
+++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt
@@ -0,0 +1,154 @@
+/*
+ * 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.service.usecases
+
+import foundation.e.advancedprivacy.domain.entities.FeatureState
+import foundation.e.advancedprivacy.domain.entities.MainFeatures
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.IpScrambling
+import foundation.e.advancedprivacy.domain.entities.MainFeatures.TrackersControl
+import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository
+import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase
+import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureSupervisor
+import foundation.e.advancedprivacy.ipscrambler.OrbotSupervisor
+import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersSupervisor
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.launch
+
+class VpnSupervisorUseCaseStandalone(
+ private val localStateRepository: LocalStateRepository,
+ private val trackersSupervisor: TrackersSupervisor,
+ private val orbotSupervisor: OrbotSupervisor,
+ private val scope: CoroutineScope,
+) : VpnSupervisorUseCase {
+ private var applySettingJob: Job? = null
+
+ init {
+ listenSettings()
+ }
+
+ override fun listenSettings() {
+ var previousBlockTrackers: Boolean? = null
+
+ localStateRepository.blockTrackers.combine(
+ localStateRepository.ipScramblingSetting
+ ) { blockTrackers, hideIp ->
+ applySettingJob?.cancel()
+ applySettingJob = scope.launch {
+ when {
+ blockTrackers && !hideIp ->
+ launchVpnService(trackersSupervisor)
+
+ !blockTrackers && !hideIp ->
+ stopAllServices()
+
+ else -> {
+ if (blockTrackers && previousBlockTrackers != true) {
+ localStateRepository.emitStartVpnDisclaimer(IpScrambling())
+ }
+
+ launchVpnService(orbotSupervisor)
+ }
+ }
+
+ previousBlockTrackers = blockTrackers
+ }
+ }.launchIn(scope)
+ }
+
+ private fun stopAllServices() {
+ listOf(orbotSupervisor, trackersSupervisor).map { stopVpnService(it) }
+ }
+
+ private fun stopVpnService(supervisor: FeatureSupervisor): FeatureSupervisor {
+ when (supervisor.state.value) {
+ FeatureState.ON,
+ FeatureState.STARTING ->
+ supervisor.stop()
+
+ else -> {}
+ }
+ return supervisor
+ }
+
+ private suspend fun launchVpnService(supervisor: FeatureSupervisor) {
+ stopVpnService(otherSupervisor(supervisor)).let { otherSupervisor ->
+ otherSupervisor.state.first { it == FeatureState.OFF }
+ }
+
+ when (supervisor.state.value) {
+ FeatureState.STOPPING -> {
+ supervisor.state.first { it == FeatureState.OFF }
+ initiateStartVpnService(supervisor)
+ }
+
+ FeatureState.OFF -> initiateStartVpnService(supervisor)
+ else -> {}
+ }
+ }
+
+ private fun otherSupervisor(supervisor: FeatureSupervisor): FeatureSupervisor {
+ return when (supervisor) {
+ trackersSupervisor -> orbotSupervisor
+ else -> trackersSupervisor
+ }
+ }
+
+ private fun getSupervisor(feature: MainFeatures): FeatureSupervisor {
+ return when (feature) {
+ is TrackersControl -> trackersSupervisor
+ else -> orbotSupervisor
+ }
+ }
+
+ private suspend fun initiateStartVpnService(supervisor: FeatureSupervisor) {
+ val authorizeVpnIntent = orbotSupervisor.prepareAndroidVpn()
+ val feature = when (supervisor) {
+ trackersSupervisor -> TrackersControl(authorizeVpnIntent)
+ else -> IpScrambling(authorizeVpnIntent)
+ }
+
+ if (authorizeVpnIntent == null) {
+ localStateRepository.emitStartVpnDisclaimer(feature)
+ startVpnService(feature)
+ } else {
+ localStateRepository.emitStartVpnDisclaimer(feature)
+ }
+ }
+
+ override fun startVpnService(feature: MainFeatures) {
+ if (feature is IpScrambling) {
+ localStateRepository.internetPrivacyMode.value = FeatureState.STARTING
+ orbotSupervisor.setDNSFilter(trackersSupervisor.dnsFilterForIpScrambling)
+ }
+
+ getSupervisor(feature).start()
+ }
+
+ override fun cancelStartVpnService(feature: MainFeatures) {
+ when (feature) {
+ is IpScrambling ->
+ localStateRepository.setIpScramblingSetting(enabled = false)
+ is TrackersControl ->
+ trackersSupervisor.stop()
+ else -> {}
+ }
+ }
+}