summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.idea/.name1
-rw-r--r--app/build.gradle21
-rw-r--r--app/src/e/res/values/strings.xml3
-rw-r--r--app/src/google/res/values/strings.xml3
-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
-rw-r--r--privacymodulesapi/build.gradle2
-rw-r--r--privacymodulesapi/privacymodulesapi-debug.aarbin0 -> 34149 bytes
-rw-r--r--privacymodulese/build.gradle3
-rw-r--r--privacymodulese/privacymodulese-debug.aarbin0 -> 16445 bytes
-rw-r--r--privacymodulesgoogle/build.gradle2
-rw-r--r--privacymodulesgoogle/privacymodulesgoogle-release.aarbin0 -> 45057 bytes
-rw-r--r--settings.gradle3
15 files changed, 179 insertions, 19 deletions
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..d32d4d9
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+PrivacyCentralApp \ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 5352608..a095464 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -18,6 +18,21 @@ android {
resValue("string", "mapbox_key", MAPBOX_KEY)
}
+ // We define here the OS flavor e, specific for the /e/ OS version, and google, for any
+ // Andriod device. The e or google prefix is then used in resources, dependencies, ... as
+ // expected by the android gradle plugin.
+ flavorDimensions 'os'
+ productFlavors {
+ e {
+ applicationId 'foundation.e.privacymodulesdemo.e'
+ dimension 'os'
+ }
+ google {
+ applicationId 'foundation.e.privacymodeulesdemo.google'
+ dimension 'os'
+ }
+ }
+
buildTypes {
release {
minifyEnabled false
@@ -41,6 +56,12 @@ android {
}
dependencies {
+ implementation project(":privacymodulesapi")
+
+ // include the google specific version of the modules, just for the google flavor
+ googleImplementation project(":privacymodulesgoogle")
+ // include the e specific version of the modules, just for the e flavor
+ eImplementation project(":privacymodulese")
implementation project(":flow-mvi")
implementation Libs.Kotlin.stdlib
implementation Libs.AndroidX.coreKtx
diff --git a/app/src/e/res/values/strings.xml b/app/src/e/res/values/strings.xml
new file mode 100644
index 0000000..73affbc
--- /dev/null
+++ b/app/src/e/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="app_name">e - PrivacyModulesDemo</string>
+</resources>
diff --git a/app/src/google/res/values/strings.xml b/app/src/google/res/values/strings.xml
new file mode 100644
index 0000000..ebf51d0
--- /dev/null
+++ b/app/src/google/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="app_name">google - PrivacyModulesDemo</string>
+</resources>
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)
+ }
+ }
+}
diff --git a/privacymodulesapi/build.gradle b/privacymodulesapi/build.gradle
new file mode 100644
index 0000000..e9e42c9
--- /dev/null
+++ b/privacymodulesapi/build.gradle
@@ -0,0 +1,2 @@
+configurations.maybeCreate("default")
+artifacts.add("default", file('privacymodulesapi-debug.aar'))
diff --git a/privacymodulesapi/privacymodulesapi-debug.aar b/privacymodulesapi/privacymodulesapi-debug.aar
new file mode 100644
index 0000000..233eb30
--- /dev/null
+++ b/privacymodulesapi/privacymodulesapi-debug.aar
Binary files differ
diff --git a/privacymodulese/build.gradle b/privacymodulese/build.gradle
new file mode 100644
index 0000000..7eb2490
--- /dev/null
+++ b/privacymodulese/build.gradle
@@ -0,0 +1,3 @@
+configurations.maybeCreate("default")
+//artifacts.add("default", file('privacymodulese-release.aar'))
+artifacts.add("default", file('privacymodulese-debug.aar'))
diff --git a/privacymodulese/privacymodulese-debug.aar b/privacymodulese/privacymodulese-debug.aar
new file mode 100644
index 0000000..5107fc8
--- /dev/null
+++ b/privacymodulese/privacymodulese-debug.aar
Binary files differ
diff --git a/privacymodulesgoogle/build.gradle b/privacymodulesgoogle/build.gradle
new file mode 100644
index 0000000..845fe8f
--- /dev/null
+++ b/privacymodulesgoogle/build.gradle
@@ -0,0 +1,2 @@
+configurations.maybeCreate("default")
+artifacts.add("default", file('privacymodulesgoogle-release.aar'))
diff --git a/privacymodulesgoogle/privacymodulesgoogle-release.aar b/privacymodulesgoogle/privacymodulesgoogle-release.aar
new file mode 100644
index 0000000..22871cb
--- /dev/null
+++ b/privacymodulesgoogle/privacymodulesgoogle-release.aar
Binary files differ
diff --git a/settings.gradle b/settings.gradle
index dca731c..6532f7b 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,3 +1,6 @@
include ':flow-mvi'
include ':app'
+include ':privacymodulesgoogle'
+include ':privacymodulese'
+include ':privacymodulesapi'
rootProject.name = "PrivacyCentralApp" \ No newline at end of file