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

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

Allow on ipscrambling feature.

parent 66baccf4
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import foundation.e.privacymodules.permissions.IPermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
@@ -41,6 +42,9 @@ class IpScramblingStateUseCase(
    coroutineScope: CoroutineScope
) {

    val _configuredMode = MutableStateFlow(localStateRepository.isIpScramblingEnabled)
    val configuredMode: StateFlow<Boolean> = _configuredMode

    val internetPrivacyMode: StateFlow<InternetPrivacyMode> = callbackFlow {
        val listener = object : IIpScramblerModule.Listener {
            override fun onStatusChanged(newStatus: IIpScramblerModule.Status) {
@@ -78,11 +82,15 @@ class IpScramblingStateUseCase(
    }

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

        localStateRepository.isIpScramblingEnabled = hideIp
        _configuredMode.value = hideIp

        if (!localStateRepository.isQuickPrivacyEnabled) {
            localStateRepository.setShowQuickPrivacyDisabledMessage(true)
        } else {
            applySettings(true, hideIp)
        }
    }

    private fun getHiddenPackageNames(): List<String> {
        return appListsRepository.getHiddenSystemApps().map { it.packageName }
+32 −18
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
@@ -63,7 +64,8 @@ class InternetPrivacyFeature(
        val bypassTorApps: Collection<String>,
        val selectedLocation: String,
        val availableLocationIds: List<String>,
        val forceRedraw: Boolean = false
        val forceRedraw: Boolean = false,
        val showQuickPrivacyDisabledMessage: Boolean = false
    ) {
        fun getApps(): List<Pair<ApplicationDescription, Boolean>> {
            return availableApps.map { it to (it.packageName !in bypassTorApps) }
@@ -84,6 +86,7 @@ class InternetPrivacyFeature(
        data class AndroidVpnActivityResultAction(val resultCode: Int) : Action()
        data class ToggleAppIpScrambled(val packageName: String) : Action()
        data class SelectLocationAction(val position: Int) : Action()
        object CloseQuickPrivacyDisabledMessage : Action()
    }

    sealed class Effect {
@@ -100,6 +103,7 @@ class InternetPrivacyFeature(
        data class LocationSelectedEffect(val locationId: String) : Effect()
        object WarningStartingLongEffect : Effect()
        data class ErrorEffect(val message: String) : Effect()
        data class ShowQuickPrivacyDisabledMessageEffect(val show: Boolean) : Effect()
    }

    companion object {
@@ -131,6 +135,7 @@ class InternetPrivacyFeature(
                    )
                    is Effect.LocationSelectedEffect -> state.copy(selectedLocation = effect.locationId)
                    Effect.QuickPrivacyDisabledWarningEffect -> state.copy(forceRedraw = !state.forceRedraw)
                    is Effect.ShowQuickPrivacyDisabledMessageEffect -> state.copy(showQuickPrivacyDisabledMessage = effect.show)
                    else -> state
                }
            },
@@ -139,9 +144,24 @@ class InternetPrivacyFeature(
                    action is Action.LoadInternetModeAction -> merge(
                        getQuickPrivacyStateUseCase.quickPrivacyEnabledFlow
                            .map { Effect.QuickPrivacyUpdatedEffect(it) },
                        ipScramblingStateUseCase.internetPrivacyMode
                        getQuickPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map {
                            Effect.ShowQuickPrivacyDisabledMessageEffect(it)
                        },
                        getQuickPrivacyStateUseCase.quickPrivacyEnabledFlow.flatMapLatest { enabled ->
                            if (enabled) ipScramblingStateUseCase.internetPrivacyMode
                                .map { Effect.ModeUpdatedEffect(it) }
                            .shareIn(scope = coroutineScope, started = SharingStarted.Lazily, replay = 0),
                                .shareIn(
                                    scope = coroutineScope,
                                    started = SharingStarted.Lazily,
                                    replay = 0
                                )
                            else ipScramblingStateUseCase.configuredMode.map {
                                Effect.ModeUpdatedEffect(
                                    if (it) InternetPrivacyMode.HIDE_IP
                                    else InternetPrivacyMode.REAL_IP
                                )
                            }
                        },
                        appListUseCase.getAppsUsingInternet().map { apps ->
                            Effect.AvailableAppsListEffect(
                                apps,
@@ -175,24 +195,16 @@ class InternetPrivacyFeature(
                        InternetPrivacyMode.HIDE_IP_LOADING,
                        InternetPrivacyMode.REAL_IP_LOADING
                    ) -> {
                        if (getQuickPrivacyStateUseCase.isQuickPrivacyEnabled) {
                        ipScramblingStateUseCase.toggle(hideIp = false)
                        flowOf(Effect.ModeUpdatedEffect(InternetPrivacyMode.REAL_IP_LOADING))
                        } else {
                            flowOf(Effect.QuickPrivacyDisabledWarningEffect)
                        }
                    }
                    action is Action.UseHiddenIPAction
                        && state.mode in listOf(
                            InternetPrivacyMode.REAL_IP,
                            InternetPrivacyMode.REAL_IP_LOADING
                        ) -> {
                        if (getQuickPrivacyStateUseCase.isQuickPrivacyEnabled) {
                        ipScramblingStateUseCase.toggle(hideIp = true)
                        flowOf(Effect.ModeUpdatedEffect(InternetPrivacyMode.HIDE_IP_LOADING))
                        } else {
                            flowOf(Effect.QuickPrivacyDisabledWarningEffect)
                        }
                    }

                    action is Action.ToggleAppIpScrambled -> {
@@ -208,6 +220,10 @@ class InternetPrivacyFeature(
                            flowOf(Effect.NoEffect)
                        }
                    }
                    action is Action.CloseQuickPrivacyDisabledMessage -> {
                        getQuickPrivacyStateUseCase.resetQuickPrivacyDisabledMessage()
                        flowOf(Effect.NoEffect)
                    }
                    else -> flowOf(Effect.NoEffect)
                }
            },
@@ -216,8 +232,6 @@ class InternetPrivacyFeature(
                    effect is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message)
                    effect is Effect.WarningStartingLongEffect ->
                        SingleEvent.ErrorEvent(R.string.ipscrambling_warning_starting_long)
                    effect is Effect.QuickPrivacyDisabledWarningEffect -> SingleEvent.ErrorEvent(error = R.string.ipscrambling_error_quickprivacy_disabled)

                    action is Action.UseHiddenIPAction
                        && effect is Effect.ShowAndroidVpnDisclaimerEffect ->
                        SingleEvent.StartAndroidVpnActivityEvent(effect.intent)
+11 −0
Original line number Diff line number Diff line
@@ -26,12 +26,14 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import foundation.e.flowmvi.MVIView
import foundation.e.privacycentralapp.DependencyContainer
import foundation.e.privacycentralapp.PrivacyCentralApplication
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.common.NavToolbarFragment
import foundation.e.privacycentralapp.common.ToggleAppsAdapter
import foundation.e.privacycentralapp.common.initQuickPrivacySnackbar
import foundation.e.privacycentralapp.databinding.FragmentInternetActivityPolicyBinding
import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.extensions.toText
@@ -56,6 +58,8 @@ class InternetPrivacyFragment :

    private lateinit var binding: FragmentInternetActivityPolicyBinding

    private var qpDisabledSnackbar: Snackbar? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycleScope.launchWhenStarted {
@@ -132,12 +136,19 @@ class InternetPrivacyFragment :
            }
        }

        qpDisabledSnackbar = initQuickPrivacySnackbar(binding.root) {
            viewModel.submitAction(InternetPrivacyFeature.Action.CloseQuickPrivacyDisabledMessage)
        }

        binding.executePendingBindings()
    }

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

    override fun render(state: InternetPrivacyFeature.State) {
        if (state.showQuickPrivacyDisabledMessage) qpDisabledSnackbar?.show()
        else qpDisabledSnackbar?.dismiss()

        binding.radioUseHiddenIp.radiobutton.apply {
            isChecked = state.mode in listOf(
                InternetPrivacyMode.HIDE_IP,
+0 −1
Original line number Diff line number Diff line
@@ -109,7 +109,6 @@ class FakeLocationFeature(
                when (action) {
                    is Action.Init -> {
                        fakeLocationStateUseCase.startListeningLocation()

                        merge(
                            getQuickPrivacyStateUseCase.quickPrivacyEnabledFlow.map { Effect.QuickPrivacyUpdatedEffect(it) },
                            fakeLocationStateUseCase.configuredLocationMode.map { (mode, lat, lon) ->
+0 −2
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@
        android:layout_width="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        >

        <LinearLayout
            android:background="@color/background"
            android:gravity="center_horizontal"
@@ -200,7 +199,6 @@ android:text="@string/dashboard_state_ipaddress_off"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/graph"
                    />

                <View
                    android:id="@+id/graph_legend_blocked_icon"
                    android:layout_width="16dp"