From 10564e2605d03a23fcc1b3728502bd5ffd77cc74 Mon Sep 17 00:00:00 2001 From: jacquarg Date: Mon, 29 Nov 2021 09:40:42 +0100 Subject: Fix crashes on ipScrambling screen, avoid useless settings toggles. --- .../privacycentralapp/common/ToggleAppsAdapter.kt | 6 +-- .../domain/usecases/AppListUseCase.kt | 13 ++--- .../internetprivacy/InternetPrivacyFeature.kt | 39 +++++++-------- .../internetprivacy/InternetPrivacyFragment.kt | 55 ++++++++++------------ .../internetprivacy/InternetPrivacyViewModel.kt | 5 +- 5 files changed, 54 insertions(+), 64 deletions(-) (limited to 'app/src') diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/ToggleAppsAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/common/ToggleAppsAdapter.kt index 1817a0d..82f8d43 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/common/ToggleAppsAdapter.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/common/ToggleAppsAdapter.kt @@ -29,7 +29,7 @@ import foundation.e.privacymodules.permissions.data.ApplicationDescription class ToggleAppsAdapter( private val itemsLayout: Int, - private val listener: (String, Boolean) -> Unit + private val listener: (String) -> Unit ) : RecyclerView.Adapter() { @@ -56,8 +56,8 @@ class ToggleAppsAdapter( val view = LayoutInflater.from(parent.context) .inflate(itemsLayout, parent, false) val holder = ViewHolder(view) - holder.togglePermission.setOnCheckedChangeListener { _, isChecked -> - listener(dataSet[holder.adapterPosition].first.packageName, isChecked) + holder.togglePermission.setOnClickListener { + listener(dataSet[holder.adapterPosition].first.packageName) } return holder } diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/AppListUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/AppListUseCase.kt index a72360e..e44aa76 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/AppListUseCase.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/AppListUseCase.kt @@ -33,25 +33,18 @@ class AppListUseCase( ) { private val _appsUsingInternet = MutableStateFlow>(emptyList()) - private val _installedAppsUsingInternet = MutableStateFlow>(emptyList()) + private val _appsBlockableTrackers = MutableStateFlow>(emptyList()) init { corouteineScope.launch { _appsUsingInternet.value = getAppsUsingInternetList() } } - fun getInstalledAppsUsingInternet(): Flow> { - corouteineScope.launch { - _installedAppsUsingInternet.value = getInstalledAppsUsingInternetList() - } - return _installedAppsUsingInternet - } - fun getBlockableApps(): Flow> { corouteineScope.launch { - _installedAppsUsingInternet.value = getBlockableAppsList() + _appsBlockableTrackers.value = getBlockableAppsList() } - return _installedAppsUsingInternet + return _appsBlockableTrackers } private fun getBlockableAppsList(): List { diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt index 183e400..767ac7a 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt @@ -33,7 +33,6 @@ import foundation.e.privacymodules.permissions.data.ApplicationDescription import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map @@ -80,7 +79,7 @@ class InternetPrivacyFeature( object UseRealIPAction : Action() object UseHiddenIPAction : Action() data class AndroidVpnActivityResultAction(val resultCode: Int) : Action() - data class ToggleAppIpScrambled(val packageName: String, val isIpScrambled: Boolean) : Action() + data class ToggleAppIpScrambled(val packageName: String) : Action() data class SelectLocationAction(val position: Int) : Action() } @@ -96,24 +95,24 @@ class InternetPrivacyFeature( val ipScrambledApps: Collection ) : Effect() data class LocationSelectedEffect(val locationId: String) : Effect() - data class AvailableCountriesEffect(val availableLocationsIds: List) : Effect() data class ErrorEffect(val message: String) : Effect() } companion object { fun create( + coroutineScope: CoroutineScope, + ipScramblerModule: IIpScramblerModule, + getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase, + ipScramblingStateUseCase: IpScramblingStateUseCase, + appListUseCase: AppListUseCase, + availablesLocationsIds: List, initialState: State = State( mode = InternetPrivacyMode.REAL_IP, availableApps = emptyList(), ipScrambledApps = emptyList(), - availableLocationIds = emptyList(), + availableLocationIds = availablesLocationsIds, selectedLocation = "" - ), - coroutineScope: CoroutineScope, - ipScramblerModule: IIpScramblerModule, - getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase, - ipScramblingStateUseCase: IpScramblingStateUseCase, - appListUseCase: AppListUseCase + ) ) = InternetPrivacyFeature( initialState, coroutineScope, reducer = { state, effect -> @@ -124,7 +123,6 @@ class InternetPrivacyFeature( availableApps = effect.apps, ipScrambledApps = effect.ipScrambledApps ) - is Effect.AvailableCountriesEffect -> state.copy(availableLocationIds = effect.availableLocationsIds) is Effect.LocationSelectedEffect -> state.copy(selectedLocation = effect.locationId) Effect.QuickPrivacyDisabledWarningEffect -> state.copy(forceRedraw = !state.forceRedraw) else -> state @@ -145,11 +143,6 @@ class InternetPrivacyFeature( ipScramblerModule.appList ) }, - flow { - val locationIds = mutableListOf("") - locationIds.addAll(ipScramblerModule.getAvailablesLocations().sorted()) - emit(Effect.AvailableCountriesEffect(locationIds)) - }, flowOf(Effect.LocationSelectedEffect(ipScramblerModule.exitCountry)) ).flowOn(Dispatchers.Default) action is Action.AndroidVpnActivityResultAction -> @@ -196,18 +189,22 @@ class InternetPrivacyFeature( action is Action.ToggleAppIpScrambled -> { val ipScrambledApps = mutableSetOf() ipScrambledApps.addAll(ipScramblerModule.appList) - if (action.isIpScrambled) { - ipScrambledApps.add(action.packageName) - } else { + if (ipScrambledApps.contains(action.packageName)) { ipScrambledApps.remove(action.packageName) + } else { + ipScrambledApps.add(action.packageName) } ipScramblerModule.appList = ipScrambledApps flowOf(Effect.IpScrambledAppsUpdatedEffect(ipScrambledApps = ipScrambledApps)) } action is Action.SelectLocationAction -> { val locationId = state.availableLocationIds[action.position] - ipScramblerModule.exitCountry = locationId - flowOf(Effect.LocationSelectedEffect(locationId)) + if (locationId != ipScramblerModule.exitCountry) { + ipScramblerModule.exitCountry = locationId + flowOf(Effect.LocationSelectedEffect(locationId)) + } else { + flowOf(Effect.NoEffect) + } } else -> flowOf(Effect.NoEffect) } 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 135b563..3e0b549 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 @@ -91,12 +91,9 @@ class InternetPrivacyFragment : binding.apps.apply { layoutManager = LinearLayoutManager(requireContext()) setHasFixedSize(true) - adapter = ToggleAppsAdapter(R.layout.ipscrambling_item_app_toggle) { packageName, isIpScrambled -> + adapter = ToggleAppsAdapter(R.layout.ipscrambling_item_app_toggle) { packageName -> viewModel.submitAction( - InternetPrivacyFeature.Action.ToggleAppIpScrambled( - packageName, - isIpScrambled - ) + InternetPrivacyFeature.Action.ToggleAppIpScrambled(packageName) ) } } @@ -109,6 +106,29 @@ class InternetPrivacyFragment : viewModel.submitAction(InternetPrivacyFeature.Action.UseHiddenIPAction) } + binding.ipscramblingSelectLocation.apply { + adapter = ArrayAdapter( + requireContext(), android.R.layout.simple_spinner_item, + viewModel.availablesLocationsIds.map { + if (it == "") { + getString(R.string.ipscrambling_any_location) + } else { + Locale("", it).displayCountry + } + } + ).apply { + setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + } + + onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(parentView: AdapterView<*>, selectedItemView: View?, position: Int, id: Long) { + viewModel.submitAction(InternetPrivacyFeature.Action.SelectLocationAction(position)) + } + + override fun onNothingSelected(parentView: AdapterView<*>?) {} + } + } + binding.executePendingBindings() } @@ -131,30 +151,7 @@ class InternetPrivacyFragment : isEnabled = state.mode != InternetPrivacyMode.REAL_IP_LOADING } - binding.ipscramblingSelectLocation.apply { - adapter = ArrayAdapter( - requireContext(), android.R.layout.simple_spinner_item, - state.availableLocationIds.map { - if (it == "") { - getString(R.string.ipscrambling_any_location) - } else { - Locale("", it).displayCountry - } - } - ).apply { - setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - } - - setOnItemSelectedListener(object : AdapterView.OnItemSelectedListener { - override fun onItemSelected(parentView: AdapterView<*>, selectedItemView: View?, position: Int, id: Long) { - viewModel.submitAction(InternetPrivacyFeature.Action.SelectLocationAction(position)) - } - - override fun onNothingSelected(parentView: AdapterView<*>?) {} - }) - - setSelection(state.selectedLocationPosition) - } + binding.ipscramblingSelectLocation.setSelection(state.selectedLocationPosition) // TODO: this should not be mandatory. binding.apps.post { 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 2ffa92e..08da69e 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 @@ -38,13 +38,16 @@ class InternetPrivacyViewModel( private val _actions = MutableSharedFlow() val actions = _actions.asSharedFlow() + val availablesLocationsIds = listOf("", *ipScramblerModule.getAvailablesLocations().sorted().toTypedArray()) + val internetPrivacyFeature: InternetPrivacyFeature by lazy { InternetPrivacyFeature.create( coroutineScope = viewModelScope, ipScramblerModule = ipScramblerModule, getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase, ipScramblingStateUseCase = ipScramblingStateUseCase, - appListUseCase = appListUseCase + appListUseCase = appListUseCase, + availablesLocationsIds = availablesLocationsIds ) } -- cgit v1.2.1