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