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

Commit 41164f39 authored by Guillaume Jacquart's avatar Guillaume Jacquart Committed by Jonathan Klee
Browse files

2397: Fake location from AdvancedPrivacy ContentProvider.

parent 99bc76b2
Loading
Loading
Loading
Loading
+56 −0
Original line number Original line Diff line number Diff line
package org.microg.gms.location.manager

import android.content.Context
import android.location.Location
import android.net.Uri
import android.os.Bundle
import com.google.android.gms.location.internal.ClientIdentity

object FakeLocationResolver {
    private val FAKE_LOCATIONS_URI = "content://foundation.e.advancedprivacy.fakelocations"

    private val PARAM_UID = "uid"
    private val PARAM_LATITUDE = "latitude"
    private val PARAM_LONGITUDE = "longitude"

    private data class FakeLocation(var latitude: Double, var longitude: Double)

    fun fakeLocations(
        context: Context,
        identity: ClientIdentity,
        baseLocations: List<Location>
    ): List<Location> {
        val latLon = getFakeLocation(context, identity.packageName, identity.uid)
            ?: return baseLocations

        return baseLocations.map { overrideLatLon(it, latLon) }
    }

    private fun getFakeLocation(context: Context, packageName: String, uid: Int): FakeLocation? {
        return runCatching {
            context.contentResolver.call(
                Uri.parse(FAKE_LOCATIONS_URI),
                "",
                packageName,
                Bundle().apply {
                    putInt(PARAM_UID, uid)
                }
            )?.let {
                FakeLocation(
                    it.getDouble(PARAM_LATITUDE),
                    it.getDouble(PARAM_LONGITUDE)
                )
            }
        }.getOrNull()
    }

    private fun overrideLatLon(baseLocation: Location, latLont: FakeLocation): Location {
        val location = Location(baseLocation)
        location.latitude = latLont.latitude
        location.longitude = latLont.longitude
        location.altitude = 3.0
        location.speed = 0.01f

        return location
    }
}
+5 −1
Original line number Original line Diff line number Diff line
@@ -475,7 +475,11 @@ class LocationRequestManager(private val context: Context, override val lifecycl
                        Location(location).apply { provider = "fused" }
                        Location(location).apply { provider = "fused" }
                    }
                    }
                }
                }
                val result = LocationResult.create(listOf(returnedLocation))

                val result = LocationResult.create(FakeLocationResolver.fakeLocations(
                    context, clientIdentity, listOf(returnedLocation)
                ))

                callback?.onLocationResult(result)
                callback?.onLocationResult(result)
                pendingIntent?.send(context, 0, Intent().apply { putExtra(LocationResult.EXTRA_LOCATION_RESULT, result) })
                pendingIntent?.send(context, 0, Intent().apply { putExtra(LocationResult.EXTRA_LOCATION_RESULT, result) })
                if (request.maxUpdates != Int.MAX_VALUE) updates++
                if (request.maxUpdates != Int.MAX_VALUE) updates++