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

Commit 74fb6729 authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

Centralise activate IPScrambling funcitonnality

parent 9035bac3
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Context
import android.os.Process
import foundation.e.privacycentralapp.data.repositories.LocalStateRepository
import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.privacycentralapp.domain.usecases.IpScramblingStateUseCase
import foundation.e.privacycentralapp.features.dashboard.DashBoardViewModelFactory
import foundation.e.privacycentralapp.features.internetprivacy.InternetPrivacyViewModelFactory
import foundation.e.privacycentralapp.features.location.FakeLocationViewModelFactory
@@ -32,6 +33,7 @@ import foundation.e.privacymodules.location.FakeLocation
import foundation.e.privacymodules.location.IFakeLocation
import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.GlobalScope
import lineageos.blockers.BlockerInterface

/**
@@ -68,9 +70,12 @@ class DependencyContainer constructor(val app: Application) {
    private val getQuickPrivacyStateUseCase by lazy {
        GetQuickPrivacyStateUseCase(localStateRepository)
    }
    private val ipScramblingStateUseCase by lazy {
        IpScramblingStateUseCase(ipScramblerModule, localStateRepository, GlobalScope)
    }

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

    val fakeLocationViewModelFactory by lazy {
@@ -80,6 +85,6 @@ class DependencyContainer constructor(val app: Application) {
    val blockerService = BlockerInterface.getInstance(context)

    val internetPrivacyViewModelFactory by lazy {
        InternetPrivacyViewModelFactory(ipScramblerModule, permissionsModule)
        InternetPrivacyViewModelFactory(ipScramblerModule, permissionsModule, getQuickPrivacyStateUseCase, ipScramblingStateUseCase)
    }
}
+16 −3
Original line number Diff line number Diff line
@@ -18,18 +18,31 @@
package foundation.e.privacycentralapp.data.repositories

import android.content.Context
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow

class LocalStateRepository(context: Context) {
    companion object {
        private const val SHARED_PREFS_FILE = "localState"
        private const val KEY_QUICK_PRIVACY = "quickPrivacy"
        private const val KEY_IP_SCRAMBLING = "ipScrambling"
    }

    val sharedPref = context.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE)
    private val sharedPref = context.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE)

    private val quickPrivacyEnabledMutableFlow = MutableStateFlow<Boolean>(sharedPref.getBoolean(KEY_QUICK_PRIVACY, false))
    var isQuickPrivacyEnabled: Boolean
        get() = sharedPref.getBoolean(KEY_QUICK_PRIVACY, false)
        set(value) = set(KEY_QUICK_PRIVACY, value)
        get() = quickPrivacyEnabledMutableFlow.value
        set(value) {
            set(KEY_QUICK_PRIVACY, value)
            quickPrivacyEnabledMutableFlow.value = value
        }

    var quickPrivacyEnabledFlow: Flow<Boolean> = quickPrivacyEnabledMutableFlow

    var isIpScramblingEnabled: Boolean
        get() = sharedPref.getBoolean(KEY_IP_SCRAMBLING, false)
        set(value) = set(KEY_IP_SCRAMBLING, value)

    private fun set(key: String, value: Boolean) {
        sharedPref.edit().putBoolean(key, value).commit()
+4 −1
Original line number Diff line number Diff line
@@ -18,5 +18,8 @@
package foundation.e.privacycentralapp.domain.entities

enum class InternetPrivacyMode {
    REAL_IP, HIDE_IP
    REAL_IP,
    HIDE_IP,
    HIDE_IP_LOADING,
    REAL_IP_LOADING
}
+2 −1
Original line number Diff line number Diff line
@@ -20,7 +20,8 @@ package foundation.e.privacycentralapp.domain.usecases
import foundation.e.privacycentralapp.data.repositories.LocalStateRepository

class GetQuickPrivacyStateUseCase(private val localStateRepository: LocalStateRepository) {
    val isQuickPrivacyEnabled = localStateRepository.isQuickPrivacyEnabled
    val quickPrivacyEnabledFlow = localStateRepository.quickPrivacyEnabledFlow
    val isQuickPrivacyEnabled get() = localStateRepository.isQuickPrivacyEnabled

    fun toggle(): Boolean {
        val newState = !localStateRepository.isQuickPrivacyEnabled
+116 −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.domain.usecases

import android.content.Intent
import android.util.Log
import foundation.e.privacycentralapp.data.repositories.LocalStateRepository
import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacymodules.ipscramblermodule.IIpScramblerModule
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch

class IpScramblingStateUseCase(
    private val ipScramblerModule: IIpScramblerModule,
    private val localStateRepository: LocalStateRepository,
    private val coroutineScope: CoroutineScope
) {

    // private val internetPrivacyModeMutableFlow = MutableStateFlow(InternetPrivacyMode.REAL_IP)
    val internetPrivacyMode: StateFlow<InternetPrivacyMode> = callbackFlow {
        val listener = object : IIpScramblerModule.Listener {
            override fun onStatusChanged(newStatus: IIpScramblerModule.Status) {
                offer(map(newStatus))
            }

            override fun log(message: String) {}
            override fun onTrafficUpdate(
                upload: Long,
                download: Long,
                read: Long,
                write: Long
            ) {
            }
        }
        ipScramblerModule.addListener(listener)
        ipScramblerModule.requestStatus()
        awaitClose { ipScramblerModule.removeListener(listener) }
    }.stateIn(
        scope = coroutineScope,
        started = SharingStarted.Eagerly,
        initialValue = InternetPrivacyMode.REAL_IP
    )

    init {
        coroutineScope.launch {
            localStateRepository.quickPrivacyEnabledFlow.collect {
                Log.d("testQPFlow", "QuickPrivacy enabled: $it")
                applySettings(it, localStateRepository.isIpScramblingEnabled)
            }
        }
    }

    fun toggle(hideIp: Boolean): Intent? {
        if (!localStateRepository.isQuickPrivacyEnabled) return null

        localStateRepository.isIpScramblingEnabled = hideIp
        return applySettings(true, hideIp)
    }

    private fun applySettings(isQuickPrivacyEnabled: Boolean, isIpScramblingEnabled: Boolean): Intent? {
        when {
            isQuickPrivacyEnabled && isIpScramblingEnabled -> when (internetPrivacyMode.value) {
                InternetPrivacyMode.REAL_IP, InternetPrivacyMode.REAL_IP_LOADING -> {
                    val intent = ipScramblerModule.prepareAndroidVpn()
                    if (intent != null) {
                        return intent
                    } else {
                        ipScramblerModule.start()
                    }
                }
                else -> {
                    Log.d("testQPFlow", "Not starting tor, already in started state")
                }
            }
            else -> when (internetPrivacyMode.value) {
                InternetPrivacyMode.HIDE_IP, InternetPrivacyMode.HIDE_IP_LOADING -> ipScramblerModule.stop()

                else -> {
                    Log.d("testQPFlow", "Not stoping tor, already in stop or stoping state")
                }
            }
        }
        return null
    }

    private fun map(status: IIpScramblerModule.Status): InternetPrivacyMode {
        return when (status) {
            IIpScramblerModule.Status.OFF -> InternetPrivacyMode.REAL_IP
            IIpScramblerModule.Status.ON -> InternetPrivacyMode.HIDE_IP
            IIpScramblerModule.Status.STARTING -> InternetPrivacyMode.HIDE_IP_LOADING
            IIpScramblerModule.Status.STOPPING,
            IIpScramblerModule.Status.START_DISABLED -> InternetPrivacyMode.REAL_IP_LOADING
        }
    }
}
Loading