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

Commit 187f4fde authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

UI fixes on location

parent 5891ac8e
Loading
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -95,14 +95,14 @@ dependencies {
    compileOnly files('libs/e-ui-sdk-1.0.1-q.jar')
    implementation files('libs/lineage-sdk.jar')
    implementation files('libs/trackerfilter.aar')
    //implementation project(":privacymodulesapi")

    // include the google specific version of the modules, just for the google flavor
    googleImplementation project(":privacymodulesgoogle")
    //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.4.1'
    implementation 'foundation.e:privacymodule.e-29:0.3.2'
    implementation 'foundation.e:privacymodule.tor:0.1.1'

    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
+5 −3
Original line number Diff line number Diff line
@@ -94,18 +94,20 @@ class DependencyContainer constructor(val app: Application) {

    private val fakeLocationStateUseCase by lazy {
        FakeLocationStateUseCase(
            fakeLocationModule, permissionsModule, localStateRepository, CityDataSource, appDesc, GlobalScope)
            fakeLocationModule, permissionsModule, localStateRepository, CityDataSource, appDesc, context, GlobalScope
        )
    }

    // ViewModelFactories
    val dashBoardViewModelFactory by lazy {
        DashBoardViewModelFactory(getQuickPrivacyStateUseCase, ipScramblingStateUseCase, trackersStatisticsUseCase, trackersStateUseCase)
        DashBoardViewModelFactory(getQuickPrivacyStateUseCase, ipScramblingStateUseCase, trackersStatisticsUseCase, trackersStateUseCase, fakeLocationStateUseCase)
    }

    val fakeLocationViewModelFactory by lazy {
        FakeLocationViewModelFactory(
            getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase,
            fakeLocationStateUseCase = fakeLocationStateUseCase)
            fakeLocationStateUseCase = fakeLocationStateUseCase
        )
    }

    val blockerService = BlockerInterface.getInstance(context)
+8 −5
Original line number Diff line number Diff line
@@ -44,10 +44,13 @@ class LocalStateRepository(context: Context) {

    var fakeLocation: Pair<Float, Float>?
        get() = if (sharedPref.contains(KEY_FAKE_LATITUDE) && sharedPref.contains(
                    KEY_FAKE_LONGITUDE))
                KEY_FAKE_LONGITUDE
            )
        )
            Pair(
                sharedPref.getFloat(KEY_FAKE_LATITUDE, 0f),
                            sharedPref.getFloat(KEY_FAKE_LONGITUDE, 0f))
                sharedPref.getFloat(KEY_FAKE_LONGITUDE, 0f)
            )
        else null
        set(value) {
            if (value == null) {
+106 −17
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@
package foundation.e.privacycentralapp.domain.usecases

import android.app.AppOpsManager
import android.content.Context
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.util.Log
import foundation.e.privacycentralapp.data.repositories.LocalStateRepository
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.dummy.CityDataSource
@@ -26,19 +31,23 @@ import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.AppOpModes
import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlin.random.Random

class FakeLocationStateUseCase(
    private val fakeLocationModule: IFakeLocationModule,

    private val permissionsModule: PermissionsPrivacyModule,
    private val localStateRepository: LocalStateRepository,
    private val citiesRepository: CityDataSource,
    private val appDesc: ApplicationDescription,
    private val appContext: Context,
    private val coroutineScope: CoroutineScope
) {
    private val _locationMode = MutableStateFlow(LocationMode.REAL_LOCATION)
    val locationMode: StateFlow<LocationMode> = _locationMode

    init {
        coroutineScope.launch {
@@ -48,15 +57,27 @@ class FakeLocationStateUseCase(
        }
    }

    fun getLocationMode(): LocationMode = when(localStateRepository.fakeLocation) {
        null -> LocationMode.REAL_LOCATION
        in citiesRepository.citiesLocationsList -> LocationMode.RANDOM_LOCATION
        else -> LocationMode.SPECIFIC_LOCATION
    private val locationManager: LocationManager
        get() = appContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager

    fun getLocationMode(): Triple<LocationMode, Float?, Float?> {
        val fakeLocation = localStateRepository.fakeLocation
        return if (fakeLocation != null && _locationMode.value == LocationMode.SPECIFIC_LOCATION) {
            Triple(
                LocationMode.SPECIFIC_LOCATION,
                fakeLocation.first,
                fakeLocation.second
            )
        } else {
            Triple(_locationMode.value, null, null)
        }
    }

    private fun acquireLocationPermission() {
        permissionsModule.toggleDangerousPermission(appDesc,
            android.Manifest.permission.ACCESS_FINE_LOCATION, true)
        permissionsModule.toggleDangerousPermission(
            appDesc,
            android.Manifest.permission.ACCESS_FINE_LOCATION, true
        )

        // permissionsModule.setAppOpMode(
        //     appDesc, AppOpsManager.OPSTR_COARSE_LOCATION,
@@ -74,10 +95,12 @@ class FakeLocationStateUseCase(
                permissionsModule.setAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION, AppOpModes.ALLOWED)
            }
            fakeLocationModule.startFakeLocation()

            fakeLocationModule.setFakeLocation(fakeLocation.first.toDouble(), fakeLocation.second.toDouble())
            _locationMode.value = if (fakeLocation in citiesRepository.citiesLocationsList) LocationMode.RANDOM_LOCATION
            else LocationMode.SPECIFIC_LOCATION
        } else {
            fakeLocationModule.stopFakeLocation()
            _locationMode.value = LocationMode.REAL_LOCATION
        }
    }

@@ -102,4 +125,70 @@ class FakeLocationStateUseCase(
        applySettings(true, null)
    }

    private var listener: LocationListener? = null

    val currentLocation = MutableStateFlow<Location?>(null)

    private var localListener = object : LocationListener {
        val providerName = LocationManager.NETWORK_PROVIDER

        override fun onLocationChanged(location: Location) {
            Log.e("DebugLoc", "onLocationChanged $location")
            currentLocation.value = location
        }

        override fun onProviderEnabled(provider: String?) {
            Log.e("DebugLoc", "ProvuderEnabled: $provider")
            reset(provider)
        }

        override fun onProviderDisabled(provider: String?) {
            Log.e("DebugLoc", "ProvuderDisabled: $provider")
            reset(provider)
        }

        private fun reset(provider: String?) {
            if (provider == providerName) {
                stopListeningLocation()
                currentLocation.value = null
                startListeningLocation()
            }
        }
    }

    fun startListeningLocation() {
        requestLocationUpdates(localListener)
    }

    fun stopListeningLocation() {
        removeUpdates(localListener)
    }

    fun requestLocationUpdates(listener: LocationListener) {
        acquireLocationPermission()
        try {
            Log.e("DebugLoc", "requestLocationUpdates")
            locationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, // TODO: tight this with fakelocation module.
                0L,
                0f,
                listener
            )
            // locationManager.requestLocationUpdates(
            //     LocationManager.NETWORK_PROVIDER, // TODO: tight this with fakelocation module.
            //     0L,
            //     0f,
            //     listener
            // )

            val location: Location? = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
            location?.let { listener.onLocationChanged(it) }
        } catch (se: SecurityException) {
            Log.e("DebugLoc", "Missing permission", se)
        }
    }

    fun removeUpdates(listener: LocationListener) {
        locationManager.removeUpdates(listener)
    }
}
+9 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import foundation.e.flowmvi.SingleEventProducer
import foundation.e.flowmvi.feature.BaseFeature
import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.domain.usecases.FakeLocationStateUseCase
import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
import foundation.e.privacycentralapp.domain.usecases.IpScramblingStateUseCase
import foundation.e.privacycentralapp.domain.usecases.TrackersStateUseCase
@@ -56,7 +57,7 @@ class DashboardFeature(
        val totalGraph: Int? = null,
        // val graphData
        val trackersCount: Int? = null,
        val activeTrackersCount: Int? = null,
        val dayTrackersCount: Int? = null,
        val dayStatistics: List<Int>? = null
    )

@@ -122,7 +123,8 @@ class DashboardFeature(
            getPrivacyStateUseCase: GetQuickPrivacyStateUseCase,
            ipScramblingStateUseCase: IpScramblingStateUseCase,
            trackersStatisticsUseCase: TrackersStatisticsUseCase,
            trackersStateUseCase: TrackersStateUseCase
            trackersStateUseCase: TrackersStateUseCase,
            fakeLocationStateUseCase: FakeLocationStateUseCase
        ): DashboardFeature =
            DashboardFeature(
                initialState = State(),
@@ -140,6 +142,8 @@ class DashboardFeature(
                        is Effect.TrackersBlockedUpdatedEffect -> state.copy(
                            isAllTrackersBlocked = effect.areAllTrackersBlocked
                        )
                        is Effect.UpdateLocationModeEffect -> state.copy(locationMode = effect.mode)

                        /*is Effect.OpenDashboardEffect -> State.DashboardState(
                            effect.trackersCount,
                            effect.activeTrackersCount,
@@ -214,6 +218,9 @@ class DashboardFeature(
                            },
                            trackersStateUseCase.areAllTrackersBlocked.map {
                                Effect.TrackersBlockedUpdatedEffect(it)
                            },
                            fakeLocationStateUseCase.locationMode.map {
                                Effect.UpdateLocationModeEffect(it)
                            }
                        )
                        /*
Loading