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.fine; 18 19 import static android.Manifest.permission.LOCATION_BYPASS; 20 import static android.Manifest.permission.WRITE_SECURE_SETTINGS; 21 import static android.app.AppOpsManager.OPSTR_MONITOR_HIGH_POWER_LOCATION; 22 import static android.app.AppOpsManager.OPSTR_MONITOR_LOCATION; 23 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; 24 import static android.content.pm.PackageManager.FEATURE_TELEVISION; 25 import static android.content.pm.PackageManager.FEATURE_WATCH; 26 import static android.location.LocationManager.EXTRA_PROVIDER_ENABLED; 27 import static android.location.LocationManager.EXTRA_PROVIDER_NAME; 28 import static android.location.LocationManager.FUSED_PROVIDER; 29 import static android.location.LocationManager.GPS_PROVIDER; 30 import static android.location.LocationManager.NETWORK_PROVIDER; 31 import static android.location.LocationManager.PASSIVE_PROVIDER; 32 import static android.location.LocationManager.PROVIDERS_CHANGED_ACTION; 33 import static android.location.LocationRequest.PASSIVE_INTERVAL; 34 import static android.location.LocationRequest.QUALITY_HIGH_ACCURACY; 35 import static android.os.PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF; 36 import static android.os.PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF; 37 import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF; 38 39 import static androidx.test.ext.truth.content.IntentSubject.assertThat; 40 import static androidx.test.ext.truth.location.LocationSubject.assertThat; 41 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 42 43 import static com.android.compatibility.common.util.LocationUtils.createLocation; 44 45 import static com.google.common.truth.Truth.assertThat; 46 47 import static org.junit.Assert.assertFalse; 48 import static org.junit.Assert.assertTrue; 49 import static org.junit.Assert.fail; 50 import static org.junit.Assume.assumeFalse; 51 import static org.junit.Assume.assumeTrue; 52 53 import android.Manifest; 54 import android.annotation.NonNull; 55 import android.app.AppOpsManager; 56 import android.app.PendingIntent; 57 import android.app.UiAutomation; 58 import android.content.Context; 59 import android.content.Intent; 60 import android.location.Criteria; 61 import android.location.GnssMeasurementsEvent; 62 import android.location.GnssNavigationMessage; 63 import android.location.GnssStatus; 64 import android.location.LastLocationRequest; 65 import android.location.Location; 66 import android.location.LocationListener; 67 import android.location.LocationManager; 68 import android.location.LocationProvider; 69 import android.location.LocationRequest; 70 import android.location.OnNmeaMessageListener; 71 import android.location.cts.common.BroadcastCapture; 72 import android.location.cts.common.GetCurrentLocationCapture; 73 import android.location.cts.common.LocationListenerCapture; 74 import android.location.cts.common.LocationPendingIntentCapture; 75 import android.location.cts.common.OpActiveChangedCapture; 76 import android.location.cts.common.ProviderRequestChangedListenerCapture; 77 import android.location.cts.common.gnss.GnssAntennaInfoCapture; 78 import android.location.cts.common.gnss.GnssMeasurementsCapture; 79 import android.location.cts.common.gnss.GnssNavigationMessageCapture; 80 import android.location.provider.ProviderProperties; 81 import android.os.Build; 82 import android.os.HandlerThread; 83 import android.os.Looper; 84 import android.os.PowerManager; 85 import android.os.SystemClock; 86 import android.os.SystemProperties; 87 import android.platform.test.annotations.AppModeFull; 88 import android.provider.DeviceConfig; 89 import android.util.ArraySet; 90 import android.util.Log; 91 92 import androidx.test.core.app.ApplicationProvider; 93 import androidx.test.ext.junit.runners.AndroidJUnit4; 94 import androidx.test.platform.app.InstrumentationRegistry; 95 96 import com.android.compatibility.common.util.BatteryUtils; 97 import com.android.compatibility.common.util.DeviceConfigStateHelper; 98 import com.android.compatibility.common.util.LocationUtils; 99 import com.android.compatibility.common.util.ScreenUtils; 100 import com.android.compatibility.common.util.ScreenUtils.ScreenResetter; 101 102 import org.junit.After; 103 import org.junit.Before; 104 import org.junit.Ignore; 105 import org.junit.Test; 106 import org.junit.runner.RunWith; 107 108 import java.util.Collections; 109 import java.util.HashSet; 110 import java.util.List; 111 import java.util.Objects; 112 import java.util.Random; 113 import java.util.concurrent.Executors; 114 115 @RunWith(AndroidJUnit4.class) 116 public class LocationManagerFineTest { 117 118 private static final String TAG = "LocationManagerFineTest"; 119 120 private static final long TIMEOUT_MS = 5000; 121 private static final long FAILURE_TIMEOUT_MS = 200; 122 123 private static final String TEST_PROVIDER = "test_provider"; 124 125 private static final String VALID_LOCATION_ATTRIBUTION_TAG = "valid_location_attribution_tag"; 126 private static final String ANOTHER_VALID_LOCATION_ATTRIBUTION_TAG = 127 "another_valid_location_attribution_tag"; 128 private static final String INVALID_LOCATION_ATTRIBUTION_TAG = 129 "invalid_location_attribution_tag"; 130 131 private static final String IGNORE_SETTINGS_ALLOWLIST = "ignore_settings_allowlist"; 132 private static final String ADAS_SETTINGS_ALLOWLIST = "adas_settings_allowlist"; 133 134 private Random mRandom; 135 private Context mContext; 136 private LocationManager mManager; 137 138 @Before setUp()139 public void setUp() throws Exception { 140 LocationUtils.registerMockLocationProvider(getInstrumentation(), 141 true); 142 143 long seed = System.currentTimeMillis(); 144 Log.i(TAG, "location random seed: " + seed); 145 146 mRandom = new Random(seed); 147 mContext = ApplicationProvider.getApplicationContext(); 148 mManager = Objects.requireNonNull(mContext.getSystemService(LocationManager.class)); 149 150 for (String provider : mManager.getAllProviders()) { 151 mManager.removeTestProvider(provider); 152 } 153 154 mManager.addTestProvider(TEST_PROVIDER, 155 new ProviderProperties.Builder() 156 .setHasNetworkRequirement(true) 157 .setHasCellRequirement(true) 158 .setPowerUsage(ProviderProperties.POWER_USAGE_HIGH) 159 .setAccuracy(ProviderProperties.ACCURACY_FINE).build()); 160 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 161 } 162 163 @After tearDown()164 public void tearDown() throws Exception { 165 if (mManager != null) { 166 for (String provider : mManager.getAllProviders()) { 167 mManager.removeTestProvider(provider); 168 } 169 mManager.removeTestProvider(FUSED_PROVIDER); 170 } 171 172 LocationUtils.registerMockLocationProvider(getInstrumentation(), 173 false); 174 } 175 176 @Test testIsLocationEnabled()177 public void testIsLocationEnabled() { 178 assertThat(mManager.isLocationEnabled()).isTrue(); 179 } 180 181 @Test testIsProviderEnabled()182 public void testIsProviderEnabled() { 183 assertThat(mManager.isProviderEnabled(TEST_PROVIDER)).isTrue(); 184 185 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 186 assertThat(mManager.isProviderEnabled(TEST_PROVIDER)).isFalse(); 187 188 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 189 assertThat(mManager.isProviderEnabled(TEST_PROVIDER)).isTrue(); 190 191 for (String provider : mManager.getAllProviders()) { 192 mManager.isProviderEnabled(provider); 193 } 194 195 try { 196 mManager.isProviderEnabled(null); 197 fail("Should throw IllegalArgumentException if provider is null!"); 198 } catch (IllegalArgumentException e) { 199 // expected 200 } 201 } 202 203 @Test testGetLastKnownLocation()204 public void testGetLastKnownLocation() { 205 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 206 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 207 208 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 209 assertThat(mManager.getLastKnownLocation(TEST_PROVIDER)).isEqualTo(loc1); 210 211 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 212 assertThat(mManager.getLastKnownLocation(TEST_PROVIDER)).isEqualTo(loc2); 213 214 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 215 assertThat(mManager.getLastKnownLocation(TEST_PROVIDER)).isNull(); 216 217 try { 218 mManager.getLastKnownLocation(null); 219 fail("Should throw IllegalArgumentException if provider is null!"); 220 } catch (IllegalArgumentException e) { 221 // expected 222 } 223 } 224 225 @Test testGetLastKnownLocation_AdasLocationSettings_ReturnsLocation()226 public void testGetLastKnownLocation_AdasLocationSettings_ReturnsLocation() throws Exception { 227 assumeTrue(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)); 228 229 try (LocationListenerCapture capture = new LocationListenerCapture(mContext); 230 DeviceConfigStateHelper locationDeviceConfigStateHelper = 231 new DeviceConfigStateHelper(DeviceConfig.NAMESPACE_LOCATION)) { 232 233 locationDeviceConfigStateHelper.set(ADAS_SETTINGS_ALLOWLIST, 234 mContext.getPackageName()); 235 236 mManager.addTestProvider( 237 GPS_PROVIDER, 238 false, 239 true, 240 false, 241 false, 242 true, 243 true, 244 true, 245 Criteria.POWER_HIGH, 246 Criteria.ACCURACY_FINE); 247 248 Location loc = createLocation(GPS_PROVIDER, mRandom); 249 mManager.setTestProviderLocation(GPS_PROVIDER, loc); 250 251 mManager.setTestProviderEnabled(GPS_PROVIDER, true); 252 253 getInstrumentation() 254 .getUiAutomation() 255 .adoptShellPermissionIdentity(LOCATION_BYPASS, WRITE_SECURE_SETTINGS); 256 257 try { 258 // Returns loc when ADAS toggle is on. 259 mManager.setLocationEnabledForUser(false, mContext.getUser()); 260 mManager.setAdasGnssLocationEnabled(true); 261 assertThat( 262 mManager.getLastKnownLocation( 263 GPS_PROVIDER, 264 new LastLocationRequest.Builder() 265 .setAdasGnssBypass(true) 266 .build())) 267 .isEqualTo(loc); 268 269 } finally { 270 mManager.setLocationEnabledForUser(true, android.os.Process.myUserHandle()); 271 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 272 } 273 } 274 } 275 276 @Test testGetLastKnownLocation_AdasLocationSettings_ReturnsNull()277 public void testGetLastKnownLocation_AdasLocationSettings_ReturnsNull() throws Exception { 278 assumeTrue(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)); 279 280 try (LocationListenerCapture capture = new LocationListenerCapture(mContext); 281 DeviceConfigStateHelper locationDeviceConfigStateHelper = 282 new DeviceConfigStateHelper(DeviceConfig.NAMESPACE_LOCATION)) { 283 284 locationDeviceConfigStateHelper.set(ADAS_SETTINGS_ALLOWLIST, 285 mContext.getPackageName()); 286 287 mManager.addTestProvider( 288 GPS_PROVIDER, 289 false, 290 true, 291 false, 292 false, 293 true, 294 true, 295 true, 296 Criteria.POWER_HIGH, 297 Criteria.ACCURACY_FINE); 298 299 Location loc = createLocation(GPS_PROVIDER, mRandom); 300 mManager.setTestProviderLocation(GPS_PROVIDER, loc); 301 302 mManager.setTestProviderEnabled(GPS_PROVIDER, true); 303 304 getInstrumentation() 305 .getUiAutomation() 306 .adoptShellPermissionIdentity(LOCATION_BYPASS, WRITE_SECURE_SETTINGS); 307 308 try { 309 // Returns null when ADAS toggle is off 310 mManager.setAdasGnssLocationEnabled(false); 311 mManager.setLocationEnabledForUser(false, mContext.getUser()); 312 313 assertThat( 314 mManager.getLastKnownLocation( 315 GPS_PROVIDER, 316 new LastLocationRequest.Builder() 317 .setAdasGnssBypass(true) 318 .build())) 319 .isNull(); 320 321 } finally { 322 mManager.setLocationEnabledForUser(true, android.os.Process.myUserHandle()); 323 mManager.setAdasGnssLocationEnabled(true); 324 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 325 } 326 } 327 } 328 329 @Test testGetLastKnownLocation_RemoveProvider()330 public void testGetLastKnownLocation_RemoveProvider() { 331 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 332 333 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 334 mManager.removeTestProvider(TEST_PROVIDER); 335 assertThat(mManager.getLastKnownLocation(TEST_PROVIDER)).isNull(); 336 } 337 338 @Test testGetCurrentLocation()339 public void testGetCurrentLocation() throws Exception { 340 Location loc = createLocation(TEST_PROVIDER, mRandom); 341 342 try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) { 343 mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(), 344 Executors.newSingleThreadExecutor(), capture); 345 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 346 assertThat(capture.getLocation(TIMEOUT_MS)).isEqualTo(loc); 347 } 348 349 try { 350 mManager.getCurrentLocation((String) null, null, Executors.newSingleThreadExecutor(), 351 (location) -> {}); 352 fail("Should throw IllegalArgumentException if provider is null!"); 353 } catch (IllegalArgumentException e) { 354 // expected 355 } 356 } 357 358 @Test testGetCurrentLocation_Timeout()359 public void testGetCurrentLocation_Timeout() throws Exception { 360 try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) { 361 mManager.getCurrentLocation( 362 TEST_PROVIDER, 363 new LocationRequest.Builder(0).setDurationMillis(500).build(), 364 capture.getCancellationSignal(), 365 Executors.newSingleThreadExecutor(), 366 capture); 367 assertThat(capture.getLocation(1000)).isNull(); 368 } 369 370 try { 371 mManager.getCurrentLocation((String) null, null, Executors.newSingleThreadExecutor(), 372 (location) -> {}); 373 fail("Should throw IllegalArgumentException if provider is null!"); 374 } catch (IllegalArgumentException e) { 375 // expected 376 } 377 } 378 379 @Test testGetCurrentLocation_FreshOldLocation()380 public void testGetCurrentLocation_FreshOldLocation() throws Exception { 381 Location loc = createLocation(TEST_PROVIDER, mRandom); 382 383 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 384 try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) { 385 mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(), 386 Executors.newSingleThreadExecutor(), capture); 387 assertThat(capture.getLocation(TIMEOUT_MS)).isEqualTo(loc); 388 } 389 } 390 391 @Test testGetCurrentLocation_DirectExecutor()392 public void testGetCurrentLocation_DirectExecutor() throws Exception { 393 Location loc = createLocation(TEST_PROVIDER, mRandom); 394 395 try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) { 396 mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(), 397 Runnable::run, capture); 398 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 399 assertThat(capture.getLocation(TIMEOUT_MS)).isEqualTo(loc); 400 } 401 } 402 403 @Test testGetCurrentLocation_Cancellation()404 public void testGetCurrentLocation_Cancellation() throws Exception { 405 Location loc = createLocation(TEST_PROVIDER, mRandom); 406 407 try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) { 408 mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(), 409 Executors.newSingleThreadExecutor(), capture); 410 capture.getCancellationSignal().cancel(); 411 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 412 assertThat(capture.hasLocation(FAILURE_TIMEOUT_MS)).isFalse(); 413 } 414 } 415 416 @Test testGetCurrentLocation_ProviderDisabled()417 public void testGetCurrentLocation_ProviderDisabled() throws Exception { 418 try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) { 419 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 420 mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(), 421 Executors.newSingleThreadExecutor(), capture); 422 assertThat(capture.getLocation(FAILURE_TIMEOUT_MS)).isNull(); 423 } 424 425 try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) { 426 mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(), 427 Executors.newSingleThreadExecutor(), capture); 428 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 429 assertThat(capture.getLocation(FAILURE_TIMEOUT_MS)).isNull(); 430 } 431 } 432 433 @Test testRequestLocationUpdates()434 public void testRequestLocationUpdates() throws Exception { 435 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 436 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 437 438 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 439 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, 440 Executors.newSingleThreadExecutor(), capture); 441 442 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 443 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 444 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 445 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc2); 446 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 447 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.FALSE); 448 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 449 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.TRUE); 450 451 mManager.removeUpdates(capture); 452 453 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 454 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 455 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 456 assertThat(capture.getNextProviderChange(FAILURE_TIMEOUT_MS)).isNull(); 457 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 458 assertThat(capture.getNextProviderChange(FAILURE_TIMEOUT_MS)).isNull(); 459 } 460 461 try { 462 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, null, Looper.getMainLooper()); 463 fail("Should throw IllegalArgumentException if listener is null!"); 464 } catch (IllegalArgumentException e) { 465 // expected 466 } 467 468 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 469 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, null, capture); 470 fail("Should throw IllegalArgumentException if executor is null!"); 471 } catch (IllegalArgumentException e) { 472 // expected 473 } 474 475 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 476 mManager.requestLocationUpdates(null, 0, 0, capture, Looper.getMainLooper()); 477 fail("Should throw IllegalArgumentException if provider is null!"); 478 } catch (IllegalArgumentException e) { 479 // expected 480 } 481 482 try { 483 mManager.removeUpdates((LocationListener) null); 484 fail("Should throw IllegalArgumentException if listener is null!"); 485 } catch (IllegalArgumentException e) { 486 // expected 487 } 488 } 489 490 @Test testRequestLocationUpdates_Passive()491 public void testRequestLocationUpdates_Passive() throws Exception { 492 Location loc = createLocation(TEST_PROVIDER, mRandom); 493 494 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 495 mManager.requestLocationUpdates( 496 TEST_PROVIDER, 497 new LocationRequest.Builder(PASSIVE_INTERVAL) 498 .setMinUpdateIntervalMillis(0) 499 .build(), 500 Runnable::run, 501 capture); 502 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 503 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc); 504 } 505 } 506 507 @Test testRequestLocationUpdates_PendingIntent()508 public void testRequestLocationUpdates_PendingIntent() throws Exception { 509 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 510 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 511 512 try (LocationPendingIntentCapture capture = new LocationPendingIntentCapture(mContext)) { 513 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, capture.getPendingIntent()); 514 515 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 516 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 517 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 518 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc2); 519 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 520 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.FALSE); 521 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 522 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.TRUE); 523 524 mManager.removeUpdates(capture.getPendingIntent()); 525 526 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 527 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 528 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 529 assertThat(capture.getNextProviderChange(FAILURE_TIMEOUT_MS)).isNull(); 530 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 531 assertThat(capture.getNextProviderChange(FAILURE_TIMEOUT_MS)).isNull(); 532 } 533 534 try { 535 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, (PendingIntent) null); 536 fail("Should throw IllegalArgumentException if pending intent is null!"); 537 } catch (IllegalArgumentException e) { 538 // expected 539 } 540 541 PendingIntent immutablePI = PendingIntent.getBroadcast(mContext, 0, 542 new Intent("IMMUTABLE_TEST_ACTION") 543 .setPackage(mContext.getPackageName()) 544 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), 545 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); 546 try { 547 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, immutablePI); 548 fail("Should throw IllegalArgumentException if pending intent is immutable!"); 549 } catch (IllegalArgumentException e) { 550 // expected 551 } finally { 552 immutablePI.cancel(); 553 } 554 555 try (LocationPendingIntentCapture capture = new LocationPendingIntentCapture(mContext)) { 556 mManager.requestLocationUpdates(null, 0, 0, capture.getPendingIntent()); 557 fail("Should throw IllegalArgumentException if provider is null!"); 558 } catch (IllegalArgumentException e) { 559 // expected 560 } 561 562 try { 563 mManager.removeUpdates((PendingIntent) null); 564 fail("Should throw IllegalArgumentException if pending intent is null!"); 565 } catch (IllegalArgumentException e) { 566 // expected 567 } 568 } 569 570 @Test testRequestLocationUpdates_DirectExecutor()571 public void testRequestLocationUpdates_DirectExecutor() throws Exception { 572 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 573 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 574 575 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 576 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, Runnable::run, capture); 577 578 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 579 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 580 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 581 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc2); 582 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 583 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.FALSE); 584 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 585 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.TRUE); 586 } 587 } 588 589 @Test testRequestLocationUpdates_Looper()590 public void testRequestLocationUpdates_Looper() throws Exception { 591 HandlerThread thread = new HandlerThread("locationTestThread"); 592 thread.start(); 593 Looper looper = thread.getLooper(); 594 try { 595 596 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 597 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 598 599 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 600 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, capture, looper); 601 602 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 603 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 604 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 605 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc2); 606 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 607 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.FALSE); 608 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 609 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.TRUE); 610 } 611 612 } finally { 613 looper.quit(); 614 } 615 } 616 617 @Test testRequestLocationUpdates_Criteria()618 public void testRequestLocationUpdates_Criteria() throws Exception { 619 // criteria API will always use the fused provider... 620 mManager.addTestProvider(FUSED_PROVIDER, 621 false, 622 false, 623 false, 624 false, 625 true, 626 true, 627 true, 628 Criteria.POWER_LOW, 629 Criteria.ACCURACY_FINE); 630 mManager.setTestProviderEnabled(FUSED_PROVIDER, true); 631 632 Criteria criteria = new Criteria(); 633 criteria.setAccuracy(Criteria.ACCURACY_FINE); 634 criteria.setPowerRequirement(Criteria.POWER_LOW); 635 636 Location loc1 = createLocation(FUSED_PROVIDER, mRandom); 637 Location loc2 = createLocation(FUSED_PROVIDER, mRandom); 638 639 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 640 mManager.requestLocationUpdates(0, 0, criteria, Executors.newSingleThreadExecutor(), capture); 641 642 mManager.setTestProviderLocation(FUSED_PROVIDER, loc1); 643 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 644 mManager.setTestProviderLocation(FUSED_PROVIDER, loc2); 645 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc2); 646 mManager.setTestProviderEnabled(FUSED_PROVIDER, false); 647 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.FALSE); 648 mManager.setTestProviderEnabled(FUSED_PROVIDER, true); 649 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(Boolean.TRUE); 650 651 mManager.removeUpdates(capture); 652 653 mManager.setTestProviderLocation(FUSED_PROVIDER, loc1); 654 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 655 mManager.setTestProviderEnabled(FUSED_PROVIDER, false); 656 assertThat(capture.getNextProviderChange(FAILURE_TIMEOUT_MS)).isNull(); 657 mManager.setTestProviderEnabled(FUSED_PROVIDER, true); 658 assertThat(capture.getNextProviderChange(FAILURE_TIMEOUT_MS)).isNull(); 659 } 660 661 662 try { 663 mManager.requestLocationUpdates(0, 0, criteria, null, Looper.getMainLooper()); 664 fail("Should throw IllegalArgumentException if listener is null!"); 665 } catch (IllegalArgumentException e) { 666 // expected 667 } 668 669 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 670 mManager.requestLocationUpdates(0, 0, criteria, null, capture); 671 fail("Should throw IllegalArgumentException if executor is null!"); 672 } catch (IllegalArgumentException e) { 673 // expected 674 } 675 676 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 677 mManager.requestLocationUpdates(0, 0, null, Executors.newSingleThreadExecutor(), capture); 678 fail("Should throw IllegalArgumentException if criteria is null!"); 679 } catch (IllegalArgumentException e) { 680 // expected 681 } 682 } 683 684 @Test testRequestLocationUpdates_ReplaceRequest()685 public void testRequestLocationUpdates_ReplaceRequest() throws Exception { 686 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 687 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 688 689 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 690 mManager.requestLocationUpdates(TEST_PROVIDER, 1000, 1000, (runnable) -> {}, capture); 691 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, Executors.newSingleThreadExecutor(), capture); 692 693 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 694 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 695 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 696 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc2); 697 } 698 } 699 700 @Test testRequestLocationUpdates_NumUpdates()701 public void testRequestLocationUpdates_NumUpdates() throws Exception { 702 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 703 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 704 705 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 706 mManager.requestLocationUpdates( 707 TEST_PROVIDER, 708 new LocationRequest.Builder(0).setMaxUpdates(1).build(), 709 Executors.newSingleThreadExecutor(), 710 capture); 711 712 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 713 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 714 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 715 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 716 } 717 } 718 719 @Test testRequestLocationUpdates_MinUpdateInterval()720 public void testRequestLocationUpdates_MinUpdateInterval() throws Exception { 721 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 722 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 723 724 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 725 mManager.requestLocationUpdates( 726 TEST_PROVIDER, 727 new LocationRequest.Builder(5000).build(), 728 Executors.newSingleThreadExecutor(), 729 capture); 730 731 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 732 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 733 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 734 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 735 } 736 } 737 738 @Test testRequestLocationUpdates_MinUpdateDistance()739 public void testRequestLocationUpdates_MinUpdateDistance() throws Exception { 740 Location loc1 = createLocation(TEST_PROVIDER, 0, 0, 10); 741 Location loc2 = createLocation(TEST_PROVIDER, 0, 1, 10); 742 743 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 744 mManager.requestLocationUpdates( 745 TEST_PROVIDER, 746 new LocationRequest.Builder(0).setMinUpdateDistanceMeters(200000).build(), 747 Executors.newSingleThreadExecutor(), 748 capture); 749 750 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 751 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 752 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 753 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 754 } 755 } 756 757 @Test 758 @AppModeFull(reason = "Instant apps can't access ACTION_BATTERY_CHANGED intent") testRequestLocationUpdates_BatterySaver_GpsDisabledScreenOff()759 public void testRequestLocationUpdates_BatterySaver_GpsDisabledScreenOff() throws Exception { 760 // battery saver is unsupported on auto, tv and watch 761 assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)); 762 assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION)); 763 assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)); 764 assumeTrue(BatteryUtils.isBatterySaverSupported()); 765 766 PowerManager powerManager = Objects.requireNonNull( 767 mContext.getSystemService(PowerManager.class)); 768 769 mManager.addTestProvider(GPS_PROVIDER, 770 false, 771 true, 772 false, 773 false, 774 true, 775 true, 776 true, 777 Criteria.POWER_HIGH, 778 Criteria.ACCURACY_FINE); 779 mManager.setTestProviderEnabled(GPS_PROVIDER, true); 780 781 LocationRequest request = new LocationRequest.Builder(0).build(); 782 783 try (LocationListenerCapture capture = new LocationListenerCapture(mContext); 784 ScreenResetter ignored = new ScreenResetter(); 785 DeviceConfigStateHelper batterySaverDeviceConfigStateHelper = 786 new DeviceConfigStateHelper(DeviceConfig.NAMESPACE_BATTERY_SAVER)) { 787 mManager.requestLocationUpdates(GPS_PROVIDER, request, 788 Executors.newSingleThreadExecutor(), capture); 789 mManager.requestLocationUpdates(TEST_PROVIDER, request, 790 Executors.newSingleThreadExecutor(), capture); 791 792 batterySaverDeviceConfigStateHelper.set("location_mode", "1"); 793 BatteryUtils.runDumpsysBatteryUnplug(); 794 BatteryUtils.enableBatterySaver(true); 795 assertThat(powerManager.getLocationPowerSaveMode()).isEqualTo( 796 LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF); 797 798 // check screen off behavior 799 ScreenUtils.setScreenOn(false); 800 assertFalse(powerManager.isInteractive()); 801 Location loc = createLocation(TEST_PROVIDER, mRandom); 802 mManager.setTestProviderLocation(GPS_PROVIDER, loc); 803 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 804 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 805 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc); 806 807 // check screen on behavior 808 ScreenUtils.setScreenOn(true); 809 assertTrue(powerManager.isInteractive()); 810 loc = createLocation(TEST_PROVIDER, mRandom); 811 mManager.setTestProviderLocation(GPS_PROVIDER, loc); 812 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc); 813 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 814 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc); 815 } finally { 816 BatteryUtils.enableBatterySaver(false); 817 BatteryUtils.runDumpsysBatteryReset(); 818 } 819 } 820 821 @Test 822 @AppModeFull(reason = "Instant apps can't access ACTION_BATTERY_CHANGED intent") testRequestLocationUpdates_BatterySaver_AllDisabledScreenOff()823 public void testRequestLocationUpdates_BatterySaver_AllDisabledScreenOff() throws Exception { 824 // battery saver is unsupported on auto, tv and watch 825 assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)); 826 assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION)); 827 assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)); 828 assumeTrue(BatteryUtils.isBatterySaverSupported()); 829 830 PowerManager powerManager = Objects.requireNonNull( 831 mContext.getSystemService(PowerManager.class)); 832 833 LocationRequest request = new LocationRequest.Builder(0).build(); 834 835 try (LocationListenerCapture capture = new LocationListenerCapture(mContext); 836 ScreenResetter ignored = new ScreenResetter(); 837 DeviceConfigStateHelper batterySaverDeviceConfigStateHelper = 838 new DeviceConfigStateHelper(DeviceConfig.NAMESPACE_BATTERY_SAVER)) { 839 mManager.requestLocationUpdates(TEST_PROVIDER, request, 840 Executors.newSingleThreadExecutor(), capture); 841 842 batterySaverDeviceConfigStateHelper.set("location_mode", "2"); 843 BatteryUtils.runDumpsysBatteryUnplug(); 844 BatteryUtils.enableBatterySaver(true); 845 assertThat(powerManager.getLocationPowerSaveMode()).isEqualTo( 846 LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF); 847 848 // check screen off behavior 849 ScreenUtils.setScreenOn(false); 850 assertFalse(powerManager.isInteractive()); 851 mManager.setTestProviderLocation(TEST_PROVIDER, createLocation(TEST_PROVIDER, mRandom)); 852 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 853 854 // check screen on behavior 855 ScreenUtils.setScreenOn(true); 856 assertTrue(powerManager.isInteractive()); 857 Location loc = createLocation(TEST_PROVIDER, mRandom); 858 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 859 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc); 860 } finally { 861 BatteryUtils.enableBatterySaver(false); 862 BatteryUtils.runDumpsysBatteryReset(); 863 } 864 } 865 866 @Test 867 @AppModeFull(reason = "Instant apps can't access ACTION_BATTERY_CHANGED intent") testRequestLocationUpdates_BatterySaver_ThrottleScreenOff()868 public void testRequestLocationUpdates_BatterySaver_ThrottleScreenOff() throws Exception { 869 // battery saver is unsupported on auto, tv and watch 870 assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)); 871 assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION)); 872 assumeFalse(mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)); 873 assumeTrue(BatteryUtils.isBatterySaverSupported()); 874 875 PowerManager powerManager = Objects.requireNonNull( 876 mContext.getSystemService(PowerManager.class)); 877 878 LocationRequest request = new LocationRequest.Builder(0).build(); 879 880 try (LocationListenerCapture capture = new LocationListenerCapture(mContext); 881 ScreenResetter ignored = new ScreenResetter(); 882 DeviceConfigStateHelper batterySaverDeviceConfigStateHelper = 883 new DeviceConfigStateHelper(DeviceConfig.NAMESPACE_BATTERY_SAVER)) { 884 mManager.requestLocationUpdates(TEST_PROVIDER, request, 885 Executors.newSingleThreadExecutor(), capture); 886 887 batterySaverDeviceConfigStateHelper.set("location_mode", "4"); 888 BatteryUtils.runDumpsysBatteryUnplug(); 889 BatteryUtils.enableBatterySaver(true); 890 assertThat(powerManager.getLocationPowerSaveMode()).isEqualTo( 891 LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF); 892 893 // check screen off behavior 894 ScreenUtils.setScreenOn(false); 895 assertFalse(powerManager.isInteractive()); 896 mManager.setTestProviderLocation(TEST_PROVIDER, createLocation(TEST_PROVIDER, mRandom)); 897 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 898 899 // check screen on behavior 900 ScreenUtils.setScreenOn(true); 901 assertTrue(powerManager.isInteractive()); 902 Location loc = createLocation(TEST_PROVIDER, mRandom); 903 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 904 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc); 905 } finally { 906 BatteryUtils.enableBatterySaver(false); 907 BatteryUtils.runDumpsysBatteryReset(); 908 } 909 } 910 911 @Test testRequestLocationUpdates_LocationSettingsIgnored()912 public void testRequestLocationUpdates_LocationSettingsIgnored() throws Exception { 913 try (LocationListenerCapture capture = new LocationListenerCapture(mContext); 914 DeviceConfigStateHelper locationDeviceConfigStateHelper = 915 new DeviceConfigStateHelper(DeviceConfig.NAMESPACE_LOCATION)) { 916 917 locationDeviceConfigStateHelper.set(IGNORE_SETTINGS_ALLOWLIST, 918 mContext.getPackageName()); 919 920 getInstrumentation().getUiAutomation() 921 .adoptShellPermissionIdentity(LOCATION_BYPASS); 922 try { 923 mManager.requestLocationUpdates( 924 TEST_PROVIDER, 925 new LocationRequest.Builder(0) 926 .setLocationSettingsIgnored(true) 927 .build(), 928 Executors.newSingleThreadExecutor(), 929 capture); 930 } finally { 931 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 932 } 933 934 // turn off provider 935 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 936 937 // test that all restrictions are bypassed 938 Location loc = createLocation(TEST_PROVIDER, mRandom); 939 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 940 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isEqualTo(loc); 941 loc = createLocation(TEST_PROVIDER, mRandom); 942 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 943 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isEqualTo(loc); 944 } 945 } 946 947 @Test testRequestLocationUpdates_AdasGnssBypass()948 public void testRequestLocationUpdates_AdasGnssBypass() throws Exception { 949 assumeTrue(mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)); 950 951 try (LocationListenerCapture capture = new LocationListenerCapture(mContext); 952 DeviceConfigStateHelper locationDeviceConfigStateHelper = 953 new DeviceConfigStateHelper(DeviceConfig.NAMESPACE_LOCATION)) { 954 955 locationDeviceConfigStateHelper.set(ADAS_SETTINGS_ALLOWLIST, 956 mContext.getPackageName()); 957 958 mManager.addTestProvider( 959 GPS_PROVIDER, 960 false, 961 true, 962 false, 963 false, 964 true, 965 true, 966 true, 967 Criteria.POWER_HIGH, 968 Criteria.ACCURACY_FINE); 969 970 getInstrumentation().getUiAutomation() 971 .adoptShellPermissionIdentity(LOCATION_BYPASS); 972 try { 973 mManager.requestLocationUpdates( 974 GPS_PROVIDER, 975 new LocationRequest.Builder(0) 976 .setAdasGnssBypass(true) 977 .build(), 978 Executors.newSingleThreadExecutor(), 979 capture); 980 } finally { 981 getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); 982 } 983 984 // turn off provider 985 mManager.setTestProviderEnabled(GPS_PROVIDER, false); 986 987 // test that all restrictions are bypassed 988 Location loc = createLocation(GPS_PROVIDER, mRandom); 989 mManager.setTestProviderLocation(GPS_PROVIDER, loc); 990 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isEqualTo(loc); 991 loc = createLocation(GPS_PROVIDER, mRandom); 992 mManager.setTestProviderLocation(GPS_PROVIDER, loc); 993 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isEqualTo(loc); 994 } 995 } 996 997 @Test testMonitoring()998 public void testMonitoring() throws Exception { 999 AppOpsManager appOps = Objects.requireNonNull( 1000 mContext.getSystemService(AppOpsManager.class)); 1001 1002 try (OpActiveChangedCapture opCapture = new OpActiveChangedCapture(appOps, 1003 OPSTR_MONITOR_LOCATION); 1004 OpActiveChangedCapture opHighPowerCapture = new OpActiveChangedCapture(appOps, 1005 OPSTR_MONITOR_HIGH_POWER_LOCATION); 1006 LocationListenerCapture capture1 = new LocationListenerCapture(mContext); 1007 LocationListenerCapture capture2 = new LocationListenerCapture(mContext); 1008 LocationListenerCapture capture3 = new LocationListenerCapture(mContext)) { 1009 appOps.startWatchingActive(new String[]{OPSTR_MONITOR_LOCATION}, Runnable::run, 1010 opCapture); 1011 appOps.startWatchingActive(new String[]{OPSTR_MONITOR_HIGH_POWER_LOCATION}, 1012 Runnable::run, opHighPowerCapture); 1013 1014 mManager.requestLocationUpdates(TEST_PROVIDER, 1015 new LocationRequest.Builder(Long.MAX_VALUE - 1).build(), 1016 Executors.newSingleThreadExecutor(), capture1); 1017 assertThat(opCapture.getNextActive(TIMEOUT_MS)).isTrue(); 1018 assertThat(opHighPowerCapture.getNextActive(FAILURE_TIMEOUT_MS)).isNull(); 1019 1020 mManager.requestLocationUpdates(TEST_PROVIDER, new LocationRequest.Builder( 1021 0).setQuality( 1022 QUALITY_HIGH_ACCURACY).build(), 1023 Executors.newSingleThreadExecutor(), capture2); 1024 assertThat(opCapture.getNextActive(FAILURE_TIMEOUT_MS)).isNull(); 1025 assertThat(opHighPowerCapture.getNextActive(TIMEOUT_MS)).isTrue(); 1026 1027 mManager.requestLocationUpdates(TEST_PROVIDER, new LocationRequest.Builder( 1028 0).setQuality( 1029 QUALITY_HIGH_ACCURACY).build(), 1030 Executors.newSingleThreadExecutor(), capture3); 1031 assertThat(opCapture.getNextActive(FAILURE_TIMEOUT_MS)).isNull(); 1032 assertThat(opHighPowerCapture.getNextActive(FAILURE_TIMEOUT_MS)).isNull(); 1033 1034 mManager.removeUpdates(capture2); 1035 assertThat(opCapture.getNextActive(FAILURE_TIMEOUT_MS)).isNull(); 1036 assertThat(opHighPowerCapture.getNextActive(FAILURE_TIMEOUT_MS)).isNull(); 1037 1038 mManager.removeUpdates(capture3); 1039 assertThat(opCapture.getNextActive(FAILURE_TIMEOUT_MS)).isNull(); 1040 assertThat(opHighPowerCapture.getNextActive(TIMEOUT_MS)).isFalse(); 1041 1042 mManager.removeUpdates(capture1); 1043 assertThat(opCapture.getNextActive(TIMEOUT_MS)).isFalse(); 1044 assertThat(opHighPowerCapture.getNextActive(FAILURE_TIMEOUT_MS)).isNull(); 1045 } 1046 } 1047 1048 @Test 1049 @AppModeFull(reason = "Instant apps can't hold INTERACT_ACROSS_USERS permission") testAddProviderRequestListener()1050 public void testAddProviderRequestListener() throws Exception { 1051 InstrumentationRegistry.getInstrumentation().getUiAutomation() 1052 .adoptShellPermissionIdentity(Manifest.permission.LOCATION_HARDWARE); 1053 1054 try (ProviderRequestChangedListenerCapture requestlistener = 1055 new ProviderRequestChangedListenerCapture(mContext); 1056 LocationListenerCapture locationListener = new LocationListenerCapture(mContext)) { 1057 mManager.addProviderRequestChangedListener(Executors.newSingleThreadExecutor(), 1058 requestlistener); 1059 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, 1060 Executors.newSingleThreadExecutor(), locationListener); 1061 1062 assertThat(requestlistener.getNextProviderRequest(TIMEOUT_MS)).isNotNull(); 1063 } finally { 1064 InstrumentationRegistry.getInstrumentation().getUiAutomation() 1065 .dropShellPermissionIdentity(); 1066 } 1067 } 1068 1069 @Test 1070 @AppModeFull(reason = "Instant apps can't hold ACCESS_LOCATION_EXTRA_COMMANDS permission") testRequestGpsUpdates_B9758659()1071 public void testRequestGpsUpdates_B9758659() throws Exception { 1072 assumeTrue(mManager.hasProvider(GPS_PROVIDER)); 1073 1074 // test for b/9758659, where the gps provider may reuse network provider positions creating 1075 // an unnatural feedback loop 1076 assertThat(mManager.isProviderEnabled(GPS_PROVIDER)).isTrue(); 1077 1078 Location networkLocation = createLocation(NETWORK_PROVIDER, mRandom); 1079 1080 mManager.addTestProvider(NETWORK_PROVIDER, 1081 false, 1082 false, 1083 false, 1084 false, 1085 true, 1086 true, 1087 true, 1088 Criteria.POWER_LOW, 1089 Criteria.ACCURACY_COARSE); 1090 mManager.setTestProviderEnabled(NETWORK_PROVIDER, true); 1091 mManager.setTestProviderLocation(NETWORK_PROVIDER, networkLocation); 1092 1093 // reset gps provider to give it a cold start scenario 1094 mManager.sendExtraCommand(GPS_PROVIDER, "delete_aiding_data", null); 1095 1096 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 1097 mManager.requestLocationUpdates( 1098 GPS_PROVIDER, 1099 new LocationRequest.Builder(0).build(), 1100 Executors.newSingleThreadExecutor(), 1101 capture); 1102 1103 Location location = capture.getNextLocation(TIMEOUT_MS); 1104 if (location != null) { 1105 assertThat(location.distanceTo(networkLocation)).isGreaterThan(1000.0f); 1106 } 1107 } 1108 } 1109 1110 @Test testRequestFlush()1111 public void testRequestFlush() throws Exception { 1112 try (LocationListenerCapture capture1 = new LocationListenerCapture(mContext); 1113 LocationListenerCapture capture2 = new LocationListenerCapture(mContext)) { 1114 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, 1115 Executors.newSingleThreadExecutor(), capture1); 1116 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, 1117 Executors.newSingleThreadExecutor(), capture2); 1118 1119 mManager.requestFlush(TEST_PROVIDER, capture1, 1); 1120 mManager.requestFlush(TEST_PROVIDER, capture2, 1); 1121 assertThat(capture1.getNextFlush(TIMEOUT_MS)).isEqualTo(1); 1122 assertThat(capture2.getNextFlush(TIMEOUT_MS)).isEqualTo(1); 1123 assertThat(capture1.getNextFlush(FAILURE_TIMEOUT_MS)).isNull(); 1124 assertThat(capture2.getNextFlush(FAILURE_TIMEOUT_MS)).isNull(); 1125 } 1126 1127 try { 1128 mManager.requestFlush(TEST_PROVIDER, (LocationListener) null, 0); 1129 fail("Should throw IllegalArgumentException if listener is null!"); 1130 } catch (IllegalArgumentException e) { 1131 // expected 1132 } 1133 1134 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 1135 mManager.requestFlush(TEST_PROVIDER, capture, 0); 1136 fail("Should throw IllegalArgumentException if listener is not registered!"); 1137 } catch (IllegalArgumentException e) { 1138 // expected 1139 } 1140 1141 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 1142 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, Executors.newSingleThreadExecutor(), capture); 1143 mManager.requestFlush(GPS_PROVIDER, capture, 0); 1144 fail("Should throw IllegalArgumentException if listener is not registered!"); 1145 } catch (IllegalArgumentException e) { 1146 // expected 1147 } 1148 1149 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 1150 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, Executors.newSingleThreadExecutor(), capture); 1151 mManager.requestFlush(null, capture, 0); 1152 fail("Should throw IllegalArgumentException if provider is null!"); 1153 } catch (IllegalArgumentException e) { 1154 // expected 1155 } 1156 } 1157 1158 @Test testRequestFlush_PendingIntent()1159 public void testRequestFlush_PendingIntent() throws Exception { 1160 try (LocationPendingIntentCapture capture = new LocationPendingIntentCapture(mContext)) { 1161 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, capture.getPendingIntent()); 1162 1163 mManager.requestFlush(TEST_PROVIDER, capture.getPendingIntent(), 1); 1164 assertThat(capture.getNextFlush(TIMEOUT_MS)).isEqualTo(1); 1165 } 1166 1167 try { 1168 mManager.requestFlush(TEST_PROVIDER, (PendingIntent) null, 0); 1169 fail("Should throw IllegalArgumentException if pending intent is null!"); 1170 } catch (IllegalArgumentException e) { 1171 // expected 1172 } 1173 1174 try (LocationPendingIntentCapture capture = new LocationPendingIntentCapture(mContext)) { 1175 mManager.requestFlush(TEST_PROVIDER, capture.getPendingIntent(), 0); 1176 fail("Should throw IllegalArgumentException if pending intent is not registered!"); 1177 } catch (IllegalArgumentException e) { 1178 // expected 1179 } 1180 1181 try (LocationPendingIntentCapture capture = new LocationPendingIntentCapture(mContext)) { 1182 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, capture.getPendingIntent()); 1183 mManager.requestFlush(GPS_PROVIDER, capture.getPendingIntent(), 0); 1184 fail("Should throw IllegalArgumentException if pending intent is not registered!"); 1185 } catch (IllegalArgumentException e) { 1186 // expected 1187 } 1188 1189 try (LocationPendingIntentCapture capture = new LocationPendingIntentCapture(mContext)) { 1190 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, capture.getPendingIntent()); 1191 mManager.requestFlush(null, capture.getPendingIntent(), 0); 1192 fail("Should throw IllegalArgumentException if provider is null!"); 1193 } catch (IllegalArgumentException e) { 1194 // expected 1195 } 1196 } 1197 1198 @Test testRequestFlush_Ordering()1199 public void testRequestFlush_Ordering() throws Exception { 1200 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 1201 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, 1202 Executors.newSingleThreadExecutor(), capture); 1203 1204 for (int i = 0; i < 100; i++) { 1205 mManager.requestFlush(TEST_PROVIDER, capture, i); 1206 } 1207 for (int i = 0; i < 100; i++) { 1208 assertThat(capture.getNextFlush(TIMEOUT_MS)).isEqualTo(i); 1209 } 1210 } 1211 } 1212 1213 @Test testRequestFlush_Gnss()1214 public void testRequestFlush_Gnss() throws Exception { 1215 assumeTrue(SystemProperties.getInt("ro.product.first_api_level", 0) 1216 >= Build.VERSION_CODES.S); 1217 assumeTrue(mManager.hasProvider(GPS_PROVIDER)); 1218 1219 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 1220 mManager.requestLocationUpdates(GPS_PROVIDER, 0, 0, 1221 Executors.newSingleThreadExecutor(), capture); 1222 1223 mManager.requestFlush(GPS_PROVIDER, capture, 1); 1224 assertThat(capture.getNextFlush(TIMEOUT_MS)).isEqualTo(1); 1225 } 1226 } 1227 1228 @Test testListenProviderEnable_Listener()1229 public void testListenProviderEnable_Listener() throws Exception { 1230 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 1231 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, 1232 Executors.newSingleThreadExecutor(), capture); 1233 1234 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1235 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(false); 1236 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 1237 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(true); 1238 1239 mManager.removeUpdates(capture); 1240 1241 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1242 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 1243 } 1244 } 1245 1246 @Test testListenProviderEnable_PendingIntent()1247 public void testListenProviderEnable_PendingIntent() throws Exception { 1248 try (LocationPendingIntentCapture capture = new LocationPendingIntentCapture(mContext)) { 1249 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, capture.getPendingIntent()); 1250 1251 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1252 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(false); 1253 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 1254 assertThat(capture.getNextProviderChange(TIMEOUT_MS)).isEqualTo(true); 1255 1256 mManager.removeUpdates(capture.getPendingIntent()); 1257 1258 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1259 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 1260 } 1261 } 1262 1263 @Test 1264 @AppModeFull(reason = "Instant apps can only receive whitelisted broadcasts") testListenProviderEnable_Broadcast()1265 public void testListenProviderEnable_Broadcast() throws Exception { 1266 try (BroadcastCapture capture = new BroadcastCapture(mContext, PROVIDERS_CHANGED_ACTION)) { 1267 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1268 Intent broadcast = capture.getNextIntent(TIMEOUT_MS); 1269 assertThat(broadcast).isNotNull(); 1270 assertThat(broadcast).hasAction(PROVIDERS_CHANGED_ACTION); 1271 assertThat(broadcast).extras().string(EXTRA_PROVIDER_NAME).isEqualTo(TEST_PROVIDER); 1272 assertThat(broadcast).extras().bool(EXTRA_PROVIDER_ENABLED).isFalse(); 1273 1274 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 1275 broadcast = capture.getNextIntent(TIMEOUT_MS); 1276 assertThat(broadcast).isNotNull(); 1277 assertThat(broadcast).hasAction(PROVIDERS_CHANGED_ACTION); 1278 assertThat(broadcast).extras().string(EXTRA_PROVIDER_NAME).isEqualTo(TEST_PROVIDER); 1279 assertThat(broadcast).extras().bool(EXTRA_PROVIDER_ENABLED).isTrue(); 1280 } 1281 } 1282 1283 @Test testGetAllProviders()1284 public void testGetAllProviders() { 1285 List<String> providers = mManager.getAllProviders(); 1286 if (mManager.hasProvider(GPS_PROVIDER)) { 1287 assertThat(providers.contains(LocationManager.GPS_PROVIDER)).isTrue(); 1288 } 1289 assertThat(providers.contains(PASSIVE_PROVIDER)).isTrue(); 1290 assertThat(providers.contains(TEST_PROVIDER)).isTrue(); 1291 assertThat(providers.size()).isEqualTo(new HashSet<>(providers).size()); 1292 1293 mManager.removeTestProvider(TEST_PROVIDER); 1294 1295 providers = mManager.getAllProviders(); 1296 assertThat(providers.contains(PASSIVE_PROVIDER)).isTrue(); 1297 assertThat(providers.contains(TEST_PROVIDER)).isFalse(); 1298 } 1299 1300 @Test testGetProviders()1301 public void testGetProviders() { 1302 List<String> providers = mManager.getProviders(false); 1303 assertThat(providers.contains(TEST_PROVIDER)).isTrue(); 1304 1305 providers = mManager.getProviders(true); 1306 assertThat(providers.contains(TEST_PROVIDER)).isTrue(); 1307 1308 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1309 1310 providers = mManager.getProviders(false); 1311 assertThat(providers.contains(TEST_PROVIDER)).isTrue(); 1312 1313 providers = mManager.getProviders(true); 1314 assertThat(providers.contains(TEST_PROVIDER)).isFalse(); 1315 } 1316 1317 @Test testGetProviders_Criteria()1318 public void testGetProviders_Criteria() { 1319 Criteria criteria = new Criteria(); 1320 1321 List<String> providers = mManager.getProviders(criteria, false); 1322 assertThat(providers.contains(TEST_PROVIDER)).isTrue(); 1323 1324 providers = mManager.getProviders(criteria, true); 1325 assertThat(providers.contains(TEST_PROVIDER)).isTrue(); 1326 1327 criteria.setPowerRequirement(Criteria.POWER_LOW); 1328 1329 providers = mManager.getProviders(criteria, false); 1330 assertThat(providers.contains(TEST_PROVIDER)).isFalse(); 1331 1332 providers = mManager.getProviders(criteria, true); 1333 assertThat(providers.contains(TEST_PROVIDER)).isFalse(); 1334 } 1335 1336 @Test testGetBestProvider()1337 public void testGetBestProvider() { 1338 List<String> allProviders = mManager.getAllProviders(); 1339 Criteria criteria = new Criteria(); 1340 1341 String bestProvider = mManager.getBestProvider(criteria, false); 1342 if (allProviders.contains(FUSED_PROVIDER)) { 1343 assertThat(bestProvider).isEqualTo(FUSED_PROVIDER); 1344 } else if (allProviders.contains(GPS_PROVIDER)) { 1345 assertThat(bestProvider).isEqualTo(GPS_PROVIDER); 1346 } else if (allProviders.contains(NETWORK_PROVIDER)) { 1347 assertThat(bestProvider).isEqualTo(NETWORK_PROVIDER); 1348 } else { 1349 assertThat(bestProvider).isEqualTo(TEST_PROVIDER); 1350 } 1351 1352 // the "perfect" provider - this test case only works if there is no real provider on the 1353 // device with the same "perfect" properties 1354 mManager.addTestProvider(TEST_PROVIDER, 1355 false, 1356 false, 1357 false, 1358 false, 1359 true, 1360 true, 1361 true, 1362 Criteria.POWER_LOW, 1363 Criteria.ACCURACY_FINE); 1364 mManager.addTestProvider(FUSED_PROVIDER, 1365 true, 1366 false, 1367 true, 1368 false, 1369 false, 1370 false, 1371 false, 1372 Criteria.POWER_HIGH, 1373 Criteria.ACCURACY_COARSE); 1374 1375 criteria.setAccuracy(Criteria.ACCURACY_FINE); 1376 criteria.setPowerRequirement(Criteria.POWER_LOW); 1377 assertThat(mManager.getBestProvider(criteria, false)).isEqualTo(TEST_PROVIDER); 1378 1379 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1380 assertThat(mManager.getBestProvider(criteria, true)).isNotEqualTo(TEST_PROVIDER); 1381 } 1382 1383 @Test testGetProvider()1384 public void testGetProvider() { 1385 LocationProvider provider = mManager.getProvider(TEST_PROVIDER); 1386 assertThat(provider).isNotNull(); 1387 assertThat(provider.getName()).isEqualTo(TEST_PROVIDER); 1388 1389 provider = mManager.getProvider(LocationManager.GPS_PROVIDER); 1390 if (mManager.hasProvider(GPS_PROVIDER)) { 1391 assertThat(provider).isNotNull(); 1392 assertThat(provider.getName()).isEqualTo(LocationManager.GPS_PROVIDER); 1393 } else { 1394 assertThat(provider).isNull(); 1395 } 1396 1397 assertThat(mManager.getProvider("fake")).isNull(); 1398 1399 try { 1400 mManager.getProvider(null); 1401 fail("Should throw IllegalArgumentException when provider is null!"); 1402 } catch (IllegalArgumentException e) { 1403 // expected 1404 } 1405 } 1406 1407 @Test testHasProvider()1408 public void testHasProvider() { 1409 for (String provider : mManager.getAllProviders()) { 1410 assertThat(mManager.hasProvider(provider)).isTrue(); 1411 } 1412 1413 assertThat(mManager.hasProvider("fake")).isFalse(); 1414 } 1415 1416 @Test testGetProviderProperties()1417 public void testGetProviderProperties() { 1418 for (String provider : mManager.getAllProviders()) { 1419 mManager.getProviderProperties(provider); 1420 } 1421 1422 try { 1423 mManager.getProviderProperties("fake"); 1424 fail("Should throw IllegalArgumentException for non-existent provider"); 1425 } catch (IllegalArgumentException e) { 1426 // expected 1427 } 1428 } 1429 1430 @Test 1431 @AppModeFull(reason = "Instant apps can't hold ACCESS_LOCATION_EXTRA_COMMANDS permission") testSendExtraCommand()1432 public void testSendExtraCommand() { 1433 for (String provider : mManager.getAllProviders()) { 1434 boolean res = mManager.sendExtraCommand(provider, "dontCrash", null); 1435 assertThat(res).isTrue(); 1436 1437 try { 1438 mManager.sendExtraCommand(provider, null, null); 1439 fail("Should throw IllegalArgumentException if command is null!"); 1440 } catch (IllegalArgumentException e) { 1441 // expected 1442 } 1443 } 1444 1445 try { 1446 mManager.sendExtraCommand(null, "crash", null); 1447 fail("Should throw IllegalArgumentException if provider is null!"); 1448 } catch (IllegalArgumentException e) { 1449 // expected 1450 } 1451 } 1452 1453 @Test testAddTestProvider()1454 public void testAddTestProvider() { 1455 // overwriting providers should not crash 1456 for (String provider : mManager.getAllProviders()) { 1457 if (PASSIVE_PROVIDER.equals(provider)) { 1458 continue; 1459 } 1460 1461 mManager.addTestProvider(provider, true, 1462 false, 1463 true, 1464 false, 1465 false, 1466 false, 1467 false, 1468 Criteria.POWER_MEDIUM, 1469 Criteria.ACCURACY_FINE); 1470 mManager.setTestProviderLocation(provider, createLocation(provider, mRandom)); 1471 } 1472 1473 try { 1474 mManager.addTestProvider("passive", 1475 true, 1476 false, 1477 true, 1478 false, 1479 false, 1480 false, 1481 false, 1482 Criteria.POWER_MEDIUM, 1483 Criteria.ACCURACY_FINE); 1484 fail("Should throw IllegalArgumentException if provider is passive!"); 1485 } catch (IllegalArgumentException e) { 1486 // expected 1487 } 1488 1489 try { 1490 mManager.addTestProvider(null, 1491 true, 1492 false, 1493 true, 1494 false, 1495 false, 1496 false, 1497 false, 1498 Criteria.POWER_MEDIUM, 1499 Criteria.ACCURACY_FINE); 1500 fail("Should throw IllegalArgumentException if provider is null!"); 1501 } catch (IllegalArgumentException e) { 1502 // expected 1503 } 1504 } 1505 1506 @Test testSetTestProviderEnabled()1507 public void testSetTestProviderEnabled() { 1508 for (String provider : mManager.getAllProviders()) { 1509 if (TEST_PROVIDER.equals(provider)) { 1510 mManager.setTestProviderEnabled(provider, false); 1511 assertThat(mManager.isProviderEnabled(provider)).isFalse(); 1512 mManager.setTestProviderEnabled(provider, true); 1513 assertThat(mManager.isProviderEnabled(provider)).isTrue(); 1514 } else { 1515 try { 1516 mManager.setTestProviderEnabled(provider, false); 1517 fail("Should throw IllegalArgumentException since " + provider 1518 + " is not a test provider!"); 1519 } catch (IllegalArgumentException e) { 1520 // expected 1521 } 1522 } 1523 } 1524 1525 mManager.removeTestProvider(TEST_PROVIDER); 1526 try { 1527 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1528 fail("Should throw IllegalArgumentException since " + TEST_PROVIDER 1529 + " is not a test provider!"); 1530 } catch (IllegalArgumentException e) { 1531 // expected 1532 } 1533 1534 try { 1535 mManager.setTestProviderEnabled(null, false); 1536 fail("Should throw IllegalArgumentException since provider is null!"); 1537 } catch (IllegalArgumentException e) { 1538 // expected 1539 } 1540 } 1541 1542 @Test testSetTestProviderLocation()1543 public void testSetTestProviderLocation() throws Exception { 1544 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 1545 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 1546 1547 for (String provider : mManager.getAllProviders()) { 1548 if (TEST_PROVIDER.equals(provider)) { 1549 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 1550 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, 1551 Executors.newSingleThreadExecutor(), capture); 1552 mManager.setTestProviderLocation(provider, loc1); 1553 1554 Location received = capture.getNextLocation(TIMEOUT_MS); 1555 assertThat(received).isEqualTo(loc1); 1556 assertThat(received.isFromMockProvider()).isTrue(); 1557 assertThat(mManager.getLastKnownLocation(provider)).isEqualTo(loc1); 1558 1559 mManager.setTestProviderEnabled(provider, false); 1560 mManager.setTestProviderLocation(provider, loc2); 1561 assertThat(mManager.getLastKnownLocation(provider)).isNull(); 1562 assertThat(capture.getNextLocation(FAILURE_TIMEOUT_MS)).isNull(); 1563 } 1564 } else { 1565 try { 1566 mManager.setTestProviderLocation(provider, loc1); 1567 fail("Should throw IllegalArgumentException since " + provider 1568 + " is not a test provider!"); 1569 } catch (IllegalArgumentException e) { 1570 // expected 1571 } 1572 } 1573 } 1574 1575 try { 1576 mManager.setTestProviderLocation(TEST_PROVIDER, null); 1577 fail("Should throw IllegalArgumentException since location is null!"); 1578 } catch (IllegalArgumentException e) { 1579 // expected 1580 } 1581 1582 mManager.removeTestProvider(TEST_PROVIDER); 1583 try { 1584 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 1585 fail("Should throw IllegalArgumentException since " + TEST_PROVIDER 1586 + " is not a test provider!"); 1587 } catch (IllegalArgumentException e) { 1588 // expected 1589 } 1590 1591 try { 1592 mManager.setTestProviderLocation(null, loc1); 1593 fail("Should throw IllegalArgumentException since provider is null!"); 1594 } catch (IllegalArgumentException e) { 1595 // expected 1596 } 1597 } 1598 1599 @Test 1600 @SuppressWarnings("TryFailThrowable") testSetTestProviderLocation_B33091107()1601 public void testSetTestProviderLocation_B33091107() throws Exception { 1602 // test for b/33091107, where a malicious app could fool a real provider into providing a 1603 // mock location that isn't marked as being mock 1604 1605 List<String> providers = mManager.getAllProviders(); 1606 if (providers.size() <= 2) { 1607 // can't perform the test without any real providers, and no need to do so since there 1608 // are no providers a malicious app could fool 1609 assertThat(providers.contains(TEST_PROVIDER)).isTrue(); 1610 assertThat(providers.contains(PASSIVE_PROVIDER)).isTrue(); 1611 return; 1612 } 1613 1614 providers.remove(TEST_PROVIDER); 1615 providers.remove(PASSIVE_PROVIDER); 1616 1617 String realProvider = providers.get(0); 1618 Location loc = createLocation(realProvider, mRandom); 1619 1620 try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) { 1621 mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(), 1622 Executors.newSingleThreadExecutor(), capture); 1623 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 1624 1625 Location received = capture.getLocation(TIMEOUT_MS); 1626 assertThat(received).isEqualTo(loc); 1627 assertThat(received.isFromMockProvider()).isTrue(); 1628 1629 Location realProvideLocation = mManager.getLastKnownLocation(realProvider); 1630 if (realProvideLocation != null) { 1631 boolean passed = false; 1632 try { 1633 assertThat(realProvideLocation).isEqualTo(loc); 1634 } catch (AssertionError e) { 1635 passed = true; 1636 } 1637 if (!passed) { 1638 fail("real provider saw " + TEST_PROVIDER + " location!"); 1639 } 1640 } 1641 } 1642 } 1643 1644 @Test testRemoveTestProvider()1645 public void testRemoveTestProvider() { 1646 // removing providers should not crash 1647 for (String provider : mManager.getAllProviders()) { 1648 mManager.removeTestProvider(provider); 1649 } 1650 } 1651 1652 @Test testGetGnssCapabilities()1653 public void testGetGnssCapabilities() { 1654 assumeTrue(mManager.hasProvider(GPS_PROVIDER)); 1655 assertThat(mManager.getGnssCapabilities()).isNotNull(); 1656 } 1657 1658 @Test testGetGnssYearOfHardware()1659 public void testGetGnssYearOfHardware() { 1660 assumeTrue(mManager.hasProvider(GPS_PROVIDER)); 1661 mManager.getGnssYearOfHardware(); 1662 } 1663 1664 @Test testGetGnssHardwareModelName()1665 public void testGetGnssHardwareModelName() { 1666 assumeTrue(mManager.hasProvider(GPS_PROVIDER)); 1667 1668 // model name should be longer than 4 characters 1669 String gnssHardwareModelName = mManager.getGnssHardwareModelName(); 1670 1671 // Hardware model name was added in HAL 1.1. HAL 1.0 and earlier do not have this set. 1672 if (gnssHardwareModelName == null) { 1673 Log.w(TAG, "gnssHardwareModelName is null. Skipping test."); 1674 return; 1675 } 1676 assertThat(gnssHardwareModelName.length()).isGreaterThan(3); 1677 } 1678 1679 @Test testGetGnssAntennaInfos()1680 public void testGetGnssAntennaInfos() { 1681 assumeTrue(mManager.hasProvider(GPS_PROVIDER)); 1682 if (mManager.getGnssCapabilities().hasAntennaInfo()) { 1683 assertThat(mManager.getGnssAntennaInfos()).isNotNull(); 1684 } else { 1685 assertThat(mManager.getGnssAntennaInfos()).isNull(); 1686 } 1687 } 1688 1689 @Test testRegisterGnssStatusCallback()1690 public void testRegisterGnssStatusCallback() { 1691 GnssStatus.Callback callback = new GnssStatus.Callback() { 1692 }; 1693 1694 mManager.registerGnssStatusCallback(Executors.newSingleThreadExecutor(), callback); 1695 mManager.unregisterGnssStatusCallback(callback); 1696 } 1697 1698 @Test testAddNmeaListener()1699 public void testAddNmeaListener() { 1700 OnNmeaMessageListener listener = (message, timestamp) -> { 1701 }; 1702 1703 mManager.addNmeaListener(Executors.newSingleThreadExecutor(), listener); 1704 mManager.removeNmeaListener(listener); 1705 } 1706 1707 @Test testRegisterGnssMeasurementsCallback()1708 public void testRegisterGnssMeasurementsCallback() throws Exception { 1709 try (GnssMeasurementsCapture capture = new GnssMeasurementsCapture(mContext)) { 1710 mManager.registerGnssMeasurementsCallback(Runnable::run, capture); 1711 1712 // test deprecated status messages 1713 if (mManager.hasProvider(GPS_PROVIDER)) { 1714 Integer status = capture.getNextStatus(TIMEOUT_MS); 1715 assertThat(status).isNotNull(); 1716 assertThat(status).isEqualTo(GnssMeasurementsEvent.Callback.STATUS_READY); 1717 } 1718 } 1719 } 1720 1721 @Test testRegisterGnssAntennaInfoCallback()1722 public void testRegisterGnssAntennaInfoCallback() { 1723 try (GnssAntennaInfoCapture capture = new GnssAntennaInfoCapture(mContext)) { 1724 mManager.registerAntennaInfoListener(Runnable::run, capture); 1725 } 1726 } 1727 1728 @Test testRegisterGnssNavigationMessageCallback()1729 public void testRegisterGnssNavigationMessageCallback() throws Exception { 1730 try (GnssNavigationMessageCapture capture = new GnssNavigationMessageCapture(mContext)) { 1731 mManager.registerGnssNavigationMessageCallback(Runnable::run, capture); 1732 1733 // test deprecated status messages 1734 if (mManager.hasProvider(GPS_PROVIDER)) { 1735 Integer status = capture.getNextStatus(TIMEOUT_MS); 1736 assertThat(status).isNotNull(); 1737 assertThat(status).isEqualTo(GnssNavigationMessage.Callback.STATUS_READY); 1738 } 1739 } 1740 } 1741 addTestProviderForAttributionTag(String... attributionTags)1742 private void addTestProviderForAttributionTag(String... attributionTags) { 1743 mManager.removeTestProvider(TEST_PROVIDER); 1744 mManager.addTestProvider(TEST_PROVIDER, 1745 new ProviderProperties.Builder().build(), (attributionTags != null) 1746 ? new ArraySet<>(attributionTags) 1747 : Collections.emptySet()); 1748 mManager.setTestProviderEnabled(TEST_PROVIDER, true); 1749 } 1750 1751 @Ignore("b/181693958") 1752 @Test testLocationAttributionTagBlaming()1753 public void testLocationAttributionTagBlaming() { 1754 // No tag set 1755 addTestProviderForAttributionTag(); 1756 long timeBeforeLocationAccess = System.currentTimeMillis(); 1757 accessLocation(VALID_LOCATION_ATTRIBUTION_TAG); 1758 assertNotedOpsSinceLastLocationAccess(timeBeforeLocationAccess, 1759 /*expectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION, 1760 /*unexpectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1761 VALID_LOCATION_ATTRIBUTION_TAG); 1762 1763 // Tag set and using that correct tag 1764 addTestProviderForAttributionTag(VALID_LOCATION_ATTRIBUTION_TAG); 1765 timeBeforeLocationAccess = System.currentTimeMillis(); 1766 accessLocation(VALID_LOCATION_ATTRIBUTION_TAG); 1767 assertNotedOpsSinceLastLocationAccess(timeBeforeLocationAccess, 1768 /*expectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1769 /*unexpectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION, 1770 VALID_LOCATION_ATTRIBUTION_TAG); 1771 1772 // Tag set and using a wrong tag 1773 timeBeforeLocationAccess = System.currentTimeMillis(); 1774 accessLocation(INVALID_LOCATION_ATTRIBUTION_TAG); 1775 assertNotedOpsSinceLastLocationAccess(timeBeforeLocationAccess, 1776 /*expectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION, 1777 /*unexpectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1778 INVALID_LOCATION_ATTRIBUTION_TAG); 1779 1780 // Tag set and using that correct tag 1781 timeBeforeLocationAccess = System.currentTimeMillis(); 1782 accessLocation(VALID_LOCATION_ATTRIBUTION_TAG); 1783 assertNotedOpsSinceLastLocationAccess(timeBeforeLocationAccess, 1784 /*expectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1785 /*unexpectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION, 1786 VALID_LOCATION_ATTRIBUTION_TAG); 1787 1788 // No tag set 1789 addTestProviderForAttributionTag(); 1790 timeBeforeLocationAccess = System.currentTimeMillis(); 1791 accessLocation(VALID_LOCATION_ATTRIBUTION_TAG); 1792 assertNotedOpsSinceLastLocationAccess(timeBeforeLocationAccess, 1793 /*expectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION, 1794 /*unexpectedOp*/ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1795 VALID_LOCATION_ATTRIBUTION_TAG); 1796 } 1797 1798 @Test testGetLastKnownLocationNoteOps()1799 public void testGetLastKnownLocationNoteOps() { 1800 long timeBeforeLocationAccess = System.currentTimeMillis(); 1801 mManager.getLastKnownLocation(TEST_PROVIDER); 1802 assertNotedOpsSinceLastLocationAccess(timeBeforeLocationAccess, 1803 /* expectedOp */ AppOpsManager.OPSTR_FINE_LOCATION, 1804 /* unexpectedOp */ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1805 null); 1806 1807 // Ensure no note ops when provider disabled 1808 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1809 timeBeforeLocationAccess = System.currentTimeMillis(); 1810 mManager.getLastKnownLocation(TEST_PROVIDER); 1811 assertNoOpsNotedSinceLastLocationAccess(timeBeforeLocationAccess, 1812 AppOpsManager.OPSTR_FINE_LOCATION, null); 1813 } 1814 1815 @Test testGetCurrentLocationNoteOps()1816 public void testGetCurrentLocationNoteOps() throws Exception { 1817 long timeBeforeLocationAccess = System.currentTimeMillis(); 1818 Location loc = createLocation(TEST_PROVIDER, mRandom); 1819 1820 try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) { 1821 mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(), 1822 Executors.newSingleThreadExecutor(), capture); 1823 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 1824 assertThat(capture.getLocation(TIMEOUT_MS)).isEqualTo(loc); 1825 assertNotedOpsSinceLastLocationAccess(timeBeforeLocationAccess, 1826 /* expectedOp */ AppOpsManager.OPSTR_FINE_LOCATION, 1827 /* unexpectedOp */ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1828 null); 1829 } 1830 1831 // Ensure no note ops when provider disabled 1832 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1833 timeBeforeLocationAccess = System.currentTimeMillis(); 1834 try (GetCurrentLocationCapture capture2 = new GetCurrentLocationCapture()) { 1835 mManager.getCurrentLocation(TEST_PROVIDER, capture2.getCancellationSignal(), 1836 Executors.newSingleThreadExecutor(), capture2); 1837 mManager.setTestProviderLocation(TEST_PROVIDER, loc); 1838 assertNoOpsNotedSinceLastLocationAccess(timeBeforeLocationAccess, 1839 AppOpsManager.OPSTR_FINE_LOCATION, null); 1840 } 1841 } 1842 1843 @Test testRequestLocationUpdatesNoteOps()1844 public void testRequestLocationUpdatesNoteOps() throws Exception { 1845 long timeBeforeLocationAccess = System.currentTimeMillis(); 1846 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 1847 1848 try (LocationListenerCapture capture = new LocationListenerCapture(mContext)) { 1849 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, 1850 Executors.newSingleThreadExecutor(), capture); 1851 1852 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 1853 assertThat(capture.getNextLocation(TIMEOUT_MS)).isEqualTo(loc1); 1854 assertNotedOpsSinceLastLocationAccess(timeBeforeLocationAccess, 1855 /* expectedOp */ AppOpsManager.OPSTR_FINE_LOCATION, 1856 /* unexpectedOp */ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1857 null); 1858 } 1859 1860 // Ensure no note ops when provider disabled 1861 mManager.setTestProviderEnabled(TEST_PROVIDER, false); 1862 timeBeforeLocationAccess = System.currentTimeMillis(); 1863 try (LocationListenerCapture capture2 = new LocationListenerCapture(mContext)) { 1864 mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, 1865 Executors.newSingleThreadExecutor(), capture2); 1866 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 1867 assertNoOpsNotedSinceLastLocationAccess(timeBeforeLocationAccess, 1868 AppOpsManager.OPSTR_FINE_LOCATION, null); 1869 } 1870 } 1871 1872 @Test testRequestLocationUpdatesNoteOps_simultaneousRequests()1873 public void testRequestLocationUpdatesNoteOps_simultaneousRequests() { 1874 Context attributionContextFast = 1875 mContext.createAttributionContext(VALID_LOCATION_ATTRIBUTION_TAG); 1876 Context attributionContextSlow = 1877 mContext.createAttributionContext(ANOTHER_VALID_LOCATION_ATTRIBUTION_TAG); 1878 Location loc1 = createLocation(TEST_PROVIDER, mRandom); 1879 Location loc2 = createLocation(TEST_PROVIDER, mRandom); 1880 1881 try (LocationListenerCapture fastCapture = 1882 new LocationListenerCapture(attributionContextFast); 1883 LocationListenerCapture slowCapture = 1884 new LocationListenerCapture(attributionContextSlow)) { 1885 attributionContextFast 1886 .getSystemService(LocationManager.class) 1887 .requestLocationUpdates( 1888 TEST_PROVIDER, 1889 new LocationRequest.Builder(0).build(), 1890 Runnable::run, 1891 fastCapture); 1892 attributionContextSlow 1893 .getSystemService(LocationManager.class) 1894 .requestLocationUpdates( 1895 TEST_PROVIDER, 1896 new LocationRequest.Builder(600000).build(), 1897 Runnable::run, 1898 slowCapture); 1899 1900 // Set initial location. 1901 long timeBeforeLocationAccess = System.currentTimeMillis(); 1902 mManager.setTestProviderLocation(TEST_PROVIDER, loc1); 1903 assertNotedOpsSinceLastLocationAccess( 1904 timeBeforeLocationAccess, 1905 /* expectedOp */ AppOpsManager.OPSTR_FINE_LOCATION, 1906 /* unexpectedOp */ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1907 VALID_LOCATION_ATTRIBUTION_TAG); 1908 1909 // Verify noteOp for the fast request. 1910 timeBeforeLocationAccess = System.currentTimeMillis(); 1911 mManager.setTestProviderLocation(TEST_PROVIDER, loc2); 1912 assertNotedOpsSinceLastLocationAccess( 1913 timeBeforeLocationAccess, 1914 /* expectedOp */ AppOpsManager.OPSTR_FINE_LOCATION, 1915 /* unexpectedOp */ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1916 VALID_LOCATION_ATTRIBUTION_TAG); 1917 assertNoOpsNotedSinceLastLocationAccess( 1918 timeBeforeLocationAccess, 1919 AppOpsManager.OPSTR_FINE_LOCATION, 1920 ANOTHER_VALID_LOCATION_ATTRIBUTION_TAG); 1921 1922 // Verify noteOp for the slow request. 1923 timeBeforeLocationAccess = System.currentTimeMillis(); 1924 Location loc3 = createLocation(TEST_PROVIDER, 0, 1, 10, 1925 SystemClock.elapsedRealtimeNanos() + 600000000000L); 1926 mManager.setTestProviderLocation(TEST_PROVIDER, loc3); 1927 assertNotedOpsSinceLastLocationAccess( 1928 timeBeforeLocationAccess, 1929 /* expectedOp */ AppOpsManager.OPSTR_FINE_LOCATION, 1930 /* unexpectedOp */ AppOpsManager.OPSTR_FINE_LOCATION_SOURCE, 1931 ANOTHER_VALID_LOCATION_ATTRIBUTION_TAG); 1932 } 1933 } 1934 accessLocation(String attributionTag)1935 private void accessLocation(String attributionTag) { 1936 Context attributionContext = mContext.createAttributionContext(attributionTag); 1937 attributionContext.getSystemService(LocationManager.class).getLastKnownLocation( 1938 TEST_PROVIDER); 1939 } 1940 assertNotedOpsSinceLastLocationAccess( long timeBeforeLocationAccess, @NonNull String expectedOp, @NonNull String unexpectedOp, String attributionTag)1941 private void assertNotedOpsSinceLastLocationAccess( 1942 long timeBeforeLocationAccess, 1943 @NonNull String expectedOp, 1944 @NonNull String unexpectedOp, 1945 String attributionTag) { 1946 final UiAutomation automation = 1947 InstrumentationRegistry.getInstrumentation().getUiAutomation(); 1948 automation.adoptShellPermissionIdentity(android.Manifest.permission.GET_APP_OPS_STATS); 1949 1950 try { 1951 final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); 1952 final List<AppOpsManager.PackageOps> affectedPackageOps = 1953 appOpsManager.getPackagesForOps(new String[]{expectedOp, unexpectedOp}); 1954 for (AppOpsManager.PackageOps packageOps : affectedPackageOps) { 1955 if (mContext.getPackageName().equals(packageOps.getPackageName())) { 1956 // We are pulling stats only for one app op. 1957 for (AppOpsManager.OpEntry opEntry : packageOps.getOps()) { 1958 if (unexpectedOp.equals(opEntry.getOpStr())) { 1959 fail("Unexpected access to " + unexpectedOp); 1960 } else if (expectedOp.equals(opEntry.getOpStr()) 1961 && opEntry.getAttributedOpEntries().containsKey(attributionTag) 1962 && opEntry 1963 .getAttributedOpEntries() 1964 .get(attributionTag) 1965 .getLastAccessTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED) 1966 >= timeBeforeLocationAccess) { 1967 return; 1968 } 1969 } 1970 } 1971 } 1972 fail("No expected access to " + expectedOp); 1973 } finally { 1974 automation.dropShellPermissionIdentity(); 1975 } 1976 } 1977 assertNoOpsNotedSinceLastLocationAccess( long timeBeforeLocationAccess, @NonNull String unexpectedOp, String attributionTag)1978 private void assertNoOpsNotedSinceLastLocationAccess( 1979 long timeBeforeLocationAccess, @NonNull String unexpectedOp, String attributionTag) { 1980 final UiAutomation automation = 1981 InstrumentationRegistry.getInstrumentation().getUiAutomation(); 1982 automation.adoptShellPermissionIdentity(android.Manifest.permission.GET_APP_OPS_STATS); 1983 try { 1984 final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); 1985 final List<AppOpsManager.PackageOps> affectedPackageOps = 1986 appOpsManager.getPackagesForOps(new String[]{unexpectedOp}); 1987 for (AppOpsManager.PackageOps packageOps : affectedPackageOps) { 1988 if (mContext.getPackageName().equals(packageOps.getPackageName())) { 1989 // We are pulling stats only for one app op. 1990 for (AppOpsManager.OpEntry opEntry : packageOps.getOps()) { 1991 if (unexpectedOp.equals(opEntry.getOpStr()) 1992 && opEntry.getAttributedOpEntries().containsKey(attributionTag) 1993 && opEntry 1994 .getAttributedOpEntries() 1995 .get(attributionTag) 1996 .getLastAccessTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED) 1997 >= timeBeforeLocationAccess) { 1998 fail("Unexpected access to " + unexpectedOp); 1999 } 2000 } 2001 } 2002 } 2003 } finally { 2004 automation.dropShellPermissionIdentity(); 2005 } 2006 } 2007 } 2008