diff --git a/app/build.gradle b/app/build.gradle
index 82717d34801b8fbda90b85904a49141bcf27d8f0..323a1186847bcfcbacd53cb15e2cfef118f4de19 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -132,7 +132,7 @@ dependencies {
implementation project(':trackers')
- implementation 'foundation.e:privacymodule.tor:1.3.0-orbot-16.6.2'
+ implementation 'foundation.e:privacymodule.tor:1.6.0-dev-orbot-16.6.2'
implementation 'foundation.e:elib:0.0.1-alpha11'
diff --git a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
index 670b81ee8c0c36872c7ff3a13e1b02199816dd2e..345307c4d09b977400f5770862030c59a04b838f 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
@@ -82,7 +82,7 @@ class DependencyContainer(val app: Application) {
// Usecases
val getQuickPrivacyStateUseCase by lazy {
- GetQuickPrivacyStateUseCase(localStateRepository, GlobalScope)
+ GetQuickPrivacyStateUseCase(localStateRepository)
}
private val ipScramblingStateUseCase by lazy {
IpScramblingStateUseCase(
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/QuickPrivacyDisabledSnackbar.kt b/app/src/main/java/foundation/e/privacycentralapp/common/QuickPrivacyDisabledSnackbar.kt
deleted file mode 100644
index 705f65d339fc35366184ac90139076c4daa9c56c..0000000000000000000000000000000000000000
--- a/app/src/main/java/foundation/e/privacycentralapp/common/QuickPrivacyDisabledSnackbar.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.privacycentralapp.common
-
-import android.view.View
-import com.google.android.material.snackbar.BaseTransientBottomBar
-import com.google.android.material.snackbar.Snackbar
-import foundation.e.privacycentralapp.R
-
-fun initQuickPrivacySnackbar(view: View, onDismiss: () -> Unit): Snackbar {
- val snackbar = Snackbar.make(view, R.string.quickprivacy_disabled_message, Snackbar.LENGTH_INDEFINITE)
- snackbar.setAction(R.string.close) { onDismiss() }
-
- snackbar.addCallback(object : BaseTransientBottomBar.BaseCallback() {
- override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
- super.onDismissed(transientBottomBar, event)
- if (event == DISMISS_EVENT_SWIPE) onDismiss()
- }
- })
- return snackbar
-}
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 d39ee43f20da6687a608cc3824b0ad5b805b0932..92ee0c1647337fb9cafab427d9f9b86b4817330b 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
@@ -24,14 +24,13 @@ import foundation.e.privacymodules.permissions.data.ApplicationDescription
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 {
private const val SHARED_PREFS_FILE = "localState"
- private const val KEY_QUICK_PRIVACY = "quickPrivacy"
+ private const val KEY_BLOCK_TRACKERS = "blockTrackers"
private const val KEY_IP_SCRAMBLING = "ipScrambling"
private const val KEY_FAKE_LOCATION = "fakeLocation"
private const val KEY_FAKE_LATITUDE = "fakeLatitude"
@@ -41,58 +40,48 @@ class LocalStateRepository(context: Context) {
private val sharedPref = context.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE)
- private val quickPrivacyEnabledMutableFlow =
- MutableStateFlow(sharedPref.getBoolean(KEY_QUICK_PRIVACY, false))
- val isQuickPrivacyEnabled: Boolean get() = quickPrivacyEnabledMutableFlow.value
+ private val _blockTrackers = MutableStateFlow(sharedPref.getBoolean(KEY_BLOCK_TRACKERS, true))
+ val blockTrackers = _blockTrackers.asStateFlow()
- fun setQuickPrivacyReturnIsFirstActivation(value: Boolean): Boolean {
- val isFirstActivation = value && !sharedPref.contains(KEY_QUICK_PRIVACY)
- set(KEY_QUICK_PRIVACY, value)
- quickPrivacyEnabledMutableFlow.value = value
- return isFirstActivation
+ fun setBlockTrackers(enabled: Boolean) {
+ set(KEY_BLOCK_TRACKERS, enabled)
+ _blockTrackers.update { enabled }
}
- private val _otherVpnRunning = MutableSharedFlow()
- suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) {
- _otherVpnRunning.emit(appDesc)
- }
+ val areAllTrackersBlocked: MutableStateFlow = MutableStateFlow(false)
- val otherVpnRunning: SharedFlow = _otherVpnRunning
+ private val _fakeLocationEnabled = MutableStateFlow(sharedPref.getBoolean(KEY_FAKE_LOCATION, true))
- var quickPrivacyEnabledFlow: StateFlow = quickPrivacyEnabledMutableFlow
+ val fakeLocationEnabled = _fakeLocationEnabled.asStateFlow()
- val areAllTrackersBlocked: MutableStateFlow = MutableStateFlow(false)
+ fun setFakeLocationEnabled(enabled: Boolean) {
+ set(KEY_FAKE_LOCATION, enabled)
+ _fakeLocationEnabled.update { enabled }
+ }
- var fakeLocation: Pair?
- get() = if (sharedPref.getBoolean(KEY_FAKE_LOCATION, true))
- Pair(
- // Initial default value is Quezon City
- sharedPref.getFloat(KEY_FAKE_LATITUDE, 14.6760f),
- sharedPref.getFloat(KEY_FAKE_LONGITUDE, 121.0437f)
- )
- else null
+ var fakeLocation: Pair
+ get() = Pair(
+ // Initial default value is Quezon City
+ sharedPref.getFloat(KEY_FAKE_LATITUDE, 14.6760f),
+ sharedPref.getFloat(KEY_FAKE_LONGITUDE, 121.0437f)
+ )
set(value) {
- if (value == null) {
- sharedPref.edit()
- .putBoolean(KEY_FAKE_LOCATION, false)
- .remove(KEY_FAKE_LATITUDE)
- .remove(KEY_FAKE_LONGITUDE)
- .commit()
- } else {
- sharedPref.edit()
- .putBoolean(KEY_FAKE_LOCATION, true)
- .putFloat(KEY_FAKE_LATITUDE, value.first)
- .putFloat(KEY_FAKE_LONGITUDE, value.second)
- .commit()
- }
+ sharedPref.edit()
+ .putFloat(KEY_FAKE_LATITUDE, value.first)
+ .putFloat(KEY_FAKE_LONGITUDE, value.second)
+ .apply()
}
val locationMode: MutableStateFlow = MutableStateFlow(LocationMode.REAL_LOCATION)
- private val _ipScramblingSetting = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, true))
+ private val _ipScramblingSetting = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, false))
val ipScramblingSetting = _ipScramblingSetting.asStateFlow()
+ fun isIpScramblingFirstActivation(enabled: Boolean): Boolean {
+ return enabled && !sharedPref.contains(KEY_IP_SCRAMBLING)
+ }
+
fun setIpScramblingSetting(enabled: Boolean) {
set(KEY_IP_SCRAMBLING, enabled)
_ipScramblingSetting.update { enabled }
@@ -100,18 +89,17 @@ class LocalStateRepository(context: Context) {
val internetPrivacyMode: MutableStateFlow = MutableStateFlow(InternetPrivacyMode.REAL_IP)
- private val _showQuickPrivacyDisabledMessage = MutableStateFlow(false)
- val showQuickPrivacyDisabledMessage: StateFlow = _showQuickPrivacyDisabledMessage
-
- fun setShowQuickPrivacyDisabledMessage(show: Boolean) {
- _showQuickPrivacyDisabledMessage.value = show
+ private val _otherVpnRunning = MutableSharedFlow()
+ suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) {
+ _otherVpnRunning.emit(appDesc)
}
+ val otherVpnRunning: SharedFlow = _otherVpnRunning
var firstBoot: Boolean
get() = sharedPref.getBoolean(KEY_FIRST_BOOT, true)
set(value) = set(KEY_FIRST_BOOT, value)
private fun set(key: String, value: Boolean) {
- sharedPref.edit().putBoolean(key, value).commit()
+ sharedPref.edit().putBoolean(key, value).apply()
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/entities/InternetPrivacyMode.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/entities/InternetPrivacyMode.kt
index 534bb2f64eea7c358f0d6e5f926ab5a9da8a7706..f849d57e08aade4ec715313c3bb643a92ab48caa 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/entities/InternetPrivacyMode.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/entities/InternetPrivacyMode.kt
@@ -21,5 +21,9 @@ enum class InternetPrivacyMode {
REAL_IP,
HIDE_IP,
HIDE_IP_LOADING,
- REAL_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/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt
index e9da8555bc618df559b8c97da74178bb68b635fa..2910f26a9c79376299b609b0757b8d54cf69ab84 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt
@@ -57,7 +57,7 @@ class FakeLocationStateUseCase(
init {
coroutineScope.launch {
- localStateRepository.quickPrivacyEnabledFlow.collect {
+ localStateRepository.fakeLocationEnabled.collect {
applySettings(it, localStateRepository.fakeLocation)
}
}
@@ -71,10 +71,10 @@ class FakeLocationStateUseCase(
permissionsModule.toggleDangerousPermission(appDesc, android.Manifest.permission.ACCESS_FINE_LOCATION, true)
}
- private fun applySettings(isQuickPrivacyEnabled: Boolean, fakeLocation: Pair?, isSpecificLocation: Boolean = false) {
- _configuredLocationMode.value = computeLocationMode(fakeLocation, isSpecificLocation)
+ private fun applySettings(isEnabled: Boolean, fakeLocation: Pair, isSpecificLocation: Boolean = false) {
+ _configuredLocationMode.value = computeLocationMode(isEnabled, fakeLocation, isSpecificLocation)
- if (isQuickPrivacyEnabled && fakeLocation != null && hasAcquireMockLocationPermission()) {
+ if (isEnabled && hasAcquireMockLocationPermission()) {
fakeLocationModule.startFakeLocation()
fakeLocationModule.setFakeLocation(fakeLocation.first.toDouble(), fakeLocation.second.toDouble())
localStateRepository.locationMode.value = configuredLocationMode.value.first
@@ -90,18 +90,10 @@ class FakeLocationStateUseCase(
}
fun setSpecificLocation(latitude: Float, longitude: Float) {
- if (!localStateRepository.isQuickPrivacyEnabled) {
- localStateRepository.setShowQuickPrivacyDisabledMessage(true)
- }
-
setFakeLocation(latitude to longitude, true)
}
fun setRandomLocation() {
- if (!localStateRepository.isQuickPrivacyEnabled) {
- localStateRepository.setShowQuickPrivacyDisabledMessage(true)
- }
-
val randomIndex = Random.nextInt(citiesRepository.citiesLocationsList.size)
val location = citiesRepository.citiesLocationsList[randomIndex]
@@ -110,26 +102,29 @@ class FakeLocationStateUseCase(
private fun setFakeLocation(location: Pair, isSpecificLocation: Boolean = false) {
localStateRepository.fakeLocation = location
- applySettings(localStateRepository.isQuickPrivacyEnabled, location, isSpecificLocation)
+ localStateRepository.setFakeLocationEnabled(true)
+ applySettings(true, location, isSpecificLocation)
}
fun stopFakeLocation() {
- if (!localStateRepository.isQuickPrivacyEnabled) {
- localStateRepository.setShowQuickPrivacyDisabledMessage(true)
- }
-
- localStateRepository.fakeLocation = null
- applySettings(localStateRepository.isQuickPrivacyEnabled, null)
+ localStateRepository.setFakeLocationEnabled(false)
+ applySettings(false, localStateRepository.fakeLocation)
}
- private fun computeLocationMode(fakeLocation: Pair?, isSpecificLocation: Boolean = false): Triple {
+ private fun computeLocationMode(
+ isFakeLocationEnabled: Boolean,
+ fakeLocation: Pair,
+ isSpecificLocation: Boolean = false,
+ ): Triple {
return Triple(
when {
- fakeLocation == null -> LocationMode.REAL_LOCATION
- fakeLocation in citiesRepository.citiesLocationsList && !isSpecificLocation -> LocationMode.RANDOM_LOCATION
+ !isFakeLocationEnabled -> LocationMode.REAL_LOCATION
+ (fakeLocation in citiesRepository.citiesLocationsList && !isSpecificLocation) ->
+ LocationMode.RANDOM_LOCATION
else -> LocationMode.SPECIFIC_LOCATION
},
- fakeLocation?.first, fakeLocation?.second
+ fakeLocation.first,
+ fakeLocation.second
)
}
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 46e054e678056430fa274734ee2c111a8773eb11..85410d009394d51406b6adde9944110422ba0983 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
@@ -23,88 +23,69 @@ import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.domain.entities.QuickPrivacyState
import foundation.e.privacycentralapp.domain.entities.TrackerMode
import foundation.e.privacymodules.permissions.data.ApplicationDescription
-import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.flow.map
class GetQuickPrivacyStateUseCase(
- private val localStateRepository: LocalStateRepository,
- coroutineScope: CoroutineScope
+ private val localStateRepository: LocalStateRepository
) {
-
- init {
- coroutineScope.launch {
- localStateRepository.quickPrivacyEnabledFlow.collect {
- if (it) resetQuickPrivacyDisabledMessage()
- }
- }
- }
-
- val quickPrivacyEnabledFlow: Flow = localStateRepository.quickPrivacyEnabledFlow
-
- val isQuickPrivacyEnabled: Boolean get() = localStateRepository.isQuickPrivacyEnabled
-
val quickPrivacyState: Flow = combine(
- localStateRepository.quickPrivacyEnabledFlow,
+ localStateRepository.blockTrackers,
localStateRepository.areAllTrackersBlocked,
localStateRepository.locationMode,
localStateRepository.internetPrivacyMode
- ) { isQuickPrivacyEnabled, isAllTrackersBlocked, locationMode, internetPrivacyMode ->
+ ) { isBlockTrackers, isAllTrackersBlocked, locationMode, internetPrivacyMode ->
when {
- !isQuickPrivacyEnabled -> QuickPrivacyState.DISABLED
+ !isBlockTrackers &&
+ locationMode == LocationMode.REAL_LOCATION &&
+ internetPrivacyMode == InternetPrivacyMode.REAL_IP -> QuickPrivacyState.DISABLED
+
isAllTrackersBlocked &&
locationMode != LocationMode.REAL_LOCATION &&
internetPrivacyMode in listOf(
InternetPrivacyMode.HIDE_IP,
InternetPrivacyMode.HIDE_IP_LOADING
) -> QuickPrivacyState.FULL_ENABLED
+
else -> QuickPrivacyState.ENABLED
}
}
val trackerMode: Flow = combine(
- localStateRepository.quickPrivacyEnabledFlow,
+ localStateRepository.blockTrackers,
localStateRepository.areAllTrackersBlocked
- ) { isQuickPrivacyEnabled, isAllTrackersBlocked ->
+ ) { isBlockTrackers, isAllTrackersBlocked ->
when {
- isQuickPrivacyEnabled && isAllTrackersBlocked -> TrackerMode.DENIED
- isQuickPrivacyEnabled && !isAllTrackersBlocked -> TrackerMode.CUSTOM
+ isBlockTrackers && isAllTrackersBlocked -> TrackerMode.DENIED
+ isBlockTrackers && !isAllTrackersBlocked -> TrackerMode.CUSTOM
else -> TrackerMode.VULNERABLE
}
}
- val isLocationHidden: Flow = combine(
- localStateRepository.quickPrivacyEnabledFlow,
- localStateRepository.locationMode
- ) { isQuickPrivacyEnabled, locationMode ->
- isQuickPrivacyEnabled && locationMode != LocationMode.REAL_LOCATION
+ val isLocationHidden: Flow = localStateRepository.locationMode.map { locationMode ->
+ locationMode != LocationMode.REAL_LOCATION
}
val locationMode: StateFlow = localStateRepository.locationMode
- val isIpHidden: Flow = combine(
- localStateRepository.quickPrivacyEnabledFlow,
- localStateRepository.internetPrivacyMode
- ) { isQuickPrivacyEnabled, internetPrivacyMode ->
- when {
- !isQuickPrivacyEnabled || internetPrivacyMode == InternetPrivacyMode.REAL_IP -> false
- internetPrivacyMode == InternetPrivacyMode.HIDE_IP -> true
- else -> null
- }
- }
+ val ipScramblingMode: Flow = localStateRepository.internetPrivacyMode
- fun toggleReturnIsFirstActivation(): Boolean {
- val newState = !localStateRepository.isQuickPrivacyEnabled
- return localStateRepository.setQuickPrivacyReturnIsFirstActivation(newState)
+ fun toggleTrackers() {
+ localStateRepository.setBlockTrackers(!localStateRepository.blockTrackers.value)
}
- val showQuickPrivacyDisabledMessage: StateFlow = localStateRepository.showQuickPrivacyDisabledMessage
+ fun toggleLocation() {
+ localStateRepository.setFakeLocationEnabled(!localStateRepository.fakeLocationEnabled.value)
+ }
- fun resetQuickPrivacyDisabledMessage() {
- localStateRepository.setShowQuickPrivacyDisabledMessage(false)
+ fun toggleIpScramblingIsFirstActivation(): Boolean {
+ val enabled = !localStateRepository.ipScramblingSetting.value
+ val firstActivation = localStateRepository.isIpScramblingFirstActivation(enabled)
+ localStateRepository.setIpScramblingSetting(enabled)
+ return firstActivation
}
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 cb9fcd58351ad2b74a34d45f2553a3411db0f8ab..9216233ec2835fac7e12bac8fdd63566b4b5b5d9 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
@@ -28,6 +28,7 @@ import foundation.e.privacymodules.ipscramblermodule.IIpScramblerModule
import foundation.e.privacymodules.permissions.IPermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -43,9 +44,6 @@ class IpScramblingStateUseCase(
private val appListsRepository: AppListsRepository,
private val coroutineScope: CoroutineScope
) {
-
- val configuredMode: StateFlow = localStateRepository.ipScramblingSetting
-
val internetPrivacyMode: StateFlow = callbackFlow {
val listener = object : IIpScramblerModule.Listener {
override fun onStatusChanged(newStatus: IIpScramblerModule.Status) {
@@ -67,13 +65,13 @@ class IpScramblingStateUseCase(
}.stateIn(
scope = coroutineScope,
started = SharingStarted.Eagerly,
- initialValue = InternetPrivacyMode.REAL_IP
+ initialValue = REAL_IP
)
init {
- coroutineScope.launch {
- localStateRepository.quickPrivacyEnabledFlow.collect {
- applySettings(it, localStateRepository.ipScramblingSetting.value)
+ coroutineScope.launch(Dispatchers.Default) {
+ localStateRepository.ipScramblingSetting.collect {
+ applySettings(it)
}
}
@@ -84,12 +82,7 @@ class IpScramblingStateUseCase(
fun toggle(hideIp: Boolean) {
localStateRepository.setIpScramblingSetting(enabled = hideIp)
-
- if (!localStateRepository.isQuickPrivacyEnabled) {
- localStateRepository.setShowQuickPrivacyDisabledMessage(true)
- } else {
- applySettings(true, hideIp)
- }
+ applySettings(hideIp)
}
private fun getHiddenPackageNames(): List {
@@ -129,15 +122,13 @@ class IpScramblingStateUseCase(
ipScramblerModule.appList = rawList
}
- private fun applySettings(isQuickPrivacyEnabled: Boolean, isIpScramblingEnabled: Boolean) {
- val settingEnabled = isQuickPrivacyEnabled && isIpScramblingEnabled
+ private fun applySettings(isIpScramblingEnabled: Boolean) {
val currentMode = localStateRepository.internetPrivacyMode.value
-
when {
- settingEnabled && currentMode in setOf(REAL_IP, REAL_IP_LOADING) ->
+ isIpScramblingEnabled && currentMode in setOf(REAL_IP, REAL_IP_LOADING) ->
applyStartIpScrambling()
- !settingEnabled && currentMode in setOf(HIDE_IP, HIDE_IP_LOADING) ->
+ !isIpScramblingEnabled && currentMode in setOf(HIDE_IP, HIDE_IP_LOADING) ->
ipScramblerModule.stop()
else -> {}
@@ -162,11 +153,11 @@ class IpScramblingStateUseCase(
private fun map(status: IIpScramblerModule.Status): InternetPrivacyMode {
return when (status) {
- IIpScramblerModule.Status.OFF -> InternetPrivacyMode.REAL_IP
- IIpScramblerModule.Status.ON -> InternetPrivacyMode.HIDE_IP
- IIpScramblerModule.Status.STARTING -> InternetPrivacyMode.HIDE_IP_LOADING
+ IIpScramblerModule.Status.OFF -> REAL_IP
+ IIpScramblerModule.Status.ON -> HIDE_IP
+ IIpScramblerModule.Status.STARTING -> HIDE_IP_LOADING
IIpScramblerModule.Status.STOPPING,
- IIpScramblerModule.Status.START_DISABLED -> InternetPrivacyMode.REAL_IP_LOADING
+ IIpScramblerModule.Status.START_DISABLED -> REAL_IP_LOADING
}
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt
index 17e5096b054cd74c365fb1cdaf1911d4a8227266..8b37152349d4345b592ce8cba63d2a99b43b33b2 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt
@@ -38,7 +38,7 @@ class TrackersStateUseCase(
init {
trackersPrivacyModule.start(trackersRepository.trackers, enableNotification = false)
coroutineScope.launch {
- localStateRepository.quickPrivacyEnabledFlow.collect { enabled ->
+ localStateRepository.blockTrackers.collect { enabled ->
if (enabled) {
blockTrackersPrivacyModule.enableBlocking()
} else {
@@ -76,10 +76,6 @@ class TrackersStateUseCase(
}
fun toggleAppWhitelist(appUid: Int, isWhitelisted: Boolean) {
- if (!localStateRepository.isQuickPrivacyEnabled) {
- localStateRepository.setShowQuickPrivacyDisabledMessage(true)
- }
-
if (appUid == appListsRepository.dummySystemApp.uid) {
appListsRepository.getHiddenSystemApps().forEach {
blockTrackersPrivacyModule.setWhiteListed(it.uid, isWhitelisted)
@@ -90,9 +86,6 @@ class TrackersStateUseCase(
}
fun blockTracker(appUid: Int, tracker: Tracker, isBlocked: Boolean) {
- if (!localStateRepository.isQuickPrivacyEnabled) {
- localStateRepository.setShowQuickPrivacyDisabledMessage(true)
- }
if (appUid == appListsRepository.dummySystemApp.uid) {
appListsRepository.getHiddenSystemApps().forEach {
blockTrackersPrivacyModule.setWhiteListed(tracker, it.uid, !isBlocked)
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt
index 6cd259e527b68c300a9192490ada98ec90c94b03..8a0a3d4aba854b661767e04ef73cacb867538180 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt
@@ -32,14 +32,13 @@ import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
-import com.google.android.material.snackbar.Snackbar
import foundation.e.privacycentralapp.DependencyContainer
import foundation.e.privacycentralapp.PrivacyCentralApplication
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.common.GraphHolder
import foundation.e.privacycentralapp.common.NavToolbarFragment
-import foundation.e.privacycentralapp.common.initQuickPrivacySnackbar
import foundation.e.privacycentralapp.databinding.FragmentDashboardBinding
+import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.domain.entities.QuickPrivacyState
import foundation.e.privacycentralapp.domain.entities.TrackerMode
@@ -72,8 +71,6 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
private var _binding: FragmentDashboardBinding? = null
private val binding get() = _binding!!
- private var qpDisabledSnackbar: Snackbar? = null
-
private var highlightIndexOnStart: Int? = null
override fun onCreate(savedInstanceState: Bundle?) {
@@ -91,8 +88,14 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
binding.leakingAppButton.setOnClickListener {
viewModel.submitAction(Action.ShowMostLeakedApp)
}
- binding.togglePrivacyCentral.setOnClickListener {
- viewModel.submitAction(Action.TogglePrivacyAction)
+ binding.toggleTrackers.setOnClickListener {
+ viewModel.submitAction(Action.ToggleTrackers)
+ }
+ binding.toggleLocation.setOnClickListener {
+ viewModel.submitAction(Action.ToggleLocation)
+ }
+ binding.toggleIpscrambling.setOnClickListener {
+ viewModel.submitAction(Action.ToggleIpScrambling)
}
binding.myLocation.container.setOnClickListener {
viewModel.submitAction(Action.ShowFakeMyLocationAction)
@@ -108,10 +111,6 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
viewModel.submitAction(Action.ShowTrackers)
}
- qpDisabledSnackbar = initQuickPrivacySnackbar(binding.root) {
- viewModel.submitAction(Action.CloseQuickPrivacyDisabledMessage)
- }
-
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
render(viewModel.state.value)
@@ -185,9 +184,6 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
}
private fun render(state: DashboardState) {
- if (state.showQuickPrivacyDisabledMessage) qpDisabledSnackbar?.show()
- else qpDisabledSnackbar?.dismiss()
-
binding.stateLabel.text = getString(
when (state.quickPrivacyState) {
QuickPrivacyState.DISABLED -> R.string.dashboard_state_title_off
@@ -201,7 +197,7 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
else R.drawable.ic_shield_off
)
- binding.togglePrivacyCentral.isChecked = state.quickPrivacyState.isEnabled()
+ binding.toggleTrackers.isChecked = state.trackerMode != TrackerMode.VULNERABLE
binding.stateTrackers.text = getString(
when (state.trackerMode) {
@@ -218,6 +214,8 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
)
)
+ binding.toggleLocation.isChecked = state.isLocationHidden
+
binding.stateGeolocation.text = getString(
if (state.isLocationHidden) R.string.dashboard_state_geolocation_on
else R.string.dashboard_state_geolocation_off
@@ -230,10 +228,11 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
)
)
- val isLoading = state.isIpHidden == null
+ binding.toggleIpscrambling.isChecked = state.ipScramblingMode.isChecked
+ val isLoading = state.ipScramblingMode.isLoading
binding.stateIpAddress.text = getString(
- if (state.isIpHidden == true) R.string.dashboard_state_ipaddress_on
+ if (state.ipScramblingMode == InternetPrivacyMode.HIDE_IP) R.string.dashboard_state_ipaddress_on
else R.string.dashboard_state_ipaddress_off
)
@@ -243,7 +242,7 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
binding.stateIpAddress.setTextColor(
getColor(
requireContext(),
- if (state.isIpHidden == true) R.color.green_valid
+ if (state.ipScramblingMode == InternetPrivacyMode.HIDE_IP) R.color.green_valid
else R.color.red_off
)
)
@@ -292,7 +291,7 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
)
binding.internetActivityPrivacy.subTitle = getString(
- if (state.isIpHidden == true) R.string.dashboard_internet_activity_privacy_subtitle_on
+ if (state.ipScramblingMode == InternetPrivacyMode.HIDE_IP) R.string.dashboard_internet_activity_privacy_subtitle_on
else R.string.dashboard_internet_activity_privacy_subtitle_off
)
@@ -301,7 +300,6 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
override fun onDestroyView() {
super.onDestroyView()
- qpDisabledSnackbar = null
graphHolder = null
_binding = null
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardState.kt
index 04b7ae858139ed008d65710e0e76a9ddfe2a63e1..937fa221b55daf64321b128f653af44960b7f93b 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardState.kt
@@ -17,6 +17,7 @@
package foundation.e.privacycentralapp.features.dashboard
+import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.domain.entities.QuickPrivacyState
import foundation.e.privacycentralapp.domain.entities.TrackerMode
@@ -25,12 +26,11 @@ data class DashboardState(
val quickPrivacyState: QuickPrivacyState = QuickPrivacyState.DISABLED,
val trackerMode: TrackerMode = TrackerMode.VULNERABLE,
val isLocationHidden: Boolean = false,
- val isIpHidden: Boolean? = false,
+ val ipScramblingMode: InternetPrivacyMode = InternetPrivacyMode.REAL_IP_LOADING,
val locationMode: LocationMode = LocationMode.REAL_LOCATION,
val leakedTrackersCount: Int? = null,
val trackersCount: Int? = null,
val allowedTrackersCount: Int? = null,
val dayStatistics: List>? = null,
val dayLabels: List? = null,
- val showQuickPrivacyDisabledMessage: Boolean = 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 d7d74c6b830bad2f6f57960d472ebdb4971c7a3c..57e77908b6090b8e8314a5c8d4577485eeaa2061 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
@@ -25,6 +25,7 @@ import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCas
import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -58,8 +59,8 @@ class DashboardViewModel(
getPrivacyStateUseCase.quickPrivacyState.map {
_state.update { s -> s.copy(quickPrivacyState = it) }
},
- getPrivacyStateUseCase.isIpHidden.map {
- _state.update { s -> s.copy(isIpHidden = it) }
+ getPrivacyStateUseCase.ipScramblingMode.map {
+ _state.update { s -> s.copy(ipScramblingMode = it) }
},
trackersStatisticsUseCase.listenUpdates().flatMapLatest {
fetchStatistics()
@@ -73,9 +74,6 @@ class DashboardViewModel(
getPrivacyStateUseCase.locationMode.map {
_state.update { s -> s.copy(locationMode = it) }
},
- getPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map {
- _state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) }
- },
getPrivacyStateUseCase.otherVpnRunning.map {
_singleEvents.emit(
SingleEvent.ToastMessageSingleEvent(
@@ -89,7 +87,14 @@ class DashboardViewModel(
fun submitAction(action: Action) = viewModelScope.launch {
when (action) {
- is Action.TogglePrivacyAction -> actionTogglePrivacy()
+ is Action.ToggleTrackers -> {
+ getPrivacyStateUseCase.toggleTrackers()
+ // Add delay here to prevent race condition with trackers state.
+ delay(200)
+ fetchStatistics().first()
+ }
+ is Action.ToggleLocation -> getPrivacyStateUseCase.toggleLocation()
+ is Action.ToggleIpScrambling -> actionToggleIpScrambling()
is Action.ShowFakeMyLocationAction ->
_singleEvents.emit(SingleEvent.NavigateToLocationSingleEvent)
is Action.ShowAppsPermissions ->
@@ -98,8 +103,6 @@ class DashboardViewModel(
_singleEvents.emit(SingleEvent.NavigateToInternetActivityPrivacySingleEvent)
is Action.ShowTrackers ->
_singleEvents.emit(SingleEvent.NavigateToTrackersSingleEvent)
- is Action.CloseQuickPrivacyDisabledMessage ->
- getPrivacyStateUseCase.resetQuickPrivacyDisabledMessage()
is Action.ShowMostLeakedApp -> actionShowMostLeakedApp()
}
}
@@ -120,9 +123,8 @@ class DashboardViewModel(
}
}
- private suspend fun actionTogglePrivacy() = withContext(Dispatchers.IO) {
- val isFirstActivation = getPrivacyStateUseCase.toggleReturnIsFirstActivation()
- fetchStatistics().first()
+ private suspend fun actionToggleIpScrambling() = withContext(Dispatchers.IO) {
+ val isFirstActivation = getPrivacyStateUseCase.toggleIpScramblingIsFirstActivation()
if (isFirstActivation) _singleEvents.emit(
SingleEvent.ToastMessageSingleEvent(
@@ -152,12 +154,13 @@ class DashboardViewModel(
}
sealed class Action {
- object TogglePrivacyAction : Action()
+ object ToggleTrackers : Action()
+ object ToggleLocation : Action()
+ object ToggleIpScrambling : Action()
object ShowFakeMyLocationAction : Action()
object ShowInternetActivityPrivacyAction : Action()
object ShowAppsPermissions : Action()
object ShowTrackers : Action()
- object CloseQuickPrivacyDisabledMessage : Action()
object ShowMostLeakedApp : Action()
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt
index 99aa2170d461a50cb23ee8c469d61d8ac82a490b..afef9863d9d121c6e9390d6f87105264fda9c203 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt
@@ -27,13 +27,11 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
-import com.google.android.material.snackbar.Snackbar
import foundation.e.privacycentralapp.DependencyContainer
import foundation.e.privacycentralapp.PrivacyCentralApplication
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.common.NavToolbarFragment
import foundation.e.privacycentralapp.common.ToggleAppsAdapter
-import foundation.e.privacycentralapp.common.initQuickPrivacySnackbar
import foundation.e.privacycentralapp.common.setToolTipForAsterisk
import foundation.e.privacycentralapp.databinding.FragmentInternetActivityPolicyBinding
import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
@@ -53,8 +51,6 @@ class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_ac
private var _binding: FragmentInternetActivityPolicyBinding? = null
private val binding get() = _binding!!
- private var qpDisabledSnackbar: Snackbar? = null
-
private fun displayToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT)
.show()
@@ -120,10 +116,6 @@ class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_ac
}
}
- qpDisabledSnackbar = initQuickPrivacySnackbar(binding.root) {
- viewModel.submitAction(InternetPrivacyViewModel.Action.CloseQuickPrivacyDisabledMessage)
- }
-
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
render(viewModel.state.value)
@@ -152,9 +144,6 @@ class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_ac
override fun getTitle(): String = getString(R.string.ipscrambling_title)
private fun render(state: InternetPrivacyState) {
- if (state.showQuickPrivacyDisabledMessage) qpDisabledSnackbar?.show()
- else qpDisabledSnackbar?.dismiss()
-
binding.radioUseHiddenIp.radiobutton.apply {
isChecked = state.mode in listOf(
InternetPrivacyMode.HIDE_IP,
@@ -207,7 +196,6 @@ class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_ac
override fun onDestroyView() {
super.onDestroyView()
- qpDisabledSnackbar = null
_binding = null
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyState.kt
index 6991196834d978943759def38277aa749954db87..54b7e0197e881358fd1330f79550af14186c448b 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyState.kt
@@ -27,7 +27,6 @@ data class InternetPrivacyState(
val selectedLocation: String = "",
val availableLocationIds: List = emptyList(),
val forceRedraw: Boolean = false,
- val showQuickPrivacyDisabledMessage: Boolean = false
) {
fun getApps(): List> {
return availableApps.map { it to (it.packageName !in bypassTorApps) }
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 be6cd4d290163a51d14dcca9368c44bc7a2e25d6..bbd62394211e6ae75540275745b502cd62e6d326 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
@@ -73,9 +73,6 @@ class InternetPrivacyViewModel(
suspend fun doOnStartedState() = withContext(Dispatchers.IO) {
launch {
merge(
- getQuickPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map {
- _state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) }
- },
appListUseCase.getAppsUsingInternet().map { apps ->
_state.update { s ->
s.copy(
@@ -84,17 +81,8 @@ class InternetPrivacyViewModel(
)
}
},
- if (getQuickPrivacyStateUseCase.isQuickPrivacyEnabled)
- ipScramblingStateUseCase.internetPrivacyMode.map {
- _state.update { s -> s.copy(mode = it) }
- }
- else ipScramblingStateUseCase.configuredMode.map {
- _state.update { s ->
- s.copy(
- mode = if (it) InternetPrivacyMode.HIDE_IP
- else InternetPrivacyMode.REAL_IP
- )
- }
+ ipScramblingStateUseCase.internetPrivacyMode.map {
+ _state.update { s -> s.copy(mode = it) }
}
).collect {}
}
@@ -129,8 +117,6 @@ class InternetPrivacyViewModel(
is Action.UseHiddenIPAction -> actionUseHiddenIP()
is Action.ToggleAppIpScrambled -> actionToggleAppIpScrambled(action)
is Action.SelectLocationAction -> actionSelectLocation(action)
- is Action.CloseQuickPrivacyDisabledMessage ->
- getQuickPrivacyStateUseCase.resetQuickPrivacyDisabledMessage()
}
}
@@ -167,6 +153,5 @@ class InternetPrivacyViewModel(
object UseHiddenIPAction : Action()
data class ToggleAppIpScrambled(val packageName: String) : Action()
data class SelectLocationAction(val position: Int) : Action()
- object CloseQuickPrivacyDisabledMessage : Action()
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt
index 537d0b6e47d9b68b2f450663c71be48e494e3d1c..9e3f8541f6005cf8e7fb682ff85e8d77a5e4b7ec 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt
@@ -33,7 +33,6 @@ import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
-import com.google.android.material.snackbar.Snackbar
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import com.google.android.material.textfield.TextInputLayout.END_ICON_CUSTOM
@@ -52,7 +51,6 @@ import foundation.e.privacycentralapp.DependencyContainer
import foundation.e.privacycentralapp.PrivacyCentralApplication
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.common.NavToolbarFragment
-import foundation.e.privacycentralapp.common.initQuickPrivacySnackbar
import foundation.e.privacycentralapp.databinding.FragmentFakeLocationBinding
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.features.location.FakeLocationViewModel.Action
@@ -79,8 +77,6 @@ class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location)
private var mapboxMap: MapboxMap? = null
private var locationComponent: LocationComponent? = null
- private var qpDisabledSnackbar: Snackbar? = null
-
private var inputJob: Job? = null
private val locationPermissionRequest = registerForActivityResult(
@@ -147,10 +143,6 @@ class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location)
}
}
- qpDisabledSnackbar = initQuickPrivacySnackbar(binding.root) {
- viewModel.submitAction(Action.CloseQuickPrivacyDisabledMessage)
- }
-
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
render(viewModel.state.value)
@@ -266,9 +258,6 @@ class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location)
@SuppressLint("MissingPermission")
private fun render(state: FakeLocationState) {
- if (state.showQuickPrivacyDisabledMessage) qpDisabledSnackbar?.show()
- else qpDisabledSnackbar?.dismiss()
-
binding.radioUseRandomLocation.isChecked = state.mode == LocationMode.RANDOM_LOCATION
binding.radioUseSpecificLocation.isChecked = state.mode == LocationMode.SPECIFIC_LOCATION
@@ -379,7 +368,6 @@ class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location)
override fun onDestroyView() {
super.onDestroyView()
binding.mapView.onDestroy()
- qpDisabledSnackbar = null
mapboxMap = null
locationComponent = null
inputJob = null
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationState.kt
index 9513f7774a21ee81a869f7bd8de6b874894ff810..50d7a1451752e8756a9c68765b8747597404916b 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationState.kt
@@ -26,5 +26,4 @@ data class FakeLocationState(
val specificLatitude: Float? = null,
val specificLongitude: Float? = null,
val forceRefresh: Boolean = false,
- val showQuickPrivacyDisabledMessage: Boolean = false
)
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt
index 8db35377a2d0ea656667690dcc1053cac4c63759..1cdf9f466312e5934bf36e123ffeb1c0bddb6415 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt
@@ -66,9 +66,6 @@ class FakeLocationViewModel(
)
}
},
- getQuickPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map {
- _state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) }
- },
specificLocationInputFlow
.debounce(SET_SPECIFIC_LOCATION_DELAY).map { action ->
fakeLocationStateUseCase.setSpecificLocation(action.latitude, action.longitude)
@@ -96,8 +93,6 @@ class FakeLocationViewModel(
is Action.UseRandomLocationAction -> fakeLocationStateUseCase.setRandomLocation()
is Action.UseRealLocationAction ->
fakeLocationStateUseCase.stopFakeLocation()
- is Action.CloseQuickPrivacyDisabledMessage ->
- getQuickPrivacyStateUseCase.resetQuickPrivacyDisabledMessage()
}
}
@@ -127,6 +122,5 @@ class FakeLocationViewModel(
val latitude: Float,
val longitude: Float
) : Action()
- object CloseQuickPrivacyDisabledMessage : Action()
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
index 491f62517e606403683184a86fb6b27f9b20d279..8adf2560f13b252725004e180cb6a681cc5a85c2 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
@@ -28,14 +28,12 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
-import com.google.android.material.snackbar.Snackbar
import foundation.e.privacycentralapp.DependencyContainer
import foundation.e.privacycentralapp.PrivacyCentralApplication
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.common.AppsAdapter
import foundation.e.privacycentralapp.common.GraphHolder
import foundation.e.privacycentralapp.common.NavToolbarFragment
-import foundation.e.privacycentralapp.common.initQuickPrivacySnackbar
import foundation.e.privacycentralapp.common.setToolTipForAsterisk
import foundation.e.privacycentralapp.databinding.FragmentTrackersBinding
import foundation.e.privacycentralapp.databinding.TrackersItemGraphBinding
@@ -58,7 +56,6 @@ class TrackersFragment :
private var dayGraphHolder: GraphHolder? = null
private var monthGraphHolder: GraphHolder? = null
private var yearGraphHolder: GraphHolder? = null
- private var qpDisabledSnackbar: Snackbar? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
@@ -79,10 +76,6 @@ class TrackersFragment :
}
}
- qpDisabledSnackbar = initQuickPrivacySnackbar(binding.root) {
- viewModel.submitAction(TrackersViewModel.Action.CloseQuickPrivacyDisabledMessage)
- }
-
setToolTipForAsterisk(
textView = binding.trackersAppsListTitle,
textId = R.string.trackers_applist_title,
@@ -137,9 +130,6 @@ class TrackersFragment :
override fun getTitle() = getString(R.string.trackers_title)
private fun render(state: TrackersState) {
- if (state.showQuickPrivacyDisabledMessage) qpDisabledSnackbar?.show()
- else qpDisabledSnackbar?.dismiss()
-
state.dayStatistics?.let { renderGraph(it, dayGraphHolder!!, binding.graphDay) }
state.monthStatistics?.let { renderGraph(it, monthGraphHolder!!, binding.graphMonth) }
state.yearStatistics?.let { renderGraph(it, yearGraphHolder!!, binding.graphYear) }
@@ -171,7 +161,6 @@ class TrackersFragment :
override fun onDestroyView() {
super.onDestroyView()
- qpDisabledSnackbar = null
dayGraphHolder = null
monthGraphHolder = null
yearGraphHolder = null
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersState.kt
index 2437366bab1e528ba6c7a07a249b03e2e50e851a..a3bb80ae0bc4719f505c7f82b569765a199387fc 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersState.kt
@@ -25,5 +25,4 @@ data class TrackersState(
val monthStatistics: TrackersPeriodicStatistics? = null,
val yearStatistics: TrackersPeriodicStatistics? = null,
val apps: List? = null,
- val showQuickPrivacyDisabledMessage: Boolean = false
)
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
index 3869c3948b84625fb92f2e7198075e25611ecf26..07828f8754949db4d667d9c3dfc04d2f70cb1d9f 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
@@ -46,9 +46,6 @@ class TrackersViewModel(
suspend fun doOnStartedState() = withContext(Dispatchers.IO) {
merge(
- getQuickPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map {
- _state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) }
- },
trackersStatisticsUseCase.listenUpdates().map {
trackersStatisticsUseCase.getDayMonthYearStatistics()
.let { (day, month, year) ->
@@ -70,9 +67,6 @@ class TrackersViewModel(
fun submitAction(action: Action) = viewModelScope.launch {
when (action) {
is Action.ClickAppAction -> actionClickApp(action)
- is Action.CloseQuickPrivacyDisabledMessage -> {
- getQuickPrivacyStateUseCase.resetQuickPrivacyDisabledMessage()
- }
}
}
@@ -89,6 +83,5 @@ class TrackersViewModel(
sealed class Action {
data class ClickAppAction(val packageName: String) : Action()
- object CloseQuickPrivacyDisabledMessage : Action()
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt
index cd4f6b27243310bcaebd1e9036a9f7b13349166d..6aeac8ee124f8c5d1b0342517be5972329b57fa9 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt
@@ -34,7 +34,6 @@ import foundation.e.privacycentralapp.DependencyContainer
import foundation.e.privacycentralapp.PrivacyCentralApplication
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.common.NavToolbarFragment
-import foundation.e.privacycentralapp.common.initQuickPrivacySnackbar
import foundation.e.privacycentralapp.databinding.ApptrackersFragmentBinding
import kotlinx.coroutines.launch
@@ -63,8 +62,6 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
private var _binding: ApptrackersFragmentBinding? = null
private val binding get() = _binding!!
- private var qpDisabledSnackbar: Snackbar? = null
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (arguments == null ||
@@ -101,10 +98,6 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
)
}
- qpDisabledSnackbar = initQuickPrivacySnackbar(binding.root) {
- viewModel.submitAction(AppTrackersViewModel.Action.CloseQuickPrivacyDisabledMessage)
- }
-
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.singleEvents.collect { event ->
@@ -117,6 +110,12 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
} catch (e: ActivityNotFoundException) {
displayToast("No application to see webpages")
}
+ is AppTrackersViewModel.SingleEvent.ToastTrackersControlDisabled ->
+ Snackbar.make(
+ binding.root,
+ R.string.apptrackers_tracker_control_disabled_message,
+ Snackbar.LENGTH_LONG
+ ).show()
}
}
}
@@ -137,9 +136,6 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
}
private fun render(state: AppTrackersState) {
- if (state.showQuickPrivacyDisabledMessage) qpDisabledSnackbar?.show()
- else qpDisabledSnackbar?.dismiss()
-
binding.trackersCountSummary.text = if (state.getTrackersCount() == 0) ""
else getString(
R.string.apptrackers_trackers_count_summary,
@@ -176,7 +172,6 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
override fun onDestroyView() {
super.onDestroyView()
- qpDisabledSnackbar = null
_binding = null
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt
index d6d0858a46463ecd505f3ea27cab7d6cb5bd3096..80884433df26b1d4d1c9f27456e80d4eb1489885 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt
@@ -26,7 +26,7 @@ data class AppTrackersState(
val trackersWithWhiteList: List>? = null,
val leaked: Int = 0,
val blocked: Int = 0,
- val isQuickPrivacyEnabled: Boolean = false,
+ val isTrackersBlockingEnabled: Boolean = false,
val showQuickPrivacyDisabledMessage: Boolean = false,
) {
fun getTrackersStatus(): List>? {
@@ -34,7 +34,7 @@ data class AppTrackersState(
}
fun getTrackersCount() = trackersWithWhiteList?.size ?: 0
- fun getBlockedTrackersCount(): Int = if (isQuickPrivacyEnabled && isBlockingActivated)
+ fun getBlockedTrackersCount(): Int = if (isTrackersBlockingEnabled && isBlockingActivated)
trackersWithWhiteList?.count { !it.second } ?: 0
else 0
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt
index 52ef2c43f9d7b0e8e9ca1b93339897d5963a1431..1a3384498d8956a5f08a39bfac0cd08b8ed04def 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt
@@ -21,6 +21,7 @@ import android.net.Uri
import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import foundation.e.privacycentralapp.domain.entities.TrackerMode
import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.privacycentralapp.domain.usecases.TrackersStateUseCase
import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
@@ -66,11 +67,8 @@ class AppTrackersViewModel(
suspend fun doOnStartedState() = withContext(Dispatchers.IO) {
merge(
- getQuickPrivacyStateUseCase.quickPrivacyEnabledFlow.map {
- _state.update { s -> s.copy(isQuickPrivacyEnabled = it) }
- },
- getQuickPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map {
- _state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) }
+ getQuickPrivacyStateUseCase.trackerMode.map {
+ _state.update { s -> s.copy(isTrackersBlockingEnabled = it != TrackerMode.VULNERABLE) }
},
trackersStatisticsUseCase.listenUpdates().map { fetchStatistics() }
).collect { }
@@ -81,13 +79,14 @@ class AppTrackersViewModel(
is Action.BlockAllToggleAction -> blockAllToggleAction(action)
is Action.ToggleTrackerAction -> toggleTrackerAction(action)
is Action.ClickTracker -> actionClickTracker(action)
- is Action.CloseQuickPrivacyDisabledMessage ->
- getQuickPrivacyStateUseCase.resetQuickPrivacyDisabledMessage()
}
}
private suspend fun blockAllToggleAction(action: Action.BlockAllToggleAction) {
withContext(Dispatchers.IO) {
+ if (!state.value.isTrackersBlockingEnabled) {
+ _singleEvents.emit(SingleEvent.ToastTrackersControlDisabled)
+ }
trackersStateUseCase.toggleAppWhitelist(appUid, !action.isBlocked)
_state.update {
it.copy(
@@ -99,6 +98,10 @@ class AppTrackersViewModel(
private suspend fun toggleTrackerAction(action: Action.ToggleTrackerAction) {
withContext(Dispatchers.IO) {
+ if (!state.value.isTrackersBlockingEnabled) {
+ _singleEvents.emit(SingleEvent.ToastTrackersControlDisabled)
+ }
+
if (state.value.isBlockingActivated) {
trackersStateUseCase.blockTracker(appUid, action.tracker, action.isBlocked)
_state.update {
@@ -141,12 +144,12 @@ class AppTrackersViewModel(
sealed class SingleEvent {
data class ErrorEvent(@StringRes val errorResId: Int) : SingleEvent()
data class OpenUrl(val url: Uri) : SingleEvent()
+ object ToastTrackersControlDisabled : SingleEvent()
}
sealed class Action {
data class BlockAllToggleAction(val isBlocked: Boolean) : Action()
data class ToggleTrackerAction(val tracker: Tracker, val isBlocked: Boolean) : Action()
data class ClickTracker(val tracker: Tracker) : Action()
- object CloseQuickPrivacyDisabledMessage : Action()
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt b/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt
index 58ac797685f220a2d2f52848c7bc385b22184098..a81f5b5fc7996a1aea599854d9b506190a39bc84 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt
@@ -24,7 +24,6 @@ import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.add
import androidx.fragment.app.commit
-import foundation.e.privacycentralapp.PrivacyCentralApplication
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.features.dashboard.DashboardFragment
import foundation.e.privacycentralapp.features.trackers.TrackersFragment
@@ -37,11 +36,6 @@ open class MainActivity : FragmentActivity(R.layout.activity_main) {
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
-
- (application as? PrivacyCentralApplication)
- ?.dependencyContainer?.getQuickPrivacyStateUseCase
- ?.resetQuickPrivacyDisabledMessage()
-
handleIntent(intent)
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/widget/Widget.kt b/app/src/main/java/foundation/e/privacycentralapp/widget/Widget.kt
index ddfcc2e0e87d5e73aa011b660da02f89dadf0975..3abe21bc1a43dd95f27b3e42e1f063d97eb5f739 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/widget/Widget.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/widget/Widget.kt
@@ -85,14 +85,14 @@ class Widget : AppWidgetProvider() {
getPrivacyStateUseCase.quickPrivacyState,
getPrivacyStateUseCase.trackerMode,
getPrivacyStateUseCase.isLocationHidden,
- getPrivacyStateUseCase.isIpHidden,
- ) { quickPrivacyState, trackerMode, isLocationHidden, isIpHidden ->
+ getPrivacyStateUseCase.ipScramblingMode,
+ ) { quickPrivacyState, trackerMode, isLocationHidden, ipScramblingMode ->
State(
quickPrivacyState = quickPrivacyState,
trackerMode = trackerMode,
isLocationHidden = isLocationHidden,
- isIpHidden = isIpHidden
+ ipScramblingMode = ipScramblingMode
)
}.sample(50)
.combine(
diff --git a/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetCommandReceiver.kt b/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetCommandReceiver.kt
index 831c06f9f147fc2880cdeac856de9394e66036f8..4a103e0365629e0ed8783883a148f4190d39c9d6 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetCommandReceiver.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetCommandReceiver.kt
@@ -26,10 +26,13 @@ import foundation.e.privacycentralapp.R
class WidgetCommandReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
- val privacyCentralApplication = (context?.applicationContext as? PrivacyCentralApplication)
+ val getQuickPrivacyStateUseCase = (context?.applicationContext as? PrivacyCentralApplication)?.dependencyContainer?.getQuickPrivacyStateUseCase
+
when (intent?.action) {
- ACTION_TOGGLE_PRIVACY -> {
- if (privacyCentralApplication?.dependencyContainer?.getQuickPrivacyStateUseCase?.toggleReturnIsFirstActivation() == true) {
+ ACTION_TOGGLE_TRACKERS -> getQuickPrivacyStateUseCase?.toggleTrackers()
+ ACTION_TOGGLE_LOCATION -> getQuickPrivacyStateUseCase?.toggleLocation()
+ ACTION_TOGGLE_IPSCRAMBLING -> {
+ if (getQuickPrivacyStateUseCase?.toggleIpScramblingIsFirstActivation() == true) {
Toast.makeText(
context,
context.getString(R.string.dashboard_first_ipscrambling_activation),
@@ -42,6 +45,8 @@ class WidgetCommandReceiver : BroadcastReceiver() {
}
companion object {
- const val ACTION_TOGGLE_PRIVACY = "toggle_privacy"
+ const val ACTION_TOGGLE_TRACKERS = "toggle_trackers"
+ const val ACTION_TOGGLE_LOCATION = "toggle_location"
+ const val ACTION_TOGGLE_IPSCRAMBLING = "toggle_ipscrambling"
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt b/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt
index 682e5cc44710200053320c685f7125fac1b6372b..4fdbb039364324799ddb85ea6f9dc6ba96da55dc 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt
@@ -30,16 +30,19 @@ import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.Widget
import foundation.e.privacycentralapp.Widget.Companion.isDarkText
import foundation.e.privacycentralapp.common.extensions.dpToPxF
+import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.domain.entities.QuickPrivacyState
import foundation.e.privacycentralapp.domain.entities.TrackerMode
import foundation.e.privacycentralapp.main.MainActivity
-import foundation.e.privacycentralapp.widget.WidgetCommandReceiver.Companion.ACTION_TOGGLE_PRIVACY
+import foundation.e.privacycentralapp.widget.WidgetCommandReceiver.Companion.ACTION_TOGGLE_IPSCRAMBLING
+import foundation.e.privacycentralapp.widget.WidgetCommandReceiver.Companion.ACTION_TOGGLE_LOCATION
+import foundation.e.privacycentralapp.widget.WidgetCommandReceiver.Companion.ACTION_TOGGLE_TRACKERS
data class State(
val quickPrivacyState: QuickPrivacyState = QuickPrivacyState.DISABLED,
val trackerMode: TrackerMode = TrackerMode.VULNERABLE,
val isLocationHidden: Boolean = false,
- val isIpHidden: Boolean? = false,
+ val ipScramblingMode: InternetPrivacyMode = InternetPrivacyMode.REAL_IP_LOADING,
val dayStatistics: List> = emptyList(),
val activeTrackersCount: Int = 0,
)
@@ -71,19 +74,21 @@ fun render(
}
)
)
+
setImageViewResource(
- R.id.toggle_privacy_central,
- if (state.quickPrivacyState.isEnabled()) R.drawable.ic_switch_enabled
- else R.drawable.ic_switch_disabled
+ R.id.toggle_trackers,
+ if (state.trackerMode == TrackerMode.VULNERABLE)
+ R.drawable.ic_switch_disabled
+ else R.drawable.ic_switch_enabled
)
setOnClickPendingIntent(
- R.id.toggle_privacy_central,
+ R.id.toggle_trackers,
PendingIntent.getBroadcast(
context,
- REQUEST_CODE_TOGGLE,
+ REQUEST_CODE_TOGGLE_TRACKERS,
Intent(context, WidgetCommandReceiver::class.java).apply {
- action = ACTION_TOGGLE_PRIVACY
+ action = ACTION_TOGGLE_TRACKERS
},
FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
)
@@ -100,6 +105,24 @@ fun render(
)
)
+ setImageViewResource(
+ R.id.toggle_location,
+ if (state.isLocationHidden) R.drawable.ic_switch_enabled
+ else R.drawable.ic_switch_disabled
+ )
+
+ setOnClickPendingIntent(
+ R.id.toggle_location,
+ PendingIntent.getBroadcast(
+ context,
+ REQUEST_CODE_TOGGLE_LOCATION,
+ Intent(context, WidgetCommandReceiver::class.java).apply {
+ action = ACTION_TOGGLE_LOCATION
+ },
+ FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
+ )
+ )
+
setTextViewText(
R.id.state_geolocation,
context.getString(
@@ -108,15 +131,33 @@ fun render(
)
)
+ setImageViewResource(
+ R.id.toggle_ipscrambling,
+ if (state.ipScramblingMode.isChecked) R.drawable.ic_switch_enabled
+ else R.drawable.ic_switch_disabled
+ )
+
+ setOnClickPendingIntent(
+ R.id.toggle_ipscrambling,
+ PendingIntent.getBroadcast(
+ context,
+ REQUEST_CODE_TOGGLE_IPSCRAMBLING,
+ Intent(context, WidgetCommandReceiver::class.java).apply {
+ action = ACTION_TOGGLE_IPSCRAMBLING
+ },
+ FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
+ )
+ )
+
setTextViewText(
R.id.state_ip_address,
context.getString(
- if (state.isIpHidden == true) R.string.widget_state_ipaddress_on
+ if (state.ipScramblingMode == InternetPrivacyMode.HIDE_IP) R.string.widget_state_ipaddress_on
else R.string.widget_state_ipaddress_off
)
)
- val loading = state.isIpHidden == null
+ val loading = state.ipScramblingMode.isLoading
setViewVisibility(R.id.state_ip_address, if (loading) View.GONE else View.VISIBLE)
@@ -265,8 +306,10 @@ private val leakedBarIds = listOf(
)
private const val REQUEST_CODE_DASHBOARD = 1
-private const val REQUEST_CODE_TOGGLE = 2
private const val REQUEST_CODE_TRACKERS = 3
+private const val REQUEST_CODE_TOGGLE_TRACKERS = 4
+private const val REQUEST_CODE_TOGGLE_LOCATION = 5
+private const val REQUEST_CODE_TOGGLE_IPSCRAMBLING = 6
private const val REQUEST_CODE_HIGHLIGHT = 100
fun applyDarkText(context: Context, state: State, views: RemoteViews) {
diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml
index 8b8792b4700727b8faf619b8d96331c47438a461..cedf56909c13d40e44d9a90ba14235e50192f0dd 100644
--- a/app/src/main/res/layout/fragment_dashboard.xml
+++ b/app/src/main/res/layout/fragment_dashboard.xml
@@ -42,12 +42,6 @@
android:textSize="14sp"
android:textColor="@color/secondary_text"
/>
-
+
+
+
+
diff --git a/app/src/main/res/layout/widget.xml b/app/src/main/res/layout/widget.xml
index 60cbffaedc7ad9fcb16b207783e9bc5465aa31c1..1e78bc7556b3a5f0e782c19df26d4c1b216cee2e 100644
--- a/app/src/main/res/layout/widget.xml
+++ b/app/src/main/res/layout/widget.xml
@@ -72,13 +72,6 @@
android:textSize="12sp"
android:textColor="@color/on_primary_medium_emphasis"
/>
-
-
+
+
+
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index cda8aa82483cb957a897af4833d03be4d0cbcd72..ea0bacd4c404179e5affb37a57df132bc8f7a966 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -1,12 +1,12 @@
Dein Online-Datenschutz ist nicht gewährleistet
- Tracker (Verfolger):
+ Tracker (Verfolger)
Verletzlich
Abgelehnt
- Standort:
+ Standort
Verschleiert
- Echte IP-Adresse:
+ Echte IP-Adresse
Verschleiert
Datenlecks (Nutzerdaten):
Heute
@@ -110,7 +110,6 @@
Tippe auf die Balken für weitere Informationen.
Tippe, um herauszufinden, wie Tracker einfach blockiert, dein Standort gefälscht und deine IP-Adresse verschleiert werden kann.
Benutzerdefinierte Datenschutz-Einstellungen werden angewendet
- Die Änderungen werden erst beim Aktivieren des Datenschutz-Schalters angewandt.
Schließen
Das Verschleiern deiner IP wird möglicherweise die Internetgeschwindigkeit verlangsamen.
Benutzerdefinierte Datenschutz-Einstellungen werden angewandt
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 9cbe21c135ed630181ed9380df4d93ce96c27c8b..213a9d7bbb51cb9022be1b7bd90eab4d2f57b68b 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -1,12 +1,12 @@
- Rastreadores:
+ Rastreadores
Vulnerable
Denegado
- Ubicación:
+ Ubicación
Expuesto
Falso
- Direccion IP real:
+ Direccion IP real
Expuesto
Oculto
Filtración de datos personales
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 0964d3f04b4cf6bcbb9e5208b10fc7eac822a633..b5932de4ce8a8847d615b9ba8e0cf81e6bc0efb2 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -90,17 +90,16 @@
Henkilötietojen vuoto:
Piilotettu
Paljastettu
- Todellinen IP-osoite:
+ Todellinen IP-osoite
Väärennetty
Paljastettu
- Sijainti:
+ Sijainti
Estetty
Haavoittuvainen
- Seuraimet:
+ Seuraimet
Sovelletaan mukautettuja yksityisyysasetuksia
Yksityisyytesi verkossa on suojattu
Sulje
- Muutokset tulevat voimaan vain, kun yksityisyydensuojan kytkin on käytössä.
Napauta palkkeja saadaksesi lisätietoja.
Sallittuja tietovuotoja
Estettyjä tietovuotoja
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 628cff32aee2a0f17bd8515157ba56d68181318a..b4db80f6108cf093a8d22fe68df7f7fc0b04914d 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -2,13 +2,13 @@
Votre vie privée en ligne est protégée
Votre vie privée en ligne n\'est pas protégée
- Trackers :
+ Trackers
Vulnérable
Refusé
- Localisation :
+ Localisation
Exposé
Faux
- Adresse IP réelle :
+ Adresse IP réelle
Exposé
Fuite de données personnelles :
Aujourd\'hui
@@ -96,7 +96,6 @@
- Tous les pisteurs sont désactivés.
\n- Votre géolocalisation sera falsifiée.
\n- Votre adresse IP réelle sera masquée.
- Les modifications seront effectives uniquement quand la protection de la confidentialité sera activée.
Votre vitesse Internet risque d\'être réduite tant que votre adresse IP est masquée.
Fuites autorisées
Fuites bloquées
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 9f8d02d343d5d692137c101288c79e0c8eb3b4a5..316aa4f8a82e0b7697e01e53cde802a6aee77e3d 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -1,13 +1,13 @@
La tua privacy online non è protetta
- Tracker:
+ Tracker
Vulnerabile
Negato
- Posizione:
+ Posizione
Esposta
Fasulla
- Indirizzo IP reale:
+ Indirizzo IP reale
Esposto
Nascosto
Fuga di dati personali:
@@ -110,7 +110,6 @@
Guarda
Impostazioni della privacy personalizzate applicate
Chiudi
- I cambiamenti avranno efficacia solo dopo l\'abilitazione del pulsante protezione privacy.
Tocca le barre per maggiori informazioni.
Perdite di dati ammesse
Perdite di dati bloccate
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8705ac5065a560328a7a8fa8c64c2b10f2fa2a49..a4d1040c4f0df709dab1efe0af5f065d77dfe31f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -8,21 +8,20 @@
Blocked leaks
Allowed leaks
Tap on the bars for more information.
- Changes will only be effective when privacy protection toggle is enabled.
Close
@string/app_name
Your online privacy is protected
Your online privacy is unprotected
Custom privacy settings applied
- Trackers:
+ Trackers
Vulnerable
Denied
Custom
- Location:
+ Location
Exposed
Fake
- Real IP address:
+ Real IP address
Exposed
Hidden
Personal data leakage:
@@ -87,6 +86,7 @@
Enable Quick Privacy to be able to activate/deactivate trackers.
%1$d blocked trackers out of %2$d detected trackers, %3$d blocked leaks and %4$d allowed leaks.
App not installed.
+ Changes will take effect when tracker blocker is on.
Quick protection enables these settings when turned on
- All trackers are turned off.\n- Your geolocation will be faked.\n- Your real IP address will be hidden.