From c42f4f729eaf63435a6abe0f57a4bda3dac28182 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Tue, 12 Sep 2023 08:22:47 +0200 Subject: [PATCH 1/5] epic18: Manage VPN services for Tor or Tracker control --- app/build.gradle | 1 - .../AdvancedPrivacyApplication.kt | 5 +- .../e/advancedprivacy/KoinModule.kt | 11 +- .../common/BootCompletedReceiver.kt | 7 +- .../e/advancedprivacy/common/WarningDialog.kt | 23 +-- .../data/repositories/LocalStateRepository.kt | 53 ++++--- .../usecases/FakeLocationStateUseCase.kt | 8 +- .../usecases/GetQuickPrivacyStateUseCase.kt | 3 +- .../usecases/IpScramblingStateUseCase.kt | 71 +-------- .../usecases/ShowFeaturesWarningUseCase.kt | 13 +- .../domain/usecases/TrackersStateUseCase.kt | 9 +- core/build.gradle | 9 +- .../domain/entities/LocationMode.kt | 0 .../domain/entities/MainFeatures.kt | 0 .../domain/entities/ShowFeaturesWarning.kt | 10 +- .../repositories/LocalStateRepository.kt | 61 +++++++ .../usecases/VpnServicesSupervisorUseCase.kt | 11 ++ .../FeatureServiceSupervisor.kt | 27 ++++ ipscrambling/README.md | 4 +- ipscrambling/orbotservice | 1 + .../ipscrambler/OrbotServiceSupervisor.kt | 14 +- .../TrackersServiceSupervisor.kt | 5 +- trackersservicee/build.gradle | 1 + ...rImpl.kt => TrackersServiceSupervisorE.kt} | 21 ++- .../service/VpnServicesSupervisorUseCaseE.kt | 84 ++++++++++ trackersservicestandalone/build.gradle | 1 + .../trackers/service/TrackersService.kt | 15 +- ...=> TrackersServiceSupervisorStandalone.kt} | 20 ++- .../trackers/service/TunLooper.kt | 1 + .../usecases/VpnServicesSupervisorUseCase.kt | 150 ++++++++++++++++++ 30 files changed, 479 insertions(+), 160 deletions(-) rename {app => core}/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt (100%) rename {app => core}/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt (100%) rename {app => core}/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt (75%) create mode 100644 core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt create mode 100644 core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnServicesSupervisorUseCase.kt create mode 100644 core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureServiceSupervisor.kt create mode 160000 ipscrambling/orbotservice rename trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/{TrackersServiceSupervisorImpl.kt => TrackersServiceSupervisorE.kt} (66%) create mode 100644 trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnServicesSupervisorUseCaseE.kt rename trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/{TrackersServiceSupervisorImpl.kt => TrackersServiceSupervisorStandalone.kt} (72%) create mode 100644 trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnServicesSupervisorUseCase.kt diff --git a/app/build.gradle b/app/build.gradle index 216b81af..1dc093a7 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' } diff --git a/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt b/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt index 71fef005..8877494b 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.VpnServicesSupervisorUseCase 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::class.java) get(TrackersStateUseCase::class.java) get(FakeLocationStateUseCase::class.java) + get(VpnServicesSupervisorUseCase::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 fbf12525..ec9b733d 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 { androidContext().resources } - single { - LocalStateRepository(context = androidContext()) + single { + LocalStateRepositoryImpl(context = androidContext()) } single(named("AdvancedPrivacy")) { @@ -121,14 +122,12 @@ val appModule = module { single { IpScramblingStateUseCase( orbotServiceSupervisor = get(), - permissionsPrivacyModule = get(), - appDesc = get(named("AdvancedPrivacy")), localStateRepository = get(), appListsRepository = get(), - trackersServiceSupervisor = get(), coroutineScope = get() ) } + singleOf(::ShowFeaturesWarningUseCase) singleOf(::TrackersStateUseCase) singleOf(::TrackersStatisticsUseCase) 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 d73f770c..aac3e105 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,14 @@ 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::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 589aa74f..648a684b 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt @@ -30,8 +30,8 @@ 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.usecases.ShowFeaturesWarningUseCase +import foundation.e.advancedprivacy.domain.usecases.VpnServicesSupervisorUseCase import foundation.e.advancedprivacy.main.MainActivity import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn @@ -67,12 +67,13 @@ class WarningDialog : AppCompatActivity() { } private var isWaitingForResult = false + private lateinit var feature: ShowFeaturesWarning override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) window.setBackgroundDrawable(ColorDrawable(0)) - val feature = try { + feature = try { intent.getParcelableExtra(PARAM_FEATURE)!! } catch (e: Exception) { Timber.e(e, "Missing mandatory activity parameter") @@ -92,16 +93,16 @@ class WarningDialog : AppCompatActivity() { builder.setMessage( when (feature) { - ShowFeaturesWarning.TrackersControl -> R.string.warningdialog_trackers_message - ShowFeaturesWarning.FakeLocation -> R.string.warningdialog_location_message + is ShowFeaturesWarning.TrackersControl -> R.string.warningdialog_trackers_message + is ShowFeaturesWarning.FakeLocation -> R.string.warningdialog_location_message is ShowFeaturesWarning.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.TrackersControl -> R.string.warningdialog_trackers_title + is ShowFeaturesWarning.FakeLocation -> R.string.warningdialog_location_title is ShowFeaturesWarning.IpScrambling -> R.string.warningdialog_ipscrambling_title } ) @@ -126,7 +127,7 @@ class WarningDialog : AppCompatActivity() { } else finish() } - if (feature == ShowFeaturesWarning.TrackersControl) { + if (feature is ShowFeaturesWarning.TrackersControl) { builder.setNeutralButton(R.string.warningdialog_trackers_secondary_cta) { _, _ -> MainActivity.deepLinkBuilder(this) .setDestination(R.id.trackersFragment) @@ -140,11 +141,13 @@ class WarningDialog : AppCompatActivity() { } private val launchAndroidVpnDisclaimer = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - val ipScramblingStateUseCase = get(IpScramblingStateUseCase::class.java) + val vpnServicesSupervisorUseCase = get( + VpnServicesSupervisorUseCase::class.java + ) if (result.resultCode == Activity.RESULT_OK) { - ipScramblingStateUseCase.startIpScrambling() + vpnServicesSupervisorUseCase.startVpnService(feature.toMainFeature()) } else { - ipScramblingStateUseCase.toggle(false) + vpnServicesSupervisorUseCase.cancelStartVpnService(feature.toMainFeature()) } 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 c7d4a278..ca7f0a6c 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 @@ -23,14 +23,16 @@ import android.content.Intent import foundation.e.advancedprivacy.domain.entities.ApplicationDescription import foundation.e.advancedprivacy.domain.entities.FeatureServiceState import foundation.e.advancedprivacy.domain.entities.LocationMode +import foundation.e.advancedprivacy.domain.entities.MainFeatures import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning +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 +49,25 @@ 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() + override val blockTrackers = _blockTrackers.asStateFlow() - fun setBlockTrackers(enabled: Boolean) { + override fun setBlockTrackers(enabled: Boolean) { set(KEY_BLOCK_TRACKERS, enabled) _blockTrackers.update { enabled } } - val areAllTrackersBlocked: MutableStateFlow = MutableStateFlow(false) + override val areAllTrackersBlocked: MutableStateFlow = 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 + override var fakeLocation: Pair get() = Pair( // Initial default value is Quezon City sharedPref.getFloat(KEY_FAKE_LATITUDE, 14.6760f), @@ -79,43 +81,52 @@ class LocalStateRepository(context: Context) { .apply() } - val locationMode: MutableStateFlow = MutableStateFlow(LocationMode.REAL_LOCATION) + override val locationMode: MutableStateFlow = MutableStateFlow(LocationMode.REAL_LOCATION) private val _ipScramblingSetting = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, false)) - val ipScramblingSetting = _ipScramblingSetting.asStateFlow() + override val ipScramblingSetting = _ipScramblingSetting.asStateFlow() - fun setIpScramblingSetting(enabled: Boolean) { + override fun setIpScramblingSetting(enabled: Boolean) { set(KEY_IP_SCRAMBLING, enabled) _ipScramblingSetting.update { enabled } } - val internetPrivacyMode: MutableStateFlow = MutableStateFlow(FeatureServiceState.OFF) + override val internetPrivacyMode: MutableStateFlow = MutableStateFlow(FeatureServiceState.OFF) - private val _startVpnDisclaimer = MutableSharedFlow() - suspend fun emitStartVpnDisclaimer(intent: Intent?) { - _startVpnDisclaimer.emit(ShowFeaturesWarning.IpScrambling(startVpnDisclaimer = intent)) + private val _startVpnDisclaimer = MutableSharedFlow() + + override suspend fun emitStartVpnDisclaimer(intent: Intent?, feature: MainFeatures) { + _startVpnDisclaimer.emit( + when (feature) { + MainFeatures.IP_SCRAMBLING -> + ShowFeaturesWarning.IpScrambling(startVpnDisclaimer = intent) + MainFeatures.TRACKERS_CONTROL -> + ShowFeaturesWarning.TrackersControl(startVpnDisclaimer = intent) + else -> ShowFeaturesWarning.FakeLocation + } + ) } - val startVpnDisclaimer: SharedFlow = _startVpnDisclaimer + override val startVpnDisclaimer: SharedFlow = _startVpnDisclaimer private val _otherVpnRunning = MutableSharedFlow() - suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) { + override suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) { _otherVpnRunning.emit(appDesc) } - val otherVpnRunning: SharedFlow = _otherVpnRunning + override val otherVpnRunning: SharedFlow = _otherVpnRunning - var firstBoot: Boolean + 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 983ba714..350be0da 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 @@ -53,7 +53,11 @@ class FakeLocationStateUseCase( private const val TAG = "FakeLocationStateUseCase" } - private val _configuredLocationMode = MutableStateFlow>(Triple(LocationMode.REAL_LOCATION, null, null)) + private val _configuredLocationMode = MutableStateFlow>( + Triple( + LocationMode.REAL_LOCATION, null, null + ) + ) val configuredLocationMode: StateFlow> = _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 1b8f62ce..956f4c60 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.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 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 79c79f79..32023934 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,29 +18,19 @@ 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.domain.repositories.LocalStateRepository import foundation.e.advancedprivacy.ipscrambler.OrbotServiceSupervisor -import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor 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 localStateRepository: LocalStateRepository, private val appListsRepository: AppListsRepository, - private val trackersServiceSupervisor: TrackersServiceSupervisor, private val coroutineScope: CoroutineScope ) { val internetPrivacyMode: StateFlow = orbotServiceSupervisor.state @@ -48,12 +38,6 @@ class IpScramblingStateUseCase( init { orbotServiceSupervisor.requestStatus() - coroutineScope.launch(Dispatchers.Default) { - localStateRepository.ipScramblingSetting.collect { - applySettings(it) - } - } - orbotServiceSupervisor.state.map { localStateRepository.internetPrivacyMode.value = it }.launchIn(coroutineScope) @@ -117,57 +101,4 @@ class IpScramblingStateUseCase( orbotServiceSupervisor.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 c99d5f17..09796a99 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.repositories.LocalStateRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.dropWhile @@ -35,22 +36,20 @@ class ShowFeaturesWarningUseCase( fun showWarning(): Flow { 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) { 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 9b79dcc1..2c47d709 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/core/build.gradle b/core/build.gradle index 0e53f22b..3b5234df 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 . */ -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/app/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt similarity index 100% rename from app/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt rename to core/src/main/java/foundation/e/advancedprivacy/domain/entities/LocationMode.kt diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt similarity index 100% rename from app/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt rename to core/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.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/ShowFeaturesWarning.kt similarity index 75% rename from app/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt rename to core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt index 0d8e0e8c..e418b369 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt @@ -23,9 +23,17 @@ import kotlinx.parcelize.Parcelize sealed class ShowFeaturesWarning : Parcelable { @Parcelize - object TrackersControl : ShowFeaturesWarning() + data class TrackersControl(val startVpnDisclaimer: Intent? = null) : ShowFeaturesWarning() @Parcelize object FakeLocation : ShowFeaturesWarning() @Parcelize data class IpScrambling(val startVpnDisclaimer: Intent? = null) : ShowFeaturesWarning() + + fun toMainFeature(): MainFeatures { + return when (this) { + is TrackersControl -> MainFeatures.TRACKERS_CONTROL + is FakeLocation -> MainFeatures.FAKE_LOCATION + is IpScrambling -> MainFeatures.IP_SCRAMBLING + } + } } 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 00000000..a1fbf2ab --- /dev/null +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt @@ -0,0 +1,61 @@ +/* + * 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 . + */ +package foundation.e.advancedprivacy.domain.repositories + +import android.content.Intent +import foundation.e.advancedprivacy.domain.entities.ApplicationDescription +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState +import foundation.e.advancedprivacy.domain.entities.LocationMode +import foundation.e.advancedprivacy.domain.entities.MainFeatures +import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow + +interface LocalStateRepository { + val blockTrackers: StateFlow + fun setBlockTrackers(enabled: Boolean) + + val areAllTrackersBlocked: MutableStateFlow + + val fakeLocationEnabled: StateFlow + fun setFakeLocationEnabled(enabled: Boolean) + + var fakeLocation: Pair + + val locationMode: MutableStateFlow + + fun setIpScramblingSetting(enabled: Boolean) + val ipScramblingSetting: StateFlow + + val internetPrivacyMode: MutableStateFlow + + suspend fun emitStartVpnDisclaimer(intent: Intent?, feature: MainFeatures) + + val startVpnDisclaimer: SharedFlow + + suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) + val otherVpnRunning: SharedFlow + + var firstBoot: Boolean + + var hideWarningTrackers: Boolean + + var hideWarningLocation: Boolean + + var hideWarningIpScrambling: Boolean +} diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnServicesSupervisorUseCase.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnServicesSupervisorUseCase.kt new file mode 100644 index 00000000..d7f92ba4 --- /dev/null +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnServicesSupervisorUseCase.kt @@ -0,0 +1,11 @@ +package foundation.e.advancedprivacy.domain.usecases + +import foundation.e.advancedprivacy.domain.entities.MainFeatures + +interface VpnServicesSupervisorUseCase { + fun listenSettings() + + fun startVpnService(feature: MainFeatures) + + fun cancelStartVpnService(feature: MainFeatures) +} diff --git a/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureServiceSupervisor.kt b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureServiceSupervisor.kt new file mode 100644 index 00000000..b6542e6a --- /dev/null +++ b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureServiceSupervisor.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 . + */ +package foundation.e.advancedprivacy.externalinterfaces.servicesupervisors + +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState +import kotlinx.coroutines.flow.StateFlow + +interface FeatureServiceSupervisor { + fun start(): Boolean + fun stop(): Boolean + + val state: StateFlow +} diff --git a/ipscrambling/README.md b/ipscrambling/README.md index be51828b..104060ae 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/orbotservice b/ipscrambling/orbotservice new file mode 160000 index 00000000..16c61e2f --- /dev/null +++ b/ipscrambling/orbotservice @@ -0,0 +1 @@ +Subproject commit 16c61e2f6fcb78c664aa23b9fed24048b52d943a diff --git a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt index 8813948f..d5dc52db 100644 --- a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt +++ b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt @@ -30,6 +30,7 @@ import android.os.Looper import android.os.Message import androidx.localbroadcastmanager.content.LocalBroadcastManager import foundation.e.advancedprivacy.domain.entities.FeatureServiceState +import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureServiceSupervisor import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -51,9 +52,9 @@ import java.util.function.Function class OrbotServiceSupervisor( private val context: Context, private val coroutineScope: CoroutineScope, -) { +) : FeatureServiceSupervisor { private val _state = MutableStateFlow(FeatureServiceState.OFF) - val state: StateFlow = _state + override val state: StateFlow = _state enum class Status { OFF, ON, STARTING, STOPPING, START_DISABLED @@ -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/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersServiceSupervisor.kt b/trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersServiceSupervisor.kt index 79f721bb..07f678f3 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/TrackersServiceSupervisor.kt @@ -16,12 +16,11 @@ */ package foundation.e.advancedprivacy.trackers.domain.externalinterfaces +import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureServiceSupervisor import org.pcap4j.packet.DnsPacket import java.util.function.Function -interface TrackersServiceSupervisor { - fun start(): Boolean - fun stop(): Boolean +interface TrackersServiceSupervisor : FeatureServiceSupervisor { fun isRunning(): Boolean val dnsFilterForIpScrambling: Function? diff --git a/trackersservicee/build.gradle b/trackersservicee/build.gradle index e93d5d64..d9f80afa 100644 --- a/trackersservicee/build.gradle +++ b/trackersservicee/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/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt b/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorE.kt similarity index 66% rename from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt rename to trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorE.kt index dcdf0d41..9f8e3620 100644 --- a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt +++ b/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorE.kt @@ -18,15 +18,22 @@ 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.domain.usecases.VpnServicesSupervisorUseCase import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor 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 TrackersServiceSupervisorE(private val context: Context) : TrackersServiceSupervisor { + + override val state: StateFlow = MutableStateFlow(FeatureServiceState.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) { + singleOf(::TrackersServiceSupervisorE) { bind() } + single { + VpnServicesSupervisorUseCaseE( + localStateRepository = get(), + orbotServiceSupervisor = get(), + trackersServiceSupervisor = get(), + appDesc = get(named("AdvancedPrivacy")), + permissionsPrivacyModule = get(), + scope = get(), + ) + } } diff --git a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnServicesSupervisorUseCaseE.kt b/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnServicesSupervisorUseCaseE.kt new file mode 100644 index 00000000..41fcfa86 --- /dev/null +++ b/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnServicesSupervisorUseCaseE.kt @@ -0,0 +1,84 @@ +package foundation.e.advancedprivacy.trackers.service + +import foundation.e.advancedprivacy.domain.entities.ApplicationDescription +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState +import foundation.e.advancedprivacy.domain.entities.MainFeatures +import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository +import foundation.e.advancedprivacy.domain.usecases.VpnServicesSupervisorUseCase +import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule +import foundation.e.advancedprivacy.ipscrambler.OrbotServiceSupervisor +import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.drop +import kotlinx.coroutines.flow.dropWhile +import kotlinx.coroutines.launch + +class VpnServicesSupervisorUseCaseE( + private val localStateRepository: LocalStateRepository, + private val orbotServiceSupervisor: OrbotServiceSupervisor, + private val trackersServiceSupervisor: TrackersServiceSupervisor, + private val appDesc: ApplicationDescription, + private val permissionsPrivacyModule: IPermissionsPrivacyModule, + private val scope: CoroutineScope, +) : VpnServicesSupervisorUseCase { + + override fun listenSettings() { + trackersServiceSupervisor.start() + + scope.launch(Dispatchers.IO) { + localStateRepository.ipScramblingSetting.collect { + applySettings(it) + } + } + + scope.launch(Dispatchers.IO) { + localStateRepository.blockTrackers.drop(1).dropWhile { !it }.collect { + localStateRepository.emitStartVpnDisclaimer(null, MainFeatures.TRACKERS_CONTROL) + } + } + } + + 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() { + if (orbotServiceSupervisor.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(null, MainFeatures.IP_SCRAMBLING) + startVpnService(MainFeatures.IP_SCRAMBLING) + } + + override fun startVpnService(feature: MainFeatures) { + localStateRepository.internetPrivacyMode.value = FeatureServiceState.STARTING + orbotServiceSupervisor.setDNSFilter(null) + orbotServiceSupervisor.start() + } + + override fun cancelStartVpnService(feature: MainFeatures) { + localStateRepository.setIpScramblingSetting(enabled = false) + } +} diff --git a/trackersservicestandalone/build.gradle b/trackersservicestandalone/build.gradle index ead9dbd3..5b574cd0 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 918977f6..16a54c04 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,7 +16,6 @@ */ package foundation.e.advancedprivacy.trackers.service -import android.content.Context import android.content.Intent import android.net.VpnService import android.os.Build @@ -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( + private val trackersServiceSupervisor: TrackersServiceSupervisorStandalone = get( TrackersServiceSupervisor::class.java - ) as TrackersServiceSupervisorImpl + ) as TrackersServiceSupervisorStandalone 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 + trackersServiceSupervisor.mutableState.value = FeatureServiceState.ON return START_STICKY } override fun onDestroy() { networkDNSAddressRepository.stop() - trackersServiceSupervisor.state.value = FeatureServiceState.OFF + trackersServiceSupervisor.mutableState.value = FeatureServiceState.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/TrackersServiceSupervisorStandalone.kt similarity index 72% rename from trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt rename to trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorStandalone.kt index e2a66929..9d15b3c1 100644 --- a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorImpl.kt +++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorStandalone.kt @@ -19,36 +19,41 @@ 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.domain.usecases.VpnServicesSupervisorUseCase import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor 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.VpnServicesSupervisorUseCaseStandalone 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 TrackersServiceSupervisorStandalone( private val context: Context, private val resolveDNSUseCase: ResolveDNSUseCase ) : TrackersServiceSupervisor { - internal val state: MutableStateFlow = MutableStateFlow(FeatureServiceState.OFF) + internal val mutableState: MutableStateFlow = MutableStateFlow(FeatureServiceState.OFF) + override val state: StateFlow = mutableState override fun start(): Boolean { return if (!isRunning()) { - state.value = FeatureServiceState.STARTING - TrackersService.start(context) + mutableState.value = FeatureServiceState.STARTING + val intent = Intent(context, TrackersService::class.java) + context.startService(intent) true } else false } override fun stop(): Boolean { - return when (state.value) { + return when (mutableState.value) { FeatureServiceState.ON -> { - state.value = FeatureServiceState.STOPPING + mutableState.value = FeatureServiceState.STOPPING kotlin.runCatching { TrackersService.coroutineScope.cancel() } context.stopService(Intent(context, TrackersService::class.java)) true @@ -69,5 +74,6 @@ val trackerServiceModule = module { singleOf(::RequestDNSRepository) singleOf(::ResolveDNSUseCase) singleOf(::TunLooper) - singleOf(::TrackersServiceSupervisorImpl) { bind() } + singleOf(::TrackersServiceSupervisorStandalone) { bind() } + singleOf(::VpnServicesSupervisorUseCaseStandalone) { bind() } } 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 7813c674..bb349ebe 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/VpnServicesSupervisorUseCase.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnServicesSupervisorUseCase.kt new file mode 100644 index 00000000..7536a8fd --- /dev/null +++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnServicesSupervisorUseCase.kt @@ -0,0 +1,150 @@ +/* + * 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 . + */ +package foundation.e.advancedprivacy.trackers.service.usecases + +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState +import foundation.e.advancedprivacy.domain.entities.MainFeatures +import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository +import foundation.e.advancedprivacy.domain.usecases.VpnServicesSupervisorUseCase +import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureServiceSupervisor +import foundation.e.advancedprivacy.ipscrambler.OrbotServiceSupervisor +import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor +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 VpnServicesSupervisorUseCaseStandalone( + private val localStateRepository: LocalStateRepository, + private val trackersServiceSupervisor: TrackersServiceSupervisor, + private val orbotserviceSupervisor: OrbotServiceSupervisor, + private val scope: CoroutineScope, +) : VpnServicesSupervisorUseCase { + 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(MainFeatures.TRACKERS_CONTROL) + + !blockTrackers && !hideIp -> + stopAllServices() + + else -> { + if (blockTrackers && previousBlockTrackers != true) { + localStateRepository.emitStartVpnDisclaimer(null, MainFeatures.IP_SCRAMBLING) + } + launchVpnService(MainFeatures.IP_SCRAMBLING) + } + } + previousBlockTrackers = blockTrackers + } + }.launchIn(scope) + } + + private fun stopAllServices() { + listOf(MainFeatures.IP_SCRAMBLING, MainFeatures.TRACKERS_CONTROL).map { + stopVpnService(it) + } + } + + private fun stopVpnService(mainFeatures: MainFeatures): FeatureServiceSupervisor { + val supervisor = getSupervisor(mainFeatures) + when (supervisor.state.value) { + FeatureServiceState.ON, + FeatureServiceState.STARTING -> + supervisor.stop() + + else -> {} + } + return supervisor + } + + private suspend fun launchVpnService(mainFeature: MainFeatures) { + stopVpnService(otherFeature(mainFeature)).let { otherSupervisor -> + otherSupervisor.state.first { it == FeatureServiceState.OFF } + } + + val supervisor = getSupervisor(mainFeature) + when (supervisor.state.value) { + FeatureServiceState.STOPPING -> { + supervisor.state.first { it == FeatureServiceState.OFF } + initiateStartVpnService(mainFeature) + } + + FeatureServiceState.OFF -> initiateStartVpnService(mainFeature) + else -> {} + } + } + + private fun otherFeature(feature: MainFeatures): MainFeatures { + return when (feature) { + MainFeatures.TRACKERS_CONTROL -> MainFeatures.IP_SCRAMBLING + else -> MainFeatures.TRACKERS_CONTROL + } + } + + private fun getSupervisor(feature: MainFeatures): FeatureServiceSupervisor { + return when (feature) { + MainFeatures.TRACKERS_CONTROL -> trackersServiceSupervisor + else -> orbotserviceSupervisor + } + } + + private suspend fun initiateStartVpnService(feature: MainFeatures) { + val authorizeVpnIntent = orbotserviceSupervisor.prepareAndroidVpn() + if (authorizeVpnIntent == null) { + localStateRepository.emitStartVpnDisclaimer(null, feature) + startVpnService(feature) + } else { + localStateRepository.emitStartVpnDisclaimer(authorizeVpnIntent, feature) + } + } + + override fun startVpnService(feature: MainFeatures) { + if (feature == MainFeatures.IP_SCRAMBLING) { + localStateRepository.internetPrivacyMode.value = FeatureServiceState.STARTING + orbotserviceSupervisor.setDNSFilter(trackersServiceSupervisor.dnsFilterForIpScrambling) + } + + getSupervisor(feature).start() + } + + override fun cancelStartVpnService(feature: MainFeatures) { + when (feature) { + MainFeatures.IP_SCRAMBLING -> + localStateRepository.setIpScramblingSetting(enabled = false) + MainFeatures.TRACKERS_CONTROL -> + // TODO + trackersServiceSupervisor.stop() + else -> {} + } + } +} -- GitLab From adf80d3d13bbeb45ebc6e59909822f54b19e107f Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Tue, 24 Oct 2023 19:50:03 +0200 Subject: [PATCH 2/5] MR fixes --- .../AdvancedPrivacyApplication.kt | 4 +- .../e/advancedprivacy/KoinModule.kt | 2 +- .../e/advancedprivacy/Notifications.kt | 4 +- .../e/advancedprivacy/common/WarningDialog.kt | 27 +++++---- .../data/repositories/LocalStateRepository.kt | 15 ++--- .../usecases/FakeLocationStateUseCase.kt | 8 +-- .../usecases/GetQuickPrivacyStateUseCase.kt | 10 ++-- .../usecases/IpScramblingStateUseCase.kt | 24 ++++---- .../features/dashboard/DashboardFragment.kt | 10 ++-- .../features/dashboard/DashboardState.kt | 4 +- .../InternetPrivacyFragment.kt | 8 +-- .../internetprivacy/InternetPrivacyState.kt | 4 +- .../InternetPrivacyViewModel.kt | 4 +- .../e/advancedprivacy/widget/WidgetUI.kt | 6 +- ...FeatureServiceState.kt => FeatureState.kt} | 2 +- .../domain/entities/ShowFeaturesWarning.kt | 19 +++++- .../repositories/LocalStateRepository.kt | 4 +- .../usecases/VpnServicesSupervisorUseCase.kt | 11 ---- .../domain/usecases/VpnSupervisorUseCase.kt | 27 +++++++++ ...viceSupervisor.kt => FeatureSupervisor.kt} | 6 +- .../advancedprivacy/ipscrambler/KoinModule.kt | 2 +- ...erviceSupervisor.kt => OrbotSupervisor.kt} | 24 ++++---- ...iceSupervisor.kt => TrackersSupervisor.kt} | 4 +- ...eSupervisorE.kt => TrackersSupervisorE.kt} | 22 +++---- ...orUseCaseE.kt => VpnSupervisorUseCaseE.kt} | 58 +++++++++++++------ .../trackers/service/TrackersService.kt | 14 ++--- ...one.kt => TrackersSupervisorStandalone.kt} | 28 ++++----- ...e.kt => VpnSupervisorUseCaseStandalone.kt} | 46 +++++++-------- 28 files changed, 219 insertions(+), 178 deletions(-) rename core/src/main/java/foundation/e/advancedprivacy/domain/entities/{FeatureServiceState.kt => FeatureState.kt} (96%) delete mode 100644 core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnServicesSupervisorUseCase.kt create mode 100644 core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnSupervisorUseCase.kt rename core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/{FeatureServiceSupervisor.kt => FeatureSupervisor.kt} (84%) rename ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/{OrbotServiceSupervisor.kt => OrbotSupervisor.kt} (94%) rename trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/{TrackersServiceSupervisor.kt => TrackersSupervisor.kt} (90%) rename trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/{TrackersServiceSupervisorE.kt => TrackersSupervisorE.kt} (75%) rename trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/{VpnServicesSupervisorUseCaseE.kt => VpnSupervisorUseCaseE.kt} (61%) rename trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/{TrackersServiceSupervisorStandalone.kt => TrackersSupervisorStandalone.kt} (73%) rename trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/{VpnServicesSupervisorUseCase.kt => VpnSupervisorUseCaseStandalone.kt} (76%) diff --git a/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt b/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt index 8877494b..0fc1d673 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/AdvancedPrivacyApplication.kt @@ -26,7 +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.VpnServicesSupervisorUseCase +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 @@ -72,6 +72,6 @@ class AdvancedPrivacyApplication : Application() { get(IpScramblingStateUseCase::class.java) get(TrackersStateUseCase::class.java) get(FakeLocationStateUseCase::class.java) - get(VpnServicesSupervisorUseCase::class.java).listenSettings() + get(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 ec9b733d..efcd096c 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt @@ -121,7 +121,7 @@ val appModule = module { singleOf(::GetQuickPrivacyStateUseCase) single { IpScramblingStateUseCase( - orbotServiceSupervisor = get(), + orbotSupervisor = get(), localStateRepository = get(), appListsRepository = get(), coroutineScope = get() diff --git a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt index 639ede48..d80d3eed 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt @@ -29,7 +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.FeatureState import foundation.e.advancedprivacy.domain.entities.MainFeatures import foundation.e.advancedprivacy.domain.entities.NOTIFICATION_FAKE_LOCATION_FLAG import foundation.e.advancedprivacy.domain.entities.NOTIFICATION_FIRST_BOOT @@ -105,7 +105,7 @@ object Notifications { }.launchIn(appScope) getQuickPrivacyStateUseCase.ipScramblingMode.map { - it != FeatureServiceState.OFF + it != FeatureState.OFF }.distinctUntilChanged().onEach { if (it) { showFlagNotification(appContext, MainFeatures.IP_SCRAMBLING) 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 648a684b..02cadabd 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt @@ -30,8 +30,11 @@ 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.entities.ShowFeaturesWarning.FakeLocation +import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning.IpScrambling +import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning.TrackersControl import foundation.e.advancedprivacy.domain.usecases.ShowFeaturesWarningUseCase -import foundation.e.advancedprivacy.domain.usecases.VpnServicesSupervisorUseCase +import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase import foundation.e.advancedprivacy.main.MainActivity import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn @@ -93,23 +96,23 @@ class WarningDialog : AppCompatActivity() { builder.setMessage( when (feature) { - is ShowFeaturesWarning.TrackersControl -> R.string.warningdialog_trackers_message - is 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) { - is ShowFeaturesWarning.TrackersControl -> R.string.warningdialog_trackers_title - is 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 } ) { _, _ -> @@ -141,13 +144,13 @@ class WarningDialog : AppCompatActivity() { } private val launchAndroidVpnDisclaimer = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - val vpnServicesSupervisorUseCase = get( - VpnServicesSupervisorUseCase::class.java + val vpnSupervisorUseCase = get( + VpnSupervisorUseCase::class.java ) if (result.resultCode == Activity.RESULT_OK) { - vpnServicesSupervisorUseCase.startVpnService(feature.toMainFeature()) + vpnSupervisorUseCase.startVpnService(feature.toMainFeature()) } else { - vpnServicesSupervisorUseCase.cancelStartVpnService(feature.toMainFeature()) + vpnSupervisorUseCase.cancelStartVpnService(feature.toMainFeature()) } 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 ca7f0a6c..faa9de24 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 @@ -21,7 +21,7 @@ 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.MainFeatures import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning @@ -91,21 +91,14 @@ class LocalStateRepositoryImpl(context: Context) : LocalStateRepository { _ipScramblingSetting.update { enabled } } - override val internetPrivacyMode: MutableStateFlow = MutableStateFlow(FeatureServiceState.OFF) + override val internetPrivacyMode: MutableStateFlow = MutableStateFlow(FeatureState.OFF) private val _startVpnDisclaimer = MutableSharedFlow() override suspend fun emitStartVpnDisclaimer(intent: Intent?, feature: MainFeatures) { - _startVpnDisclaimer.emit( - when (feature) { - MainFeatures.IP_SCRAMBLING -> - ShowFeaturesWarning.IpScrambling(startVpnDisclaimer = intent) - MainFeatures.TRACKERS_CONTROL -> - ShowFeaturesWarning.TrackersControl(startVpnDisclaimer = intent) - else -> ShowFeaturesWarning.FakeLocation - } - ) + _startVpnDisclaimer.emit(ShowFeaturesWarning.fromMainFeature(feature, intent)) } + override val startVpnDisclaimer: SharedFlow = _startVpnDisclaimer private val _otherVpnRunning = MutableSharedFlow() 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 350be0da..9437f3e5 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 @@ -49,14 +49,8 @@ class FakeLocationStateUseCase( private val appContext: Context, coroutineScope: CoroutineScope ) { - companion object { - private const val TAG = "FakeLocationStateUseCase" - } - private val _configuredLocationMode = MutableStateFlow>( - Triple( - LocationMode.REAL_LOCATION, null, null - ) + Triple(LocationMode.REAL_LOCATION, null, null) ) val configuredLocationMode: StateFlow> = _configuredLocationMode 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 956f4c60..480d3b35 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 @@ -19,7 +19,7 @@ package foundation.e.advancedprivacy.domain.usecases 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 @@ -42,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 @@ -72,7 +72,7 @@ class GetQuickPrivacyStateUseCase( val locationMode: StateFlow = localStateRepository.locationMode - val ipScramblingMode: Flow = + val ipScramblingMode: Flow = 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 32023934..00613dd4 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/IpScramblingStateUseCase.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/domain/usecases/IpScramblingStateUseCase.kt @@ -19,26 +19,26 @@ package foundation.e.advancedprivacy.domain.usecases import foundation.e.advancedprivacy.data.repositories.AppListsRepository -import foundation.e.advancedprivacy.domain.entities.FeatureServiceState +import foundation.e.advancedprivacy.domain.entities.FeatureState import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository -import foundation.e.advancedprivacy.ipscrambler.OrbotServiceSupervisor +import foundation.e.advancedprivacy.ipscrambler.OrbotSupervisor import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map class IpScramblingStateUseCase( - private val orbotServiceSupervisor: OrbotServiceSupervisor, + private val orbotSupervisor: OrbotSupervisor, private val localStateRepository: LocalStateRepository, private val appListsRepository: AppListsRepository, private val coroutineScope: CoroutineScope ) { - val internetPrivacyMode: StateFlow = orbotServiceSupervisor.state + val internetPrivacyMode: StateFlow = orbotSupervisor.state init { - orbotServiceSupervisor.requestStatus() + orbotSupervisor.requestStatus() - orbotServiceSupervisor.state.map { + orbotSupervisor.state.map { localStateRepository.internetPrivacyMode.value = it }.launchIn(coroutineScope) } @@ -52,7 +52,7 @@ class IpScramblingStateUseCase( } val bypassTorApps: Set get() { - var whitelist = orbotServiceSupervisor.appList + var whitelist = orbotSupervisor.appList if (getHiddenPackageNames().any { it in whitelist }) { val mutable = whitelist.toMutableSet() mutable.removeAll(getHiddenPackageNames()) @@ -70,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) { @@ -89,16 +89,16 @@ class IpScramblingStateUseCase( rawList.add(packageName) } } - orbotServiceSupervisor.appList = rawList + orbotSupervisor.appList = rawList } - val availablesLocations: List = orbotServiceSupervisor.getAvailablesLocations().sorted() + val availablesLocations: List = 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) } } } 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 0a53c6c4..56cf81f6 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 069ff041..d26c53d1 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 b4fc8a12..482a7738 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 e607d6c9..9ba716f0 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 = emptyList(), val bypassTorApps: Collection = 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 10530e1e..b2f93c27 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 1bd86932..e3454b90 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> = 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/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureServiceState.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureState.kt similarity index 96% rename from core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureServiceState.kt rename to core/src/main/java/foundation/e/advancedprivacy/domain/entities/FeatureState.kt index f079c565..c756f4af 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/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt index e418b369..e01e03a0 100644 --- a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt @@ -19,6 +19,9 @@ package foundation.e.advancedprivacy.domain.entities import android.content.Intent import android.os.Parcelable +import foundation.e.advancedprivacy.domain.entities.MainFeatures.FAKE_LOCATION +import foundation.e.advancedprivacy.domain.entities.MainFeatures.IP_SCRAMBLING +import foundation.e.advancedprivacy.domain.entities.MainFeatures.TRACKERS_CONTROL import kotlinx.parcelize.Parcelize sealed class ShowFeaturesWarning : Parcelable { @@ -31,9 +34,19 @@ sealed class ShowFeaturesWarning : Parcelable { fun toMainFeature(): MainFeatures { return when (this) { - is TrackersControl -> MainFeatures.TRACKERS_CONTROL - is FakeLocation -> MainFeatures.FAKE_LOCATION - is IpScrambling -> MainFeatures.IP_SCRAMBLING + is TrackersControl -> TRACKERS_CONTROL + is FakeLocation -> FAKE_LOCATION + is IpScrambling -> IP_SCRAMBLING + } + } + + companion object { + fun fromMainFeature(mainFeature: MainFeatures, startVpnDisclaimer: Intent?): ShowFeaturesWarning { + return when (mainFeature) { + TRACKERS_CONTROL -> TrackersControl(startVpnDisclaimer) + FAKE_LOCATION -> FakeLocation + IP_SCRAMBLING -> IpScrambling(startVpnDisclaimer) + } } } } 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 index a1fbf2ab..fe167450 100644 --- a/core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt @@ -18,7 +18,7 @@ package foundation.e.advancedprivacy.domain.repositories 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.MainFeatures import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning @@ -42,7 +42,7 @@ interface LocalStateRepository { fun setIpScramblingSetting(enabled: Boolean) val ipScramblingSetting: StateFlow - val internetPrivacyMode: MutableStateFlow + val internetPrivacyMode: MutableStateFlow suspend fun emitStartVpnDisclaimer(intent: Intent?, feature: MainFeatures) diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnServicesSupervisorUseCase.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnServicesSupervisorUseCase.kt deleted file mode 100644 index d7f92ba4..00000000 --- a/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnServicesSupervisorUseCase.kt +++ /dev/null @@ -1,11 +0,0 @@ -package foundation.e.advancedprivacy.domain.usecases - -import foundation.e.advancedprivacy.domain.entities.MainFeatures - -interface VpnServicesSupervisorUseCase { - fun listenSettings() - - fun startVpnService(feature: MainFeatures) - - fun cancelStartVpnService(feature: MainFeatures) -} diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnSupervisorUseCase.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnSupervisorUseCase.kt new file mode 100644 index 00000000..fce9fd0c --- /dev/null +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/usecases/VpnSupervisorUseCase.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 . + */ +package foundation.e.advancedprivacy.domain.usecases + +import foundation.e.advancedprivacy.domain.entities.MainFeatures + +interface VpnSupervisorUseCase { + fun listenSettings() + + fun startVpnService(feature: MainFeatures) + + fun cancelStartVpnService(feature: MainFeatures) +} diff --git a/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureServiceSupervisor.kt b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureSupervisor.kt similarity index 84% rename from core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureServiceSupervisor.kt rename to core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureSupervisor.kt index b6542e6a..632172dd 100644 --- a/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureServiceSupervisor.kt +++ b/core/src/main/java/foundation/e/advancedprivacy/externalinterfaces/servicesupervisors/FeatureSupervisor.kt @@ -16,12 +16,12 @@ */ package foundation.e.advancedprivacy.externalinterfaces.servicesupervisors -import foundation.e.advancedprivacy.domain.entities.FeatureServiceState +import foundation.e.advancedprivacy.domain.entities.FeatureState import kotlinx.coroutines.flow.StateFlow -interface FeatureServiceSupervisor { +interface FeatureSupervisor { fun start(): Boolean fun stop(): Boolean - val state: StateFlow + val state: StateFlow } 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 79aeb056..d9ef0be3 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 similarity index 94% rename from ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt rename to ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotSupervisor.kt index d5dc52db..6e0e2055 100644 --- a/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotServiceSupervisor.kt +++ b/ipscrambling/src/main/java/foundation/e/advancedprivacy/ipscrambler/OrbotSupervisor.kt @@ -29,8 +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.externalinterfaces.servicesupervisors.FeatureServiceSupervisor +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 @@ -49,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, -) : FeatureServiceSupervisor { - private val _state = MutableStateFlow(FeatureServiceState.OFF) - override val state: StateFlow = _state +) : FeatureSupervisor { + private val _state = MutableStateFlow(FeatureState.OFF) + override val state: StateFlow = _state enum class Status { OFF, ON, STARTING, STOPPING, START_DISABLED @@ -151,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) 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 similarity index 90% rename from trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersServiceSupervisor.kt rename to trackers/src/main/java/foundation/e/advancedprivacy/trackers/domain/externalinterfaces/TrackersSupervisor.kt index 07f678f3..a0c7935f 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,11 +16,11 @@ */ package foundation.e.advancedprivacy.trackers.domain.externalinterfaces -import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureServiceSupervisor +import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureSupervisor import org.pcap4j.packet.DnsPacket import java.util.function.Function -interface TrackersServiceSupervisor : FeatureServiceSupervisor { +interface TrackersSupervisor : FeatureSupervisor { fun isRunning(): Boolean val dnsFilterForIpScrambling: Function? diff --git a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorE.kt b/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorE.kt similarity index 75% rename from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorE.kt rename to trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorE.kt index 9f8e3620..cfe1cb4f 100644 --- a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorE.kt +++ b/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorE.kt @@ -18,9 +18,9 @@ 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.domain.usecases.VpnServicesSupervisorUseCase -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 @@ -31,9 +31,9 @@ import org.koin.core.module.dsl.singleOf import org.koin.core.qualifier.named import org.koin.dsl.module -class TrackersServiceSupervisorE(private val context: Context) : TrackersServiceSupervisor { +class TrackersSupervisorE(private val context: Context) : TrackersSupervisor { - override val state: StateFlow = MutableStateFlow(FeatureServiceState.ON) + override val state: StateFlow = MutableStateFlow(FeatureState.ON) override fun start(): Boolean { val intent = Intent(context, TrackersService::class.java) @@ -54,14 +54,14 @@ class TrackersServiceSupervisorE(private val context: Context) : TrackersService val trackerServiceModule = module { factoryOf(::DNSBlocker) - singleOf(::TrackersServiceSupervisorE) { - bind() + singleOf(::TrackersSupervisorE) { + bind() } - single { - VpnServicesSupervisorUseCaseE( + single { + VpnSupervisorUseCaseE( localStateRepository = get(), - orbotServiceSupervisor = get(), - trackersServiceSupervisor = get(), + orbotSupervisor = get(), + trackersSupervisor = get(), appDesc = get(named("AdvancedPrivacy")), permissionsPrivacyModule = get(), scope = get(), diff --git a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnServicesSupervisorUseCaseE.kt b/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseE.kt similarity index 61% rename from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnServicesSupervisorUseCaseE.kt rename to trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseE.kt index 41fcfa86..d9623984 100644 --- a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnServicesSupervisorUseCaseE.kt +++ b/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseE.kt @@ -1,30 +1,46 @@ +/* + * 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 . + */ package foundation.e.advancedprivacy.trackers.service 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.MainFeatures import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository -import foundation.e.advancedprivacy.domain.usecases.VpnServicesSupervisorUseCase +import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase 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.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 VpnServicesSupervisorUseCaseE( +class VpnSupervisorUseCaseE( private val localStateRepository: LocalStateRepository, - private val orbotServiceSupervisor: OrbotServiceSupervisor, - private val trackersServiceSupervisor: TrackersServiceSupervisor, + private val orbotSupervisor: OrbotSupervisor, + private val trackersSupervisor: TrackersSupervisor, private val appDesc: ApplicationDescription, private val permissionsPrivacyModule: IPermissionsPrivacyModule, private val scope: CoroutineScope, -) : VpnServicesSupervisorUseCase { +) : VpnSupervisorUseCase { override fun listenSettings() { - trackersServiceSupervisor.start() + trackersSupervisor.start() scope.launch(Dispatchers.IO) { localStateRepository.ipScramblingSetting.collect { @@ -42,18 +58,24 @@ class VpnServicesSupervisorUseCaseE( private suspend fun applySettings(isIpScramblingEnabled: Boolean) { val currentMode = localStateRepository.internetPrivacyMode.value when { - isIpScramblingEnabled && currentMode in setOf(FeatureServiceState.OFF, FeatureServiceState.STOPPING) -> + ( + isIpScramblingEnabled && + currentMode in setOf(FeatureState.OFF, FeatureState.STOPPING) + ) -> { applyStartIpScrambling() - - !isIpScramblingEnabled && currentMode in setOf(FeatureServiceState.ON, FeatureServiceState.STARTING) -> - orbotServiceSupervisor.stop() - + } + ( + !isIpScramblingEnabled && + currentMode in setOf(FeatureState.ON, FeatureState.STARTING) + ) -> { + orbotSupervisor.stop() + } else -> {} } } private suspend fun applyStartIpScrambling() { - if (orbotServiceSupervisor.prepareAndroidVpn() != null) { + if (orbotSupervisor.prepareAndroidVpn() != null) { permissionsPrivacyModule.setVpnPackageAuthorization(appDesc.packageName) val alwaysOnVpnPackage = permissionsPrivacyModule.getAlwaysOnVpnPackage() if (alwaysOnVpnPackage != null) { @@ -73,9 +95,9 @@ class VpnServicesSupervisorUseCaseE( } override fun startVpnService(feature: MainFeatures) { - localStateRepository.internetPrivacyMode.value = FeatureServiceState.STARTING - orbotServiceSupervisor.setDNSFilter(null) - orbotServiceSupervisor.start() + localStateRepository.internetPrivacyMode.value = FeatureState.STARTING + orbotSupervisor.setDNSFilter(null) + orbotSupervisor.start() } override fun cancelStartVpnService(feature: MainFeatures) { 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 16a54c04..152a3e95 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 @@ -21,10 +21,10 @@ 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 @@ -41,9 +41,9 @@ class TrackersService : VpnService() { } private val networkDNSAddressRepository: NetworkDNSAddressRepository = get(NetworkDNSAddressRepository::class.java) - private val trackersServiceSupervisor: TrackersServiceSupervisorStandalone = get( - TrackersServiceSupervisor::class.java - ) as TrackersServiceSupervisorStandalone + private val trackersSupervisor: TrackersSupervisorStandalone = get( + TrackersSupervisor::class.java + ) as TrackersSupervisorStandalone private val notificationTrackerFlag: NotificationContent = get(NotificationContent::class.java, named("notificationTrackerFlag")) @@ -57,14 +57,14 @@ class TrackersService : VpnService() { content = notificationTrackerFlag ).build() ) - trackersServiceSupervisor.mutableState.value = FeatureServiceState.ON + trackersSupervisor.mutableState.value = FeatureState.ON return START_STICKY } override fun onDestroy() { networkDNSAddressRepository.stop() - trackersServiceSupervisor.mutableState.value = FeatureServiceState.OFF + trackersSupervisor.mutableState.value = FeatureState.OFF super.onDestroy() } diff --git a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorStandalone.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorStandalone.kt similarity index 73% rename from trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorStandalone.kt rename to trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorStandalone.kt index 9d15b3c1..ac06ced4 100644 --- a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersServiceSupervisorStandalone.kt +++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorStandalone.kt @@ -18,13 +18,13 @@ 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.domain.usecases.VpnServicesSupervisorUseCase -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.VpnServicesSupervisorUseCaseStandalone +import foundation.e.advancedprivacy.trackers.service.usecases.VpnSupervisorUseCaseStandalone import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -34,16 +34,16 @@ import org.koin.dsl.module import org.pcap4j.packet.DnsPacket import java.util.function.Function -class TrackersServiceSupervisorStandalone( +class TrackersSupervisorStandalone( private val context: Context, private val resolveDNSUseCase: ResolveDNSUseCase -) : TrackersServiceSupervisor { - internal val mutableState: MutableStateFlow = MutableStateFlow(FeatureServiceState.OFF) - override val state: StateFlow = mutableState +) : TrackersSupervisor { + internal val mutableState: MutableStateFlow = MutableStateFlow(FeatureState.OFF) + override val state: StateFlow = mutableState override fun start(): Boolean { return if (!isRunning()) { - mutableState.value = FeatureServiceState.STARTING + mutableState.value = FeatureState.STARTING val intent = Intent(context, TrackersService::class.java) context.startService(intent) true @@ -52,8 +52,8 @@ class TrackersServiceSupervisorStandalone( override fun stop(): Boolean { return when (mutableState.value) { - FeatureServiceState.ON -> { - mutableState.value = FeatureServiceState.STOPPING + FeatureState.ON -> { + mutableState.value = FeatureState.STOPPING kotlin.runCatching { TrackersService.coroutineScope.cancel() } context.stopService(Intent(context, TrackersService::class.java)) true @@ -63,7 +63,7 @@ class TrackersServiceSupervisorStandalone( } override fun isRunning(): Boolean { - return state.value != FeatureServiceState.OFF + return state.value != FeatureState.OFF } override val dnsFilterForIpScrambling = Function { dnsRequest -> resolveDNSUseCase.shouldBlock(dnsRequest) } @@ -74,6 +74,6 @@ val trackerServiceModule = module { singleOf(::RequestDNSRepository) singleOf(::ResolveDNSUseCase) singleOf(::TunLooper) - singleOf(::TrackersServiceSupervisorStandalone) { bind() } - singleOf(::VpnServicesSupervisorUseCaseStandalone) { bind() } + singleOf(::TrackersSupervisorStandalone) { bind() } + singleOf(::VpnSupervisorUseCaseStandalone) { bind() } } diff --git a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnServicesSupervisorUseCase.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt similarity index 76% rename from trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnServicesSupervisorUseCase.kt rename to trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt index 7536a8fd..7573a71b 100644 --- a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnServicesSupervisorUseCase.kt +++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt @@ -16,13 +16,13 @@ */ package foundation.e.advancedprivacy.trackers.service.usecases -import foundation.e.advancedprivacy.domain.entities.FeatureServiceState +import foundation.e.advancedprivacy.domain.entities.FeatureState import foundation.e.advancedprivacy.domain.entities.MainFeatures import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository -import foundation.e.advancedprivacy.domain.usecases.VpnServicesSupervisorUseCase -import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureServiceSupervisor -import foundation.e.advancedprivacy.ipscrambler.OrbotServiceSupervisor -import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor +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 @@ -30,12 +30,12 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.launch -class VpnServicesSupervisorUseCaseStandalone( +class VpnSupervisorUseCaseStandalone( private val localStateRepository: LocalStateRepository, - private val trackersServiceSupervisor: TrackersServiceSupervisor, - private val orbotserviceSupervisor: OrbotServiceSupervisor, + private val trackersSupervisor: TrackersSupervisor, + private val orbotSupervisor: OrbotSupervisor, private val scope: CoroutineScope, -) : VpnServicesSupervisorUseCase { +) : VpnSupervisorUseCase { private var applySettingJob: Job? = null init { @@ -75,11 +75,11 @@ class VpnServicesSupervisorUseCaseStandalone( } } - private fun stopVpnService(mainFeatures: MainFeatures): FeatureServiceSupervisor { + private fun stopVpnService(mainFeatures: MainFeatures): FeatureSupervisor { val supervisor = getSupervisor(mainFeatures) when (supervisor.state.value) { - FeatureServiceState.ON, - FeatureServiceState.STARTING -> + FeatureState.ON, + FeatureState.STARTING -> supervisor.stop() else -> {} @@ -89,17 +89,17 @@ class VpnServicesSupervisorUseCaseStandalone( private suspend fun launchVpnService(mainFeature: MainFeatures) { stopVpnService(otherFeature(mainFeature)).let { otherSupervisor -> - otherSupervisor.state.first { it == FeatureServiceState.OFF } + otherSupervisor.state.first { it == FeatureState.OFF } } val supervisor = getSupervisor(mainFeature) when (supervisor.state.value) { - FeatureServiceState.STOPPING -> { - supervisor.state.first { it == FeatureServiceState.OFF } + FeatureState.STOPPING -> { + supervisor.state.first { it == FeatureState.OFF } initiateStartVpnService(mainFeature) } - FeatureServiceState.OFF -> initiateStartVpnService(mainFeature) + FeatureState.OFF -> initiateStartVpnService(mainFeature) else -> {} } } @@ -111,15 +111,15 @@ class VpnServicesSupervisorUseCaseStandalone( } } - private fun getSupervisor(feature: MainFeatures): FeatureServiceSupervisor { + private fun getSupervisor(feature: MainFeatures): FeatureSupervisor { return when (feature) { - MainFeatures.TRACKERS_CONTROL -> trackersServiceSupervisor - else -> orbotserviceSupervisor + MainFeatures.TRACKERS_CONTROL -> trackersSupervisor + else -> orbotSupervisor } } private suspend fun initiateStartVpnService(feature: MainFeatures) { - val authorizeVpnIntent = orbotserviceSupervisor.prepareAndroidVpn() + val authorizeVpnIntent = orbotSupervisor.prepareAndroidVpn() if (authorizeVpnIntent == null) { localStateRepository.emitStartVpnDisclaimer(null, feature) startVpnService(feature) @@ -130,8 +130,8 @@ class VpnServicesSupervisorUseCaseStandalone( override fun startVpnService(feature: MainFeatures) { if (feature == MainFeatures.IP_SCRAMBLING) { - localStateRepository.internetPrivacyMode.value = FeatureServiceState.STARTING - orbotserviceSupervisor.setDNSFilter(trackersServiceSupervisor.dnsFilterForIpScrambling) + localStateRepository.internetPrivacyMode.value = FeatureState.STARTING + orbotSupervisor.setDNSFilter(trackersSupervisor.dnsFilterForIpScrambling) } getSupervisor(feature).start() @@ -143,7 +143,7 @@ class VpnServicesSupervisorUseCaseStandalone( localStateRepository.setIpScramblingSetting(enabled = false) MainFeatures.TRACKERS_CONTROL -> // TODO - trackersServiceSupervisor.stop() + trackersSupervisor.stop() else -> {} } } -- GitLab From 13afeb583b94138b0c5116caf8c5528caa26f871 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Tue, 24 Oct 2023 20:02:26 +0200 Subject: [PATCH 3/5] Move flavor e and naming to eos --- .gitlab-ci.yml | 2 +- app/build.gradle | 12 ++++++------ gradle/libs.versions.toml | 6 +++--- ipscrambling/build.gradle | 2 +- {permissionse => permissionseos}/.gitignore | 0 {permissionse => permissionseos}/build.gradle | 2 +- {permissionse => permissionseos}/consumer-rules.pro | 0 .../libs/hidden-apis-stub/.gitignore | 0 .../libs/hidden-apis-stub/build.gradle | 0 .../hidden-apis-stub/src/main/AndroidManifest.xml | 0 .../src/main/java/android/app/AppOpsManager.java | 0 .../main/java/android/app/NotificationChannel.java | 0 .../main/java/android/content/pm/PackageManager.java | 0 .../src/main/java/android/content/pm/UserInfo.java | 0 .../main/java/android/net/IConnectivityManager.java | 0 .../src/main/java/android/net/VpnManager.java | 0 .../src/main/java/android/os/ServiceManager.java | 0 .../src/main/java/android/os/UserHandle.java | 0 .../src/main/java/android/os/UserManager.java | 0 {permissionse => permissionseos}/proguard-rules.pro | 0 .../src/main/AndroidManifest.xml | 2 +- .../permissions/PermissionsPrivacyModuleImpl.kt | 0 settings.gradle | 6 +++--- {trackersservicee => trackersserviceeos}/.gitignore | 0 .../build.gradle | 0 .../consumer-rules.pro | 0 .../proguard-rules.pro | 0 .../src/main/AndroidManifest.xml | 0 .../e/advancedprivacy/trackers/service/DNSBlocker.kt | 0 .../trackers/service/TrackersService.kt | 0 .../trackers/service/TrackersSupervisorEos.kt | 6 +++--- .../trackers/service/VpnSupervisorUseCaseEos.kt | 2 +- 32 files changed, 20 insertions(+), 20 deletions(-) rename {permissionse => permissionseos}/.gitignore (100%) rename {permissionse => permissionseos}/build.gradle (91%) rename {permissionse => permissionseos}/consumer-rules.pro (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/.gitignore (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/build.gradle (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/AndroidManifest.xml (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/java/android/app/AppOpsManager.java (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/java/android/app/NotificationChannel.java (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/java/android/content/pm/PackageManager.java (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/java/android/content/pm/UserInfo.java (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/java/android/os/ServiceManager.java (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/java/android/os/UserHandle.java (100%) rename {permissionse => permissionseos}/libs/hidden-apis-stub/src/main/java/android/os/UserManager.java (100%) rename {permissionse => permissionseos}/proguard-rules.pro (100%) rename {permissionse => permissionseos}/src/main/AndroidManifest.xml (97%) rename {permissionse => permissionseos}/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleImpl.kt (100%) rename {trackersservicee => trackersserviceeos}/.gitignore (100%) rename {trackersservicee => trackersserviceeos}/build.gradle (100%) rename {trackersservicee => trackersserviceeos}/consumer-rules.pro (100%) rename {trackersservicee => trackersserviceeos}/proguard-rules.pro (100%) rename {trackersservicee => trackersserviceeos}/src/main/AndroidManifest.xml (100%) rename {trackersservicee => trackersserviceeos}/src/main/java/foundation/e/advancedprivacy/trackers/service/DNSBlocker.kt (100%) rename {trackersservicee => trackersserviceeos}/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt (100%) rename trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorE.kt => trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorEos.kt (93%) rename trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseE.kt => trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt (99%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 89a6f787..9f3d1f0c 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 1dc093a7..95bbee6f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -81,7 +81,7 @@ android { // expected by the android gradle plugin. flavorDimensions 'os' productFlavors { - e { + eos { dimension 'os' minSdkVersion 29 targetSdkVersion 32 @@ -143,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, @@ -173,7 +173,7 @@ dependencies { libs.maplibre, libs.mpandroidcharts, - libs.e.telemetry, + libs.eos.telemetry, libs.timber ) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ec4122ea..5c945fa3 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/build.gradle b/ipscrambling/build.gradle index 29fed4ff..9ff3f8c3 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/permissionse/.gitignore b/permissionseos/.gitignore similarity index 100% rename from permissionse/.gitignore rename to permissionseos/.gitignore diff --git a/permissionse/build.gradle b/permissionseos/build.gradle similarity index 91% rename from permissionse/build.gradle rename to permissionseos/build.gradle index 7b6ff48d..d57ea9ce 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 similarity index 100% rename from permissionse/consumer-rules.pro rename to permissionseos/consumer-rules.pro diff --git a/permissionse/libs/hidden-apis-stub/.gitignore b/permissionseos/libs/hidden-apis-stub/.gitignore similarity index 100% rename from permissionse/libs/hidden-apis-stub/.gitignore rename to permissionseos/libs/hidden-apis-stub/.gitignore diff --git a/permissionse/libs/hidden-apis-stub/build.gradle b/permissionseos/libs/hidden-apis-stub/build.gradle similarity index 100% rename from permissionse/libs/hidden-apis-stub/build.gradle rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/AndroidManifest.xml rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/java/android/app/AppOpsManager.java rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/java/android/app/NotificationChannel.java rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/java/android/content/pm/PackageManager.java rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/java/android/content/pm/UserInfo.java rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/java/android/os/ServiceManager.java rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/java/android/os/UserHandle.java rename to 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 similarity index 100% rename from permissionse/libs/hidden-apis-stub/src/main/java/android/os/UserManager.java rename to permissionseos/libs/hidden-apis-stub/src/main/java/android/os/UserManager.java diff --git a/permissionse/proguard-rules.pro b/permissionseos/proguard-rules.pro similarity index 100% rename from permissionse/proguard-rules.pro rename to permissionseos/proguard-rules.pro diff --git a/permissionse/src/main/AndroidManifest.xml b/permissionseos/src/main/AndroidManifest.xml similarity index 97% rename from permissionse/src/main/AndroidManifest.xml rename to permissionseos/src/main/AndroidManifest.xml index 4766007d..ed25c1ce 100644 --- a/permissionse/src/main/AndroidManifest.xml +++ b/permissionseos/src/main/AndroidManifest.xml @@ -17,7 +17,7 @@ --> + package="foundation.e.advancedprivacy.permissions.eos"> 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 similarity index 100% rename from permissionse/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleImpl.kt rename to permissionseos/src/main/java/foundation/e/advancedprivacy/externalinterfaces/permissions/PermissionsPrivacyModuleImpl.kt diff --git a/settings.gradle b/settings.gradle index a25c6a83..7eadbc93 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/trackersservicee/.gitignore b/trackersserviceeos/.gitignore similarity index 100% rename from trackersservicee/.gitignore rename to trackersserviceeos/.gitignore diff --git a/trackersservicee/build.gradle b/trackersserviceeos/build.gradle similarity index 100% rename from trackersservicee/build.gradle rename to trackersserviceeos/build.gradle diff --git a/trackersservicee/consumer-rules.pro b/trackersserviceeos/consumer-rules.pro similarity index 100% rename from trackersservicee/consumer-rules.pro rename to trackersserviceeos/consumer-rules.pro diff --git a/trackersservicee/proguard-rules.pro b/trackersserviceeos/proguard-rules.pro similarity index 100% rename from trackersservicee/proguard-rules.pro rename to trackersserviceeos/proguard-rules.pro diff --git a/trackersservicee/src/main/AndroidManifest.xml b/trackersserviceeos/src/main/AndroidManifest.xml similarity index 100% rename from trackersservicee/src/main/AndroidManifest.xml rename to 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 similarity index 100% rename from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/DNSBlocker.kt rename to 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 similarity index 100% rename from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt rename to trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersService.kt diff --git a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorE.kt b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorEos.kt similarity index 93% rename from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorE.kt rename to trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorEos.kt index cfe1cb4f..71a4fc4d 100644 --- a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorE.kt +++ b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/TrackersSupervisorEos.kt @@ -31,7 +31,7 @@ import org.koin.core.module.dsl.singleOf import org.koin.core.qualifier.named import org.koin.dsl.module -class TrackersSupervisorE(private val context: Context) : TrackersSupervisor { +class TrackersSupervisorEos(private val context: Context) : TrackersSupervisor { override val state: StateFlow = MutableStateFlow(FeatureState.ON) @@ -54,11 +54,11 @@ class TrackersSupervisorE(private val context: Context) : TrackersSupervisor { val trackerServiceModule = module { factoryOf(::DNSBlocker) - singleOf(::TrackersSupervisorE) { + singleOf(::TrackersSupervisorEos) { bind() } single { - VpnSupervisorUseCaseE( + VpnSupervisorUseCaseEos( localStateRepository = get(), orbotSupervisor = get(), trackersSupervisor = get(), diff --git a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseE.kt b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt similarity index 99% rename from trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseE.kt rename to trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt index d9623984..2319f57c 100644 --- a/trackersservicee/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseE.kt +++ b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt @@ -30,7 +30,7 @@ import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.dropWhile import kotlinx.coroutines.launch -class VpnSupervisorUseCaseE( +class VpnSupervisorUseCaseEos( private val localStateRepository: LocalStateRepository, private val orbotSupervisor: OrbotSupervisor, private val trackersSupervisor: TrackersSupervisor, -- GitLab From 0bf57564ffcadda534215e69cc3aee04f896ac0d Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Fri, 27 Oct 2023 19:20:21 +0200 Subject: [PATCH 4/5] MR - remove ShowFeatureWarning entitie. --- .../e/advancedprivacy/Notifications.kt | 24 ++++----- .../e/advancedprivacy/common/WarningDialog.kt | 25 +++++---- .../data/repositories/LocalStateRepository.kt | 10 ++-- .../usecases/ShowFeaturesWarningUseCase.kt | 12 ++--- .../domain/entities/MainFeatures.kt | 15 ++++-- .../domain/entities/ShowFeaturesWarning.kt | 52 ------------------- .../repositories/LocalStateRepository.kt | 6 +-- .../service/VpnSupervisorUseCaseEos.kt | 8 +-- .../VpnSupervisorUseCaseStandalone.kt | 52 ++++++++++--------- 9 files changed, 77 insertions(+), 127 deletions(-) delete mode 100644 core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt diff --git a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt index d80d3eed..430e9d56 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt @@ -30,7 +30,6 @@ 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.FeatureState -import foundation.e.advancedprivacy.domain.entities.MainFeatures 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,9 +97,9 @@ 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) @@ -108,9 +107,9 @@ object Notifications { 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/WarningDialog.kt b/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt index 02cadabd..9dbfea97 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/common/WarningDialog.kt @@ -29,10 +29,10 @@ 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.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.usecases.ShowFeaturesWarningUseCase import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase import foundation.e.advancedprivacy.main.MainActivity @@ -60,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) @@ -70,14 +70,14 @@ class WarningDialog : AppCompatActivity() { } private var isWaitingForResult = false - private lateinit var feature: ShowFeaturesWarning + private lateinit var feature: MainFeatures override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) window.setBackgroundDrawable(ColorDrawable(0)) feature = try { - intent.getParcelableExtra(PARAM_FEATURE)!! + intent.getParcelableExtra(PARAM_FEATURE)!! } catch (e: Exception) { Timber.e(e, "Missing mandatory activity parameter") finish() @@ -86,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() } @@ -121,7 +121,7 @@ class WarningDialog : AppCompatActivity() { .doNotShowAgain(feature) } - val vpnDisclaimerIntent = (feature as? ShowFeaturesWarning.IpScrambling) + val vpnDisclaimerIntent = (feature as? MainFeatures.IpScrambling) ?.startVpnDisclaimer if (vpnDisclaimerIntent != null) { @@ -130,7 +130,7 @@ class WarningDialog : AppCompatActivity() { } else finish() } - if (feature is ShowFeaturesWarning.TrackersControl) { + if (feature is MainFeatures.TrackersControl) { builder.setNeutralButton(R.string.warningdialog_trackers_secondary_cta) { _, _ -> MainActivity.deepLinkBuilder(this) .setDestination(R.id.trackersFragment) @@ -139,7 +139,6 @@ class WarningDialog : AppCompatActivity() { finish() } } - builder.show() } @@ -148,9 +147,9 @@ class WarningDialog : AppCompatActivity() { VpnSupervisorUseCase::class.java ) if (result.resultCode == Activity.RESULT_OK) { - vpnSupervisorUseCase.startVpnService(feature.toMainFeature()) + vpnSupervisorUseCase.startVpnService(feature) } else { - vpnSupervisorUseCase.cancelStartVpnService(feature.toMainFeature()) + 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 faa9de24..f81661bc 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,12 +19,10 @@ 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.FeatureState import foundation.e.advancedprivacy.domain.entities.LocationMode import foundation.e.advancedprivacy.domain.entities.MainFeatures -import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -93,13 +91,13 @@ class LocalStateRepositoryImpl(context: Context) : LocalStateRepository { override val internetPrivacyMode: MutableStateFlow = MutableStateFlow(FeatureState.OFF) - private val _startVpnDisclaimer = MutableSharedFlow() + private val _startVpnDisclaimer = MutableSharedFlow() - override suspend fun emitStartVpnDisclaimer(intent: Intent?, feature: MainFeatures) { - _startVpnDisclaimer.emit(ShowFeaturesWarning.fromMainFeature(feature, intent)) + override suspend fun emitStartVpnDisclaimer(feature: MainFeatures) { + _startVpnDisclaimer.emit(feature) } - override val startVpnDisclaimer: SharedFlow = _startVpnDisclaimer + override val startVpnDisclaimer: SharedFlow = _startVpnDisclaimer private val _otherVpnRunning = MutableSharedFlow() override suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) { 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 09796a99..f8a0986f 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 @@ -18,10 +18,10 @@ package foundation.e.advancedprivacy.domain.usecases -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 @@ -34,7 +34,7 @@ class ShowFeaturesWarningUseCase( private val localStateRepository: LocalStateRepository ) { - fun showWarning(): Flow { + fun showWarning(): Flow { return merge( localStateRepository.fakeLocationEnabled.drop(1).dropWhile { !it } .filter { it && !localStateRepository.hideWarningLocation } @@ -46,7 +46,7 @@ class ShowFeaturesWarningUseCase( ) } - fun doNotShowAgain(feature: ShowFeaturesWarning) { + fun doNotShowAgain(feature: MainFeatures) { when (feature) { is TrackersControl -> localStateRepository.hideWarningTrackers = true is FakeLocation -> localStateRepository.hideWarningLocation = true diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt index c63d3abd..1af2ae03 100644 --- a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.kt +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/MainFeatures.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 @@ -14,9 +15,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package foundation.e.advancedprivacy.domain.entities -enum class MainFeatures { - TRACKERS_CONTROL, FAKE_LOCATION, IP_SCRAMBLING +import android.content.Intent +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +sealed class MainFeatures : Parcelable { + @Parcelize + data class TrackersControl(val startVpnDisclaimer: Intent? = null) : MainFeatures() + @Parcelize + object FakeLocation : MainFeatures() + @Parcelize + data class IpScrambling(val startVpnDisclaimer: Intent? = null) : MainFeatures() } diff --git a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt b/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt deleted file mode 100644 index e01e03a0..00000000 --- a/core/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2023 MURENA SAS - * Copyright (C) 2022 E FOUNDATION - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package foundation.e.advancedprivacy.domain.entities - -import android.content.Intent -import android.os.Parcelable -import foundation.e.advancedprivacy.domain.entities.MainFeatures.FAKE_LOCATION -import foundation.e.advancedprivacy.domain.entities.MainFeatures.IP_SCRAMBLING -import foundation.e.advancedprivacy.domain.entities.MainFeatures.TRACKERS_CONTROL -import kotlinx.parcelize.Parcelize - -sealed class ShowFeaturesWarning : Parcelable { - @Parcelize - data class TrackersControl(val startVpnDisclaimer: Intent? = null) : ShowFeaturesWarning() - @Parcelize - object FakeLocation : ShowFeaturesWarning() - @Parcelize - data class IpScrambling(val startVpnDisclaimer: Intent? = null) : ShowFeaturesWarning() - - fun toMainFeature(): MainFeatures { - return when (this) { - is TrackersControl -> TRACKERS_CONTROL - is FakeLocation -> FAKE_LOCATION - is IpScrambling -> IP_SCRAMBLING - } - } - - companion object { - fun fromMainFeature(mainFeature: MainFeatures, startVpnDisclaimer: Intent?): ShowFeaturesWarning { - return when (mainFeature) { - TRACKERS_CONTROL -> TrackersControl(startVpnDisclaimer) - FAKE_LOCATION -> FakeLocation - IP_SCRAMBLING -> IpScrambling(startVpnDisclaimer) - } - } - } -} 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 index fe167450..0266f850 100644 --- a/core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt +++ b/core/src/main/java/foundation/e/advancedprivacy/domain/repositories/LocalStateRepository.kt @@ -16,12 +16,10 @@ */ package foundation.e.advancedprivacy.domain.repositories -import android.content.Intent 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 foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow @@ -44,9 +42,9 @@ interface LocalStateRepository { val internetPrivacyMode: MutableStateFlow - suspend fun emitStartVpnDisclaimer(intent: Intent?, feature: MainFeatures) + suspend fun emitStartVpnDisclaimer(feature: MainFeatures) - val startVpnDisclaimer: SharedFlow + val startVpnDisclaimer: SharedFlow suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) val otherVpnRunning: SharedFlow 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 index 2319f57c..976a2b71 100644 --- a/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt +++ b/trackersserviceeos/src/main/java/foundation/e/advancedprivacy/trackers/service/VpnSupervisorUseCaseEos.kt @@ -19,6 +19,8 @@ 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 @@ -50,7 +52,7 @@ class VpnSupervisorUseCaseEos( scope.launch(Dispatchers.IO) { localStateRepository.blockTrackers.drop(1).dropWhile { !it }.collect { - localStateRepository.emitStartVpnDisclaimer(null, MainFeatures.TRACKERS_CONTROL) + localStateRepository.emitStartVpnDisclaimer(TrackersControl()) } } } @@ -90,8 +92,8 @@ class VpnSupervisorUseCaseEos( } } - localStateRepository.emitStartVpnDisclaimer(null, MainFeatures.IP_SCRAMBLING) - startVpnService(MainFeatures.IP_SCRAMBLING) + localStateRepository.emitStartVpnDisclaimer(IpScrambling()) + startVpnService(IpScrambling()) } override fun startVpnService(feature: MainFeatures) { 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 index 7573a71b..2d988216 100644 --- 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 @@ -18,6 +18,8 @@ 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 @@ -52,16 +54,16 @@ class VpnSupervisorUseCaseStandalone( applySettingJob = scope.launch { when { blockTrackers && !hideIp -> - launchVpnService(MainFeatures.TRACKERS_CONTROL) + launchVpnService(trackersSupervisor) !blockTrackers && !hideIp -> stopAllServices() else -> { if (blockTrackers && previousBlockTrackers != true) { - localStateRepository.emitStartVpnDisclaimer(null, MainFeatures.IP_SCRAMBLING) + localStateRepository.emitStartVpnDisclaimer(IpScrambling()) } - launchVpnService(MainFeatures.IP_SCRAMBLING) + launchVpnService(orbotSupervisor) } } previousBlockTrackers = blockTrackers @@ -70,13 +72,10 @@ class VpnSupervisorUseCaseStandalone( } private fun stopAllServices() { - listOf(MainFeatures.IP_SCRAMBLING, MainFeatures.TRACKERS_CONTROL).map { - stopVpnService(it) - } + listOf(orbotSupervisor, trackersSupervisor).map { stopVpnService(it) } } - private fun stopVpnService(mainFeatures: MainFeatures): FeatureSupervisor { - val supervisor = getSupervisor(mainFeatures) + private fun stopVpnService(supervisor: FeatureSupervisor): FeatureSupervisor { when (supervisor.state.value) { FeatureState.ON, FeatureState.STARTING -> @@ -87,49 +86,53 @@ class VpnSupervisorUseCaseStandalone( return supervisor } - private suspend fun launchVpnService(mainFeature: MainFeatures) { - stopVpnService(otherFeature(mainFeature)).let { otherSupervisor -> + private suspend fun launchVpnService(supervisor: FeatureSupervisor) { + stopVpnService(otherSupervisor(supervisor)).let { otherSupervisor -> otherSupervisor.state.first { it == FeatureState.OFF } } - val supervisor = getSupervisor(mainFeature) when (supervisor.state.value) { FeatureState.STOPPING -> { supervisor.state.first { it == FeatureState.OFF } - initiateStartVpnService(mainFeature) + initiateStartVpnService(supervisor) } - FeatureState.OFF -> initiateStartVpnService(mainFeature) + FeatureState.OFF -> initiateStartVpnService(supervisor) else -> {} } } - private fun otherFeature(feature: MainFeatures): MainFeatures { - return when (feature) { - MainFeatures.TRACKERS_CONTROL -> MainFeatures.IP_SCRAMBLING - else -> MainFeatures.TRACKERS_CONTROL + private fun otherSupervisor(supervisor: FeatureSupervisor): FeatureSupervisor { + return when (supervisor) { + trackersSupervisor -> orbotSupervisor + else -> trackersSupervisor } } private fun getSupervisor(feature: MainFeatures): FeatureSupervisor { return when (feature) { - MainFeatures.TRACKERS_CONTROL -> trackersSupervisor + is TrackersControl -> trackersSupervisor else -> orbotSupervisor } } - private suspend fun initiateStartVpnService(feature: MainFeatures) { + 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(null, feature) + localStateRepository.emitStartVpnDisclaimer(feature) startVpnService(feature) } else { - localStateRepository.emitStartVpnDisclaimer(authorizeVpnIntent, feature) + localStateRepository.emitStartVpnDisclaimer(feature) } } override fun startVpnService(feature: MainFeatures) { - if (feature == MainFeatures.IP_SCRAMBLING) { + if (feature is IpScrambling) { localStateRepository.internetPrivacyMode.value = FeatureState.STARTING orbotSupervisor.setDNSFilter(trackersSupervisor.dnsFilterForIpScrambling) } @@ -139,10 +142,9 @@ class VpnSupervisorUseCaseStandalone( override fun cancelStartVpnService(feature: MainFeatures) { when (feature) { - MainFeatures.IP_SCRAMBLING -> + is IpScrambling -> localStateRepository.setIpScramblingSetting(enabled = false) - MainFeatures.TRACKERS_CONTROL -> - // TODO + is TrackersControl -> trackersSupervisor.stop() else -> {} } -- GitLab From e35838a4298040bd13a453ed6e05e298d0d58974 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Wed, 1 Nov 2023 09:57:42 +0100 Subject: [PATCH 5/5] MR fixes, add some linebreaks. --- .../e/advancedprivacy/common/BootCompletedReceiver.kt | 1 + .../advancedprivacy/data/repositories/LocalStateRepository.kt | 4 ++++ .../domain/usecases/FakeLocationStateUseCase.kt | 1 + .../service/usecases/VpnSupervisorUseCaseStandalone.kt | 2 ++ 4 files changed, 8 insertions(+) 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 aac3e105..562144de 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/common/BootCompletedReceiver.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/common/BootCompletedReceiver.kt @@ -28,6 +28,7 @@ import org.koin.java.KoinJavaComponent.inject class BootCompletedReceiver : BroadcastReceiver() { private val localStateRepository by inject(LocalStateRepository::class.java) + override fun onReceive(context: Context, intent: Intent?) { if (intent?.action == Intent.ACTION_BOOT_COMPLETED) { if (localStateRepository.firstBoot) { 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 f81661bc..2afd6eea 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 @@ -47,6 +47,7 @@ class LocalStateRepositoryImpl(context: Context) : LocalStateRepository { private val sharedPref = context.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE) private val _blockTrackers = MutableStateFlow(sharedPref.getBoolean(KEY_BLOCK_TRACKERS, true)) + override val blockTrackers = _blockTrackers.asStateFlow() override fun setBlockTrackers(enabled: Boolean) { @@ -82,6 +83,7 @@ class LocalStateRepositoryImpl(context: Context) : LocalStateRepository { override val locationMode: MutableStateFlow = MutableStateFlow(LocationMode.REAL_LOCATION) private val _ipScramblingSetting = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, false)) + override val ipScramblingSetting = _ipScramblingSetting.asStateFlow() override fun setIpScramblingSetting(enabled: Boolean) { @@ -100,9 +102,11 @@ class LocalStateRepositoryImpl(context: Context) : LocalStateRepository { override val startVpnDisclaimer: SharedFlow = _startVpnDisclaimer private val _otherVpnRunning = MutableSharedFlow() + override suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) { _otherVpnRunning.emit(appDesc) } + override val otherVpnRunning: SharedFlow = _otherVpnRunning override var firstBoot: Boolean 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 9437f3e5..282116e7 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 @@ -52,6 +52,7 @@ class FakeLocationStateUseCase( private val _configuredLocationMode = MutableStateFlow>( Triple(LocationMode.REAL_LOCATION, null, null) ) + val configuredLocationMode: StateFlow> = _configuredLocationMode init { 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 index 2d988216..683f886d 100644 --- 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 @@ -63,9 +63,11 @@ class VpnSupervisorUseCaseStandalone( if (blockTrackers && previousBlockTrackers != true) { localStateRepository.emitStartVpnDisclaimer(IpScrambling()) } + launchVpnService(orbotSupervisor) } } + previousBlockTrackers = blockTrackers } }.launchIn(scope) -- GitLab