• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.location.LocationManager.GPS_PROVIDER;
4 import static android.location.LocationManager.NETWORK_PROVIDER;
5 import static com.google.common.truth.Truth.assertThat;
6 import static org.junit.Assert.assertEquals;
7 import static org.junit.Assert.assertFalse;
8 import static org.junit.Assert.assertNull;
9 import static org.junit.Assert.assertSame;
10 import static org.junit.Assert.assertTrue;
11 import static org.robolectric.Shadows.shadowOf;
12 
13 import android.app.Application;
14 import android.app.PendingIntent;
15 import android.content.Context;
16 import android.content.Intent;
17 import android.location.Criteria;
18 import android.location.GpsStatus.Listener;
19 import android.location.Location;
20 import android.location.LocationListener;
21 import android.location.LocationManager;
22 import android.os.Build.VERSION_CODES;
23 import android.os.Bundle;
24 import android.os.Process;
25 import androidx.test.core.app.ApplicationProvider;
26 import androidx.test.ext.junit.runners.AndroidJUnit4;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 import org.junit.Assert;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.robolectric.annotation.Config;
38 
39 @RunWith(AndroidJUnit4.class)
40 public class ShadowLocationManagerTest {
41   private LocationManager locationManager;
42   private ShadowLocationManager shadowLocationManager;
43   private Application context;
44 
45   @Before
setUp()46   public void setUp() {
47     context = ApplicationProvider.getApplicationContext();
48     locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
49     shadowLocationManager = shadowOf(locationManager);
50   }
51 
52   @Test
53   @Config(sdk = VERSION_CODES.P)
shouldReturnLocationDisabledByDefault()54   public void shouldReturnLocationDisabledByDefault() {
55     assertFalse(locationManager.isLocationEnabled());
56   }
57 
58   @Test
59   @Config(sdk = VERSION_CODES.P)
shouldReturnLocationEnabledOnceSet()60   public void shouldReturnLocationEnabledOnceSet() {
61     locationManager.setLocationEnabledForUser(true, Process.myUserHandle());
62     assertTrue(locationManager.isLocationEnabled());
63   }
64 
65   @Test
shouldReturnNoProviderEnabledByDefault()66   public void shouldReturnNoProviderEnabledByDefault() {
67     Boolean enabled = locationManager.isProviderEnabled(GPS_PROVIDER);
68     assertFalse(enabled);
69     enabled = locationManager.isProviderEnabled(NETWORK_PROVIDER);
70     assertFalse(enabled);
71     enabled = locationManager.isProviderEnabled("RANDOM_PROVIDER");
72     assertFalse(enabled);
73   }
74 
75   @Test
shouldDisableProvider()76   public void shouldDisableProvider() {
77     // No provider is enabled by default, so it must be manually enabled
78     shadowLocationManager.setProviderEnabled(GPS_PROVIDER, true);
79     shadowLocationManager.setProviderEnabled(GPS_PROVIDER, false);
80     assertFalse(locationManager.isProviderEnabled(GPS_PROVIDER));
81   }
82 
83   @Test
shouldHaveListenerOnceAdded()84   public void shouldHaveListenerOnceAdded() {
85     Listener listener = addGpsListenerToLocationManager();
86     assertTrue(shadowLocationManager.hasGpsStatusListener(listener));
87   }
88 
89   @Test
shouldNotHaveListenerOnceRemoved()90   public void shouldNotHaveListenerOnceRemoved() {
91     Listener listener = addGpsListenerToLocationManager();
92 
93     locationManager.removeGpsStatusListener(listener);
94 
95     assertFalse(shadowLocationManager.hasGpsStatusListener(listener));
96   }
97 
98   @Test
getProviders_returnsProvidersBasedOnEnabledParameter()99   public void getProviders_returnsProvidersBasedOnEnabledParameter() throws Exception {
100     assertTrue(locationManager.getProviders(true).isEmpty());
101     assertThat(locationManager.getProviders(false).size()).isEqualTo(3);
102 
103     shadowLocationManager.setProviderEnabled(NETWORK_PROVIDER, true);
104 
105     List<String> providers = locationManager.getProviders(true);
106     assertTrue(providers.contains(NETWORK_PROVIDER));
107     assertThat(providers.size()).isEqualTo(1);
108 
109     shadowLocationManager.setProviderEnabled(GPS_PROVIDER, true);
110     providers = locationManager.getProviders(true);
111     assertTrue(providers.contains(NETWORK_PROVIDER));
112     assertTrue(providers.contains(GPS_PROVIDER));
113     assertThat(providers.size()).isEqualTo(2);
114 
115     shadowLocationManager.setProviderEnabled(LocationManager.PASSIVE_PROVIDER, true);
116     providers = locationManager.getProviders(true);
117     assertTrue(providers.contains(NETWORK_PROVIDER));
118     assertTrue(providers.contains(GPS_PROVIDER));
119     assertTrue(providers.contains(LocationManager.PASSIVE_PROVIDER));
120     assertThat(providers.size()).isEqualTo(3);
121   }
122 
123   @Test
shouldReturnAllProviders()124   public void shouldReturnAllProviders() throws Exception {
125     assertThat(locationManager.getAllProviders().size()).isEqualTo(3);
126 
127     shadowLocationManager.setProviderEnabled("MY_PROVIDER", false);
128     assertThat(locationManager.getAllProviders().size()).isEqualTo(4);
129   }
130 
131   @Test
shouldReturnLastKnownLocationForAProvider()132   public void shouldReturnLastKnownLocationForAProvider() throws Exception {
133     assertNull(locationManager.getLastKnownLocation(NETWORK_PROVIDER));
134 
135     Location networkLocation = new Location(NETWORK_PROVIDER);
136     Location gpsLocation = new Location(GPS_PROVIDER);
137 
138     shadowLocationManager.setLastKnownLocation(NETWORK_PROVIDER, networkLocation);
139     shadowLocationManager.setLastKnownLocation(GPS_PROVIDER, gpsLocation);
140 
141     assertSame(locationManager.getLastKnownLocation(NETWORK_PROVIDER), networkLocation);
142     assertSame(locationManager.getLastKnownLocation(GPS_PROVIDER), gpsLocation);
143   }
144 
145   @Test
shouldStoreRequestLocationUpdateListeners()146   public void shouldStoreRequestLocationUpdateListeners() throws Exception {
147     TestLocationListener listener = new TestLocationListener();
148     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 2.0f, listener);
149     assertSame(shadowLocationManager.getRequestLocationUpdateListeners().get(0), listener);
150   }
151 
152   @Test
shouldKeepTrackOfWhichProvidersAListenerIsBoundTo_withoutDuplicates_inAnyOrder()153   public void shouldKeepTrackOfWhichProvidersAListenerIsBoundTo_withoutDuplicates_inAnyOrder() throws Exception {
154     TestLocationListener listener1 = new TestLocationListener();
155     TestLocationListener listener2 = new TestLocationListener();
156 
157     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 1, listener1);
158     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 1, listener1);
159 
160     Set<String> listOfExpectedProvidersForListener1 = new HashSet<>();
161     listOfExpectedProvidersForListener1.add(LocationManager.NETWORK_PROVIDER);
162     listOfExpectedProvidersForListener1.add(LocationManager.GPS_PROVIDER);
163 
164     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 1, listener2);
165     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 1, listener2);
166 
167     Set<String> listOfExpectedProvidersForListener2 = new HashSet<>();
168     listOfExpectedProvidersForListener2.add(LocationManager.NETWORK_PROVIDER);
169 
170     assertEquals(listOfExpectedProvidersForListener1, new HashSet<>(shadowLocationManager.getProvidersForListener(listener1)));
171     assertEquals(listOfExpectedProvidersForListener2, new HashSet<>(shadowLocationManager.getProvidersForListener(listener2)));
172 
173     locationManager.removeUpdates(listener1);
174     assertEquals(0, shadowLocationManager.getProvidersForListener(listener1).size());
175   }
176 
177   @Test
shouldRemoveLocationListeners()178   public void shouldRemoveLocationListeners() throws Exception {
179     TestLocationListener listener = new TestLocationListener();
180     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 2.0f, listener);
181     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 2.0f, listener);
182 
183     TestLocationListener otherListener = new TestLocationListener();
184     locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 2.0f, otherListener);
185 
186     locationManager.removeUpdates(listener);
187 
188     List<LocationListener> expected = new ArrayList<>();
189     expected.add(otherListener);
190     assertThat(shadowLocationManager.getRequestLocationUpdateListeners()).isEqualTo(expected);
191   }
192 
193   @Test
shouldRemovePendingIntentsWhenRequestingLocationUpdatesUsingCriteria()194   public void shouldRemovePendingIntentsWhenRequestingLocationUpdatesUsingCriteria() throws Exception {
195     Intent someIntent = new Intent("some_action");
196     PendingIntent someLocationListenerPendingIntent =
197         PendingIntent.getBroadcast(context, 0, someIntent, PendingIntent.FLAG_UPDATE_CURRENT);
198     Intent someOtherIntent = new Intent("some_other_action");
199     PendingIntent someOtherLocationListenerPendingIntent =
200         PendingIntent.getBroadcast(context, 0, someOtherIntent, PendingIntent.FLAG_UPDATE_CURRENT);
201 
202     shadowLocationManager.setProviderEnabled(GPS_PROVIDER, true);
203     shadowLocationManager.setBestProvider(LocationManager.GPS_PROVIDER, true);
204     Criteria criteria = new Criteria();
205     criteria.setAccuracy(Criteria.ACCURACY_FINE);
206 
207     locationManager.requestLocationUpdates(0, 0, criteria, someLocationListenerPendingIntent);
208     locationManager.requestLocationUpdates(0, 0, criteria, someOtherLocationListenerPendingIntent);
209 
210     locationManager.removeUpdates(someLocationListenerPendingIntent);
211 
212     Map<PendingIntent, Criteria> expectedCriteria = new HashMap<>();
213     expectedCriteria.put(someOtherLocationListenerPendingIntent, criteria);
214     assertThat(shadowLocationManager.getRequestLocationUdpateCriteriaPendingIntents()).isEqualTo(expectedCriteria);
215   }
216 
217   @Test
shouldNotSetBestEnabledProviderIfProviderIsDisabled()218   public void shouldNotSetBestEnabledProviderIfProviderIsDisabled() throws Exception {
219     shadowLocationManager.setProviderEnabled(GPS_PROVIDER, true);
220     assertTrue(shadowLocationManager.setBestProvider(LocationManager.GPS_PROVIDER, true));
221   }
222 
223   @Test
shouldNotSetBestDisabledProviderIfProviderIsEnabled()224   public void shouldNotSetBestDisabledProviderIfProviderIsEnabled() throws Exception {
225     shadowLocationManager.setProviderEnabled(GPS_PROVIDER, true);
226     assertFalse(shadowLocationManager.setBestProvider(LocationManager.GPS_PROVIDER, false));
227   }
228 
229   @Test
shouldRemovePendingIntentsWhenRequestingLocationUpdatesUsingLocationListeners()230   public void shouldRemovePendingIntentsWhenRequestingLocationUpdatesUsingLocationListeners() throws Exception {
231     Intent someIntent = new Intent("some_action");
232     PendingIntent someLocationListenerPendingIntent =
233         PendingIntent.getBroadcast(context, 0, someIntent, PendingIntent.FLAG_UPDATE_CURRENT);
234     Intent someOtherIntent = new Intent("some_other_action");
235     PendingIntent someOtherLocationListenerPendingIntent =
236         PendingIntent.getBroadcast(context, 0, someOtherIntent, PendingIntent.FLAG_UPDATE_CURRENT);
237 
238     shadowLocationManager.setProviderEnabled(GPS_PROVIDER, true);
239     shadowLocationManager.setBestProvider(LocationManager.GPS_PROVIDER, true);
240     shadowLocationManager.setProviderEnabled(NETWORK_PROVIDER, true);
241 
242     locationManager.requestLocationUpdates(GPS_PROVIDER, 0, 0, someLocationListenerPendingIntent);
243     locationManager.requestLocationUpdates(NETWORK_PROVIDER, 0, 0, someOtherLocationListenerPendingIntent);
244 
245     locationManager.removeUpdates(someLocationListenerPendingIntent);
246 
247     Map<PendingIntent, String> expectedProviders = new HashMap<>();
248     expectedProviders.put(someOtherLocationListenerPendingIntent, NETWORK_PROVIDER);
249     assertThat(shadowLocationManager.getRequestLocationUdpateProviderPendingIntents()).isEqualTo(expectedProviders);
250   }
251 
252   @Test
shouldStoreBestProviderCriteriaAndEnabledOnlyFlag()253   public void shouldStoreBestProviderCriteriaAndEnabledOnlyFlag() throws Exception {
254     Criteria criteria = new Criteria();
255     assertNull(locationManager.getBestProvider(criteria, true));
256     assertSame(criteria, shadowLocationManager.getLastBestProviderCriteria());
257     assertTrue(shadowLocationManager.getLastBestProviderEnabledOnly());
258   }
259 
260   @Test
getBestProvider_returnsProviderBasedOnCriteriaAndEnabledState()261   public void getBestProvider_returnsProviderBasedOnCriteriaAndEnabledState() throws Exception {
262     Criteria criteria = new Criteria();
263     criteria.setAccuracy(Criteria.ACCURACY_COARSE);
264     assertThat(locationManager.getBestProvider(null, false)).isEqualTo(LocationManager.GPS_PROVIDER);
265     assertThat(locationManager.getBestProvider(null, true)).isNull();
266     assertThat(locationManager.getBestProvider(criteria, false)).isEqualTo(LocationManager.NETWORK_PROVIDER);
267     assertThat(locationManager.getBestProvider(criteria, true)).isNull();
268   }
269 
270   @Test
shouldThrowExceptionWhenRequestingLocationUpdatesWithANullIntent()271   public void shouldThrowExceptionWhenRequestingLocationUpdatesWithANullIntent() throws Exception {
272     try {
273       shadowLocationManager.requestLocationUpdates(0, 0, new Criteria(), null);
274       Assert.fail("When requesting location updates the intent must not be null!");
275     } catch (Exception e) {
276       // No worries, everything is fine...
277     }
278   }
279 
280   @Test
shouldThrowExceptionWhenRequestingLocationUpdatesAndNoProviderIsFound()281   public void shouldThrowExceptionWhenRequestingLocationUpdatesAndNoProviderIsFound() throws Exception {
282     Intent someIntent = new Intent("some_action");
283     PendingIntent someLocationListenerPendingIntent =
284         PendingIntent.getBroadcast(context, 0, someIntent, PendingIntent.FLAG_UPDATE_CURRENT);
285     Criteria criteria = new Criteria();
286     criteria.setAccuracy(Criteria.ACCURACY_FINE);
287     try {
288       shadowLocationManager.requestLocationUpdates(0, 0, criteria, someLocationListenerPendingIntent);
289       Assert.fail("When requesting location updates the intent must not be null!");
290     } catch (Exception e) {
291       // No worries, everything is fine...
292     }
293   }
294 
295   @Test
shouldThrowExceptionIfTheBestProviderIsUnknown()296   public void shouldThrowExceptionIfTheBestProviderIsUnknown() throws Exception {
297     Criteria criteria = new Criteria();
298     criteria.setAccuracy(Criteria.ACCURACY_FINE);
299     try {
300       shadowLocationManager.setBestProvider("BEST_ENABLED_PROVIDER", true);
301       Assert.fail("The best provider is unknown!");
302     } catch (Exception e) {
303       // No worries, everything is fine...
304     }
305   }
306 
307   @Test
shouldReturnBestCustomProviderUsingCriteria()308   public void shouldReturnBestCustomProviderUsingCriteria() throws Exception {
309     Criteria criteria = new Criteria();
310     Criteria customProviderCriteria = new Criteria();
311 
312     // Manually set best provider should be returned
313     ArrayList<Criteria> criteriaList = new ArrayList<>();
314     customProviderCriteria.setAccuracy(Criteria.ACCURACY_COARSE);
315     criteriaList.add(customProviderCriteria);
316     shadowLocationManager.setProviderEnabled("BEST_ENABLED_PROVIDER_WITH_CRITERIA", true, criteriaList);
317     assertTrue(shadowLocationManager.setBestProvider("BEST_ENABLED_PROVIDER_WITH_CRITERIA", true));
318     criteria.setAccuracy(Criteria.ACCURACY_COARSE);
319     criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
320     assertThat(locationManager.getBestProvider(criteria, true))
321         .isEqualTo("BEST_ENABLED_PROVIDER_WITH_CRITERIA");
322     assertThat(shadowLocationManager.setBestProvider("BEST_ENABLED_PROVIDER_WITH_CRITERIA", true))
323         .isTrue();
324     assertThat(locationManager.getBestProvider(criteria, false))
325         .isEqualTo("BEST_ENABLED_PROVIDER_WITH_CRITERIA");
326     assertThat(locationManager.getBestProvider(criteria, true))
327         .isEqualTo("BEST_ENABLED_PROVIDER_WITH_CRITERIA");
328   }
329 
330   @Test
shouldReturnBestProviderUsingCriteria()331   public void shouldReturnBestProviderUsingCriteria() {
332     Criteria criteria = new Criteria();
333 
334     shadowLocationManager.setProviderEnabled(LocationManager.GPS_PROVIDER, false);
335     criteria.setAccuracy(Criteria.ACCURACY_FINE);
336     assertThat(locationManager.getBestProvider(criteria, false))
337         .isEqualTo(LocationManager.GPS_PROVIDER);
338 
339     shadowLocationManager.setProviderEnabled(LocationManager.NETWORK_PROVIDER, false);
340     criteria.setAccuracy(Criteria.ACCURACY_COARSE);
341     assertThat(locationManager.getBestProvider(criteria, false))
342         .isEqualTo(LocationManager.NETWORK_PROVIDER);
343 
344     criteria.setPowerRequirement(Criteria.POWER_LOW);
345     criteria.setAccuracy(Criteria.ACCURACY_FINE);
346     assertThat(locationManager.getBestProvider(criteria, false))
347         .isEqualTo(LocationManager.NETWORK_PROVIDER);
348   }
349 
350   @Test
shouldReturnBestDisabledProvider()351   public void shouldReturnBestDisabledProvider() throws Exception {
352     shadowLocationManager.setProviderEnabled("BEST_DISABLED_PROVIDER", false);
353     shadowLocationManager.setBestProvider("BEST_DISABLED_PROVIDER", false);
354     shadowLocationManager.setProviderEnabled("BEST_ENABLED_PROVIDER", true);
355     shadowLocationManager.setBestProvider("BEST_ENABLED_PROVIDER", true);
356 
357     assertTrue(shadowLocationManager.setBestProvider("BEST_DISABLED_PROVIDER", false));
358     assertThat(locationManager.getBestProvider(null, false)).isEqualTo("BEST_DISABLED_PROVIDER");
359     assertThat(locationManager.getBestProvider(null, true)).isEqualTo("BEST_ENABLED_PROVIDER");
360   }
361 
362   @Test
getBestProvider_returnsBestProviderBasedOnEnabledState()363   public void getBestProvider_returnsBestProviderBasedOnEnabledState() throws Exception {
364     shadowLocationManager.setProviderEnabled("BEST_ENABLED_PROVIDER", true);
365 
366     assertThat(shadowLocationManager.setBestProvider("BEST_ENABLED_PROVIDER", true)).isTrue();
367     assertThat(shadowLocationManager.setBestProvider("BEST_ENABLED_PROVIDER", false)).isFalse();
368     assertThat(locationManager.getBestProvider(null, true)).isEqualTo("BEST_ENABLED_PROVIDER");
369     assertThat(locationManager.getBestProvider(null, false)).isEqualTo(LocationManager.GPS_PROVIDER);
370   }
371 
372   @Test
shouldNotifyAllListenersIfProviderStateChanges()373   public void shouldNotifyAllListenersIfProviderStateChanges() {
374     TestLocationListener listener = new TestLocationListener();
375     locationManager.requestLocationUpdates("TEST_PROVIDER", 0, 0, listener);
376     shadowLocationManager.setProviderEnabled("TEST_PROVIDER", true);
377     assertTrue(listener.providerEnabled);
378     shadowLocationManager.setProviderEnabled("TEST_PROVIDER", false);
379     assertFalse(listener.providerEnabled);
380   }
381 
382   @Test
shouldRegisterLocationUpdatesWhenProviderGiven()383   public void shouldRegisterLocationUpdatesWhenProviderGiven() throws Exception {
384     shadowLocationManager.setProviderEnabled(GPS_PROVIDER, true);
385     shadowLocationManager.setBestProvider(LocationManager.GPS_PROVIDER, true);
386 
387     Intent someIntent = new Intent("some_action");
388     PendingIntent someLocationListenerPendingIntent =
389         PendingIntent.getBroadcast(context, 0, someIntent, PendingIntent.FLAG_UPDATE_CURRENT);
390     locationManager.requestLocationUpdates(GPS_PROVIDER, 0, 0, someLocationListenerPendingIntent);
391 
392     assertThat(shadowLocationManager.getRequestLocationUdpateProviderPendingIntents().get(someLocationListenerPendingIntent)).isEqualTo(GPS_PROVIDER);
393   }
394 
395   @Test
shouldRegisterLocationUpdatesWhenCriteriaGiven()396   public void shouldRegisterLocationUpdatesWhenCriteriaGiven() throws Exception {
397     shadowLocationManager.setProviderEnabled(NETWORK_PROVIDER, true);
398     shadowLocationManager.setBestProvider(LocationManager.NETWORK_PROVIDER, true);
399     Criteria criteria = new Criteria();
400     criteria.setAccuracy(Criteria.ACCURACY_COARSE);
401 
402     Intent someIntent = new Intent("some_action");
403     PendingIntent someLocationListenerPendingIntent =
404         PendingIntent.getBroadcast(context, 0, someIntent, PendingIntent.FLAG_UPDATE_CURRENT);
405     Criteria someCriteria = new Criteria();
406     someCriteria.setAccuracy(Criteria.ACCURACY_COARSE);
407     locationManager.requestLocationUpdates(0, 0, someCriteria, someLocationListenerPendingIntent);
408 
409     assertThat(shadowLocationManager.getRequestLocationUdpateCriteriaPendingIntents().get(someLocationListenerPendingIntent)).isEqualTo(someCriteria);
410   }
411 
412   @Test
simulateLocation_shouldNotNotifyListenerIfLessThanFastestInterval()413   public void simulateLocation_shouldNotNotifyListenerIfLessThanFastestInterval() throws Exception {
414     TestLocationListener listener = new TestLocationListener();
415     shadowLocationManager.requestLocationUpdates(GPS_PROVIDER, 2000, 0, listener);
416     long time = System.currentTimeMillis();
417 
418     Location location1 = new Location(GPS_PROVIDER);
419     location1.setTime(time);
420 
421     Location location2 = new Location(GPS_PROVIDER);
422     location2.setTime(time + 1000);
423 
424     shadowLocationManager.simulateLocation(location1);
425     shadowLocationManager.simulateLocation(location2);
426     assertThat(listener.location.getTime()).isEqualTo(location1.getTime());
427   }
428 
429   @Test
simulateLocation_shouldNotNotifyListenerIfLessThanMinimumDistance()430   public void simulateLocation_shouldNotNotifyListenerIfLessThanMinimumDistance() throws Exception {
431     TestLocationListener listener = new TestLocationListener();
432     locationManager.requestLocationUpdates(GPS_PROVIDER, 0, 200000, listener);
433 
434     Location location1 = new Location(GPS_PROVIDER);
435     location1.setLatitude(1);
436     location1.setLongitude(2);
437     location1.setTime(0);
438 
439     Location location2 = new Location(GPS_PROVIDER);
440     location2.setLatitude(1.5);
441     location2.setLongitude(2.5);
442     location2.setTime(1000);
443 
444     shadowLocationManager.simulateLocation(location1);
445     shadowLocationManager.simulateLocation(location2);
446 
447     assertThat(listener.location.getLatitude()).isEqualTo(1.0d);
448     assertThat(listener.location.getLongitude()).isEqualTo(2.0d);
449   }
450 
451   @Test
shouldNotThrowExceptionIfLocationListenerRemovedInsideOnLocationChanged()452   public void shouldNotThrowExceptionIfLocationListenerRemovedInsideOnLocationChanged() throws Exception {
453     TestLocationListenerSelfRemoval listener = new TestLocationListenerSelfRemoval(locationManager);
454     shadowLocationManager.requestLocationUpdates(GPS_PROVIDER, 0, 0, listener);
455 
456     Location location = new Location(GPS_PROVIDER);
457     location.setLatitude(0);
458     location.setLongitude(0);
459 
460     shadowLocationManager.simulateLocation(location);
461     assertThat(shadowLocationManager.getRequestLocationUpdateListeners().size()).isEqualTo(0);
462   }
463 
464   @Test
requestLocationUpdates_shouldNotRegisterDuplicateListeners()465   public void requestLocationUpdates_shouldNotRegisterDuplicateListeners() throws Exception {
466     TestLocationListener listener = new TestLocationListener();
467     shadowLocationManager.requestLocationUpdates(GPS_PROVIDER, 0, 0, listener);
468     shadowLocationManager.requestLocationUpdates(GPS_PROVIDER, 0, 0, listener);
469     shadowLocationManager.simulateLocation(new Location(GPS_PROVIDER));
470     assertThat(listener.updateCount).isEqualTo(1);
471   }
472 
addGpsListenerToLocationManager()473   private Listener addGpsListenerToLocationManager() {
474     Listener listener = new TestGpsListener();
475     locationManager.addGpsStatusListener(listener);
476     return listener;
477   }
478 
479   private static class TestLocationListener implements LocationListener {
480     boolean providerEnabled;
481     Location location;
482     int updateCount;
483 
484     @Override
onLocationChanged(Location location)485     public void onLocationChanged(Location location) {
486       this.location = location;
487       updateCount++;
488     }
489 
490     @Override
onStatusChanged(String s, int i, Bundle bundle)491     public void onStatusChanged(String s, int i, Bundle bundle) {
492     }
493 
494     @Override
onProviderEnabled(String s)495     public void onProviderEnabled(String s) {
496       providerEnabled = true;
497     }
498 
499     @Override
onProviderDisabled(String s)500     public void onProviderDisabled(String s) {
501       providerEnabled = false;
502     }
503   }
504 
505   private static class TestLocationListenerSelfRemoval implements LocationListener {
506     LocationManager locationManager;
507 
TestLocationListenerSelfRemoval(LocationManager locationManager)508     public TestLocationListenerSelfRemoval(LocationManager locationManager) {
509       this.locationManager = locationManager;
510     }
511 
512     @Override
onLocationChanged(Location location)513     public void onLocationChanged(Location location) {
514       locationManager.removeUpdates(this);
515     }
516 
517     @Override
onStatusChanged(String s, int i, Bundle bundle)518     public void onStatusChanged(String s, int i, Bundle bundle) {
519     }
520 
521     @Override
onProviderEnabled(String s)522     public void onProviderEnabled(String s) {
523     }
524 
525     @Override
onProviderDisabled(String s)526     public void onProviderDisabled(String s) {
527     }
528   }
529 
530   private static class TestGpsListener implements Listener {
531 
532     @Override
onGpsStatusChanged(int event)533     public void onGpsStatusChanged(int event) {
534 
535     }
536   }
537 }
538