Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0d90798 authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

Add graph view on home dashboard.

parent 880a48c8
Loading
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -94,15 +94,18 @@ android {
dependencies {
    compileOnly files('libs/e-ui-sdk-1.0.1-q.jar')
    implementation files('libs/lineage-sdk.jar')
    implementation project(":privacymodulesapi")
    //implementation project(":privacymodulesapi")

    // include the google specific version of the modules, just for the google flavor
    googleImplementation project(":privacymodulesgoogle")
    // include the e specific version of the modules, just for the e flavor
    eImplementation project(":privacymodulese")

    implementation 'foundation.e:privacymodule.api:0.2.1'
    implementation 'foundation.e:privacymodule.tor:0.1.0'

    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

    implementation project(":flow-mvi")
    implementation Libs.Kotlin.stdlib
    implementation Libs.AndroidX.coreKtx
+7 −2
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import foundation.e.privacycentralapp.data.repositories.LocalStateRepository
import foundation.e.privacycentralapp.domain.usecases.AppListUseCase
import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.privacycentralapp.domain.usecases.IpScramblingStateUseCase
import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase
import foundation.e.privacycentralapp.dummy.TrackTrackersPrivacyMock
import foundation.e.privacycentralapp.features.dashboard.DashBoardViewModelFactory
import foundation.e.privacycentralapp.features.internetprivacy.InternetPrivacyViewModelFactory
import foundation.e.privacycentralapp.features.location.FakeLocationViewModelFactory
@@ -66,7 +68,7 @@ class DependencyContainer constructor(val app: Application) {

    // Repositories
    private val localStateRepository by lazy { LocalStateRepository(context) }

    private val trackTrackersPrivacyModule by lazy { TrackTrackersPrivacyMock() }
    // Usecases
    private val getQuickPrivacyStateUseCase by lazy {
        GetQuickPrivacyStateUseCase(localStateRepository)
@@ -77,9 +79,12 @@ class DependencyContainer constructor(val app: Application) {
    private val appListUseCase by lazy {
        AppListUseCase(permissionsModule)
    }
    private val trackersStatisticsUseCase by lazy {
        TrackersStatisticsUseCase(trackTrackersPrivacyModule)
    }

    val dashBoardViewModelFactory by lazy {
        DashBoardViewModelFactory(getQuickPrivacyStateUseCase, ipScramblingStateUseCase)
        DashBoardViewModelFactory(getQuickPrivacyStateUseCase, ipScramblingStateUseCase, trackersStatisticsUseCase)
    }

    val fakeLocationViewModelFactory by lazy {
+29 −0
Original line number Diff line number Diff line
@@ -15,26 +15,15 @@
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package foundation.e.privacycentralapp.features.dashboard
package foundation.e.privacycentralapp.domain.usecases

import android.content.Context
import androidx.activity.addCallback
import androidx.fragment.app.activityViewModels
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.common.NavToolbarFragment
import foundation.e.privacycentralapp.dummy.TrackTrackersPrivacyMock

class QuickProtectionFragment : NavToolbarFragment(R.layout.fragment_quick_protection) {
class TrackersStatisticsUseCase(
    private val trackTrackersPrivacyModule: TrackTrackersPrivacyMock
) {

    private val viewModel: DashboardViewModel by activityViewModels()

    override fun getTitle(): String = getString(R.string.quick_protection)

    override fun onAttach(context: Context) {
        super.onAttach(context)
        requireActivity().onBackPressedDispatcher.addCallback(this, true) {
            // viewModel.submitAction(DashboardFeature.Action.ShowDashboardAction)
            this.isEnabled = false
            requireActivity().onBackPressed()
        }
    fun getPast24HoursTrackersCalls(): List<Int> {
        return trackTrackersPrivacyModule.getPast24HoursTrackersCalls()
    }
}
+60 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 E FOUNDATION
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package foundation.e.privacycentralapp.dummy

import foundation.e.privacymodules.trackers.ITrackTrackersPrivacyModule
import foundation.e.privacymodules.trackers.Tracker

class TrackTrackersPrivacyMock : ITrackTrackersPrivacyModule {
    override fun getPast24HoursTrackersCalls(): List<Int> {
        return listOf(
            2000, 2300, 130, 2500, 1000, 2000,
            2000, 2300, 130, 2500, 1000, 2000,
            2000, 2300, 130, 2500, 1000, 2000,
            2000, 2300, 130, 2500, 1000, 2000
        )
    }

    override fun getPastMonthTrackersCalls(): List<Int> {
        return listOf(
            20000, 23000, 24130, 12500, 31000, 22000,
            20000, 23000, 24130, 12500, 31000, 22000,
            20000, 23000, 24130, 12500, 31000, 22000,
            20000, 23000, 24130, 12500, 31000, 22000,
            20000, 23000, 24130, 12500, 31000, 22000
        )
    }

    override fun getPastYearTrackersCalls(): List<Int> {
        return listOf(
            620000, 823000, 424130, 712500, 831000, 922000,
            620000, 823000, 424130, 712500, 831000, 922000
        )
    }

    override fun getTrackersCount(): Int {
        return 72
    }

    override fun getTrackersForApp(appUid: Int): List<Tracker> {
        return listOf(
            Tracker("Crashlytics", null),
            Tracker(label = "Facebook", null)
        )
    }
}
+26 −48
Original line number Diff line number Diff line
@@ -26,7 +26,9 @@ import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.privacycentralapp.domain.usecases.IpScramblingStateUseCase
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
@@ -45,24 +47,17 @@ class DashboardFeature(
    initialState, actor, reducer, coroutineScope, { message -> Log.d("DashboardFeature", message) },
    singleEventProducer
) {
    sealed class State() {
        object LoadingState : State()
        data class DisabledState(
            val totalGraph: Int = 230,
            // val graphData
            val trackersCount: Int = 77,
            val activeTrackersCount: Int = 22
        ) : State()
        data class EnabledState(
    data class State(
        val isQuickPrivacyEnabled: Boolean = false,
        val isAllTrackersBlocked: Boolean = false,
            val locationMode: LocationMode = LocationMode.CUSTOM_LOCATION,
            val internetPrivacyMode: InternetPrivacyMode,
            val totalGraph: Int = 150,
        val locationMode: LocationMode = LocationMode.REAL_LOCATION,
        val internetPrivacyMode: InternetPrivacyMode = InternetPrivacyMode.REAL_IP,
        val totalGraph: Int? = null,
        // val graphData
            val trackersCount: Int = 80,
            val activeTrackersCount: Int = 10
        ) : State()
    }
        val trackersCount: Int? = null,
        val activeTrackersCount: Int? = null,
        val dayStatistics: List<Int>? = null
    )

    sealed class SingleEvent {
        object NavigateToQuickProtectionSingleEvent : SingleEvent()
@@ -89,6 +84,7 @@ class DashboardFeature(
        object NoEffect : Effect()
        data class UpdateStateEffect(val isEnabled: Boolean) : Effect()
        data class IpScramblingModeUpdatedEffect(val mode: InternetPrivacyMode) : Effect()
        data class TrackersStatisticsUpdatedEffect(val dayStatistics: List<Int>) : Effect()

        object OpenQuickPrivacyProtectionEffect : Effect()
        data class OpenDashboardEffect(
@@ -118,36 +114,17 @@ class DashboardFeature(
        fun create(
            coroutineScope: CoroutineScope,
            getPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
            ipScramblingStateUseCase: IpScramblingStateUseCase
            ipScramblingStateUseCase: IpScramblingStateUseCase,
            trackersStatisticsUseCase: TrackersStatisticsUseCase
        ): DashboardFeature =
            DashboardFeature(
                initialState = State.DisabledState(),
                initialState = State(),
                coroutineScope,
                reducer = { state, effect ->
                    if (state is State.LoadingState) state
                    else when (effect) {
                        is Effect.UpdateStateEffect -> when {
                            effect.isEnabled && state is State.EnabledState
                                || !effect.isEnabled && state is State.DisabledState -> state
                            effect.isEnabled && state is State.DisabledState -> State.EnabledState(
                                isAllTrackersBlocked = false,
                                locationMode = LocationMode.REAL_LOCATION,
                                internetPrivacyMode = InternetPrivacyMode.REAL_IP,
                                totalGraph = state.totalGraph,
                                // val graphData
                                trackersCount = state.trackersCount,
                                activeTrackersCount = state.activeTrackersCount
                            )
                            !effect.isEnabled && state is State.EnabledState -> State.DisabledState(
                                totalGraph = state.totalGraph,
                                // val graphData
                                trackersCount = state.trackersCount,
                                activeTrackersCount = state.activeTrackersCount
                            )
                            else -> state
                        }
                        is Effect.IpScramblingModeUpdatedEffect -> if (state is State.EnabledState) state.copy(internetPrivacyMode = effect.mode)
                        else state
                    when (effect) {
                        is Effect.UpdateStateEffect -> state.copy(isQuickPrivacyEnabled = effect.isEnabled)
                        is Effect.IpScramblingModeUpdatedEffect -> state.copy(internetPrivacyMode = effect.mode)
                        is Effect.TrackersStatisticsUpdatedEffect -> state.copy(dayStatistics = effect.dayStatistics)

                        /*is Effect.OpenDashboardEffect -> State.DashboardState(
                            effect.trackersCount,
@@ -196,13 +173,11 @@ class DashboardFeature(
                        else -> state
                    }
                },
                actor = { state: State, action: Action ->
                actor = { _: State, action: Action ->
                    Log.d("Feature", "action: $action")
                    when (action) {
                        Action.TogglePrivacyAction -> {
                            if (state != State.LoadingState) {
                            getPrivacyStateUseCase.toggle()
                            }
                            flowOf(Effect.NoEffect)
                        }

@@ -213,6 +188,9 @@ class DashboardFeature(
                            },
                            ipScramblingStateUseCase.internetPrivacyMode.map {
                                Effect.IpScramblingModeUpdatedEffect(it)
                            },
                            flow {
                                emit(Effect.TrackersStatisticsUpdatedEffect(trackersStatisticsUseCase.getPast24HoursTrackersCalls()))
                            }
                        )
                        /*
Loading