summaryrefslogtreecommitdiff
path: root/app/src/main/java/foundation
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/foundation')
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt5
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt33
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt23
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt16
4 files changed, 51 insertions, 26 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
index 6be3724..a44a00a 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
@@ -40,16 +40,15 @@ import foundation.e.privacycentralapp.features.location.FakeLocationViewModel
import foundation.e.privacycentralapp.features.trackers.TrackersViewModel
import foundation.e.privacycentralapp.features.trackers.apptrackers.AppTrackersFragment
import foundation.e.privacycentralapp.features.trackers.apptrackers.AppTrackersViewModel
+import foundation.e.privacymodules.fakelocation.FakeLocationModule
import foundation.e.privacymodules.ipscrambler.IpScramblerModule
import foundation.e.privacymodules.ipscramblermodule.IIpScramblerModule
-import foundation.e.privacymodules.location.FakeLocationModule
import foundation.e.privacymodules.location.IFakeLocationModule
import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.ApplicationDescription
import foundation.e.privacymodules.trackers.api.BlockTrackersPrivacyModule
import foundation.e.privacymodules.trackers.api.TrackTrackersPrivacyModule
import kotlinx.coroutines.DelicateCoroutinesApi
-import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.GlobalScope
/**
@@ -61,7 +60,7 @@ class DependencyContainer(val app: Application) {
val context: Context by lazy { app.applicationContext }
// Drivers
- private val fakeLocationModule: IFakeLocationModule by lazy { FakeLocationModule(app.applicationContext) }
+ private val fakeLocationModule: FakeLocationModule by lazy { FakeLocationModule(app.applicationContext) }
private val permissionsModule by lazy { PermissionsPrivacyModule(app.applicationContext) }
private val ipScramblerModule: IIpScramblerModule by lazy { IpScramblerModule(app.applicationContext) }
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt
index aa4276d..f7b5439 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt
@@ -28,7 +28,7 @@ import android.util.Log
import foundation.e.privacycentralapp.data.repositories.LocalStateRepository
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.dummy.CityDataSource
-import foundation.e.privacymodules.location.IFakeLocationModule
+import foundation.e.privacymodules.fakelocation.FakeLocationModule
import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.AppOpModes
import foundation.e.privacymodules.permissions.data.ApplicationDescription
@@ -39,7 +39,7 @@ import kotlinx.coroutines.launch
import kotlin.random.Random
class FakeLocationStateUseCase(
- private val fakeLocationModule: IFakeLocationModule,
+ private val fakeLocationModule: FakeLocationModule,
private val permissionsModule: PermissionsPrivacyModule,
private val localStateRepository: LocalStateRepository,
private val citiesRepository: CityDataSource,
@@ -61,23 +61,15 @@ class FakeLocationStateUseCase(
private val locationManager: LocationManager
get() = appContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
- private fun acquireLocationPermission() {
- if (appContext.checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- permissionsModule.toggleDangerousPermission(
- appDesc,
- android.Manifest.permission.ACCESS_FINE_LOCATION,
- true
- )
- }
+ private fun hasAcquireLocationPermission(): Boolean {
+ return (appContext.checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
+ || permissionsModule.toggleDangerousPermission(appDesc, android.Manifest.permission.ACCESS_FINE_LOCATION, true)
}
private fun applySettings(isQuickPrivacyEnabled: Boolean, fakeLocation: Pair<Float, Float>?, isSpecificLocation: Boolean = false) {
_configuredLocationMode.value = computeLocationMode(fakeLocation, isSpecificLocation)
- if (isQuickPrivacyEnabled && fakeLocation != null) {
- if (permissionsModule.getAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION) != AppOpModes.ALLOWED) {
- permissionsModule.setAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION, AppOpModes.ALLOWED)
- }
+ if (isQuickPrivacyEnabled && fakeLocation != null && hasAcquireMockLocationPermission()) {
fakeLocationModule.startFakeLocation()
fakeLocationModule.setFakeLocation(fakeLocation.first.toDouble(), fakeLocation.second.toDouble())
localStateRepository.locationMode.value = configuredLocationMode.value.first
@@ -87,6 +79,11 @@ class FakeLocationStateUseCase(
}
}
+ private fun hasAcquireMockLocationPermission(): Boolean {
+ return (permissionsModule.getAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION) == AppOpModes.ALLOWED)
+ || permissionsModule.setAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION, AppOpModes.ALLOWED)
+ }
+
fun setSpecificLocation(latitude: Float, longitude: Float) {
if (!localStateRepository.isQuickPrivacyEnabled) {
localStateRepository.setShowQuickPrivacyDisabledMessage(true)
@@ -161,8 +158,11 @@ class FakeLocationStateUseCase(
}
}
- fun startListeningLocation() {
- requestLocationUpdates(localListener)
+ fun startListeningLocation(): Boolean {
+ return if (hasAcquireLocationPermission()) {
+ requestLocationUpdates(localListener)
+ true
+ } else false
}
fun stopListeningLocation() {
@@ -170,7 +170,6 @@ class FakeLocationStateUseCase(
}
fun requestLocationUpdates(listener: LocationListener) {
- acquireLocationPermission()
try {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, // TODO: tight this with fakelocation module.
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt
index 2b858e9..d98cb5d 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt
@@ -17,6 +17,7 @@
package foundation.e.privacycentralapp.features.location
+import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.location.Location
@@ -24,6 +25,7 @@ import android.os.Bundle
import android.text.Editable
import android.view.View
import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.NonNull
import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
@@ -81,6 +83,16 @@ class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location)
private var inputJob: Job? = null
+ private val locationPermissionRequest = registerForActivityResult(
+ ActivityResultContracts.RequestMultiplePermissions()
+ ) { permissions ->
+ if (permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false)
+ || permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false)
+ ) {
+ viewModel.submitAction(Action.StartListeningLocation)
+ } // TODO: else.
+ }
+
companion object {
private const val DEBOUNCE_PERIOD = 1000L
}
@@ -147,6 +159,13 @@ class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location)
is FakeLocationViewModel.SingleEvent.LocationUpdatedEvent -> {
updateLocation(event.location, event.mode)
}
+ is FakeLocationViewModel.SingleEvent.RequestLocationPermission -> {
+ // TODO for standalone: rationale dialog
+ locationPermissionRequest.launch(arrayOf(
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.ACCESS_COARSE_LOCATION
+ ))
+ }
}
}
}
@@ -326,13 +345,13 @@ class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location)
override fun onResume() {
super.onResume()
- viewModel.submitAction(Action.EnterScreen)
+ viewModel.submitAction(Action.StartListeningLocation)
binding.mapView.onResume()
}
override fun onPause() {
super.onPause()
- viewModel.submitAction(Action.LeaveScreen)
+ viewModel.submitAction(Action.StopListeningLocation)
binding.mapView.onPause()
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt
index af20a72..afba3d0 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt
@@ -86,8 +86,8 @@ class FakeLocationViewModel(
fun submitAction(action: Action) = viewModelScope.launch {
when (action) {
- is Action.EnterScreen -> fakeLocationStateUseCase.startListeningLocation()
- is Action.LeaveScreen -> fakeLocationStateUseCase.stopListeningLocation()
+ is Action.StartListeningLocation -> actionStartListeningLocation()
+ is Action.StopListeningLocation -> fakeLocationStateUseCase.stopListeningLocation()
is Action.SetSpecificLocationAction -> setSpecificLocation(action)
is Action.UseRandomLocationAction -> fakeLocationStateUseCase.setRandomLocation()
is Action.UseRealLocationAction ->
@@ -97,18 +97,26 @@ class FakeLocationViewModel(
}
}
+ private suspend fun actionStartListeningLocation() {
+ val started = fakeLocationStateUseCase.startListeningLocation()
+ if (!started) {
+ _singleEvents.emit(SingleEvent.RequestLocationPermission)
+ }
+ }
+
private suspend fun setSpecificLocation(action: Action.SetSpecificLocationAction) {
specificLocationInputFlow.emit(action)
}
sealed class SingleEvent {
data class LocationUpdatedEvent(val mode: LocationMode, val location: Location?) : SingleEvent()
+ object RequestLocationPermission: SingleEvent()
data class ErrorEvent(val error: String) : SingleEvent()
}
sealed class Action {
- object EnterScreen : Action()
- object LeaveScreen : Action()
+ object StartListeningLocation : Action()
+ object StopListeningLocation : Action()
object UseRealLocationAction : Action()
object UseRandomLocationAction : Action()
data class SetSpecificLocationAction(