1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.location.cts; 18 19 import android.app.PendingIntent; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.content.pm.PackageManager; 25 import android.location.Criteria; 26 import android.location.GnssStatus; 27 import android.location.Location; 28 import android.location.LocationListener; 29 import android.location.LocationManager; 30 import android.location.LocationProvider; 31 import android.location.OnNmeaMessageListener; 32 import android.os.Bundle; 33 import android.os.Handler; 34 import android.os.HandlerThread; 35 import android.os.Looper; 36 import android.os.SystemClock; 37 import android.os.UserManager; 38 import android.test.UiThreadTest; 39 import android.util.Log; 40 41 import java.util.List; 42 43 /** 44 * Requires the permissions 45 * android.permission.ACCESS_MOCK_LOCATION to mock provider 46 * android.permission.ACCESS_COARSE_LOCATION to access network provider 47 * android.permission.ACCESS_FINE_LOCATION to access GPS provider 48 * android.permission.ACCESS_LOCATION_EXTRA_COMMANDS to send extra commands to GPS provider 49 */ 50 public class LocationManagerTest extends BaseMockLocationTest { 51 52 private static final String TAG = "LocationManagerTest"; 53 54 private static final long TEST_TIME_OUT = 5000; 55 56 private static final String TEST_MOCK_PROVIDER_NAME = "test_provider"; 57 58 private static final String UNKNOWN_PROVIDER_NAME = "unknown_provider"; 59 60 private static final String FUSED_PROVIDER_NAME = "fused"; 61 62 private LocationManager mManager; 63 64 private Context mContext; 65 66 private PendingIntent mPendingIntent; 67 68 private TestIntentReceiver mIntentReceiver; 69 70 @Override 71 protected void setUp() throws Exception { 72 super.setUp(); 73 mContext = getInstrumentation().getTargetContext(); 74 75 mManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); 76 77 // remove test provider if left over from an aborted run 78 LocationProvider lp = mManager.getProvider(TEST_MOCK_PROVIDER_NAME); 79 if (lp != null) { 80 mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME); 81 } 82 83 addTestProvider(TEST_MOCK_PROVIDER_NAME); 84 } 85 86 /** 87 * Helper method to add a test provider with given name. 88 */ 89 private void addTestProvider(final String providerName) { 90 mManager.addTestProvider(providerName, true, //requiresNetwork, 91 false, // requiresSatellite, 92 true, // requiresCell, 93 false, // hasMonetaryCost, 94 false, // supportsAltitude, 95 false, // supportsSpeed, 96 false, // supportsBearing, 97 Criteria.POWER_MEDIUM, // powerRequirement 98 Criteria.ACCURACY_FINE); // accuracy 99 mManager.setTestProviderEnabled(providerName, true); 100 } 101 102 @Override 103 protected void tearDown() throws Exception { 104 LocationProvider provider = mManager.getProvider(TEST_MOCK_PROVIDER_NAME); 105 if (provider != null) { 106 mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME); 107 } 108 if (mPendingIntent != null) { 109 mManager.removeProximityAlert(mPendingIntent); 110 } 111 if (mIntentReceiver != null) { 112 mContext.unregisterReceiver(mIntentReceiver); 113 } 114 super.tearDown(); 115 } 116 117 public void testRemoveTestProvider() { 118 // this test assumes TEST_MOCK_PROVIDER_NAME was created in setUp. 119 LocationProvider provider = mManager.getProvider(TEST_MOCK_PROVIDER_NAME); 120 assertNotNull(provider); 121 122 try { 123 mManager.addTestProvider(TEST_MOCK_PROVIDER_NAME, true, //requiresNetwork, 124 false, // requiresSatellite, 125 true, // requiresCell, 126 false, // hasMonetaryCost, 127 false, // supportsAltitude, 128 false, // supportsSpeed, 129 false, // supportsBearing, 130 Criteria.POWER_MEDIUM, // powerRequirement 131 Criteria.ACCURACY_FINE); // accuracy 132 fail("Should throw IllegalArgumentException when provider already exists!"); 133 } catch (IllegalArgumentException e) { 134 // expected 135 } 136 137 mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME); 138 provider = mManager.getProvider(TEST_MOCK_PROVIDER_NAME); 139 assertNull(provider); 140 141 try { 142 mManager.removeTestProvider(UNKNOWN_PROVIDER_NAME); 143 fail("Should throw IllegalArgumentException when no provider exists!"); 144 } catch (IllegalArgumentException e) { 145 // expected 146 } 147 } 148 149 public void testGetProviders() { 150 List<String> providers = mManager.getAllProviders(); 151 assertTrue(providers.size() >= 2); 152 assertTrue(hasTestProvider(providers)); 153 154 assertEquals(hasGpsFeature(), hasGpsProvider(providers)); 155 156 int oldSizeAllProviders = providers.size(); 157 158 providers = mManager.getProviders(false); 159 assertEquals(oldSizeAllProviders, providers.size()); 160 assertTrue(hasTestProvider(providers)); 161 162 providers = mManager.getProviders(true); 163 assertTrue(providers.size() >= 1); 164 assertTrue(hasTestProvider(providers)); 165 int oldSizeTrueProviders = providers.size(); 166 167 mManager.setTestProviderEnabled(TEST_MOCK_PROVIDER_NAME, false); 168 providers = mManager.getProviders(true); 169 assertEquals(oldSizeTrueProviders - 1, providers.size()); 170 assertFalse(hasTestProvider(providers)); 171 172 providers = mManager.getProviders(false); 173 assertEquals(oldSizeAllProviders, providers.size()); 174 assertTrue(hasTestProvider(providers)); 175 176 mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME); 177 providers = mManager.getAllProviders(); 178 assertEquals(oldSizeAllProviders - 1, providers.size()); 179 assertFalse(hasTestProvider(providers)); 180 } 181 182 private boolean hasTestProvider(List<String> providers) { 183 return hasProvider(providers, TEST_MOCK_PROVIDER_NAME); 184 } 185 186 private boolean hasGpsProvider(List<String> providers) { 187 return hasProvider(providers, LocationManager.GPS_PROVIDER); 188 } 189 190 private boolean hasGpsFeature() { 191 return mContext.getPackageManager().hasSystemFeature( 192 PackageManager.FEATURE_LOCATION_GPS); 193 } 194 195 private boolean hasProvider(List<String> providers, String providerName) { 196 for (String provider : providers) { 197 if (provider != null && provider.equals(providerName)) { 198 return true; 199 } 200 } 201 return false; 202 } 203 204 public void testGetProvider() { 205 LocationProvider p = mManager.getProvider(TEST_MOCK_PROVIDER_NAME); 206 assertNotNull(p); 207 assertEquals(TEST_MOCK_PROVIDER_NAME, p.getName()); 208 209 p = mManager.getProvider(LocationManager.GPS_PROVIDER); 210 if (hasGpsFeature()) { 211 assertNotNull(p); 212 assertEquals(LocationManager.GPS_PROVIDER, p.getName()); 213 } else { 214 assertNull(p); 215 } 216 217 p = mManager.getProvider(UNKNOWN_PROVIDER_NAME); 218 assertNull(p); 219 220 try { 221 mManager.getProvider(null); 222 fail("Should throw IllegalArgumentException when provider is null!"); 223 } catch (IllegalArgumentException e) { 224 // expected 225 } 226 } 227 228 public void testGetProvidersWithCriteria() { 229 Criteria criteria = new Criteria(); 230 List<String> providers = mManager.getProviders(criteria, true); 231 assertTrue(providers.size() >= 1); 232 assertTrue(hasTestProvider(providers)); 233 234 criteria = new Criteria(); 235 criteria.setPowerRequirement(Criteria.POWER_HIGH); 236 String p = mManager.getBestProvider(criteria, true); 237 if (p != null) { // we may not have any enabled providers 238 assertTrue(mManager.isProviderEnabled(p)); 239 } 240 241 criteria.setPowerRequirement(Criteria.POWER_MEDIUM); 242 p = mManager.getBestProvider(criteria, false); 243 assertNotNull(p); 244 245 criteria.setPowerRequirement(Criteria.POWER_LOW); 246 p = mManager.getBestProvider(criteria, true); 247 if (p != null) { // we may not have any enabled providers 248 assertTrue(mManager.isProviderEnabled(p)); 249 } 250 251 criteria.setPowerRequirement(Criteria.NO_REQUIREMENT); 252 p = mManager.getBestProvider(criteria, false); 253 assertNotNull(p); 254 } 255 256 /** 257 * Returns true if the {@link LocationManager} reports that the device includes this flavor 258 * of location provider. 259 */ 260 private boolean deviceHasProvider(String provider) { 261 List<String> providers = mManager.getAllProviders(); 262 for (String aProvider : providers) { 263 if (aProvider.equals(provider)) { 264 return true; 265 } 266 } 267 return false; 268 } 269 270 /** 271 * Ensures the test provider is removed. {@link LocationManager#removeTestProvider(String)} 272 * throws an {@link java.lang.IllegalArgumentException} if there is no such test provider, 273 * so we have to add it before we clear it. 274 */ 275 private void forceRemoveTestProvider(String provider) { 276 addTestProvider(provider); 277 mManager.removeTestProvider(provider); 278 } 279 280 public void testLocationUpdatesWithLocationListener() throws InterruptedException { 281 doLocationUpdatesWithLocationListener(TEST_MOCK_PROVIDER_NAME); 282 283 try { 284 mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, 285 (LocationListener) null); 286 fail("Should throw IllegalArgumentException if param listener is null!"); 287 } catch (IllegalArgumentException e) { 288 // expected 289 } 290 291 try { 292 mManager.requestLocationUpdates(null, 0, 0, new MockLocationListener()); 293 fail("Should throw IllegalArgumentException if param provider is null!"); 294 } catch (IllegalArgumentException e) { 295 // expected 296 } 297 298 try { 299 mManager.removeUpdates( (LocationListener) null ); 300 fail("Should throw IllegalArgumentException if listener is null!"); 301 } catch (IllegalArgumentException e) { 302 // expected 303 } 304 } 305 306 /** 307 * Helper method to test a location update with given mock location provider 308 * 309 * @param providerName name of provider to test. Must already exist. 310 * @throws InterruptedException 311 */ 312 private void doLocationUpdatesWithLocationListener(final String providerName) 313 throws InterruptedException { 314 final double latitude1 = 10; 315 final double longitude1 = 40; 316 final double latitude2 = 35; 317 final double longitude2 = 80; 318 final MockLocationListener listener = new MockLocationListener(); 319 320 // update location and notify listener 321 new Thread(new Runnable() { 322 public void run() { 323 Looper.prepare(); 324 mManager.requestLocationUpdates(providerName, 0, 0, listener); 325 listener.setLocationRequested(); 326 Looper.loop(); 327 } 328 }).start(); 329 // wait for location requested to be called first, otherwise setLocation can be called 330 // before there is a listener attached 331 assertTrue(listener.hasCalledLocationRequested(TEST_TIME_OUT)); 332 updateLocation(providerName, latitude1, longitude1); 333 assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 334 Location location = listener.getLocation(); 335 assertEquals(providerName, location.getProvider()); 336 assertEquals(latitude1, location.getLatitude()); 337 assertEquals(longitude1, location.getLongitude()); 338 assertEquals(true, location.isFromMockProvider()); 339 340 // update location without notifying listener 341 listener.reset(); 342 assertFalse(listener.hasCalledOnLocationChanged(0)); 343 mManager.removeUpdates(listener); 344 updateLocation(providerName, latitude2, longitude2); 345 assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 346 } 347 348 /** 349 * Verifies that all real location providers can be replaced by a mock provider. 350 * <p/> 351 * This feature is quite useful for developer automated testing. 352 * This test may fail if another unknown test provider already exists, because there is no 353 * known way to determine if a given provider is a test provider. 354 * @throws InterruptedException 355 */ 356 public void testReplaceRealProvidersWithMocks() throws InterruptedException { 357 for (String providerName : mManager.getAllProviders()) { 358 if (!providerName.equals(TEST_MOCK_PROVIDER_NAME) && 359 !providerName.equals(LocationManager.PASSIVE_PROVIDER)) { 360 addTestProvider(providerName); 361 try { 362 // run the update location test logic to ensure location updates can be injected 363 doLocationUpdatesWithLocationListener(providerName); 364 } finally { 365 mManager.removeTestProvider(providerName); 366 } 367 } 368 } 369 } 370 371 public void testLocationUpdatesWithLocationListenerAndLooper() throws InterruptedException { 372 double latitude1 = 60; 373 double longitude1 = 20; 374 double latitude2 = 40; 375 double longitude2 = 30; 376 final MockLocationListener listener = new MockLocationListener(); 377 378 // update location and notify listener 379 HandlerThread handlerThread = new HandlerThread("testLocationUpdates"); 380 handlerThread.start(); 381 mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, listener, 382 handlerThread.getLooper()); 383 384 updateLocation(latitude1, longitude1); 385 assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 386 Location location = listener.getLocation(); 387 assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider()); 388 assertEquals(latitude1, location.getLatitude()); 389 assertEquals(longitude1, location.getLongitude()); 390 assertEquals(true, location.isFromMockProvider()); 391 392 // update location without notifying listener 393 mManager.removeUpdates(listener); 394 listener.reset(); 395 updateLocation(latitude2, longitude2); 396 assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 397 398 try { 399 mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, 400 (LocationListener) null, Looper.myLooper()); 401 fail("Should throw IllegalArgumentException if param listener is null!"); 402 } catch (IllegalArgumentException e) { 403 // expected 404 } 405 406 try { 407 mManager.requestLocationUpdates(null, 0, 0, listener, Looper.myLooper()); 408 fail("Should throw IllegalArgumentException if param provider is null!"); 409 } catch (IllegalArgumentException e) { 410 // expected 411 } 412 413 try { 414 mManager.removeUpdates((LocationListener) null ); 415 fail("Should throw IllegalArgumentException if listener is null!"); 416 } catch (IllegalArgumentException e) { 417 // expected 418 } 419 } 420 421 public void testLocationUpdatesWithPendingIntent() throws InterruptedException { 422 double latitude1 = 20; 423 double longitude1 = 40; 424 double latitude2 = 30; 425 double longitude2 = 50; 426 427 // update location and receive broadcast. 428 registerIntentReceiver(); 429 mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent); 430 updateLocation(latitude1, longitude1); 431 waitForReceiveBroadcast(); 432 433 assertNotNull(mIntentReceiver.getLastReceivedIntent()); 434 Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME); 435 assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider()); 436 assertEquals(latitude1, location.getLatitude()); 437 assertEquals(longitude1, location.getLongitude()); 438 assertEquals(true, location.isFromMockProvider()); 439 440 // update location without receiving broadcast. 441 mManager.removeUpdates(mPendingIntent); 442 mIntentReceiver.clearReceivedIntents(); 443 updateLocation(latitude2, longitude2); 444 waitForReceiveBroadcast(); 445 assertNull(mIntentReceiver.getLastReceivedIntent()); 446 447 try { 448 mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, 449 (PendingIntent) null); 450 fail("Should throw IllegalArgumentException if param intent is null!"); 451 } catch (IllegalArgumentException e) { 452 // expected 453 } 454 455 try { 456 mManager.requestLocationUpdates(null, 0, 0, mPendingIntent); 457 fail("Should throw IllegalArgumentException if param provider is null!"); 458 } catch (IllegalArgumentException e) { 459 // expected 460 } 461 462 try { 463 mManager.removeUpdates( (PendingIntent) null ); 464 fail("Should throw IllegalArgumentException if intent is null!"); 465 } catch (IllegalArgumentException e) { 466 // expected 467 } 468 } 469 470 public void testSingleUpdateWithLocationListenerAndLooper() throws InterruptedException { 471 double latitude1 = 60; 472 double longitude1 = 20; 473 double latitude2 = 40; 474 double longitude2 = 30; 475 double latitude3 = 10; 476 double longitude3 = 50; 477 final MockLocationListener listener = new MockLocationListener(); 478 479 // update location and notify listener 480 HandlerThread handlerThread = new HandlerThread("testLocationUpdates4"); 481 handlerThread.start(); 482 mManager.requestSingleUpdate(TEST_MOCK_PROVIDER_NAME, listener, handlerThread.getLooper()); 483 484 updateLocation(latitude1, longitude1); 485 assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 486 Location location = listener.getLocation(); 487 assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider()); 488 assertEquals(latitude1, location.getLatitude()); 489 assertEquals(longitude1, location.getLongitude()); 490 assertEquals(true, location.isFromMockProvider()); 491 492 // Any further location change doesn't trigger an update. 493 updateLocation(latitude2, longitude2); 494 assertEquals(latitude1, location.getLatitude()); 495 assertEquals(longitude1, location.getLongitude()); 496 497 // update location without notifying listener 498 mManager.removeUpdates(listener); 499 listener.reset(); 500 updateLocation(latitude3, longitude3); 501 assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 502 503 try { 504 mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, mPendingIntent); 505 fail("Should throw IllegalArgumentException if PendingIntent is null!"); 506 } catch (IllegalArgumentException e) { 507 // expected 508 } 509 510 try { 511 mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, (LocationListener) null, 512 Looper.myLooper()); 513 fail("Should throw IllegalArgumentException if param listener is null!"); 514 } catch (IllegalArgumentException e) { 515 // expected 516 } 517 518 try { 519 mManager.requestSingleUpdate((String) null, listener, Looper.myLooper()); 520 fail("Should throw IllegalArgumentException if param provider is null!"); 521 } catch (IllegalArgumentException e) { 522 // expected 523 } 524 525 try { 526 mManager.removeUpdates((LocationListener) null ); 527 fail("Should throw IllegalArgumentException if listener is null!"); 528 } catch (IllegalArgumentException e) { 529 // expected 530 } 531 } 532 533 public void testLocationUpdatesWithCriteriaAndPendingIntent() throws InterruptedException { 534 double latitude1 = 10; 535 double longitude1 = 20; 536 double latitude2 = 30; 537 double longitude2 = 40; 538 539 registerIntentReceiver(); 540 mockFusedLocation(); 541 542 // Update location and receive broadcast. 543 Criteria criteria = createLocationCriteria(); 544 mManager.requestLocationUpdates(0, 0 , criteria, mPendingIntent); 545 updateFusedLocation(latitude1, longitude1); 546 waitForReceiveBroadcast(); 547 548 assertNotNull(mIntentReceiver.getLastReceivedIntent()); 549 Location location = (Location) mIntentReceiver.getLastReceivedIntent().getExtras() 550 .get(LocationManager.KEY_LOCATION_CHANGED); 551 assertEquals(latitude1, location.getLatitude()); 552 assertEquals(longitude1, location.getLongitude()); 553 assertTrue(location.hasAccuracy()); 554 assertEquals(1.0f, location.getAccuracy()); 555 assertEquals(true, location.isFromMockProvider()); 556 557 // Update location without receiving broadcast. 558 mManager.removeUpdates(mPendingIntent); 559 mIntentReceiver.clearReceivedIntents(); 560 updateFusedLocation(latitude2, longitude2); 561 waitForReceiveBroadcast(); 562 assertNull(mIntentReceiver.getLastReceivedIntent()); 563 564 // Missing arguments throw exceptions. 565 try { 566 mManager.requestLocationUpdates(0, 0, criteria, (PendingIntent) null); 567 fail("Should throw IllegalArgumentException if param intent is null!"); 568 } catch (IllegalArgumentException e) { 569 // expected 570 } 571 572 try { 573 mManager.requestLocationUpdates(0, 0, null, mPendingIntent); 574 fail("Should throw IllegalArgumentException if param criteria is null!"); 575 } catch (IllegalArgumentException e) { 576 // expected 577 } 578 579 try { 580 mManager.removeUpdates( (PendingIntent) null ); 581 fail("Should throw IllegalArgumentException if param PendingIntent is null!"); 582 } catch (IllegalArgumentException e) { 583 // expected 584 } 585 586 unmockFusedLocation(); 587 } 588 589 public void testSingleUpdateWithCriteriaAndPendingIntent() throws InterruptedException { 590 double latitude1 = 10; 591 double longitude1 = 20; 592 double latitude2 = 30; 593 double longitude2 = 40; 594 double latitude3 = 50; 595 double longitude3 = 60; 596 597 registerIntentReceiver(); 598 mockFusedLocation(); 599 600 // Update location and receive broadcast. 601 Criteria criteria = createLocationCriteria(); 602 mManager.requestSingleUpdate(criteria, mPendingIntent); 603 updateFusedLocation(latitude1, longitude1); 604 waitForReceiveBroadcast(); 605 606 assertNotNull(mIntentReceiver.getLastReceivedIntent()); 607 Location location = (Location) mIntentReceiver.getLastReceivedIntent().getExtras() 608 .get(LocationManager.KEY_LOCATION_CHANGED); 609 assertEquals(latitude1, location.getLatitude()); 610 assertEquals(longitude1, location.getLongitude()); 611 assertTrue(location.hasAccuracy()); 612 assertEquals(1.0f, location.getAccuracy()); 613 assertEquals(true, location.isFromMockProvider()); 614 615 // Any further location change doesn't trigger an update. 616 updateFusedLocation(latitude2, longitude2); 617 assertEquals(latitude1, location.getLatitude()); 618 assertEquals(longitude1, location.getLongitude()); 619 620 // Update location without receiving broadcast. 621 mManager.removeUpdates(mPendingIntent); 622 mIntentReceiver.clearReceivedIntents(); 623 updateFusedLocation(latitude3, longitude3); 624 waitForReceiveBroadcast(); 625 assertNull(mIntentReceiver.getLastReceivedIntent()); 626 627 // Missing arguments throw exceptions. 628 try { 629 mManager.requestSingleUpdate(criteria, (PendingIntent) null); 630 fail("Should throw IllegalArgumentException if param intent is null!"); 631 } catch (IllegalArgumentException e) { 632 // expected 633 } 634 635 try { 636 mManager.requestSingleUpdate((Criteria) null, mPendingIntent); 637 fail("Should throw IllegalArgumentException if param criteria is null!"); 638 } catch (IllegalArgumentException e) { 639 // expected 640 } 641 642 try { 643 mManager.removeUpdates( (PendingIntent) null ); 644 fail("Should throw IllegalArgumentException if param PendingIntent is null!"); 645 } catch (IllegalArgumentException e) { 646 // expected 647 } 648 649 unmockFusedLocation(); 650 } 651 652 public void testLocationUpdatesWithCriteriaAndLocationListenerAndLooper() 653 throws InterruptedException { 654 double latitude1 = 40; 655 double longitude1 = 10; 656 double latitude2 = 20; 657 double longitude2 = 30; 658 final MockLocationListener listener = new MockLocationListener(); 659 mockFusedLocation(); 660 661 // update location and notify listener 662 HandlerThread handlerThread = new HandlerThread("testLocationUpdates1"); 663 handlerThread.start(); 664 Criteria criteria = createLocationCriteria(); 665 mManager.requestLocationUpdates(0, 0, criteria, listener, handlerThread.getLooper()); 666 667 updateFusedLocation(latitude1, longitude1); 668 assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 669 Location location = listener.getLocation(); 670 assertEquals(latitude1, location.getLatitude()); 671 assertEquals(longitude1, location.getLongitude()); 672 assertTrue(location.hasAccuracy()); 673 assertEquals(1.0f, location.getAccuracy()); 674 assertEquals(true, location.isFromMockProvider()); 675 676 // update location without notifying listener 677 mManager.removeUpdates(listener); 678 listener.reset(); 679 updateFusedLocation(latitude2, longitude2); 680 assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 681 682 // Missing arguments throw exceptions. 683 try { 684 mManager.requestLocationUpdates(0, 0, criteria, (LocationListener) null, 685 Looper.myLooper()); 686 fail("Should throw IllegalArgumentException if param listener is null!"); 687 } catch (IllegalArgumentException e) { 688 // expected 689 } 690 691 try { 692 mManager.requestLocationUpdates(0, 0, null, listener, Looper.myLooper()); 693 fail("Should throw IllegalArgumentException if param criteria is null!"); 694 } catch (IllegalArgumentException e) { 695 // expected 696 } 697 698 try { 699 mManager.removeUpdates( (LocationListener) null ); 700 fail("Should throw IllegalArgumentException if listener is null!"); 701 } catch (IllegalArgumentException e) { 702 // expected 703 } 704 705 unmockFusedLocation(); 706 } 707 708 public void testSingleUpdateWithCriteriaAndLocationListenerAndLooper() 709 throws InterruptedException { 710 double latitude1 = 40; 711 double longitude1 = 10; 712 double latitude2 = 20; 713 double longitude2 = 30; 714 double latitude3 = 60; 715 double longitude3 = 50; 716 final MockLocationListener listener = new MockLocationListener(); 717 mockFusedLocation(); 718 719 // update location and notify listener 720 HandlerThread handlerThread = new HandlerThread("testLocationUpdates2"); 721 handlerThread.start(); 722 Criteria criteria = createLocationCriteria(); 723 mManager.requestSingleUpdate(criteria, listener, handlerThread.getLooper()); 724 725 updateFusedLocation(latitude1, longitude1); 726 assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 727 Location location = listener.getLocation(); 728 assertEquals(FUSED_PROVIDER_NAME, location.getProvider()); 729 assertEquals(latitude1, location.getLatitude()); 730 assertEquals(longitude1, location.getLongitude()); 731 assertTrue(location.hasAccuracy()); 732 assertEquals(1.0f, location.getAccuracy()); 733 assertEquals(true, location.isFromMockProvider()); 734 735 // Any further location change doesn't trigger an update. 736 updateFusedLocation(latitude2, longitude2); 737 assertEquals(latitude1, location.getLatitude()); 738 assertEquals(longitude1, location.getLongitude()); 739 740 // update location without notifying listener 741 mManager.removeUpdates(listener); 742 listener.reset(); 743 updateFusedLocation(latitude3, longitude3); 744 assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 745 746 // Missing arguments throw exceptions. 747 try { 748 mManager.requestLocationUpdates(0, 0, criteria, (LocationListener) null, 749 Looper.myLooper()); 750 fail("Should throw IllegalArgumentException if param listener is null!"); 751 } catch (IllegalArgumentException e) { 752 // expected 753 } 754 755 try { 756 mManager.requestLocationUpdates(0, 0, null, listener, Looper.myLooper()); 757 fail("Should throw IllegalArgumentException if param criteria is null!"); 758 } catch (IllegalArgumentException e) { 759 // expected 760 } 761 762 try { 763 mManager.removeUpdates( (LocationListener) null ); 764 fail("Should throw IllegalArgumentException if listener is null!"); 765 } catch (IllegalArgumentException e) { 766 // expected 767 } 768 769 unmockFusedLocation(); 770 } 771 772 public void testSingleUpdateWithPendingIntent() throws InterruptedException { 773 double latitude1 = 20; 774 double longitude1 = 40; 775 double latitude2 = 30; 776 double longitude2 = 50; 777 double latitude3 = 10; 778 double longitude3 = 60; 779 780 // update location and receive broadcast. 781 registerIntentReceiver(); 782 mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent); 783 updateLocation(latitude1, longitude1); 784 waitForReceiveBroadcast(); 785 786 assertNotNull(mIntentReceiver.getLastReceivedIntent()); 787 Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME); 788 assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider()); 789 assertEquals(latitude1, location.getLatitude()); 790 assertEquals(longitude1, location.getLongitude()); 791 assertEquals(true, location.isFromMockProvider()); 792 793 // Any further location change doesn't trigger an update. 794 updateLocation(latitude2, longitude2); 795 assertEquals(latitude1, location.getLatitude()); 796 assertEquals(longitude1, location.getLongitude()); 797 798 // update location without receiving broadcast. 799 mManager.removeUpdates(mPendingIntent); 800 mIntentReceiver.clearReceivedIntents(); 801 updateLocation(latitude3, longitude3); 802 waitForReceiveBroadcast(); 803 assertEquals(latitude1, location.getLatitude()); 804 assertEquals(longitude1, location.getLongitude()); 805 806 try { 807 mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, 808 (PendingIntent) null); 809 fail("Should throw IllegalArgumentException if param intent is null!"); 810 } catch (IllegalArgumentException e) { 811 // expected 812 } 813 814 try { 815 mManager.requestLocationUpdates(null, 0, 0, mPendingIntent); 816 fail("Should throw IllegalArgumentException if param provider is null!"); 817 } catch (IllegalArgumentException e) { 818 // expected 819 } 820 821 try { 822 mManager.removeUpdates( (PendingIntent) null ); 823 fail("Should throw IllegalArgumentException if intent is null!"); 824 } catch (IllegalArgumentException e) { 825 // expected 826 } 827 } 828 829 public void testAddProximityAlert() { 830 Intent i = new Intent(); 831 i.setAction("android.location.cts.TEST_GET_GPS_STATUS_ACTION"); 832 PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT); 833 834 mManager.addProximityAlert(0, 0, 1.0f, 5000, pi); 835 mManager.removeProximityAlert(pi); 836 } 837 838 @UiThreadTest 839 public void testNmeaListener() { 840 MockGnssNmeaListener gnssListener = new MockGnssNmeaListener(); 841 mManager.addNmeaListener(gnssListener); 842 mManager.removeNmeaListener(gnssListener); 843 844 HandlerThread handlerThread = new HandlerThread("testNmeaListener"); 845 handlerThread.start(); 846 mManager.addNmeaListener(gnssListener, new Handler(handlerThread.getLooper())); 847 mManager.removeNmeaListener(gnssListener); 848 849 mManager.addNmeaListener((OnNmeaMessageListener) null); 850 mManager.removeNmeaListener((OnNmeaMessageListener) null); 851 } 852 853 public void testIsProviderEnabled() { 854 // this test assumes enabled TEST_MOCK_PROVIDER_NAME was created in setUp. 855 assertNotNull(mManager.getProvider(TEST_MOCK_PROVIDER_NAME)); 856 assertTrue(mManager.isProviderEnabled(TEST_MOCK_PROVIDER_NAME)); 857 858 mManager.clearTestProviderEnabled(TEST_MOCK_PROVIDER_NAME); 859 assertFalse(mManager.isProviderEnabled(TEST_MOCK_PROVIDER_NAME)); 860 861 mManager.setTestProviderEnabled(TEST_MOCK_PROVIDER_NAME, true); 862 assertTrue(mManager.isProviderEnabled(TEST_MOCK_PROVIDER_NAME)); 863 864 try { 865 mManager.isProviderEnabled(null); 866 fail("Should throw IllegalArgumentException if provider is null!"); 867 } catch (IllegalArgumentException e) { 868 // expected 869 } 870 871 try { 872 mManager.setTestProviderEnabled(UNKNOWN_PROVIDER_NAME, false); 873 fail("Should throw IllegalArgumentException if provider is unknown!"); 874 } catch (IllegalArgumentException e) { 875 // expected 876 } 877 } 878 879 public void testGetLastKnownLocation() throws InterruptedException { 880 double latitude1 = 20; 881 double longitude1 = 40; 882 double latitude2 = 10; 883 double longitude2 = 70; 884 885 registerIntentReceiver(); 886 mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent); 887 updateLocation(latitude1, longitude1); 888 waitForReceiveBroadcast(); 889 890 assertNotNull(mIntentReceiver.getLastReceivedIntent()); 891 Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME); 892 assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider()); 893 assertEquals(latitude1, location.getLatitude()); 894 assertEquals(longitude1, location.getLongitude()); 895 assertEquals(true, location.isFromMockProvider()); 896 897 mIntentReceiver.clearReceivedIntents(); 898 updateLocation(latitude2, longitude2); 899 waitForReceiveBroadcast(); 900 901 assertNotNull(mIntentReceiver.getLastReceivedIntent()); 902 location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME); 903 assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider()); 904 assertEquals(latitude2, location.getLatitude()); 905 assertEquals(longitude2, location.getLongitude()); 906 assertEquals(true, location.isFromMockProvider()); 907 908 try { 909 mManager.getLastKnownLocation(null); 910 fail("Should throw IllegalArgumentException if provider is null!"); 911 } catch (IllegalArgumentException e) { 912 // expected 913 } 914 } 915 916 /** 917 * Test case for bug 33091107, where a malicious app used to be able to fool a real provider 918 * into providing a mock location that isn't marked as being mock. 919 */ 920 public void testLocationShouldStillBeMarkedMockWhenProvidersDoNotMatch() 921 throws InterruptedException { 922 double latitude = 20; 923 double longitude = 40; 924 925 List<String> providers = mManager.getAllProviders(); 926 if (providers.isEmpty()) { 927 // Device doesn't have any providers. Can't perform this test, and no need to do so: 928 // no providers that malicious app could fool 929 return; 930 } 931 String realProviderToFool = providers.get(0); 932 933 // Register for location updates, then set a mock location and ensure it is marked "mock" 934 updateLocationAndWait(TEST_MOCK_PROVIDER_NAME, realProviderToFool, latitude, longitude); 935 } 936 937 @UiThreadTest 938 public void testGnssStatusListener() { 939 MockGnssStatusCallback callback = new MockGnssStatusCallback(); 940 mManager.registerGnssStatusCallback(callback); 941 mManager.unregisterGnssStatusCallback(callback); 942 943 mManager.registerGnssStatusCallback(null); 944 mManager.unregisterGnssStatusCallback(null); 945 946 HandlerThread handlerThread = new HandlerThread("testStatusUpdates"); 947 handlerThread.start(); 948 949 mManager.registerGnssStatusCallback(callback, new Handler(handlerThread.getLooper())); 950 mManager.unregisterGnssStatusCallback(callback); 951 } 952 953 /** 954 * Tests basic proximity alert when entering proximity 955 */ 956 public void testEnterProximity() throws Exception { 957 if (!isSystemUser()) { 958 Log.i(TAG, "Skipping test on secondary user"); 959 return; 960 } 961 // need to mock the fused location provider for proximity tests 962 mockFusedLocation(); 963 964 doTestEnterProximity(10000); 965 966 unmockFusedLocation(); 967 } 968 969 /** 970 * Tests proximity alert when entering proximity, with no expiration 971 */ 972 public void testEnterProximity_noexpire() throws Exception { 973 if (!isSystemUser()) { 974 Log.i(TAG, "Skipping test on secondary user"); 975 return; 976 } 977 // need to mock the fused location provider for proximity tests 978 mockFusedLocation(); 979 980 doTestEnterProximity(-1); 981 982 unmockFusedLocation(); 983 } 984 985 /** 986 * Tests basic proximity alert when exiting proximity 987 */ 988 public void testExitProximity() throws Exception { 989 if (!isSystemUser()) { 990 Log.i(TAG, "Skipping test on secondary user"); 991 return; 992 } 993 // need to mock the fused location provider for proximity tests 994 mockFusedLocation(); 995 996 // first do enter proximity scenario 997 doTestEnterProximity(-1); 998 999 // now update to trigger exit proximity proximity 1000 mIntentReceiver.clearReceivedIntents(); 1001 updateLocationAndWait(FUSED_PROVIDER_NAME, 20, 20); 1002 waitForReceiveBroadcast(); 1003 assertProximityType(false); 1004 1005 unmockFusedLocation(); 1006 } 1007 1008 /** 1009 * Tests basic proximity alert when initially within proximity 1010 */ 1011 public void testInitiallyWithinProximity() throws Exception { 1012 if (!isSystemUser()) { 1013 Log.i(TAG, "Skipping test on secondary user"); 1014 return; 1015 } 1016 // need to mock the fused location provider for proximity tests 1017 mockFusedLocation(); 1018 1019 updateLocationAndWait(FUSED_PROVIDER_NAME, 0, 0); 1020 registerProximityListener(0, 0, 1000, 10000); 1021 waitForReceiveBroadcast(); 1022 assertProximityType(true); 1023 1024 unmockFusedLocation(); 1025 } 1026 1027 /** 1028 * Helper variant for testing enter proximity scenario 1029 * TODO: add additional parameters as more scenarios are added 1030 * 1031 * @param expiration - expiration of proximity alert 1032 */ 1033 private void doTestEnterProximity(long expiration) throws Exception { 1034 // update location to outside proximity range 1035 updateLocationAndWait(FUSED_PROVIDER_NAME, 30, 30); 1036 registerProximityListener(0, 0, 1000, expiration); 1037 1038 // Adding geofences is asynchronous, the return of LocationManager.addProximityAlert 1039 // doesn't mean that geofences are already being monitored. Wait for a few milliseconds 1040 // so that GeofenceManager is actively monitoring locations before we send the mock 1041 // location to avoid flaky tests. 1042 Thread.sleep(500); 1043 1044 updateLocationAndWait(FUSED_PROVIDER_NAME, 0, 0); 1045 waitForReceiveBroadcast(); 1046 assertProximityType(true); 1047 } 1048 1049 1050 private void updateLocationAndWait(String providerName, double latitude, double longitude) 1051 throws InterruptedException { 1052 updateLocationAndWait(providerName, providerName, latitude, longitude); 1053 } 1054 1055 /** 1056 * Like {@link #updateLocationAndWait(String, double, double)}, but allows inconsistent providers 1057 * to be used in the calls to {@link Location#Location(String)} and {@link 1058 * LocationManager#setTestProviderLocation(String, Location)} 1059 * 1060 * @param testProviderName used in {@link LocationManager#setTestProviderLocation(String, 1061 * Location)} 1062 * @param locationProviderName used in {@link Location#Location(String)} 1063 */ 1064 private void updateLocationAndWait(String testProviderName, String locationProviderName, 1065 double latitude, double longitude) throws InterruptedException { 1066 1067 // Register a listener for the location we are about to set. 1068 MockLocationListener listener = new MockLocationListener(); 1069 HandlerThread handlerThread = new HandlerThread("updateLocationAndWait"); 1070 handlerThread.start(); 1071 mManager.requestLocationUpdates(locationProviderName, 0, 0, listener, 1072 handlerThread.getLooper()); 1073 1074 // Set the location. 1075 updateLocation(testProviderName, locationProviderName, latitude, longitude); 1076 1077 // Make sure we received the location, and it is the right one. 1078 assertTrue("Listener not called", listener.hasCalledOnLocationChanged(TEST_TIME_OUT)); 1079 Location location = listener.getLocation(); 1080 assertEquals("Bad provider name", locationProviderName, location.getProvider()); 1081 assertEquals("Bad latitude", latitude, location.getLatitude()); 1082 assertEquals("Bad longitude", longitude, location.getLongitude()); 1083 assertTrue("Bad isMock", location.isFromMockProvider()); 1084 1085 // Remove the listener. 1086 mManager.removeUpdates(listener); 1087 } 1088 1089 private void registerIntentReceiver() { 1090 String intentKey = "LocationManagerTest"; 1091 Intent proximityIntent = new Intent(intentKey); 1092 mPendingIntent = PendingIntent.getBroadcast(mContext, 0, proximityIntent, 1093 PendingIntent.FLAG_CANCEL_CURRENT); 1094 mIntentReceiver = new TestIntentReceiver(intentKey); 1095 mContext.registerReceiver(mIntentReceiver, mIntentReceiver.getFilter()); 1096 } 1097 1098 /** 1099 * Registers the proximity intent receiver 1100 */ 1101 private void registerProximityListener(double latitude, double longitude, float radius, 1102 long expiration) { 1103 registerIntentReceiver(); 1104 mManager.addProximityAlert(latitude, longitude, radius, expiration, mPendingIntent); 1105 } 1106 1107 /** 1108 * Blocks until receive intent notification or time out. 1109 * 1110 * @throws InterruptedException 1111 */ 1112 private void waitForReceiveBroadcast() throws InterruptedException { 1113 synchronized (mIntentReceiver) { 1114 mIntentReceiver.wait(TEST_TIME_OUT); 1115 } 1116 } 1117 1118 /** 1119 * Asserts that the received intent had the enter proximity property set as 1120 * expected 1121 * 1122 * @param expectedEnterProximity - true if enter proximity expected, false 1123 * if exit expected 1124 */ 1125 private void assertProximityType(boolean expectedEnterProximity) throws Exception { 1126 Intent intent = mIntentReceiver.getLastReceivedIntent(); 1127 assertNotNull("Did not receive any intent", intent); 1128 boolean proximityTest = intent.getBooleanExtra( 1129 LocationManager.KEY_PROXIMITY_ENTERING, !expectedEnterProximity); 1130 assertEquals("proximity alert not set to expected enter proximity value", 1131 expectedEnterProximity, proximityTest); 1132 } 1133 1134 private void updateLocation(final String providerName, final double latitude, 1135 final double longitude) { 1136 updateLocation(providerName, providerName, latitude, longitude); 1137 } 1138 1139 /** 1140 * Like {@link #updateLocation(String, double, double)}, but allows inconsistent providers to be 1141 * used in the calls to {@link Location#Location(String)} and 1142 * {@link LocationManager#setTestProviderLocation(String, Location)}. 1143 */ 1144 private void updateLocation(String testProviderName, String locationProviderName, 1145 double latitude, double longitude) { 1146 Location location = new Location(locationProviderName); 1147 location.setLatitude(latitude); 1148 location.setLongitude(longitude); 1149 location.setAccuracy(1.0f); 1150 location.setTime(System.currentTimeMillis()); 1151 location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); 1152 mManager.setTestProviderLocation(testProviderName, location); 1153 } 1154 1155 private void updateLocation(final double latitude, final double longitude) { 1156 updateLocation(TEST_MOCK_PROVIDER_NAME, latitude, longitude); 1157 } 1158 1159 private void updateFusedLocation(final double latitude, final double longitude) { 1160 updateLocation(FUSED_PROVIDER_NAME, latitude, longitude); 1161 } 1162 1163 private Criteria createLocationCriteria() { 1164 Criteria criteria = new Criteria(); 1165 criteria.setAccuracy(Criteria.ACCURACY_FINE); 1166 criteria.setPowerRequirement(Criteria.POWER_MEDIUM); 1167 criteria.setAltitudeRequired(false); 1168 criteria.setBearingRequired(false); 1169 criteria.setCostAllowed(false); 1170 criteria.setSpeedRequired(false); 1171 return criteria; 1172 } 1173 1174 private void mockFusedLocation() { 1175 addTestProvider(FUSED_PROVIDER_NAME); 1176 } 1177 1178 private void unmockFusedLocation() { 1179 mManager.removeTestProvider(FUSED_PROVIDER_NAME); 1180 } 1181 1182 /** 1183 * Helper class that receives a proximity intent and notifies the main class 1184 * when received 1185 */ 1186 private static class TestIntentReceiver extends BroadcastReceiver { 1187 private String mExpectedAction; 1188 1189 private Intent mLastReceivedIntent; 1190 1191 public TestIntentReceiver(String expectedAction) { 1192 mExpectedAction = expectedAction; 1193 mLastReceivedIntent = null; 1194 } 1195 1196 public IntentFilter getFilter() { 1197 IntentFilter filter = new IntentFilter(mExpectedAction); 1198 return filter; 1199 } 1200 1201 @Override 1202 public void onReceive(Context context, Intent intent) { 1203 if (intent != null && mExpectedAction.equals(intent.getAction())) { 1204 synchronized (this) { 1205 mLastReceivedIntent = intent; 1206 notify(); 1207 } 1208 } 1209 } 1210 1211 public Intent getLastReceivedIntent() { 1212 return mLastReceivedIntent; 1213 } 1214 1215 public void clearReceivedIntents() { 1216 mLastReceivedIntent = null; 1217 } 1218 } 1219 1220 private static class MockLocationListener implements LocationListener { 1221 private String mProvider; 1222 private int mStatus; 1223 private Location mLocation; 1224 private Object mStatusLock = new Object(); 1225 private Object mLocationLock = new Object(); 1226 private Object mLocationRequestLock = new Object(); 1227 1228 private boolean mHasCalledOnLocationChanged; 1229 1230 private boolean mHasCalledOnProviderDisabled; 1231 1232 private boolean mHasCalledOnProviderEnabled; 1233 1234 private boolean mHasCalledOnStatusChanged; 1235 1236 private boolean mHasCalledRequestLocation; 1237 1238 public void reset(){ 1239 mHasCalledOnLocationChanged = false; 1240 mHasCalledOnProviderDisabled = false; 1241 mHasCalledOnProviderEnabled = false; 1242 mHasCalledOnStatusChanged = false; 1243 mHasCalledRequestLocation = false; 1244 mProvider = null; 1245 mStatus = 0; 1246 } 1247 1248 /** 1249 * Call to inform listener that location has been updates have been requested 1250 */ 1251 public void setLocationRequested() { 1252 synchronized (mLocationRequestLock) { 1253 mHasCalledRequestLocation = true; 1254 mLocationRequestLock.notify(); 1255 } 1256 } 1257 1258 public boolean hasCalledLocationRequested(long timeout) throws InterruptedException { 1259 synchronized (mLocationRequestLock) { 1260 if (timeout > 0 && !mHasCalledRequestLocation) { 1261 mLocationRequestLock.wait(timeout); 1262 } 1263 } 1264 return mHasCalledRequestLocation; 1265 } 1266 1267 /** 1268 * Check whether onLocationChanged() has been called. Wait up to timeout milliseconds 1269 * for the callback. 1270 * @param timeout Maximum time to wait for the callback, 0 to return immediately. 1271 */ 1272 public boolean hasCalledOnLocationChanged(long timeout) throws InterruptedException { 1273 synchronized (mLocationLock) { 1274 if (timeout > 0 && !mHasCalledOnLocationChanged) { 1275 mLocationLock.wait(timeout); 1276 } 1277 } 1278 return mHasCalledOnLocationChanged; 1279 } 1280 1281 public boolean hasCalledOnProviderDisabled() { 1282 return mHasCalledOnProviderDisabled; 1283 } 1284 1285 public boolean hasCalledOnProviderEnabled() { 1286 return mHasCalledOnProviderEnabled; 1287 } 1288 1289 public boolean hasCalledOnStatusChanged(long timeout) throws InterruptedException { 1290 synchronized(mStatusLock) { 1291 // wait(0) would wait forever 1292 if (timeout > 0 && !mHasCalledOnStatusChanged) { 1293 mStatusLock.wait(timeout); 1294 } 1295 } 1296 return mHasCalledOnStatusChanged; 1297 } 1298 1299 public void onLocationChanged(Location location) { 1300 mLocation = location; 1301 synchronized (mLocationLock) { 1302 mHasCalledOnLocationChanged = true; 1303 mLocationLock.notify(); 1304 } 1305 } 1306 1307 public void onProviderDisabled(String provider) { 1308 mHasCalledOnProviderDisabled = true; 1309 } 1310 1311 public void onProviderEnabled(String provider) { 1312 mHasCalledOnProviderEnabled = true; 1313 } 1314 1315 public void onStatusChanged(String provider, int status, Bundle extras) { 1316 mProvider = provider; 1317 mStatus = status; 1318 synchronized (mStatusLock) { 1319 mHasCalledOnStatusChanged = true; 1320 mStatusLock.notify(); 1321 } 1322 } 1323 1324 public String getProvider() { 1325 return mProvider; 1326 } 1327 1328 public int getStatus() { 1329 return mStatus; 1330 } 1331 1332 public Location getLocation() { 1333 return mLocation; 1334 } 1335 } 1336 1337 private static class MockGnssNmeaListener implements OnNmeaMessageListener { 1338 private boolean mIsNmeaReceived; 1339 1340 @Override 1341 public void onNmeaMessage(String name, long timestamp) { 1342 mIsNmeaReceived = true; 1343 } 1344 1345 public boolean isNmeaRecevied() { 1346 return mIsNmeaReceived; 1347 } 1348 1349 public void reset() { 1350 mIsNmeaReceived = false; 1351 } 1352 } 1353 1354 private static class MockGnssStatusCallback extends GnssStatus.Callback { 1355 @Override 1356 public void onSatelliteStatusChanged(GnssStatus status) { 1357 for (int i = 0; i < status.getSatelliteCount(); ++i) { 1358 status.getAzimuthDegrees(i); 1359 status.getCn0DbHz(i); 1360 status.getConstellationType(i); 1361 status.getElevationDegrees(i); 1362 status.getSvid(i); 1363 status.hasAlmanacData(i); 1364 status.hasEphemerisData(i); 1365 status.usedInFix(i); 1366 } 1367 } 1368 } 1369 1370 private boolean isSystemUser() { 1371 UserManager userManager = mContext.getSystemService(UserManager.class); 1372 return userManager.isSystemUser(); 1373 } 1374 } 1375