aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/foundation/e/privacycentralapp/features
diff options
context:
space:
mode:
authorGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2022-02-24 07:27:53 +0000
committerGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2022-02-24 07:27:53 +0000
commitac0f57662d5c953f73c0561edc11e0ae8c9a0404 (patch)
tree08cdf919a7d8c30b257cd58e73d57cbfe7c702dc /app/src/main/java/foundation/e/privacycentralapp/features
parenta80f529d4b14a6820cf2b7d47b1087e9d06f0ae8 (diff)
parent7cf785d9a8c745b961eaa68c9cddbc20d7bc7fe1 (diff)
downloadadvanced-privacy-ac0f57662d5c953f73c0561edc11e0ae8c9a0404.tar.gz
Merge branch 'stats_accuracy' into 'main'
Improve trackers statistics accuracy, #4584, #4580, #4588 See merge request e/privacy-central/privacycentralapp!15
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp/features')
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt37
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt8
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt49
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt8
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt70
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt8
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt12
7 files changed, 143 insertions, 49 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 c1d6559..5a37246 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
@@ -30,7 +30,6 @@ import foundation.e.privacycentralapp.domain.usecases.IpScramblingStateUseCase
import foundation.e.privacycentralapp.domain.usecases.TrackersStateUseCase
import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
@@ -66,6 +65,7 @@ class DashboardFeature(
object NavigateToInternetActivityPrivacySingleEvent : SingleEvent()
object NavigateToLocationSingleEvent : SingleEvent()
object NavigateToPermissionsSingleEvent : SingleEvent()
+ object NewStatisticsAvailableSingleEvent : SingleEvent()
}
sealed class Action {
@@ -75,6 +75,7 @@ class DashboardFeature(
object ShowInternetActivityPrivacyAction : Action()
object ShowAppsPermissions : Action()
object ShowTrackers : Action()
+ object FetchStatistics : Action()
}
sealed class Effect {
@@ -92,6 +93,7 @@ class DashboardFeature(
object OpenInternetActivityPrivacyEffect : Effect()
object OpenAppsPermissionsEffect : Effect()
object OpenTrackersEffect : Effect()
+ object NewStatisticsAvailablesEffect : Effect()
}
companion object {
@@ -134,21 +136,25 @@ class DashboardFeature(
Action.InitAction -> merge(
getPrivacyStateUseCase.quickPrivacyEnabledFlow.map {
-
Effect.UpdateStateEffect(it)
},
ipScramblingStateUseCase.internetPrivacyMode.map {
Effect.IpScramblingModeUpdatedEffect(it)
},
- flow {
- emit(
+ trackersStatisticsUseCase.listenUpdates().map {
+ Effect.NewStatisticsAvailablesEffect
+ },
+ flowOf<Effect>(
+ // trackersStatisticsUseCase.listenDayStatistics().map {
+ trackersStatisticsUseCase.getDayStatistics().let {
+ (dayStatistics, dayTrackersCount, trackersCount) ->
Effect.TrackersStatisticsUpdatedEffect(
- dayStatistics = trackersStatisticsUseCase.getPastDayTrackersCalls(),
- dayTrackersCount = trackersStatisticsUseCase.getPastDayTrackersCount(),
- trackersCount = trackersStatisticsUseCase.getTrackersCount()
+ dayStatistics,
+ dayTrackersCount,
+ trackersCount
)
- )
- },
+ }
+ ),
trackersStateUseCase.areAllTrackersBlocked.map {
Effect.TrackersBlockedUpdatedEffect(it)
},
@@ -162,6 +168,17 @@ class DashboardFeature(
Effect.OpenInternetActivityPrivacyEffect
)
Action.ShowTrackers -> flowOf(Effect.OpenTrackersEffect)
+ Action.FetchStatistics -> flowOf<Effect>(
+ // trackersStatisticsUseCase.listenDayStatistics().map {
+ trackersStatisticsUseCase.getDayStatistics().let {
+ (dayStatistics, dayTrackersCount, trackersCount) ->
+ Effect.TrackersStatisticsUpdatedEffect(
+ dayStatistics,
+ dayTrackersCount,
+ trackersCount
+ )
+ }
+ )
}
},
singleEventProducer = { state, _, effect ->
@@ -175,6 +192,8 @@ class DashboardFeature(
SingleEvent.NavigateToPermissionsSingleEvent
is Effect.OpenTrackersEffect ->
SingleEvent.NavigateToTrackersSingleEvent
+ is Effect.NewStatisticsAvailablesEffect ->
+ SingleEvent.NewStatisticsAvailableSingleEvent
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 60cef54..441f3d6 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
@@ -90,6 +90,9 @@ class DashboardFragment :
addToBackStack("dashboard")
}
}
+ DashboardFeature.SingleEvent.NewStatisticsAvailableSingleEvent -> {
+ viewModel.submitAction(DashboardFeature.Action.FetchStatistics)
+ }
}
}
}
@@ -122,6 +125,11 @@ class DashboardFragment :
}
}
+ override fun onResume() {
+ super.onResume()
+ viewModel.submitAction(DashboardFeature.Action.FetchStatistics)
+ }
+
override fun getTitle(): String {
return getString(R.string.dashboard_title)
}
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 64cc71e..d061c4a 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
@@ -64,11 +64,13 @@ class TrackersFeature(
sealed class SingleEvent {
data class ErrorEvent(val error: String) : SingleEvent()
data class OpenAppDetailsEvent(val appDesc: ApplicationDescription) : SingleEvent()
+ object NewStatisticsAvailableSingleEvent : SingleEvent()
}
sealed class Action {
object InitAction : Action()
data class ClickAppAction(val packageName: String) : Action()
+ object FetchStatistics : Action()
}
sealed class Effect {
@@ -86,6 +88,7 @@ class TrackersFeature(
data class OpenAppDetailsEffect(val appDesc: ApplicationDescription) : Effect()
object QuickPrivacyDisabledWarningEffect : Effect()
data class ErrorEffect(val message: String) : Effect()
+ object NewStatisticsAvailablesEffect : Effect()
}
companion object {
@@ -117,21 +120,25 @@ class TrackersFeature(
when (action) {
Action.InitAction -> merge<TrackersFeature.Effect>(
flow {
- val statistics = trackersStatisticsUseCase.getDayMonthYearStatistics()
- val counts = trackersStatisticsUseCase.getDayMonthYearCounts()
- emit(
- Effect.TrackersStatisticsLoadedEffect(
- dayStatistics = statistics.first,
- dayTrackersCount = counts.first,
- monthStatistics = statistics.second,
- monthTrackersCount = counts.second,
- yearStatistics = statistics.third,
- yearTrackersCount = counts.third
- )
- )
+ trackersStatisticsUseCase.getDayMonthYearStatistics()
+ .let { (day, month, year) ->
+ emit(
+ Effect.TrackersStatisticsLoadedEffect(
+ dayStatistics = day.first,
+ dayTrackersCount = day.second,
+ monthStatistics = month.first,
+ monthTrackersCount = month.second,
+ yearStatistics = year.first,
+ yearTrackersCount = year.second
+ )
+ )
+ }
},
appListUseCase.getBlockableApps().map { apps ->
Effect.AvailableAppsListEffect(apps)
+ },
+ trackersStatisticsUseCase.listenUpdates().map {
+ Effect.NewStatisticsAvailablesEffect
}
)
@@ -142,13 +149,29 @@ class TrackersFeature(
} ?: run { Effect.ErrorEffect("Can't find back app.") }
} else Effect.QuickPrivacyDisabledWarningEffect
)
+ is Action.FetchStatistics -> flow {
+ trackersStatisticsUseCase.getDayMonthYearStatistics()
+ .let { (day, month, year) ->
+ emit(
+ Effect.TrackersStatisticsLoadedEffect(
+ dayStatistics = day.first,
+ dayTrackersCount = day.second,
+ monthStatistics = month.first,
+ monthTrackersCount = month.second,
+ yearStatistics = year.first,
+ yearTrackersCount = year.second
+ )
+ )
+ }
+ }
}
},
singleEventProducer = { _, _, effect ->
when (effect) {
is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message)
is Effect.OpenAppDetailsEffect -> SingleEvent.OpenAppDetailsEvent(effect.appDesc)
- Effect.QuickPrivacyDisabledWarningEffect -> SingleEvent.ErrorEvent("Enabled Quick Privacy to use functionalities")
+ is Effect.QuickPrivacyDisabledWarningEffect -> SingleEvent.ErrorEvent("Enabled Quick Privacy to use functionalities")
+ is Effect.NewStatisticsAvailablesEffect -> SingleEvent.NewStatisticsAvailableSingleEvent
else -> null
}
}
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 fed5fe9..c017abd 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
@@ -73,6 +73,9 @@ class TrackersFragment :
addToBackStack("apptrackers")
}
}
+ is TrackersFeature.SingleEvent.NewStatisticsAvailableSingleEvent -> {
+ viewModel.submitAction(TrackersFeature.Action.FetchStatistics)
+ }
}
}
}
@@ -107,6 +110,11 @@ class TrackersFragment :
}
}
+ override fun onResume() {
+ super.onResume()
+ viewModel.submitAction(TrackersFeature.Action.FetchStatistics)
+ }
+
override fun getTitle() = getString(R.string.trackers_title)
override fun render(state: TrackersFeature.State) {
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 11bcf0c..18cbb93 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
@@ -23,11 +23,13 @@ import foundation.e.flowmvi.Reducer
import foundation.e.flowmvi.SingleEventProducer
import foundation.e.flowmvi.feature.BaseFeature
import foundation.e.privacycentralapp.domain.usecases.TrackersStateUseCase
+import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
import foundation.e.privacymodules.permissions.data.ApplicationDescription
import foundation.e.privacymodules.trackers.Tracker
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
// Define a state machine for Tracker feature.
@@ -62,43 +64,43 @@ class AppTrackersFeature(
sealed class SingleEvent {
data class ErrorEvent(val error: String) : SingleEvent()
+ object NewStatisticsAvailableSingleEvent : SingleEvent()
}
sealed class Action {
data class InitAction(val packageName: String) : Action()
data class BlockAllToggleAction(val isBlocked: Boolean) : Action()
data class ToggleTrackerAction(val tracker: Tracker, val isBlocked: Boolean) : Action()
+ object FetchStatistics : Action()
}
sealed class Effect {
data class SetAppEffect(val appDesc: ApplicationDescription) : Effect()
data class AppTrackersBlockingActivatedEffect(val isBlockingActivated: Boolean) : Effect()
data class AvailableTrackersListEffect(
- val isBlockingActivated: Boolean,
+ // val isBlockingActivated: Boolean,
val trackers: List<Tracker>,
- val whitelist: List<String>
+ // val whitelist: List<String>
) : Effect()
data class TrackersWhitelistUpdateEffect(val whitelist: List<String>) : Effect()
// object QuickPrivacyDisabledWarningEffect : Effect()
data class ErrorEffect(val message: String) : Effect()
+ object NewStatisticsAvailablesEffect : Effect()
}
companion object {
fun create(
initialState: State = State(),
coroutineScope: CoroutineScope,
- trackersStateUseCase: TrackersStateUseCase
+ trackersStateUseCase: TrackersStateUseCase,
+ trackersStatisticsUseCase: TrackersStatisticsUseCase
) = AppTrackersFeature(
initialState, coroutineScope,
reducer = { state, effect ->
when (effect) {
is Effect.SetAppEffect -> state.copy(appDesc = effect.appDesc)
- is Effect.AvailableTrackersListEffect -> state.copy(
- isBlockingActivated = effect.isBlockingActivated,
- trackers = effect.trackers,
- whitelist = effect.whitelist
- )
+ is Effect.AvailableTrackersListEffect -> state.copy(trackers = effect.trackers)
is Effect.AppTrackersBlockingActivatedEffect ->
state.copy(isBlockingActivated = effect.isBlockingActivated)
@@ -106,27 +108,39 @@ class AppTrackersFeature(
is Effect.TrackersWhitelistUpdateEffect ->
state.copy(whitelist = effect.whitelist)
is Effect.ErrorEffect -> state
+ else -> state
}
},
actor = { state, action ->
when (action) {
- is Action.InitAction -> merge(
- flow {
- val appDesc =
- trackersStateUseCase.getApplicationPermission(action.packageName)
- emit(Effect.SetAppEffect(appDesc))
+ is Action.InitAction -> {
+ val appDesc =
+ trackersStateUseCase.getApplicationPermission(action.packageName)
+ merge<Effect>(
+ flow {
- emit(
- Effect.AvailableTrackersListEffect(
- isBlockingActivated = !trackersStateUseCase.isWhitelisted(
- appDesc.uid
- ),
- trackers = trackersStateUseCase.getTrackers(appDesc.uid),
- whitelist = trackersStateUseCase.getTrackersWhitelistIds(appDesc.uid)
+ emit(Effect.SetAppEffect(appDesc))
+ emit(
+ Effect.AppTrackersBlockingActivatedEffect(
+ !trackersStateUseCase.isWhitelisted(appDesc.uid)
+ )
)
- )
- }
- )
+ emit(
+ Effect.TrackersWhitelistUpdateEffect(
+ trackersStateUseCase.getTrackersWhitelistIds(appDesc.uid)
+ )
+ )
+ emit(
+ Effect.AvailableTrackersListEffect(
+ trackers = trackersStatisticsUseCase.getTrackers(appDesc.uid)
+ )
+ )
+ },
+ trackersStatisticsUseCase.listenUpdates().map {
+ Effect.NewStatisticsAvailablesEffect
+ }
+ )
+ }
is Action.BlockAllToggleAction ->
state.appDesc?.uid?.let { appUid ->
flow {
@@ -157,11 +171,21 @@ class AppTrackersFeature(
}
} ?: run { flowOf(Effect.ErrorEffect("No appDesc.")) }
}
+ is Action.FetchStatistics -> flowOf(
+ state.appDesc?.uid?.let {
+ Effect.AvailableTrackersListEffect(
+ trackers = trackersStatisticsUseCase.getTrackers(it)
+ )
+ } ?: Effect.ErrorEffect("No appDesc.")
+
+ )
}
},
singleEventProducer = { _, _, effect ->
when (effect) {
is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message)
+ is Effect.NewStatisticsAvailablesEffect ->
+ SingleEvent.NewStatisticsAvailableSingleEvent
else -> null
}
}
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 6b57719..5b09be5 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
@@ -71,6 +71,9 @@ class AppTrackersFragment :
viewModel.feature.singleEvents.collect { event ->
when (event) {
is SingleEvent.ErrorEvent -> displayToast(event.error)
+ is SingleEvent.NewStatisticsAvailableSingleEvent -> {
+ viewModel.submitAction(Action.FetchStatistics)
+ }
}
}
}
@@ -111,6 +114,11 @@ class AppTrackersFragment :
}
}
+ override fun onResume() {
+ super.onResume()
+ viewModel.submitAction(Action.FetchStatistics)
+ }
+
override fun render(state: State) {
binding.blockAllToggle.isChecked = state.isBlockingActivated
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 8acbcac..37fdb85 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
@@ -22,12 +22,14 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import foundation.e.privacycentralapp.common.Factory
import foundation.e.privacycentralapp.domain.usecases.TrackersStateUseCase
+import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
class AppTrackersViewModel(
- private val trackersStateUseCase: TrackersStateUseCase
+ private val trackersStateUseCase: TrackersStateUseCase,
+ private val trackersStatisticsUseCase: TrackersStatisticsUseCase
) : ViewModel() {
private val _actions = MutableSharedFlow<AppTrackersFeature.Action>()
@@ -36,7 +38,8 @@ class AppTrackersViewModel(
val feature: AppTrackersFeature by lazy {
AppTrackersFeature.create(
coroutineScope = viewModelScope,
- trackersStateUseCase = trackersStateUseCase
+ trackersStateUseCase = trackersStateUseCase,
+ trackersStatisticsUseCase = trackersStatisticsUseCase
)
}
@@ -49,10 +52,11 @@ class AppTrackersViewModel(
}
class AppTrackersViewModelFactory(
- private val trackersStateUseCase: TrackersStateUseCase
+ private val trackersStateUseCase: TrackersStateUseCase,
+ private val trackersStatisticsUseCase: TrackersStatisticsUseCase
) :
Factory<AppTrackersViewModel> {
override fun create(): AppTrackersViewModel {
- return AppTrackersViewModel(trackersStateUseCase)
+ return AppTrackersViewModel(trackersStateUseCase, trackersStatisticsUseCase)
}
}