From 56ac9db4a6fc1ff6919e7cfe55c20c03803569e9 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Fri, 23 Sep 2022 17:34:01 +0200 Subject: [PATCH 1/2] 5561: alert user that alwaysOn 3rd party VPN is running. --- .../data/repositories/LocalStateRepository.kt | 22 ++++++++++++++++--- .../usecases/GetQuickPrivacyStateUseCase.kt | 6 +++-- .../usecases/IpScramblingStateUseCase.kt | 20 +++++++++++------ .../features/dashboard/DashboardViewModel.kt | 5 +++++ .../InternetPrivacyViewModel.kt | 12 ++++++++-- app/src/main/res/values/strings.xml | 1 + 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt index af8646a3..2331cb6d 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt @@ -20,9 +20,12 @@ package foundation.e.privacycentralapp.data.repositories import android.content.Context import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode import foundation.e.privacycentralapp.domain.entities.LocationMode -import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update class LocalStateRepository(context: Context) { companion object { @@ -48,6 +51,13 @@ class LocalStateRepository(context: Context) { return isFirstActivation } + private val alwaysOnVpnAlreadyRunningMutableFlow = MutableSharedFlow() + suspend fun touchAlwaysOnVpnAlreadyRunning() { + alwaysOnVpnAlreadyRunningMutableFlow.emit(true) + } + + val alwaysOnVpnAlreadyRunningFlow = alwaysOnVpnAlreadyRunningMutableFlow.asSharedFlow() + var quickPrivacyEnabledFlow: StateFlow = quickPrivacyEnabledMutableFlow val areAllTrackersBlocked: MutableStateFlow = MutableStateFlow(false) @@ -79,9 +89,15 @@ class LocalStateRepository(context: Context) { val locationMode: MutableStateFlow = MutableStateFlow(LocationMode.REAL_LOCATION) + private val isIpScramblingEnabledMutableFlow = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, true)) + val isIpScramblngEnabledFlow = isIpScramblingEnabledMutableFlow.asStateFlow() + var isIpScramblingEnabled: Boolean - get() = sharedPref.getBoolean(KEY_IP_SCRAMBLING, true) - set(value) = set(KEY_IP_SCRAMBLING, value) + get() = isIpScramblngEnabledFlow.value + set(value) { + set(KEY_IP_SCRAMBLING, value) + isIpScramblingEnabledMutableFlow.update { value } + } val internetPrivacyMode: MutableStateFlow = MutableStateFlow(InternetPrivacyMode.REAL_IP) diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt index a9c608eb..fd4ee2d2 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt @@ -17,7 +17,6 @@ package foundation.e.privacycentralapp.domain.usecases -import android.util.Log import foundation.e.privacycentralapp.data.repositories.LocalStateRepository import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode import foundation.e.privacycentralapp.domain.entities.LocationMode @@ -25,8 +24,8 @@ import foundation.e.privacycentralapp.domain.entities.QuickPrivacyState import foundation.e.privacycentralapp.domain.entities.TrackerMode import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch @@ -106,4 +105,7 @@ class GetQuickPrivacyStateUseCase( fun resetQuickPrivacyDisabledMessage() { localStateRepository.setShowQuickPrivacyDisabledMessage(false) } + + val showAlwaysOnVpnAlreadyRunningMessage: SharedFlow = localStateRepository.alwaysOnVpnAlreadyRunningFlow + } diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt index c7c434c9..11006072 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt @@ -25,7 +25,6 @@ import foundation.e.privacymodules.permissions.IPermissionsPrivacyModule import foundation.e.privacymodules.permissions.data.ApplicationDescription import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.callbackFlow @@ -38,11 +37,10 @@ class IpScramblingStateUseCase( private val appDesc: ApplicationDescription, private val localStateRepository: LocalStateRepository, private val appListsRepository: AppListsRepository, - coroutineScope: CoroutineScope + private val coroutineScope: CoroutineScope ) { - val _configuredMode = MutableStateFlow(localStateRepository.isIpScramblingEnabled) - val configuredMode: StateFlow = _configuredMode + val configuredMode: StateFlow = localStateRepository.isIpScramblngEnabledFlow val internetPrivacyMode: StateFlow = callbackFlow { val listener = object : IIpScramblerModule.Listener { @@ -82,7 +80,6 @@ class IpScramblingStateUseCase( fun toggle(hideIp: Boolean) { localStateRepository.isIpScramblingEnabled = hideIp - _configuredMode.value = hideIp if (!localStateRepository.isQuickPrivacyEnabled) { localStateRepository.setShowQuickPrivacyDisabledMessage(true) @@ -132,11 +129,20 @@ class IpScramblingStateUseCase( when { isQuickPrivacyEnabled && isIpScramblingEnabled -> when (localStateRepository.internetPrivacyMode.value) { InternetPrivacyMode.REAL_IP, InternetPrivacyMode.REAL_IP_LOADING -> { - val intent = ipScramblerModule.prepareAndroidVpn() + var intent = ipScramblerModule.prepareAndroidVpn() if (intent != null) { permissionsPrivacyModule.setVpnPackageAuthorization(appDesc.packageName) + intent = ipScramblerModule.prepareAndroidVpn() + } + + if (intent != null) { + coroutineScope.launch { + localStateRepository.touchAlwaysOnVpnAlreadyRunning() + } + localStateRepository.isIpScramblingEnabled = false + } else { + ipScramblerModule.start(enableNotification = false) } - ipScramblerModule.start(enableNotification = false) } else -> {} } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt index 0ddceb15..cf5ca5de 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt @@ -74,6 +74,11 @@ class DashboardViewModel( }, getPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map { _state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) } + }, + getPrivacyStateUseCase.showAlwaysOnVpnAlreadyRunningMessage.map { + _singleEvents.emit(SingleEvent.ToastMessageSingleEvent( + R.string.ipscrambling_error_always_on_vpn_already_running + )) } ).collect {} } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt index 6d083bdf..617020cb 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt @@ -105,6 +105,14 @@ class InternetPrivacyViewModel( ) } } + + launch { + getQuickPrivacyStateUseCase.showAlwaysOnVpnAlreadyRunningMessage.collect { + _singleEvents.emit(SingleEvent.ErrorEvent(R.string.ipscrambling_error_always_on_vpn_already_running)) + _state.update { it.copy(forceRedraw = !it.forceRedraw)} + + } + } } fun submitAction(action: Action) = viewModelScope.launch { @@ -126,12 +134,12 @@ class InternetPrivacyViewModel( ipScramblingStateUseCase.toggle(hideIp = true) } - suspend private fun actionToggleAppIpScrambled(action: Action.ToggleAppIpScrambled) = withContext(Dispatchers.IO) { + private suspend fun actionToggleAppIpScrambled(action: Action.ToggleAppIpScrambled) = withContext(Dispatchers.IO) { ipScramblingStateUseCase.toggleBypassTor(action.packageName) _state.update { it.copy(bypassTorApps = ipScramblingStateUseCase.bypassTorApps) } } - suspend private fun actionSelectLocation(action: Action.SelectLocationAction) = withContext(Dispatchers.IO) { + private suspend fun actionSelectLocation(action: Action.SelectLocationAction) = withContext(Dispatchers.IO) { val locationId = _state.value.availableLocationIds[action.position] if (locationId != ipScramblerModule.exitCountry) { ipScramblerModule.exitCountry = locationId diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 79b2a984..79272ae6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -54,6 +54,7 @@ Apply this setting to all selected applications * : Only apps with internet permission are listed. Enabled Quick Privacy to use functionalities + Please disable any 3rd-party VPN in order for Advanced Privacy to hide your real IP address. Our scrambling IP service is taking time to launch. It can take a few minutes. Leaving the screen won\'t interrupt the process. Manage my location -- GitLab From ad8c13c27e89e8a53ee4466625ae70d2352fbb70 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Tue, 27 Sep 2022 08:23:29 +0200 Subject: [PATCH 2/2] Shorter names. --- .../data/repositories/LocalStateRepository.kt | 24 +++++++++---------- .../usecases/GetQuickPrivacyStateUseCase.kt | 2 +- .../usecases/IpScramblingStateUseCase.kt | 10 ++++---- .../features/dashboard/DashboardViewModel.kt | 2 +- .../InternetPrivacyViewModel.kt | 2 +- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt index 2331cb6d..672f2603 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt @@ -22,8 +22,8 @@ import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode import foundation.e.privacycentralapp.domain.entities.LocationMode import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update @@ -51,12 +51,12 @@ class LocalStateRepository(context: Context) { return isFirstActivation } - private val alwaysOnVpnAlreadyRunningMutableFlow = MutableSharedFlow() - suspend fun touchAlwaysOnVpnAlreadyRunning() { - alwaysOnVpnAlreadyRunningMutableFlow.emit(true) + private val _otherVpnRunning = MutableSharedFlow() + suspend fun emitOtherVpnRunning() { + _otherVpnRunning.emit(true) } - val alwaysOnVpnAlreadyRunningFlow = alwaysOnVpnAlreadyRunningMutableFlow.asSharedFlow() + val otherVpnRunning: SharedFlow = _otherVpnRunning var quickPrivacyEnabledFlow: StateFlow = quickPrivacyEnabledMutableFlow @@ -89,15 +89,13 @@ class LocalStateRepository(context: Context) { val locationMode: MutableStateFlow = MutableStateFlow(LocationMode.REAL_LOCATION) - private val isIpScramblingEnabledMutableFlow = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, true)) - val isIpScramblngEnabledFlow = isIpScramblingEnabledMutableFlow.asStateFlow() + private val _ipScramblingSetting = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, true)) + val ipScramblingSetting = _ipScramblingSetting.asStateFlow() - var isIpScramblingEnabled: Boolean - get() = isIpScramblngEnabledFlow.value - set(value) { - set(KEY_IP_SCRAMBLING, value) - isIpScramblingEnabledMutableFlow.update { value } - } + fun setIpScramblingSetting(enabled: Boolean) { + set(KEY_IP_SCRAMBLING, enabled) + _ipScramblingSetting.update { enabled } + } val internetPrivacyMode: MutableStateFlow = MutableStateFlow(InternetPrivacyMode.REAL_IP) diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt index fd4ee2d2..e1f773f6 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt @@ -106,6 +106,6 @@ class GetQuickPrivacyStateUseCase( localStateRepository.setShowQuickPrivacyDisabledMessage(false) } - val showAlwaysOnVpnAlreadyRunningMessage: SharedFlow = localStateRepository.alwaysOnVpnAlreadyRunningFlow + val otherVpnRunning: SharedFlow = localStateRepository.otherVpnRunning } diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt index 11006072..3320721a 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt @@ -40,7 +40,7 @@ class IpScramblingStateUseCase( private val coroutineScope: CoroutineScope ) { - val configuredMode: StateFlow = localStateRepository.isIpScramblngEnabledFlow + val configuredMode: StateFlow = localStateRepository.ipScramblingSetting val internetPrivacyMode: StateFlow = callbackFlow { val listener = object : IIpScramblerModule.Listener { @@ -69,7 +69,7 @@ class IpScramblingStateUseCase( init { coroutineScope.launch { localStateRepository.quickPrivacyEnabledFlow.collect { - applySettings(it, localStateRepository.isIpScramblingEnabled) + applySettings(it, localStateRepository.ipScramblingSetting.value) } } @@ -79,7 +79,7 @@ class IpScramblingStateUseCase( } fun toggle(hideIp: Boolean) { - localStateRepository.isIpScramblingEnabled = hideIp + localStateRepository.setIpScramblingSetting(enabled = hideIp) if (!localStateRepository.isQuickPrivacyEnabled) { localStateRepository.setShowQuickPrivacyDisabledMessage(true) @@ -137,9 +137,9 @@ class IpScramblingStateUseCase( if (intent != null) { coroutineScope.launch { - localStateRepository.touchAlwaysOnVpnAlreadyRunning() + localStateRepository.emitOtherVpnRunning() } - localStateRepository.isIpScramblingEnabled = false + localStateRepository.setIpScramblingSetting(enabled = false) } else { ipScramblerModule.start(enableNotification = false) } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt index cf5ca5de..cd7e414e 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt @@ -75,7 +75,7 @@ class DashboardViewModel( getPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map { _state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) } }, - getPrivacyStateUseCase.showAlwaysOnVpnAlreadyRunningMessage.map { + getPrivacyStateUseCase.otherVpnRunning.map { _singleEvents.emit(SingleEvent.ToastMessageSingleEvent( R.string.ipscrambling_error_always_on_vpn_already_running )) diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt index 617020cb..ab5e24d9 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt @@ -107,7 +107,7 @@ class InternetPrivacyViewModel( } launch { - getQuickPrivacyStateUseCase.showAlwaysOnVpnAlreadyRunningMessage.collect { + getQuickPrivacyStateUseCase.otherVpnRunning.collect { _singleEvents.emit(SingleEvent.ErrorEvent(R.string.ipscrambling_error_always_on_vpn_already_running)) _state.update { it.copy(forceRedraw = !it.forceRedraw)} -- GitLab