diff --git a/play-services-location-core/build.gradle b/play-services-location-core/build.gradle index 0556c781..a15115fe 100644 --- a/play-services-location-core/build.gradle +++ b/play-services-location-core/build.gradle @@ -15,10 +15,10 @@ dependencies { implementation "org.microg.nlp:location-v2:$nlpVersion" implementation "org.microg.nlp:location-v3:$nlpVersion" implementation "org.microg.nlp:service:$nlpVersion" - implementation "org.microg.nlp:client:$nlpVersion" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion" + api "org.microg.nlp:client:$nlpVersion" api "org.microg.nlp:ui:$nlpVersion" } diff --git a/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManager.java b/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManager.java index ae767666..0ad9e872 100644 --- a/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManager.java +++ b/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManager.java @@ -64,18 +64,28 @@ public class GoogleLocationManager implements LocationChangeListener { this.gpsProvider = null; } if (Utils.hasSelfPermissionOrNotify(context, Manifest.permission.ACCESS_COARSE_LOCATION)) { - if (locationManager.getAllProviders().contains(NETWORK_PROVIDER)) { - this.networkProvider = new UnifiedLocationProvider(context, this); - } else { - // TODO: Add ability to directly contact UnifiedNlp without the system location provider - this.networkProvider = null; - } + this.networkProvider = new UnifiedLocationProvider(context, this); } else { this.networkProvider = null; } mockProvider = new MockLocationProvider(this); } + public void invokeOnceReady(Runnable runnable) { + Runnable networkRunnable = () -> { + if (networkProvider != null) { + networkProvider.invokeOnceReady(runnable); + } else { + runnable.run(); + } + }; + if (gpsProvider != null) { + gpsProvider.invokeOnceReady(networkRunnable); + } else { + networkRunnable.run(); + } + } + public Location getLastLocation(String packageName) { return getLocation(hasFineLocationPermission(), hasCoarseLocationPermission()); } diff --git a/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManagerService.java b/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManagerService.java index 1a105150..f2761010 100644 --- a/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManagerService.java +++ b/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManagerService.java @@ -17,6 +17,7 @@ package org.microg.gms.location; import android.os.RemoteException; +import android.util.Log; import com.google.android.gms.common.internal.GetServiceRequest; import com.google.android.gms.common.internal.IGmsCallbacks; @@ -33,6 +34,12 @@ public class GoogleLocationManagerService extends BaseService { @Override public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException { - callback.onPostInitComplete(0, impl.asBinder(), null); + impl.invokeOnceReady(() -> { + try { + callback.onPostInitComplete(0, impl.asBinder(), null); + } catch (RemoteException e) { + Log.w(TAG, e); + } + }); } } diff --git a/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManagerServiceImpl.java b/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManagerServiceImpl.java index 31ac74a3..b4315769 100644 --- a/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManagerServiceImpl.java +++ b/play-services-location-core/src/main/java/org/microg/gms/location/GoogleLocationManagerServiceImpl.java @@ -68,6 +68,10 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ this.context = context; } + public void invokeOnceReady(Runnable runnable) { + getLocationManager().invokeOnceReady(runnable); + } + private GoogleLocationManager getLocationManager() { if (locationManager == null) locationManager = new GoogleLocationManager(context); diff --git a/play-services-location-core/src/main/java/org/microg/gms/location/RealLocationProvider.java b/play-services-location-core/src/main/java/org/microg/gms/location/RealLocationProvider.java index 0fe9e67b..98e1947a 100644 --- a/play-services-location-core/src/main/java/org/microg/gms/location/RealLocationProvider.java +++ b/play-services-location-core/src/main/java/org/microg/gms/location/RealLocationProvider.java @@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicBoolean; @SuppressWarnings("MissingPermission") public class RealLocationProvider { public static final String TAG = "GmsLocProviderReal"; - private static final int MIN_GPS_TIME = 30000; + private static final int MIN_GPS_TIME = 10000; private final LocationManager locationManager; private final String name; @@ -76,6 +76,11 @@ public class RealLocationProvider { if (newLocation != null) lastLocation = newLocation; } + public void invokeOnceReady(Runnable runnable) { + // Always ready + runnable.run(); + } + public Location getLastLocation() { if (!connected.get()) { updateLastLocation(); diff --git a/play-services-location-core/src/main/java/org/microg/gms/location/UnifiedLocationProvider.kt b/play-services-location-core/src/main/java/org/microg/gms/location/UnifiedLocationProvider.kt index 51cbfbf5..e56e6c9f 100644 --- a/play-services-location-core/src/main/java/org/microg/gms/location/UnifiedLocationProvider.kt +++ b/play-services-location-core/src/main/java/org/microg/gms/location/UnifiedLocationProvider.kt @@ -3,6 +3,7 @@ package org.microg.gms.location import android.content.Context import android.location.Location import android.util.Log +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import org.microg.nlp.client.UnifiedLocationClient @@ -22,10 +23,30 @@ class UnifiedLocationProvider(context: Context?, changeListener: LocationChangeL changeListener.onLocationChanged() } } + private var ready = false + private val invokeOnceReady = hashSetOf() private fun updateLastLocation() { - GlobalScope.launch { - client.getLastLocation()?.let { lastLocation = it } + GlobalScope.launch(Dispatchers.Main) { + Log.d(TAG, "unified network: requesting last location") + val lastLocation = client.getLastLocation() + Log.d(TAG, "unified network: got last location: $lastLocation") + if (lastLocation != null) { + this@UnifiedLocationProvider.lastLocation = lastLocation + } + synchronized(invokeOnceReady) { + for (runnable in invokeOnceReady) { + runnable.run() + } + ready = true + } + } + } + + fun invokeOnceReady(runnable: Runnable) { + synchronized(invokeOnceReady) { + if (ready) runnable.run() + else invokeOnceReady.add(runnable) } } @@ -92,4 +113,4 @@ class UnifiedLocationProvider(context: Context?, changeListener: LocationChangeL this.changeListener = changeListener updateLastLocation() } -} \ No newline at end of file +}