From 53f4a9ce311d612d43fa770cf7e8f8e98fbb43a0 Mon Sep 17 00:00:00 2001 From: Guillaume Jacquart Date: Tue, 12 Sep 2023 06:17:39 +0000 Subject: 2: organise module with clean archi, use Koin for injection. --- .../e/advancedprivacy/fakelocation/KoinModule.kt | 9 ++ .../domain/usecases/FakeLocationModule.kt | 133 +++++++++++++++++++++ .../fakelocation/services/FakeLocationService.kt | 111 +++++++++++++++++ .../fakelocation/FakeLocationModule.kt | 132 -------------------- .../fakelocation/FakeLocationService.kt | 110 ----------------- .../fakelocation/IFakeLocationModule.kt | 41 ------- 6 files changed, 253 insertions(+), 283 deletions(-) create mode 100644 fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/KoinModule.kt create mode 100644 fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/domain/usecases/FakeLocationModule.kt create mode 100644 fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/services/FakeLocationService.kt delete mode 100644 fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt delete mode 100644 fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt delete mode 100644 fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/IFakeLocationModule.kt (limited to 'fakelocation/src/main/java/foundation/e') diff --git a/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/KoinModule.kt b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/KoinModule.kt new file mode 100644 index 0000000..b833181 --- /dev/null +++ b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/KoinModule.kt @@ -0,0 +1,9 @@ +package foundation.e.advancedprivacy.fakelocation + +import foundation.e.advancedprivacy.fakelocation.domain.usecases.FakeLocationModule +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.module + +val fakelocationModule = module { + singleOf(::FakeLocationModule) +} diff --git a/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/domain/usecases/FakeLocationModule.kt b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/domain/usecases/FakeLocationModule.kt new file mode 100644 index 0000000..c9aac0a --- /dev/null +++ b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/domain/usecases/FakeLocationModule.kt @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2022 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 . + */ + +package foundation.e.advancedprivacy.fakelocation.domain.usecases + +import android.content.Context +import android.content.Context.LOCATION_SERVICE +import android.location.Location +import android.location.LocationManager +import android.location.LocationManager.GPS_PROVIDER +import android.location.LocationManager.NETWORK_PROVIDER +import android.location.provider.ProviderProperties +import android.os.Build +import android.os.SystemClock +import android.util.Log +import foundation.e.advancedprivacy.fakelocation.services.FakeLocationService + +/** + * Implementation of the functionality of fake location. + * All of them are available for normal application, so just one version is enough. + * + * @param context an Android context, to retrieve system services for example. + */ +class FakeLocationModule(private val context: Context) { + companion object { + private const val TAG = "FakeLocationModule" + } + + /** + * Handy accessor to the locationManager service. + * We avoid getting it on module initialization to wait for the context to be ready. + */ + private val locationManager: LocationManager get() = + context.getSystemService(LOCATION_SERVICE) as LocationManager + + /** + * List of all the Location provider that will be mocked. + */ + private val providers = locationManager.allProviders + .intersect(listOf(GPS_PROVIDER, NETWORK_PROVIDER)) + + /** + * @see IFakeLocationModule.startFakeLocation + */ + @Synchronized + fun startFakeLocation() { + providers.forEach { provider -> + try { + locationManager.removeTestProvider(provider) + } catch (e: Exception) { + Log.w(TAG, "Test provider $provider already removed.") + } + + locationManager.addTestProvider( + provider, + false, + false, + false, + false, + false, + true, + true, + ProviderProperties.POWER_USAGE_LOW, + ProviderProperties.ACCURACY_FINE + ) + try { + locationManager.setTestProviderEnabled(provider, true) + } catch (e: Exception) { + Log.e(TAG, "Can't enable test $provider", e) + } + } + } + + fun setFakeLocation(latitude: Double, longitude: Double) { + context.startService(FakeLocationService.buildFakeLocationIntent(context, latitude, longitude)) + } + + internal fun setTestProviderLocation(latitude: Double, longitude: Double) { + providers.forEach { provider -> + val location = Location(provider) + location.latitude = latitude + location.longitude = longitude + + // Set default value for all the other required fields. + location.altitude = 3.0 + location.time = System.currentTimeMillis() + location.speed = 0.01f + location.bearing = 1f + location.accuracy = 3f + location.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos() + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + location.bearingAccuracyDegrees = 0.1f + location.verticalAccuracyMeters = 0.1f + location.speedAccuracyMetersPerSecond = 0.01f + } + try { + locationManager.setTestProviderLocation(provider, location) + } catch (e: Exception) { + Log.e(TAG, "Can't set location for test provider $provider", e) + } + } + } + + /** + * @see IFakeLocationModule.stopFakeLocation + */ + fun stopFakeLocation() { + context.stopService(FakeLocationService.buildStopIntent(context)) + providers.forEach { provider -> + try { + locationManager.setTestProviderEnabled(provider, false) + locationManager.removeTestProvider(provider) + } catch (e: Exception) { + Log.d(TAG, "Test provider $provider already removed.") + } + } + } +} diff --git a/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/services/FakeLocationService.kt b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/services/FakeLocationService.kt new file mode 100644 index 0000000..6eaae54 --- /dev/null +++ b/fakelocation/src/main/java/foundation/e/advancedprivacy/fakelocation/services/FakeLocationService.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2022 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 . + */ + +package foundation.e.advancedprivacy.fakelocation.services + +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.CountDownTimer +import android.os.IBinder +import android.util.Log +import foundation.e.advancedprivacy.fakelocation.domain.usecases.FakeLocationModule + +class FakeLocationService : Service() { + + enum class Actions { + START_FAKE_LOCATION + } + + companion object { + private const val PERIOD_LOCATION_UPDATE = 1000L + private const val PERIOD_UPDATES_SERIE = 2 * 60 * 1000L + + private const val PARAM_LATITUDE = "PARAM_LATITUDE" + private const val PARAM_LONGITUDE = "PARAM_LONGITUDE" + + fun buildFakeLocationIntent(context: Context, latitude: Double, longitude: Double): Intent { + return Intent(context, FakeLocationService::class.java).apply { + action = Actions.START_FAKE_LOCATION.name + putExtra(PARAM_LATITUDE, latitude) + putExtra(PARAM_LONGITUDE, longitude) + } + } + + fun buildStopIntent(context: Context) = Intent(context, FakeLocationService::class.java) + } + + private lateinit var fakeLocationModule: FakeLocationModule + + private var countDownTimer: CountDownTimer? = null + + private var fakeLocation: Pair? = null + + override fun onCreate() { + super.onCreate() + fakeLocationModule = FakeLocationModule(applicationContext) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + intent?.let { + when (it.action?.let { str -> Actions.valueOf(str) }) { + Actions.START_FAKE_LOCATION -> { + + fakeLocation = Pair( + it.getDoubleExtra(PARAM_LATITUDE, 0.0), + it.getDoubleExtra(PARAM_LONGITUDE, 0.0) + ) + initTimer() + } + else -> {} + } + } + + return START_STICKY + } + + override fun onDestroy() { + countDownTimer?.cancel() + super.onDestroy() + } + + private fun initTimer() { + countDownTimer?.cancel() + countDownTimer = object : CountDownTimer(PERIOD_UPDATES_SERIE, PERIOD_LOCATION_UPDATE) { + override fun onTick(millisUntilFinished: Long) { + fakeLocation?.let { + try { + fakeLocationModule.setTestProviderLocation( + it.first, + it.second + ) + } catch (e: Exception) { + Log.d("FakeLocationService", "setting fake location", e) + } + } + } + + override fun onFinish() { + initTimer() + } + }.start() + } + + override fun onBind(intent: Intent?): IBinder? { + return null + } +} diff --git a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt b/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt deleted file mode 100644 index 4245836..0000000 --- a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2022 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 . - */ - -package foundation.e.privacymodules.fakelocation - -import android.content.Context -import android.content.Context.LOCATION_SERVICE -import android.location.Location -import android.location.LocationManager -import android.location.LocationManager.GPS_PROVIDER -import android.location.LocationManager.NETWORK_PROVIDER -import android.location.provider.ProviderProperties -import android.os.Build -import android.os.SystemClock -import android.util.Log - -/** - * Implementation of the functionality of fake location. - * All of them are available for normal application, so just one version is enough. - * - * @param context an Android context, to retrieve system services for example. - */ -class FakeLocationModule(private val context: Context) : IFakeLocationModule { - companion object { - private const val TAG = "FakeLocationModule" - } - - /** - * Handy accessor to the locationManager service. - * We avoid getting it on module initialization to wait for the context to be ready. - */ - private val locationManager: LocationManager get() = - context.getSystemService(LOCATION_SERVICE) as LocationManager - - /** - * List of all the Location provider that will be mocked. - */ - private val providers = locationManager.allProviders - .intersect(listOf(GPS_PROVIDER, NETWORK_PROVIDER)) - - /** - * @see IFakeLocationModule.startFakeLocation - */ - @Synchronized - override fun startFakeLocation() { - providers.forEach { provider -> - try { - locationManager.removeTestProvider(provider) - } catch (e: Exception) { - Log.w(TAG, "Test provider $provider already removed.") - } - - locationManager.addTestProvider( - provider, - false, - false, - false, - false, - false, - true, - true, - ProviderProperties.POWER_USAGE_LOW, - ProviderProperties.ACCURACY_FINE - ) - try { - locationManager.setTestProviderEnabled(provider, true) - } catch (e: Exception) { - Log.e(TAG, "Can't enable test $provider", e) - } - } - } - - override fun setFakeLocation(latitude: Double, longitude: Double) { - context.startService(FakeLocationService.buildFakeLocationIntent(context, latitude, longitude)) - } - - internal fun setTestProviderLocation(latitude: Double, longitude: Double) { - providers.forEach { provider -> - val location = Location(provider) - location.latitude = latitude - location.longitude = longitude - - // Set default value for all the other required fields. - location.altitude = 3.0 - location.time = System.currentTimeMillis() - location.speed = 0.01f - location.bearing = 1f - location.accuracy = 3f - location.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos() - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - location.bearingAccuracyDegrees = 0.1f - location.verticalAccuracyMeters = 0.1f - location.speedAccuracyMetersPerSecond = 0.01f - } - try { - locationManager.setTestProviderLocation(provider, location) - } catch (e: Exception) { - Log.e(TAG, "Can't set location for test provider $provider", e) - } - } - } - - /** - * @see IFakeLocationModule.stopFakeLocation - */ - override fun stopFakeLocation() { - context.stopService(FakeLocationService.buildStopIntent(context)) - providers.forEach { provider -> - try { - locationManager.setTestProviderEnabled(provider, false) - locationManager.removeTestProvider(provider) - } catch (e: Exception) { - Log.d(TAG, "Test provider $provider already removed.") - } - } - } -} diff --git a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt b/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt deleted file mode 100644 index 34620fe..0000000 --- a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2022 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 . - */ - -package foundation.e.privacymodules.fakelocation - -import android.app.Service -import android.content.Context -import android.content.Intent -import android.os.CountDownTimer -import android.os.IBinder -import android.util.Log - -class FakeLocationService : Service() { - - enum class Actions { - START_FAKE_LOCATION - } - - companion object { - private const val PERIOD_LOCATION_UPDATE = 1000L - private const val PERIOD_UPDATES_SERIE = 2 * 60 * 1000L - - private const val PARAM_LATITUDE = "PARAM_LATITUDE" - private const val PARAM_LONGITUDE = "PARAM_LONGITUDE" - - fun buildFakeLocationIntent(context: Context, latitude: Double, longitude: Double): Intent { - return Intent(context, FakeLocationService::class.java).apply { - action = Actions.START_FAKE_LOCATION.name - putExtra(PARAM_LATITUDE, latitude) - putExtra(PARAM_LONGITUDE, longitude) - } - } - - fun buildStopIntent(context: Context) = Intent(context, FakeLocationService::class.java) - } - - private lateinit var fakeLocationModule: FakeLocationModule - - private var countDownTimer: CountDownTimer? = null - - private var fakeLocation: Pair? = null - - override fun onCreate() { - super.onCreate() - fakeLocationModule = FakeLocationModule(applicationContext) - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - intent?.let { - when (it.action?.let { str -> Actions.valueOf(str) }) { - Actions.START_FAKE_LOCATION -> { - - fakeLocation = Pair( - it.getDoubleExtra(PARAM_LATITUDE, 0.0), - it.getDoubleExtra(PARAM_LONGITUDE, 0.0) - ) - initTimer() - } - else -> {} - } - } - - return START_STICKY - } - - override fun onDestroy() { - countDownTimer?.cancel() - super.onDestroy() - } - - private fun initTimer() { - countDownTimer?.cancel() - countDownTimer = object : CountDownTimer(PERIOD_UPDATES_SERIE, PERIOD_LOCATION_UPDATE) { - override fun onTick(millisUntilFinished: Long) { - fakeLocation?.let { - try { - fakeLocationModule.setTestProviderLocation( - it.first, - it.second - ) - } catch (e: Exception) { - Log.d("FakeLocationService", "setting fake location", e) - } - } - } - - override fun onFinish() { - initTimer() - } - }.start() - } - - override fun onBind(intent: Intent?): IBinder? { - return null - } -} diff --git a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/IFakeLocationModule.kt b/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/IFakeLocationModule.kt deleted file mode 100644 index 32906f8..0000000 --- a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/IFakeLocationModule.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2022 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 . - */ - -package foundation.e.privacymodules.fakelocation - -/** - * Manage a fake location on the device. - */ -interface IFakeLocationModule { - /** - * Start to fake the location module. Call [setFakeLocation] after to set the fake - * position. - */ - fun startFakeLocation() - - /** - * Set or update the faked position. - * @param latitude the latitude of the fake position in degrees. - * @param longitude the longitude of the fake position in degrees. - */ - fun setFakeLocation(latitude: Double, longitude: Double) - - /** - * Stop the fake location module, giving back hand to the true location modules. - */ - fun stopFakeLocation() -} -- cgit v1.2.1