diff options
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp/features')
5 files changed, 71 insertions, 35 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt index 3ed3168..5192229 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt @@ -27,6 +27,7 @@ import foundation.e.privacycentralapp.domain.entities.LocationMode import foundation.e.privacycentralapp.domain.entities.QuickPrivacyState import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase +import foundation.e.privacymodules.permissions.data.ApplicationDescription import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf @@ -66,6 +67,7 @@ class DashboardFeature( object NavigateToInternetActivityPrivacySingleEvent : SingleEvent() object NavigateToLocationSingleEvent : SingleEvent() object NavigateToPermissionsSingleEvent : SingleEvent() + data class NavigateToAppDetailsEvent(val appDesc: ApplicationDescription) : SingleEvent() object NewStatisticsAvailableSingleEvent : SingleEvent() data class ToastMessageSingleEvent(val message: Int) : SingleEvent() } @@ -79,6 +81,7 @@ class DashboardFeature( object ShowTrackers : Action() object FetchStatistics : Action() object CloseQuickPrivacyDisabledMessage : Action() + object ShowMostLeakedApp : Action() } sealed class Effect { @@ -102,6 +105,7 @@ class DashboardFeature( object FirstIPTrackerActivationEffect : Effect() data class LocationHiddenUpdatedEffect(val isLocationHidden: Boolean) : Effect() data class ShowQuickPrivacyDisabledMessageEffect(val show: Boolean) : Effect() + data class OpenAppDetailsEffect(val appDesc: ApplicationDescription) : Effect() } companion object { @@ -146,29 +150,32 @@ class DashboardFeature( } } - Action.InitAction -> merge( - getPrivacyStateUseCase.quickPrivacyState.map { - Effect.UpdateStateEffect(it) - }, - getPrivacyStateUseCase.isIpHidden.map { - Effect.IpScramblingModeUpdatedEffect(it) - }, - trackersStatisticsUseCase.listenUpdates().map { - Effect.NewStatisticsAvailablesEffect - }, - getPrivacyStateUseCase.isTrackersDenied.map { - Effect.TrackersBlockedUpdatedEffect(it) - }, - getPrivacyStateUseCase.isLocationHidden.map { - Effect.LocationHiddenUpdatedEffect(it) - }, - getPrivacyStateUseCase.locationMode.map { - Effect.UpdateLocationModeEffect(it) - }, - getPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map { - Effect.ShowQuickPrivacyDisabledMessageEffect(it) - }, - ) + Action.InitAction -> { + trackersStatisticsUseCase.initAppList() + merge( + getPrivacyStateUseCase.quickPrivacyState.map { + Effect.UpdateStateEffect(it) + }, + getPrivacyStateUseCase.isIpHidden.map { + Effect.IpScramblingModeUpdatedEffect(it) + }, + trackersStatisticsUseCase.listenUpdates().map { + Effect.NewStatisticsAvailablesEffect + }, + getPrivacyStateUseCase.isTrackersDenied.map { + Effect.TrackersBlockedUpdatedEffect(it) + }, + getPrivacyStateUseCase.isLocationHidden.map { + Effect.LocationHiddenUpdatedEffect(it) + }, + getPrivacyStateUseCase.locationMode.map { + Effect.UpdateLocationModeEffect(it) + }, + getPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map { + Effect.ShowQuickPrivacyDisabledMessageEffect(it) + }, + ) + } Action.ShowFakeMyLocationAction -> flowOf(Effect.OpenFakeMyLocationEffect) Action.ShowAppsPermissions -> flowOf(Effect.OpenAppsPermissionsEffect) Action.ShowInternetActivityPrivacyAction -> flowOf( @@ -193,6 +200,12 @@ class DashboardFeature( getPrivacyStateUseCase.resetQuickPrivacyDisabledMessage() flowOf(Effect.NoEffect) } + is Action.ShowMostLeakedApp -> { + Log.d("mostleak", "Action.ShowMostLeakedApp") + flowOf( + trackersStatisticsUseCase.getMostLeakedApp()?.let { Effect.OpenAppDetailsEffect(appDesc = it) } ?: Effect.NoEffect + ) + } } }, singleEventProducer = { _, _, effect -> @@ -211,6 +224,7 @@ class DashboardFeature( SingleEvent.ToastMessageSingleEvent( message = R.string.dashboard_first_ipscrambling_activation ) + is Effect.OpenAppDetailsEffect -> SingleEvent.NavigateToAppDetailsEvent(effect.appDesc) else -> null } } 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 3f849a6..398a594 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 @@ -46,6 +46,7 @@ import foundation.e.privacycentralapp.features.dashboard.DashboardFeature.State import foundation.e.privacycentralapp.features.internetprivacy.InternetPrivacyFragment import foundation.e.privacycentralapp.features.location.FakeLocationFragment import foundation.e.privacycentralapp.features.trackers.TrackersFragment +import foundation.e.privacycentralapp.features.trackers.apptrackers.AppTrackersFragment import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.Job import kotlinx.coroutines.flow.Flow @@ -118,6 +119,13 @@ class DashboardFragment : addToBackStack("dashboard") } } + is DashboardFeature.SingleEvent.NavigateToAppDetailsEvent -> { + requireActivity().supportFragmentManager.commit { + replace<AppTrackersFragment>(R.id.container, args = AppTrackersFragment.buildArgs(event.appDesc.label.toString(), event.appDesc.packageName)) + setReorderingAllowed(true) + addToBackStack("dashboard") + } + } DashboardFeature.SingleEvent.NewStatisticsAvailableSingleEvent -> { viewModel.submitAction(DashboardFeature.Action.FetchStatistics) } @@ -138,6 +146,9 @@ class DashboardFragment : graphHolder = GraphHolder(binding.graph, requireContext()) + binding.leakingAppButton.setOnClickListener { + viewModel.submitAction(DashboardFeature.Action.ShowMostLeakedApp) + } binding.togglePrivacyCentral.setOnClickListener { viewModel.submitAction(DashboardFeature.Action.TogglePrivacyAction) } @@ -247,10 +258,12 @@ class DashboardFragment : if (state.dayStatistics?.all { it.first == 0 && it.second == 0 } == true) { binding.graph.visibility = View.INVISIBLE binding.graphLegend.isVisible = false + binding.leakingAppButton.isVisible = false binding.graphEmpty.isVisible = true } else { binding.graph.isVisible = true binding.graphLegend.isVisible = true + binding.leakingAppButton.isVisible = true binding.graphEmpty.isVisible = false state.dayStatistics?.let { graphHolder.data = it } state.dayLabels?.let { graphHolder.labels = it } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt index 34ddfbe..25443e9 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt @@ -109,7 +109,6 @@ class TrackersFeature( actor = { state, action -> when (action) { Action.InitAction -> merge<Effect>( - flowOf(Effect.NewStatisticsAvailablesEffect), trackersStatisticsUseCase.listenUpdates().map { Effect.NewStatisticsAvailablesEffect }, diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt index ad82337..f6d7d67 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt @@ -55,8 +55,10 @@ class AppTrackersFeature( val isBlockingActivated: Boolean = false, val trackers: List<Tracker>? = null, val whitelist: List<String>? = null, + val leaked: Int = 0, + val blocked: Int = 0, val isQuickPrivacyEnabled: Boolean = false, - val showQuickPrivacyDisabledMessage: Boolean = false + val showQuickPrivacyDisabledMessage: Boolean = false, ) { fun getTrackersStatus(): List<Pair<Tracker, Boolean>>? { if (trackers != null && whitelist != null) { @@ -92,7 +94,11 @@ class AppTrackersFeature( data class ErrorEffect(val message: Any) : Effect() data class SetAppEffect(val appDesc: ApplicationDescription) : Effect() data class AppTrackersBlockingActivatedEffect(val isBlockingActivated: Boolean) : Effect() - data class AvailableTrackersListEffect(val trackers: List<Tracker>) : Effect() + data class AvailableTrackersListEffect( + val trackers: List<Tracker>, + val blocked: Int, + val leaked: Int + ) : Effect() data class TrackersWhitelistUpdateEffect(val whitelist: List<String>) : Effect() object NewStatisticsAvailablesEffect : Effect() data class QuickPrivacyUpdatedEffect(val enabled: Boolean) : Effect() @@ -114,7 +120,11 @@ class AppTrackersFeature( reducer = { state, effect -> when (effect) { is Effect.SetAppEffect -> state.copy(appDesc = effect.appDesc) - is Effect.AvailableTrackersListEffect -> state.copy(trackers = effect.trackers) + is Effect.AvailableTrackersListEffect -> state.copy( + trackers = effect.trackers, + leaked = effect.leaked, + blocked = effect.blocked + ) is Effect.AppTrackersBlockingActivatedEffect -> state.copy(isBlockingActivated = effect.isBlockingActivated) @@ -135,7 +145,6 @@ class AppTrackersFeature( .getApplicationDescription(action.packageName)?.let { appDesc -> merge<Effect>( flow { - emit(Effect.SetAppEffect(appDesc)) emit( Effect.AppTrackersBlockingActivatedEffect( @@ -147,11 +156,6 @@ class AppTrackersFeature( trackersStateUseCase.getTrackersWhitelistIds(appDesc.uid) ) ) - emit( - Effect.AvailableTrackersListEffect( - trackers = trackersStatisticsUseCase.getTrackers(appDesc.uid) - ) - ) }, trackersStatisticsUseCase.listenUpdates().map { Effect.NewStatisticsAvailablesEffect @@ -208,8 +212,12 @@ class AppTrackersFeature( } is Action.FetchStatistics -> flowOf( state.appDesc?.uid?.let { + val (blocked, leaked) = trackersStatisticsUseCase.getCalls(it) + Effect.AvailableTrackersListEffect( - trackers = trackersStatisticsUseCase.getTrackers(it) + trackers = trackersStatisticsUseCase.getTrackers(it), + leaked = leaked, + blocked = blocked, ) } ?: Effect.ErrorEffect("No appDesc.") ) 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 7e606af..406d26c 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 @@ -143,7 +143,9 @@ class AppTrackersFragment : else getString( R.string.apptrackers_trackers_count_summary, state.getBlockedTrackersCount(), - state.getTrackersCount() + state.getTrackersCount(), + state.blocked, + state.leaked ) binding.blockAllToggle.isChecked = state.isBlockingActivated |