Loading app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt +18 −4 Original line number Diff line number Diff line Loading @@ -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.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update class LocalStateRepository(context: Context) { companion object { Loading @@ -48,6 +51,13 @@ class LocalStateRepository(context: Context) { return isFirstActivation } private val _otherVpnRunning = MutableSharedFlow<Boolean>() suspend fun emitOtherVpnRunning() { _otherVpnRunning.emit(true) } val otherVpnRunning: SharedFlow<Boolean> = _otherVpnRunning var quickPrivacyEnabledFlow: StateFlow<Boolean> = quickPrivacyEnabledMutableFlow val areAllTrackersBlocked: MutableStateFlow<Boolean> = MutableStateFlow(false) Loading Loading @@ -79,9 +89,13 @@ class LocalStateRepository(context: Context) { val locationMode: MutableStateFlow<LocationMode> = MutableStateFlow(LocationMode.REAL_LOCATION) var isIpScramblingEnabled: Boolean get() = sharedPref.getBoolean(KEY_IP_SCRAMBLING, true) set(value) = set(KEY_IP_SCRAMBLING, value) private val _ipScramblingSetting = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, true)) val ipScramblingSetting = _ipScramblingSetting.asStateFlow() fun setIpScramblingSetting(enabled: Boolean) { set(KEY_IP_SCRAMBLING, enabled) _ipScramblingSetting.update { enabled } } val internetPrivacyMode: MutableStateFlow<InternetPrivacyMode> = MutableStateFlow(InternetPrivacyMode.REAL_IP) Loading app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt +4 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -106,4 +105,7 @@ class GetQuickPrivacyStateUseCase( fun resetQuickPrivacyDisabledMessage() { localStateRepository.setShowQuickPrivacyDisabledMessage(false) } val otherVpnRunning: SharedFlow<Boolean> = localStateRepository.otherVpnRunning } app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt +15 −9 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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<Boolean> = _configuredMode val configuredMode: StateFlow<Boolean> = localStateRepository.ipScramblingSetting val internetPrivacyMode: StateFlow<InternetPrivacyMode> = callbackFlow { val listener = object : IIpScramblerModule.Listener { Loading Loading @@ -71,7 +69,7 @@ class IpScramblingStateUseCase( init { coroutineScope.launch { localStateRepository.quickPrivacyEnabledFlow.collect { applySettings(it, localStateRepository.isIpScramblingEnabled) applySettings(it, localStateRepository.ipScramblingSetting.value) } } Loading @@ -81,8 +79,7 @@ class IpScramblingStateUseCase( } fun toggle(hideIp: Boolean) { localStateRepository.isIpScramblingEnabled = hideIp _configuredMode.value = hideIp localStateRepository.setIpScramblingSetting(enabled = hideIp) if (!localStateRepository.isQuickPrivacyEnabled) { localStateRepository.setShowQuickPrivacyDisabledMessage(true) Loading Loading @@ -132,12 +129,21 @@ 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.emitOtherVpnRunning() } localStateRepository.setIpScramblingSetting(enabled = false) } else { ipScramblerModule.start(enableNotification = false) } } else -> {} } else -> when (localStateRepository.internetPrivacyMode.value) { Loading app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt +5 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,11 @@ class DashboardViewModel( }, getPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map { _state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) } }, getPrivacyStateUseCase.otherVpnRunning.map { _singleEvents.emit(SingleEvent.ToastMessageSingleEvent( R.string.ipscrambling_error_always_on_vpn_already_running )) } ).collect {} } Loading app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt +10 −2 Original line number Diff line number Diff line Loading @@ -105,6 +105,14 @@ class InternetPrivacyViewModel( ) } } launch { getQuickPrivacyStateUseCase.otherVpnRunning.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 { Loading @@ -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 Loading Loading
app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt +18 −4 Original line number Diff line number Diff line Loading @@ -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.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update class LocalStateRepository(context: Context) { companion object { Loading @@ -48,6 +51,13 @@ class LocalStateRepository(context: Context) { return isFirstActivation } private val _otherVpnRunning = MutableSharedFlow<Boolean>() suspend fun emitOtherVpnRunning() { _otherVpnRunning.emit(true) } val otherVpnRunning: SharedFlow<Boolean> = _otherVpnRunning var quickPrivacyEnabledFlow: StateFlow<Boolean> = quickPrivacyEnabledMutableFlow val areAllTrackersBlocked: MutableStateFlow<Boolean> = MutableStateFlow(false) Loading Loading @@ -79,9 +89,13 @@ class LocalStateRepository(context: Context) { val locationMode: MutableStateFlow<LocationMode> = MutableStateFlow(LocationMode.REAL_LOCATION) var isIpScramblingEnabled: Boolean get() = sharedPref.getBoolean(KEY_IP_SCRAMBLING, true) set(value) = set(KEY_IP_SCRAMBLING, value) private val _ipScramblingSetting = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, true)) val ipScramblingSetting = _ipScramblingSetting.asStateFlow() fun setIpScramblingSetting(enabled: Boolean) { set(KEY_IP_SCRAMBLING, enabled) _ipScramblingSetting.update { enabled } } val internetPrivacyMode: MutableStateFlow<InternetPrivacyMode> = MutableStateFlow(InternetPrivacyMode.REAL_IP) Loading
app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt +4 −2 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -106,4 +105,7 @@ class GetQuickPrivacyStateUseCase( fun resetQuickPrivacyDisabledMessage() { localStateRepository.setShowQuickPrivacyDisabledMessage(false) } val otherVpnRunning: SharedFlow<Boolean> = localStateRepository.otherVpnRunning }
app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt +15 −9 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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<Boolean> = _configuredMode val configuredMode: StateFlow<Boolean> = localStateRepository.ipScramblingSetting val internetPrivacyMode: StateFlow<InternetPrivacyMode> = callbackFlow { val listener = object : IIpScramblerModule.Listener { Loading Loading @@ -71,7 +69,7 @@ class IpScramblingStateUseCase( init { coroutineScope.launch { localStateRepository.quickPrivacyEnabledFlow.collect { applySettings(it, localStateRepository.isIpScramblingEnabled) applySettings(it, localStateRepository.ipScramblingSetting.value) } } Loading @@ -81,8 +79,7 @@ class IpScramblingStateUseCase( } fun toggle(hideIp: Boolean) { localStateRepository.isIpScramblingEnabled = hideIp _configuredMode.value = hideIp localStateRepository.setIpScramblingSetting(enabled = hideIp) if (!localStateRepository.isQuickPrivacyEnabled) { localStateRepository.setShowQuickPrivacyDisabledMessage(true) Loading Loading @@ -132,12 +129,21 @@ 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.emitOtherVpnRunning() } localStateRepository.setIpScramblingSetting(enabled = false) } else { ipScramblerModule.start(enableNotification = false) } } else -> {} } else -> when (localStateRepository.internetPrivacyMode.value) { Loading
app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt +5 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,11 @@ class DashboardViewModel( }, getPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map { _state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) } }, getPrivacyStateUseCase.otherVpnRunning.map { _singleEvents.emit(SingleEvent.ToastMessageSingleEvent( R.string.ipscrambling_error_always_on_vpn_already_running )) } ).collect {} } Loading
app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt +10 −2 Original line number Diff line number Diff line Loading @@ -105,6 +105,14 @@ class InternetPrivacyViewModel( ) } } launch { getQuickPrivacyStateUseCase.otherVpnRunning.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 { Loading @@ -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 Loading