diff options
| author | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2022-11-18 07:21:50 +0000 |
|---|---|---|
| committer | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2022-11-18 07:21:50 +0000 |
| commit | 84bdb74c79a41c90d4d374bf5eb963191de3e7b3 (patch) | |
| tree | 1b81bc5228aa8c722ca8df289cd9f93c2104522f /app/src/main/java/foundation/e/privacycentralapp/features | |
| parent | 82e1bee1454fe5f8bc6653344da76b35f1d3d8a3 (diff) | |
| parent | 2ee502ad3dbfd42c09a88212f5bd179fc531e2e6 (diff) | |
| download | advanced-privacy-84bdb74c79a41c90d4d374bf5eb963191de3e7b3.tar.gz | |
Merge branch '568-individuals_activation_buttons' into 'main'
568: individuals buttons to activate trackers control, fake location and Hide my ip
See merge request e/os/advanced-privacy!102
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp/features')
15 files changed, 56 insertions, 123 deletions
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 6cd259e..8a0a3d4 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 04b7ae8..937fa22 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<Pair<Int, Int>>? = null, val dayLabels: List<String>? = 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 d7d74c6..57e7790 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 99aa217..afef986 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 6991196..54b7e01 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<String> = emptyList(), val forceRedraw: Boolean = false, - val showQuickPrivacyDisabledMessage: Boolean = false ) { fun getApps(): List<Pair<ApplicationDescription, Boolean>> { 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 be6cd4d..bbd6239 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 537d0b6..9e3f854 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 9513f77..50d7a14 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 8db3537..1cdf9f4 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 491f625..8adf256 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 2437366..a3bb80a 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<AppWithCounts>? = 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 3869c39..07828f8 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 cd4f6b2..6aeac8e 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 d6d0858..8088443 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<Pair<Tracker, Boolean>>? = null, val leaked: Int = 0, val blocked: Int = 0, - val isQuickPrivacyEnabled: Boolean = false, + val isTrackersBlockingEnabled: Boolean = false, val showQuickPrivacyDisabledMessage: Boolean = false, ) { fun getTrackersStatus(): List<Pair<Tracker, Boolean>>? { @@ -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 52ef2c4..1a33844 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() } } |
