diff options
author | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2023-10-23 15:55:13 +0000 |
---|---|---|
committer | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2023-10-23 15:55:13 +0000 |
commit | 0312ce64f85b5530a00bdc72eb310ba9dc1de05b (patch) | |
tree | 030ccbed3f44a2a1f96413947f50ec0520fb064d /app/src/main | |
parent | d0c2b36ec81cd2a102d4b0a5b0fbeb1c1aa52e70 (diff) | |
parent | 54892a227a77839ee81df90df904675f958831a3 (diff) |
Merge branch 'epic18-standalone_trackers_tor_alone' into 'main'
epic18: tracker control while tor is activated.
See merge request e/os/advanced-privacy!148
Diffstat (limited to 'app/src/main')
13 files changed, 73 insertions, 153 deletions
diff --git a/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt b/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt index 20cefd5..fbf1252 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/KoinModule.kt @@ -42,8 +42,6 @@ import foundation.e.advancedprivacy.features.trackers.TrackersViewModel import foundation.e.advancedprivacy.features.trackers.apptrackers.AppTrackersViewModel import foundation.e.advancedprivacy.ipscrambler.ipScramblerModule import foundation.e.advancedprivacy.permissions.externalinterfaces.PermissionsPrivacyModuleImpl -import foundation.e.advancedprivacy.trackers.domain.externalinterfaces.TrackersServiceSupervisor -import foundation.e.advancedprivacy.trackers.service.TrackersServiceSupervisorImpl import foundation.e.advancedprivacy.trackers.service.trackerServiceModule import foundation.e.advancedprivacy.trackers.trackersModule import org.koin.android.ext.koin.androidContext @@ -122,11 +120,12 @@ val appModule = module { singleOf(::GetQuickPrivacyStateUseCase) single { IpScramblingStateUseCase( - ipScramblerModule = get(), + orbotServiceSupervisor = get(), permissionsPrivacyModule = get(), appDesc = get(named("AdvancedPrivacy")), localStateRepository = get(), appListsRepository = get(), + trackersServiceSupervisor = get(), coroutineScope = get() ) } @@ -138,12 +137,6 @@ val appModule = module { PermissionsPrivacyModuleImpl(context = androidContext()) } - single<TrackersServiceSupervisor> { - TrackersServiceSupervisorImpl( - context = androidContext(), - ) - } - viewModel { parameters -> val appListUseCase: AppListUseCase = get() val app = appListUseCase.getApp(parameters.get()) diff --git a/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt b/app/src/main/java/foundation/e/advancedprivacy/Notifications.kt index 455b1a7..639ede4 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.InternetPrivacyMode +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState 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 != InternetPrivacyMode.REAL_IP + it != FeatureServiceState.OFF }.distinctUntilChanged().onEach { if (it) { showFlagNotification(appContext, MainFeatures.IP_SCRAMBLING) 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 abc4de0..c7d4a27 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.InternetPrivacyMode +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState import foundation.e.advancedprivacy.domain.entities.LocationMode import foundation.e.advancedprivacy.domain.entities.ShowFeaturesWarning import kotlinx.coroutines.flow.MutableSharedFlow @@ -89,7 +89,7 @@ class LocalStateRepository(context: Context) { _ipScramblingSetting.update { enabled } } - val internetPrivacyMode: MutableStateFlow<InternetPrivacyMode> = MutableStateFlow(InternetPrivacyMode.REAL_IP) + val internetPrivacyMode: MutableStateFlow<FeatureServiceState> = MutableStateFlow(FeatureServiceState.OFF) private val _startVpnDisclaimer = MutableSharedFlow<ShowFeaturesWarning.IpScrambling>() suspend fun emitStartVpnDisclaimer(intent: Intent?) { diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/InternetPrivacyMode.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/entities/InternetPrivacyMode.kt deleted file mode 100644 index 986e798..0000000 --- a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/InternetPrivacyMode.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2021 E FOUNDATION - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -package foundation.e.advancedprivacy.domain.entities - -enum class InternetPrivacyMode { - REAL_IP, - HIDE_IP, - HIDE_IP_LOADING, - REAL_IP_LOADING; - - val isChecked get() = this == HIDE_IP || this == HIDE_IP_LOADING - - val isLoading get() = this == HIDE_IP_LOADING || this == REAL_IP_LOADING -} diff --git a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt b/app/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt index 221f4e1..0d8e0e8 100644 --- a/app/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt +++ b/app/src/main/java/foundation/e/advancedprivacy/domain/entities/ShowFeaturesWarning.kt @@ -21,9 +21,11 @@ import android.content.Intent import android.os.Parcelable import kotlinx.parcelize.Parcelize -@Parcelize sealed class ShowFeaturesWarning : Parcelable { + @Parcelize object TrackersControl : ShowFeaturesWarning() + @Parcelize object FakeLocation : ShowFeaturesWarning() + @Parcelize data class IpScrambling(val startVpnDisclaimer: Intent? = null) : ShowFeaturesWarning() } 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 bc4871a..1b8f62c 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.data.repositories.LocalStateRepository import foundation.e.advancedprivacy.domain.entities.ApplicationDescription -import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode +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 @@ -41,13 +41,13 @@ class GetQuickPrivacyStateUseCase( when { !isBlockTrackers && locationMode == LocationMode.REAL_LOCATION && - internetPrivacyMode == InternetPrivacyMode.REAL_IP -> QuickPrivacyState.DISABLED + internetPrivacyMode == FeatureServiceState.OFF -> QuickPrivacyState.DISABLED isAllTrackersBlocked && locationMode != LocationMode.REAL_LOCATION && internetPrivacyMode in listOf( - InternetPrivacyMode.HIDE_IP, - InternetPrivacyMode.HIDE_IP_LOADING + FeatureServiceState.ON, + FeatureServiceState.STARTING ) -> QuickPrivacyState.FULL_ENABLED else -> QuickPrivacyState.ENABLED @@ -71,7 +71,8 @@ class GetQuickPrivacyStateUseCase( val locationMode: StateFlow<LocationMode> = localStateRepository.locationMode - val ipScramblingMode: Flow<InternetPrivacyMode> = localStateRepository.internetPrivacyMode + val ipScramblingMode: Flow<FeatureServiceState> = + localStateRepository.internetPrivacyMode fun toggleTrackers(enabled: Boolean?) { val value = enabled ?: !localStateRepository.blockTrackers.value 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 9c89329..79c79f7 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 @@ -23,74 +23,40 @@ 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.InternetPrivacyMode -import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode.HIDE_IP -import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode.HIDE_IP_LOADING -import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode.REAL_IP -import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode.REAL_IP_LOADING +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState import foundation.e.advancedprivacy.externalinterfaces.permissions.IPermissionsPrivacyModule -import foundation.e.advancedprivacy.ipscrambler.IpScramblerModule +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.channels.awaitClose -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch class IpScramblingStateUseCase( - private val ipScramblerModule: IpScramblerModule, + 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<InternetPrivacyMode> = callbackFlow { - val listener = object : IpScramblerModule.Listener { - override fun onStatusChanged(newStatus: IpScramblerModule.Status) { - trySend(map(newStatus)) - } - - override fun log(message: String) {} - override fun onTrafficUpdate( - upload: Long, - download: Long, - read: Long, - write: Long - ) { - } - } - ipScramblerModule.addListener(listener) - ipScramblerModule.requestStatus() - awaitClose { ipScramblerModule.removeListener(listener) } - }.stateIn( - scope = coroutineScope, - started = SharingStarted.Eagerly, - initialValue = REAL_IP - ) + val internetPrivacyMode: StateFlow<FeatureServiceState> = orbotServiceSupervisor.state init { + orbotServiceSupervisor.requestStatus() + coroutineScope.launch(Dispatchers.Default) { localStateRepository.ipScramblingSetting.collect { applySettings(it) } } - coroutineScope.launch(Dispatchers.IO) { - internetPrivacyMode.collect { - if ( - it == REAL_IP && - localStateRepository.internetPrivacyMode.value == REAL_IP_LOADING - ) { - // Wait for orbot to relax before allowing user to reactivate it. - delay(1000) - } - localStateRepository.internetPrivacyMode.value = it - } - } + orbotServiceSupervisor.state.map { + localStateRepository.internetPrivacyMode.value = it + }.launchIn(coroutineScope) } fun toggle(hideIp: Boolean) { @@ -102,7 +68,7 @@ class IpScramblingStateUseCase( } val bypassTorApps: Set<String> get() { - var whitelist = ipScramblerModule.appList + var whitelist = orbotServiceSupervisor.appList if (getHiddenPackageNames().any { it in whitelist }) { val mutable = whitelist.toMutableSet() mutable.removeAll(getHiddenPackageNames()) @@ -120,7 +86,7 @@ class IpScramblingStateUseCase( fun toggleBypassTor(packageName: String) { val visibleList = bypassTorApps.toMutableSet() - val rawList = ipScramblerModule.appList.toMutableSet() + val rawList = orbotServiceSupervisor.appList.toMutableSet() if (visibleList.contains(packageName)) { if (packageName == appListsRepository.dummySystemApp.packageName) { @@ -139,24 +105,34 @@ class IpScramblingStateUseCase( rawList.add(packageName) } } - ipScramblerModule.appList = rawList + orbotServiceSupervisor.appList = rawList + } + + val availablesLocations: List<String> = orbotServiceSupervisor.getAvailablesLocations().sorted() + + val exitCountry: String get() = orbotServiceSupervisor.getExitCountryCode() + + suspend fun setExitCountry(locationId: String) { + if (locationId != exitCountry) { + orbotServiceSupervisor.setExitCountryCode(locationId) + } } private suspend fun applySettings(isIpScramblingEnabled: Boolean) { val currentMode = localStateRepository.internetPrivacyMode.value when { - isIpScramblingEnabled && currentMode in setOf(REAL_IP, REAL_IP_LOADING) -> + isIpScramblingEnabled && currentMode in setOf(FeatureServiceState.OFF, FeatureServiceState.STOPPING) -> applyStartIpScrambling() - !isIpScramblingEnabled && currentMode in setOf(HIDE_IP, HIDE_IP_LOADING) -> - ipScramblerModule.stop() + !isIpScramblingEnabled && currentMode in setOf(FeatureServiceState.ON, FeatureServiceState.STARTING) -> + orbotServiceSupervisor.stop() else -> {} } } private suspend fun applyStartIpScrambling() { - val authorizeVpnIntent = ipScramblerModule.prepareAndroidVpn() + val authorizeVpnIntent = orbotServiceSupervisor.prepareAndroidVpn() if (authorizeVpnIntent == null) { localStateRepository.emitStartVpnDisclaimer(null) @@ -190,17 +166,8 @@ class IpScramblingStateUseCase( } fun startIpScrambling() { - localStateRepository.internetPrivacyMode.value = HIDE_IP_LOADING - ipScramblerModule.start(enableNotification = isStandaloneBuild) - } - - private fun map(status: IpScramblerModule.Status): InternetPrivacyMode { - return when (status) { - IpScramblerModule.Status.OFF -> REAL_IP - IpScramblerModule.Status.ON -> HIDE_IP - IpScramblerModule.Status.STARTING -> HIDE_IP_LOADING - IpScramblerModule.Status.STOPPING, - IpScramblerModule.Status.START_DISABLED -> REAL_IP_LOADING - } + localStateRepository.internetPrivacyMode.value = FeatureServiceState.STARTING + orbotServiceSupervisor.setDNSFilter((trackersServiceSupervisor.dnsFilterForIpScrambling)) + orbotServiceSupervisor.start(enableNotification = isStandaloneBuild) } } 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 999955e..0a53c6c 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.InternetPrivacyMode +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 @@ -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 != InternetPrivacyMode.REAL_IP_LOADING + state.ipScramblingMode != FeatureServiceState.STOPPING ) binding.stateIpAddress.text = getString( - if (state.ipScramblingMode == InternetPrivacyMode.HIDE_IP) R.string.dashboard_state_ipaddress_on + if (state.ipScramblingMode == FeatureServiceState.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 == InternetPrivacyMode.HIDE_IP) R.color.green_valid + if (state.ipScramblingMode == FeatureServiceState.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 == InternetPrivacyMode.HIDE_IP) R.string.dashboard_internet_activity_privacy_subtitle_on + if (state.ipScramblingMode == FeatureServiceState.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 8fc8767..069ff04 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.InternetPrivacyMode +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 @@ -26,7 +26,7 @@ data class DashboardState( val quickPrivacyState: QuickPrivacyState = QuickPrivacyState.DISABLED, val trackerMode: TrackerMode = TrackerMode.VULNERABLE, val isLocationHidden: Boolean = false, - val ipScramblingMode: InternetPrivacyMode = InternetPrivacyMode.REAL_IP_LOADING, + val ipScramblingMode: FeatureServiceState = FeatureServiceState.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 1180af3..b4fc8a1 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.InternetPrivacyMode +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState import kotlinx.coroutines.launch import org.koin.androidx.viewmodel.ext.android.viewModel import java.util.Locale @@ -136,19 +136,12 @@ class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_ac private fun render(state: InternetPrivacyState) { binding.radioUseHiddenIp.radiobutton.apply { - isChecked = state.mode in listOf( - InternetPrivacyMode.HIDE_IP, - InternetPrivacyMode.HIDE_IP_LOADING - ) - isEnabled = state.mode != InternetPrivacyMode.HIDE_IP_LOADING + isChecked = state.mode.isChecked + isEnabled = state.mode != FeatureServiceState.STARTING } binding.radioUseRealIp.radiobutton.apply { - isChecked = - state.mode in listOf( - InternetPrivacyMode.REAL_IP, - InternetPrivacyMode.REAL_IP_LOADING - ) - isEnabled = state.mode != InternetPrivacyMode.REAL_IP_LOADING + isChecked = !state.mode.isChecked + isEnabled = state.mode != FeatureServiceState.STOPPING } binding.ipscramblingSelectLocation.setSelection(state.selectedLocationPosition) @@ -157,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 == InternetPrivacyMode.HIDE_IP + isEnabled = state.mode == FeatureServiceState.ON ) } @@ -170,10 +163,7 @@ class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_ac ) when { - state.mode in listOf( - InternetPrivacyMode.HIDE_IP_LOADING, - InternetPrivacyMode.REAL_IP_LOADING - ) + state.mode.isLoading || state.availableApps.isEmpty() -> { binding.loader.visibility = View.VISIBLE viewIdsToHide.forEach { it.visibility = View.GONE } 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 4d0fb38..e607d6c 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.InternetPrivacyMode +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState data class InternetPrivacyState( - val mode: InternetPrivacyMode = InternetPrivacyMode.REAL_IP, + val mode: FeatureServiceState = FeatureServiceState.OFF, val availableApps: List<ApplicationDescription> = emptyList(), val bypassTorApps: Collection<String> = emptyList(), val selectedLocation: String = "", diff --git a/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyViewModel.kt b/app/src/main/java/foundation/e/advancedprivacy/features/internetprivacy/InternetPrivacyViewModel.kt index 059e11d..10530e1 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,11 +22,10 @@ import androidx.annotation.StringRes import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import foundation.e.advancedprivacy.R -import foundation.e.advancedprivacy.domain.entities.InternetPrivacyMode +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState import foundation.e.advancedprivacy.domain.usecases.AppListUseCase import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase import foundation.e.advancedprivacy.domain.usecases.IpScramblingStateUseCase -import foundation.e.advancedprivacy.ipscrambler.IpScramblerModule import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.MutableSharedFlow @@ -41,7 +40,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class InternetPrivacyViewModel( - private val ipScramblerModule: IpScramblerModule, private val getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase, private val ipScramblingStateUseCase: IpScramblingStateUseCase, private val appListUseCase: AppListUseCase @@ -56,7 +54,7 @@ class InternetPrivacyViewModel( private val _singleEvents = MutableSharedFlow<SingleEvent>() val singleEvents = _singleEvents.asSharedFlow() - val availablesLocationsIds = listOf("", *ipScramblerModule.getAvailablesLocations().sorted().toTypedArray()) + val availablesLocationsIds = listOf("", *ipScramblingStateUseCase.availablesLocations.toTypedArray()) init { viewModelScope.launch(Dispatchers.IO) { @@ -64,7 +62,7 @@ class InternetPrivacyViewModel( it.copy( mode = ipScramblingStateUseCase.internetPrivacyMode.value, availableLocationIds = availablesLocationsIds, - selectedLocation = ipScramblerModule.exitCountry + selectedLocation = ipScramblingStateUseCase.exitCountry ) } } @@ -90,7 +88,7 @@ class InternetPrivacyViewModel( launch { ipScramblingStateUseCase.internetPrivacyMode - .map { it == InternetPrivacyMode.HIDE_IP_LOADING } + .map { it == FeatureServiceState.STARTING } .debounce(WARNING_LOADING_LONG_DELAY) .collect { if (it) _singleEvents.emit( @@ -136,10 +134,8 @@ class InternetPrivacyViewModel( private suspend fun actionSelectLocation(action: Action.SelectLocationAction) = withContext(Dispatchers.IO) { val locationId = _state.value.availableLocationIds[action.position] - if (locationId != ipScramblerModule.exitCountry) { - ipScramblerModule.exitCountry = locationId - _state.update { it.copy(selectedLocation = locationId) } - } + ipScramblingStateUseCase.setExitCountry(locationId) + _state.update { it.copy(selectedLocation = locationId) } } sealed class SingleEvent { 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 bfd7d1a..1bd8693 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.InternetPrivacyMode +import foundation.e.advancedprivacy.domain.entities.FeatureServiceState 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: InternetPrivacyMode = InternetPrivacyMode.REAL_IP_LOADING, + val ipScramblingMode: FeatureServiceState = FeatureServiceState.STOPPING, val dayStatistics: List<Pair<Int, Int>> = emptyList(), val activeTrackersCount: Int = 0, ) @@ -157,7 +157,7 @@ fun render( setTextViewText( R.id.state_ip_address, context.getString( - if (state.ipScramblingMode == InternetPrivacyMode.HIDE_IP) R.string.widget_state_ipaddress_on + if (state.ipScramblingMode == FeatureServiceState.ON) R.string.widget_state_ipaddress_on else R.string.widget_state_ipaddress_off ) ) |