diff --git a/lost/src/main/java/com/mapzen/android/lost/internal/FusedLocationProviderApiImpl.java b/lost/src/main/java/com/mapzen/android/lost/internal/FusedLocationProviderApiImpl.java index 18a4ea9..e3c4bec 100644 --- a/lost/src/main/java/com/mapzen/android/lost/internal/FusedLocationProviderApiImpl.java +++ b/lost/src/main/java/com/mapzen/android/lost/internal/FusedLocationProviderApiImpl.java @@ -8,6 +8,7 @@ import android.content.Context; import android.location.Location; import android.os.Looper; +import android.support.annotation.VisibleForTesting; import java.io.File; import java.util.ArrayList; @@ -42,9 +43,12 @@ public Location getLastLocation() { @Override public void requestLocationUpdates(LocationRequest request, LocationListener listener) { + LocationEngine existing = locationEngines.get(request); LocationEngine engine = locationEngineForRequest(request); addListenerForEngine(engine, listener); - engine.setRequest(request); + if (existing == null) { + engine.setRequest(request); + } } @Override @@ -80,7 +84,7 @@ public void setMockMode(boolean isMockMode) { private void toggleMockMode() { mockMode = !mockMode; - shutdownAllEngines(); + toggleAllEngines(); if (mockMode) { lastLocationEngine = new MockEngine(context, null); } else { @@ -182,6 +186,41 @@ private LocationEngine removeListenerFromEngine(LocationListener listener) { return null; } + private void toggleAllEngines() { + HashMap enginesToAdd = new HashMap<>(); + HashMap> listenersToAdd = new HashMap<>(); + for (LocationRequest request : locationEngines.keySet()) { + LocationEngine existing = locationEngines.get(request); + LocationEngine engineToAdd; + if (mockMode) { + engineToAdd = new MockEngine(context, this); + } else { + engineToAdd = new FusionEngine(context, this); + } + enginesToAdd.put(request, engineToAdd); + + List listeners = engineListeners.get(existing); + listenersToAdd.put(engineToAdd, listeners); + + //Cleanup listeners + engineListeners.remove(existing); + existing.setRequest(null); + } + //Cleanup engines + locationEngines.clear(); + + //Now add new engines/listeners + for (LocationRequest request : enginesToAdd.keySet()) { + LocationEngine engine = enginesToAdd.get(request); + List listeners = listenersToAdd.get(engine); + if (listeners != null) { + for (LocationListener listener : listeners) { + requestLocationUpdates(request, listener); + } + } + } + } + private void shutdownAllEngines() { for (LocationEngine engine : locationEngines.values()) { engineListeners.remove(engine); @@ -189,4 +228,13 @@ private void shutdownAllEngines() { } locationEngines.clear(); } + + @VisibleForTesting + List getListeners() { + List listeners = new ArrayList<>(); + for (LocationEngine engine : engineListeners.keySet()) { + listeners.addAll(engineListeners.get(engine)); + } + return listeners; + } } diff --git a/lost/src/main/java/com/mapzen/android/lost/internal/LostApiClientImpl.java b/lost/src/main/java/com/mapzen/android/lost/internal/LostApiClientImpl.java index 0bb3276..93e911f 100644 --- a/lost/src/main/java/com/mapzen/android/lost/internal/LostApiClientImpl.java +++ b/lost/src/main/java/com/mapzen/android/lost/internal/LostApiClientImpl.java @@ -41,4 +41,5 @@ public void disconnect() { public boolean isConnected() { return LocationServices.FusedLocationApi != null && LocationServices.GeofencingApi != null; } + } diff --git a/lost/src/test/java/com/mapzen/android/lost/internal/FusedLocationProviderApiImplTest.java b/lost/src/test/java/com/mapzen/android/lost/internal/FusedLocationProviderApiImplTest.java index fc1383f..9ead8e5 100644 --- a/lost/src/test/java/com/mapzen/android/lost/internal/FusedLocationProviderApiImplTest.java +++ b/lost/src/test/java/com/mapzen/android/lost/internal/FusedLocationProviderApiImplTest.java @@ -222,6 +222,16 @@ public void setMockMode_shouldNotRegisterDuplicateListeners() throws Exception { assertThat(shadowLocationManager.getRequestLocationUpdateListeners()).hasSize(2); } + @Test + public void setMockMode_shouldToggleEngines() { + TestLocationListener listener = new TestLocationListener(); + LocationRequest request = LocationRequest.create(); + api.requestLocationUpdates(request, listener); + api.setMockMode(true); + api.requestLocationUpdates(request, listener); + assertThat(api.getListeners()).hasSize(2); + } + @Test public void requestLocationUpdates_shouldNotRegisterListenersWithMockModeOn() throws Exception { api.setMockMode(true);