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

Commit 379edfb3 authored by Guillaume Jacquart's avatar Guillaume Jacquart
Browse files

Merge branch '2-simplify_modules' into 'sdk-29'

Update to  privacy module API 1.2.0

See merge request !9
parents 7ea84d55 b6e5aafa
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.5.20"
    ext.kotlin_version = "1.6.10"
    ext.advanced_privacy_version = "1.2.0"
    repositories {
        google()
        mavenCentral()
+2 −3
Original line number Diff line number Diff line
@@ -9,8 +9,7 @@ android {
    defaultConfig {
        minSdkVersion 26
        targetSdkVersion 29
        versionCode 3
        versionName "0.4.3"
        versionName advanced_privacy_version
        consumerProguardFiles "consumer-rules.pro"
    }

@@ -27,7 +26,7 @@ android {
}

dependencies {
    implementation 'foundation.e:privacymodule.api:0.5.0'
    implementation "foundation.e:privacymodule.api:$advanced_privacy_version"

    implementation 'androidx.core:core-ktx:1.6.0'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
+0 −4
Original line number Diff line number Diff line
@@ -33,8 +33,4 @@
        />
    <uses-permission android:name="android.permission.CONTROL_VPN"
        tools:ignore="ProtectedPermissions" />
    <application>
        <service android:name="foundation.e.privacymodules.location.FakeLocationService"
            android:enabled="true" />
    </application>
</manifest>
+0 −100
Original line number Diff line number Diff line
package foundation.e.privacymodules.location

import android.content.Context
import android.content.Context.LOCATION_SERVICE
import android.location.Criteria
import android.location.Location
import android.location.LocationManager
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(protected val context: Context): IFakeLocationModule {

    /**
     * List of all the Location provider that will be mocked.
     */
    private val providers = listOf(LocationManager.NETWORK_PROVIDER, LocationManager.GPS_PROVIDER)

    /**
     * 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

    /**
     * @see IFakeLocationModule.startFakeLocation
     */
    @Synchronized
    override fun startFakeLocation() {
        providers.forEach { provider ->
            try {
                locationManager.removeTestProvider(provider)
            } catch(e: Exception) {
                Log.d("FakeLocationModule", "Test provider $provider already removed.")
            }

            locationManager.addTestProvider(
                provider,
                false,
                false,
                false,
                false,
                false,
                true,
                true,
                Criteria.POWER_LOW, Criteria.ACCURACY_FINE)
            locationManager.setTestProviderEnabled(provider, true)
        }
    }

    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
            }

            locationManager.setTestProviderLocation(provider, location)
        }
    }

    /**
     * @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("FakeLocationModule", "Test provider $provider already removed.")
            }
        }
    }
}
+0 −94
Original line number Diff line number Diff line
package foundation.e.privacymodules.location


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<Double, Double>? = 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()
                }
            }
        }

        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
    }
}
Loading