diff options
Diffstat (limited to 'trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt')
-rw-r--r-- | trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt new file mode 100644 index 0000000..683f886 --- /dev/null +++ b/trackersservicestandalone/src/main/java/foundation/e/advancedprivacy/trackers/service/usecases/VpnSupervisorUseCaseStandalone.kt @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2023 MURENA SAS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +package foundation.e.advancedprivacy.trackers.service.usecases + +import foundation.e.advancedprivacy.domain.entities.FeatureState +import foundation.e.advancedprivacy.domain.entities.MainFeatures +import foundation.e.advancedprivacy.domain.entities.MainFeatures.IpScrambling +import foundation.e.advancedprivacy.domain.entities.MainFeatures.TrackersControl +import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository +import foundation.e.advancedprivacy.domain.usecases.VpnSupervisorUseCase +import foundation.e.advancedprivacy.externalinterfaces.servicesupervisors.FeatureSupervisor +import foundation.e.advancedprivacy.ipscrambler.OrbotSupervisor +import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersSupervisor +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.launch + +class VpnSupervisorUseCaseStandalone( + private val localStateRepository: LocalStateRepository, + private val trackersSupervisor: TrackersSupervisor, + private val orbotSupervisor: OrbotSupervisor, + private val scope: CoroutineScope, +) : VpnSupervisorUseCase { + private var applySettingJob: Job? = null + + init { + listenSettings() + } + + override fun listenSettings() { + var previousBlockTrackers: Boolean? = null + + localStateRepository.blockTrackers.combine( + localStateRepository.ipScramblingSetting + ) { blockTrackers, hideIp -> + applySettingJob?.cancel() + applySettingJob = scope.launch { + when { + blockTrackers && !hideIp -> + launchVpnService(trackersSupervisor) + + !blockTrackers && !hideIp -> + stopAllServices() + + else -> { + if (blockTrackers && previousBlockTrackers != true) { + localStateRepository.emitStartVpnDisclaimer(IpScrambling()) + } + + launchVpnService(orbotSupervisor) + } + } + + previousBlockTrackers = blockTrackers + } + }.launchIn(scope) + } + + private fun stopAllServices() { + listOf(orbotSupervisor, trackersSupervisor).map { stopVpnService(it) } + } + + private fun stopVpnService(supervisor: FeatureSupervisor): FeatureSupervisor { + when (supervisor.state.value) { + FeatureState.ON, + FeatureState.STARTING -> + supervisor.stop() + + else -> {} + } + return supervisor + } + + private suspend fun launchVpnService(supervisor: FeatureSupervisor) { + stopVpnService(otherSupervisor(supervisor)).let { otherSupervisor -> + otherSupervisor.state.first { it == FeatureState.OFF } + } + + when (supervisor.state.value) { + FeatureState.STOPPING -> { + supervisor.state.first { it == FeatureState.OFF } + initiateStartVpnService(supervisor) + } + + FeatureState.OFF -> initiateStartVpnService(supervisor) + else -> {} + } + } + + private fun otherSupervisor(supervisor: FeatureSupervisor): FeatureSupervisor { + return when (supervisor) { + trackersSupervisor -> orbotSupervisor + else -> trackersSupervisor + } + } + + private fun getSupervisor(feature: MainFeatures): FeatureSupervisor { + return when (feature) { + is TrackersControl -> trackersSupervisor + else -> orbotSupervisor + } + } + + private suspend fun initiateStartVpnService(supervisor: FeatureSupervisor) { + val authorizeVpnIntent = orbotSupervisor.prepareAndroidVpn() + val feature = when (supervisor) { + trackersSupervisor -> TrackersControl(authorizeVpnIntent) + else -> IpScrambling(authorizeVpnIntent) + } + + if (authorizeVpnIntent == null) { + localStateRepository.emitStartVpnDisclaimer(feature) + startVpnService(feature) + } else { + localStateRepository.emitStartVpnDisclaimer(feature) + } + } + + override fun startVpnService(feature: MainFeatures) { + if (feature is IpScrambling) { + localStateRepository.internetPrivacyMode.value = FeatureState.STARTING + orbotSupervisor.setDNSFilter(trackersSupervisor.dnsFilterForIpScrambling) + } + + getSupervisor(feature).start() + } + + override fun cancelStartVpnService(feature: MainFeatures) { + when (feature) { + is IpScrambling -> + localStateRepository.setIpScramblingSetting(enabled = false) + is TrackersControl -> + trackersSupervisor.stop() + else -> {} + } + } +} |