summaryrefslogtreecommitdiff
path: root/app/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/AndroidManifest.xml7
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt27
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt45
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/LocationApiDelegate.kt81
4 files changed, 141 insertions, 19 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 74c226c..5fe282d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,9 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="foundation.e.privacycentralapp">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"
+ tools:ignore="ProtectedPermissions"
+ />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
+ tools:ignore="ProtectedPermissions"
+ />
<application
android:name=".PrivacyCentralApplication"
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt
index d94f71c..fe9359a 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt
@@ -54,10 +54,13 @@ class FakeLocationFeature(
data class ErrorEvent(val error: String) : SingleEvent()
}
- sealed class Action {
+ sealed class Action() {
data class UpdateLocationAction(val latLng: LatLng) : Action()
- object UseRealLocationAction : Action()
- data class UseRandomLocationAction(val cities: Array<String>) : Action() {
+ data class UseRealLocationAction(val locationApiDelegate: LocationApiDelegate) : Action()
+ data class UseRandomLocationAction(
+ val locationApiDelegate: LocationApiDelegate,
+ val cities: Array<String>
+ ) : Action() {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
@@ -74,8 +77,12 @@ class FakeLocationFeature(
}
}
- object UseSpecificLocationAction : Action()
- data class SetFakeLocationAction(val latitude: Double, val longitude: Double) : Action()
+ data class UseSpecificLocationAction(val locationApiDelegate: LocationApiDelegate) : Action()
+ data class SetFakeLocationAction(
+ val locationApiDelegate: LocationApiDelegate,
+ val latitude: Double,
+ val longitude: Double
+ ) : Action()
}
sealed class Effect {
@@ -139,7 +146,7 @@ class FakeLocationFeature(
action.latitude,
action.longitude
)
- // TODO: Call fake location api with specific coordinates here.
+ action.locationApiDelegate.setFakeLocation(action.latitude, action.longitude)
val success = DummyDataSource.setLocationMode(
LocationMode.CUSTOM_LOCATION,
location
@@ -156,7 +163,7 @@ class FakeLocationFeature(
}
is Action.UseRandomLocationAction -> {
val randomCity = CityDataSource.getRandomCity(action.cities)
- // TODO: Call fake location api with random location here.
+ action.locationApiDelegate.setFakeLocation(randomCity.latitude, randomCity.longitude)
val success = DummyDataSource.setLocationMode(
LocationMode.RANDOM_LOCATION,
randomCity.toRandomLocation()
@@ -171,8 +178,8 @@ class FakeLocationFeature(
)
}
}
- Action.UseRealLocationAction -> {
- // TODO: Call turn off fake location api here.
+ is Action.UseRealLocationAction -> {
+ action.locationApiDelegate.startRealLocation()
val success = DummyDataSource.setLocationMode(LocationMode.REAL_LOCATION)
if (success) {
flowOf(
@@ -184,7 +191,7 @@ class FakeLocationFeature(
)
}
}
- Action.UseSpecificLocationAction -> {
+ is Action.UseSpecificLocationAction -> {
flowOf(Effect.SpecificLocationSelectedEffect)
}
}
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 96bebb7..c11a7ea 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
@@ -21,6 +21,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.os.Looper
+import android.os.Process
import android.text.Editable
import android.util.Log
import android.view.Gravity
@@ -57,12 +58,17 @@ import com.mapbox.mapboxsdk.maps.Style
import foundation.e.flowmvi.MVIView
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.dummy.LocationMode
+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.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
+import java.lang.Exception
class FakeLocationFragment :
Fragment(R.layout.fragment_fake_location),
@@ -129,6 +135,23 @@ class FakeLocationFragment :
private const val TAG = "FakeLocationFragment"
private const val DEFAULT_INTERVAL_IN_MILLISECONDS = 1000L
private const val DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS * 5
+ private const val DROPPED_MARKER_LAYER_ID = "DROPPED_MARKER_LAYER_ID"
+ }
+
+ private val fakeLocationModule: IFakeLocation by lazy { FakeLocation(this.requireContext()) }
+ private val permissionsModule by lazy { PermissionsPrivacyModule(this.requireContext()) }
+
+ private val appDesc by lazy {
+ ApplicationDescription(
+ packageName = this.requireContext().packageName,
+ uid = Process.myUid(),
+ label = getString(R.string.app_name),
+ icon = null
+ )
+ }
+
+ private val locationApiDelegate by lazy {
+ LocationApiDelegate(fakeLocationModule, permissionsModule, appDesc)
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -146,6 +169,7 @@ class FakeLocationFragment :
}
is FakeLocationFeature.SingleEvent.SpecificLocationSavedEvent -> {
// Hide camera hover marker when custom location is picked from map.
+ displayToast("Specific location selected")
hoveringMarker?.visibility = View.GONE
isCameraMoved = false
}
@@ -161,6 +185,7 @@ class FakeLocationFragment :
}
}
}
+ locationApiDelegate.startRealLocation()
}
override fun onAttach(context: Context) {
@@ -256,31 +281,33 @@ class FakeLocationFragment :
}
}
- private fun saveSpecificLocation(latitude: Double, longitude: Double) {
- viewModel.submitAction(
- FakeLocationFeature.Action.SetFakeLocationAction(latitude, longitude)
- )
- }
-
private fun toggleLocationType(radioButton: View?) {
if (radioButton is RadioButton) {
val checked = radioButton.isChecked
when (radioButton.id) {
R.id.radio_use_real_location ->
if (checked) {
- viewModel.submitAction(FakeLocationFeature.Action.UseRealLocationAction)
+ viewModel.submitAction(
+ FakeLocationFeature.Action.UseRealLocationAction(
+ locationApiDelegate
+ )
+ )
}
R.id.radio_use_random_location ->
if (checked) {
viewModel.submitAction(
FakeLocationFeature.Action.UseRandomLocationAction(
- resources.getStringArray(R.array.cities)
+ locationApiDelegate, resources.getStringArray(R.array.cities)
)
)
}
R.id.radio_use_specific_location ->
if (checked) {
- viewModel.submitAction(FakeLocationFeature.Action.UseSpecificLocationAction)
+ viewModel.submitAction(
+ FakeLocationFeature.Action.UseSpecificLocationAction(
+ locationApiDelegate
+ )
+ )
}
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/LocationApiDelegate.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/LocationApiDelegate.kt
new file mode 100644
index 0000000..dd2e5c1
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/LocationApiDelegate.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.features.location
+
+import android.app.AppOpsManager
+import android.util.Log
+import foundation.e.privacymodules.location.IFakeLocation
+import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
+import foundation.e.privacymodules.permissions.data.AppOpModes
+import foundation.e.privacymodules.permissions.data.ApplicationDescription
+import java.lang.Exception
+
+class LocationApiDelegate(
+ private val fakeLocationModule: IFakeLocation,
+ private val permissionsModule: PermissionsPrivacyModule,
+ private val appDesc: ApplicationDescription
+) {
+
+ private val TAG = LocationApiDelegate::class.simpleName
+
+ fun setFakeLocation(latitude: Double, longitude: Double) {
+ if (permissionsModule.getAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION) != AppOpModes.ALLOWED) {
+ permissionsModule.setAppOpMode(
+ appDesc, AppOpsManager.OPSTR_MOCK_LOCATION,
+ AppOpModes.ALLOWED
+ )
+ }
+ try {
+ fakeLocationModule.startFakeLocation()
+ } catch (e: Exception) {
+ Log.e(TAG, "Can't startFakeLocation", e)
+ }
+ fakeLocationModule.setFakeLocation(latitude, longitude)
+ }
+
+ fun stopFakeLocation() {
+ try {
+ permissionsModule.setAppOpMode(
+ appDesc, AppOpsManager.OPSTR_MOCK_LOCATION,
+ AppOpModes.IGNORED
+ )
+ permissionsModule.setAppOpMode(
+ appDesc, AppOpsManager.OPSTR_MOCK_LOCATION,
+ AppOpModes.IGNORED
+ )
+ fakeLocationModule.stopFakeLocation()
+ } catch (e: Exception) {
+ Log.e(TAG, "Can't stop FakeLocation", e)
+ }
+ }
+ fun startRealLocation() {
+ stopFakeLocation()
+ try {
+ permissionsModule.setAppOpMode(
+ appDesc, AppOpsManager.OPSTR_COARSE_LOCATION,
+ AppOpModes.ALLOWED
+ )
+ permissionsModule.setAppOpMode(
+ appDesc, AppOpsManager.OPSTR_FINE_LOCATION,
+ AppOpModes.ALLOWED
+ )
+ } catch (e: Exception) {
+ Log.e(TAG, "Can't start RealLocation", e)
+ }
+ }
+}