aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/foundation/e/privacycentralapp/features
diff options
context:
space:
mode:
authorjacquarg <guillaume.jacquart@hoodbrains.com>2022-04-25 08:56:18 +0200
committerjacquarg <guillaume.jacquart@hoodbrains.com>2022-05-04 19:03:10 +0200
commit730c2bc7566c03a9774509ab35bbbbca578ecf72 (patch)
tree690e7e57530892fe5a31e12eb8f671d65d3139d2 /app/src/main/java/foundation/e/privacycentralapp/features
parentfa5d60f99a07911a13c579074affd646973655b6 (diff)
downloadadvanced-privacy-730c2bc7566c03a9774509ab35bbbbca578ecf72.tar.gz
219 highlight active trackers
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp/features')
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt60
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt13
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt1
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt28
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt4
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