Loading play-services-location/core/src/main/kotlin/org/microg/gms/location/manager/FakeLocationResolver.kt +32 −0 Original line number Diff line number Diff line Loading @@ -3,7 +3,9 @@ package org.microg.gms.location.manager import android.content.Context import android.location.Location import android.net.Uri import android.os.Build import android.os.Bundle import android.os.SystemClock import com.google.android.gms.location.internal.ClientIdentity object FakeLocationResolver { Loading @@ -13,6 +15,8 @@ object FakeLocationResolver { private val PARAM_LATITUDE = "latitude" private val PARAM_LONGITUDE = "longitude" private val FAKE_LOCATION_PROVIDER = "fused" private data class FakeLocation(var latitude: Double, var longitude: Double) fun fakeLocation( Loading @@ -26,6 +30,34 @@ object FakeLocationResolver { return overrideLatLon(baseLocation, latLon) } fun buildFakeLocation( context: Context, identity: ClientIdentity, ): Location? { val latLon = getFakeLocation(context, identity.packageName, identity.uid) ?: return null val location = Location(FAKE_LOCATION_PROVIDER) location.latitude = latLon.latitude location.longitude = latLon.longitude // Set default value for all the other required fields. location.accuracy = 3f location.altitude = 3.0 location.bearing = 1f location.speed = 0.01f location.time = System.currentTimeMillis() 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 } return location } private fun getFakeLocation(context: Context, packageName: String, uid: Int): FakeLocation? { return runCatching { context.contentResolver.call( Loading play-services-location/core/src/main/kotlin/org/microg/gms/location/manager/LocationManager.kt +1 −6 Original line number Diff line number Diff line Loading @@ -82,7 +82,7 @@ class LocationManager(private val context: Context, override val lifecycle: Life val permissionGranularity = context.granularityFromPermission(clientIdentity) var effectiveGranularity = getEffectiveGranularity(request.granularity, permissionGranularity) if (effectiveGranularity == GRANULARITY_FINE && database.getForceCoarse(clientIdentity.packageName) && !clientIdentity.isSelfUser()) effectiveGranularity = GRANULARITY_COARSE val baseLocation = if (effectiveGranularity > permissionGranularity) { val returnedLocation = if (effectiveGranularity > permissionGranularity) { // No last location available at requested granularity due to lack of permission null } else { Loading @@ -99,11 +99,6 @@ class LocationManager(private val context: Context, override val lifecycle: Life processedLocation } } val returnedLocation = baseLocation?.let { FakeLocationResolver.fakeLocation(context, clientIdentity, it) } if (!clientIdentity.isSelfUser()) database.noteAppLocation(clientIdentity.packageName, returnedLocation) return returnedLocation?.let { Location(it).apply { provider = "fused" } } } Loading play-services-location/core/src/main/kotlin/org/microg/gms/location/manager/LocationManagerInstance.kt +48 −14 Original line number Diff line number Diff line Loading @@ -164,6 +164,13 @@ class LocationManagerInstance( scope.cancel() } } val fakeLocation = FakeLocationResolver.buildFakeLocation(context, clientIdentity) if (fakeLocation != null) { launch { callbackForRequest.onLocationResult(LocationResult.create(listOf(fakeLocation))) } } else { val currentLocationRequest = LocationRequest.Builder(request.priority, 1000) .setGranularity(request.granularity) .setMaxUpdateAgeMillis(request.maxUpdateAgeMillis) Loading @@ -173,6 +180,7 @@ class LocationManagerInstance( .setThrottleBehavior(request.throttleBehavior) .build() locationManager.addBinderRequest(clientIdentity, binderIdentity, callbackForRequest, currentLocationRequest) } awaitCancellation() } catch (e: CancellationException) { // Don't send result. Either this was cancelled from the CancelToken or because a location was retrieved. Loading Loading @@ -204,7 +212,12 @@ class LocationManagerInstance( val clientIdentity = getClientIdentity() lifecycleScope.launchWhenStarted { try { val fakeLocation = FakeLocationResolver.buildFakeLocation(context, clientIdentity) if (fakeLocation != null) { callback.onLocationStatus(Status.SUCCESS, fakeLocation) } else { callback.onLocationStatus(Status.SUCCESS, locationManager.getLastLocation(clientIdentity, request)) } } catch (e: Exception) { try { callback.onLocationStatus(Status(CommonStatusCodes.ERROR, e.message), null) Loading Loading @@ -303,8 +316,16 @@ class LocationManagerInstance( val clientIdentity = getClientIdentity() lifecycleScope.launchWhenStarted { try { val fakeLocation = FakeLocationResolver.buildFakeLocation(context, clientIdentity) if (fakeLocation != null) { statusCallback.onResult(Status.SUCCESS) launch { callback.onLocationResult(LocationResult.create(listOf(fakeLocation))) } } else { locationManager.updateBinderRequest(clientIdentity, oldBinder, binder, callback, request) statusCallback.onResult(Status.SUCCESS) } } catch (e: Exception) { try { statusCallback.onResult(Status(CommonStatusCodes.ERROR, e.message)) Loading @@ -321,8 +342,21 @@ class LocationManagerInstance( val clientIdentity = getClientIdentity() lifecycleScope.launchWhenStarted { try { val fakeLocation = FakeLocationResolver.buildFakeLocation(context, clientIdentity) if (fakeLocation != null) { statusCallback.onResult(Status.SUCCESS) launch { pendingIntent.send(context, 0, Intent().apply { putExtra( LocationResult.EXTRA_LOCATION_RESULT, LocationResult.create(listOf(fakeLocation)) ) }) } } else { locationManager.addIntentRequest(clientIdentity, pendingIntent, request) statusCallback.onResult(Status.SUCCESS) } } catch (e: Exception) { try { statusCallback.onResult(Status(CommonStatusCodes.ERROR, e.message)) Loading Loading
play-services-location/core/src/main/kotlin/org/microg/gms/location/manager/FakeLocationResolver.kt +32 −0 Original line number Diff line number Diff line Loading @@ -3,7 +3,9 @@ package org.microg.gms.location.manager import android.content.Context import android.location.Location import android.net.Uri import android.os.Build import android.os.Bundle import android.os.SystemClock import com.google.android.gms.location.internal.ClientIdentity object FakeLocationResolver { Loading @@ -13,6 +15,8 @@ object FakeLocationResolver { private val PARAM_LATITUDE = "latitude" private val PARAM_LONGITUDE = "longitude" private val FAKE_LOCATION_PROVIDER = "fused" private data class FakeLocation(var latitude: Double, var longitude: Double) fun fakeLocation( Loading @@ -26,6 +30,34 @@ object FakeLocationResolver { return overrideLatLon(baseLocation, latLon) } fun buildFakeLocation( context: Context, identity: ClientIdentity, ): Location? { val latLon = getFakeLocation(context, identity.packageName, identity.uid) ?: return null val location = Location(FAKE_LOCATION_PROVIDER) location.latitude = latLon.latitude location.longitude = latLon.longitude // Set default value for all the other required fields. location.accuracy = 3f location.altitude = 3.0 location.bearing = 1f location.speed = 0.01f location.time = System.currentTimeMillis() 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 } return location } private fun getFakeLocation(context: Context, packageName: String, uid: Int): FakeLocation? { return runCatching { context.contentResolver.call( Loading
play-services-location/core/src/main/kotlin/org/microg/gms/location/manager/LocationManager.kt +1 −6 Original line number Diff line number Diff line Loading @@ -82,7 +82,7 @@ class LocationManager(private val context: Context, override val lifecycle: Life val permissionGranularity = context.granularityFromPermission(clientIdentity) var effectiveGranularity = getEffectiveGranularity(request.granularity, permissionGranularity) if (effectiveGranularity == GRANULARITY_FINE && database.getForceCoarse(clientIdentity.packageName) && !clientIdentity.isSelfUser()) effectiveGranularity = GRANULARITY_COARSE val baseLocation = if (effectiveGranularity > permissionGranularity) { val returnedLocation = if (effectiveGranularity > permissionGranularity) { // No last location available at requested granularity due to lack of permission null } else { Loading @@ -99,11 +99,6 @@ class LocationManager(private val context: Context, override val lifecycle: Life processedLocation } } val returnedLocation = baseLocation?.let { FakeLocationResolver.fakeLocation(context, clientIdentity, it) } if (!clientIdentity.isSelfUser()) database.noteAppLocation(clientIdentity.packageName, returnedLocation) return returnedLocation?.let { Location(it).apply { provider = "fused" } } } Loading
play-services-location/core/src/main/kotlin/org/microg/gms/location/manager/LocationManagerInstance.kt +48 −14 Original line number Diff line number Diff line Loading @@ -164,6 +164,13 @@ class LocationManagerInstance( scope.cancel() } } val fakeLocation = FakeLocationResolver.buildFakeLocation(context, clientIdentity) if (fakeLocation != null) { launch { callbackForRequest.onLocationResult(LocationResult.create(listOf(fakeLocation))) } } else { val currentLocationRequest = LocationRequest.Builder(request.priority, 1000) .setGranularity(request.granularity) .setMaxUpdateAgeMillis(request.maxUpdateAgeMillis) Loading @@ -173,6 +180,7 @@ class LocationManagerInstance( .setThrottleBehavior(request.throttleBehavior) .build() locationManager.addBinderRequest(clientIdentity, binderIdentity, callbackForRequest, currentLocationRequest) } awaitCancellation() } catch (e: CancellationException) { // Don't send result. Either this was cancelled from the CancelToken or because a location was retrieved. Loading Loading @@ -204,7 +212,12 @@ class LocationManagerInstance( val clientIdentity = getClientIdentity() lifecycleScope.launchWhenStarted { try { val fakeLocation = FakeLocationResolver.buildFakeLocation(context, clientIdentity) if (fakeLocation != null) { callback.onLocationStatus(Status.SUCCESS, fakeLocation) } else { callback.onLocationStatus(Status.SUCCESS, locationManager.getLastLocation(clientIdentity, request)) } } catch (e: Exception) { try { callback.onLocationStatus(Status(CommonStatusCodes.ERROR, e.message), null) Loading Loading @@ -303,8 +316,16 @@ class LocationManagerInstance( val clientIdentity = getClientIdentity() lifecycleScope.launchWhenStarted { try { val fakeLocation = FakeLocationResolver.buildFakeLocation(context, clientIdentity) if (fakeLocation != null) { statusCallback.onResult(Status.SUCCESS) launch { callback.onLocationResult(LocationResult.create(listOf(fakeLocation))) } } else { locationManager.updateBinderRequest(clientIdentity, oldBinder, binder, callback, request) statusCallback.onResult(Status.SUCCESS) } } catch (e: Exception) { try { statusCallback.onResult(Status(CommonStatusCodes.ERROR, e.message)) Loading @@ -321,8 +342,21 @@ class LocationManagerInstance( val clientIdentity = getClientIdentity() lifecycleScope.launchWhenStarted { try { val fakeLocation = FakeLocationResolver.buildFakeLocation(context, clientIdentity) if (fakeLocation != null) { statusCallback.onResult(Status.SUCCESS) launch { pendingIntent.send(context, 0, Intent().apply { putExtra( LocationResult.EXTRA_LOCATION_RESULT, LocationResult.create(listOf(fakeLocation)) ) }) } } else { locationManager.addIntentRequest(clientIdentity, pendingIntent, request) statusCallback.onResult(Status.SUCCESS) } } catch (e: Exception) { try { statusCallback.onResult(Status(CommonStatusCodes.ERROR, e.message)) Loading