1 /* 2 * Copyright (C) 2020 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 com.android.server.location.provider; 18 19 import static android.Manifest.permission.ACCESS_COARSE_LOCATION; 20 import static android.Manifest.permission.ACCESS_FINE_LOCATION; 21 import static android.Manifest.permission.LOCATION_BYPASS; 22 import static android.app.AppOpsManager.OP_FINE_LOCATION; 23 import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION; 24 import static android.app.AppOpsManager.OP_MONITOR_LOCATION; 25 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; 26 import static android.location.LocationManager.GPS_PROVIDER; 27 import static android.location.LocationRequest.PASSIVE_INTERVAL; 28 import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH; 29 import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF; 30 31 import static androidx.test.ext.truth.location.LocationSubject.assertThat; 32 33 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; 34 import static com.android.server.location.LocationPermissions.PERMISSION_COARSE; 35 import static com.android.server.location.LocationPermissions.PERMISSION_FINE; 36 import static com.android.server.location.LocationUtils.createLocation; 37 import static com.android.server.location.LocationUtils.createLocationResult; 38 39 import static com.google.common.truth.Truth.assertThat; 40 41 import static org.mockito.ArgumentMatchers.any; 42 import static org.mockito.ArgumentMatchers.anyBoolean; 43 import static org.mockito.ArgumentMatchers.anyDouble; 44 import static org.mockito.ArgumentMatchers.anyInt; 45 import static org.mockito.ArgumentMatchers.anyLong; 46 import static org.mockito.ArgumentMatchers.anyString; 47 import static org.mockito.ArgumentMatchers.eq; 48 import static org.mockito.ArgumentMatchers.isNull; 49 import static org.mockito.ArgumentMatchers.nullable; 50 import static org.mockito.Mockito.after; 51 import static org.mockito.Mockito.doReturn; 52 import static org.mockito.Mockito.inOrder; 53 import static org.mockito.Mockito.mock; 54 import static org.mockito.Mockito.never; 55 import static org.mockito.Mockito.spy; 56 import static org.mockito.Mockito.timeout; 57 import static org.mockito.Mockito.times; 58 import static org.mockito.Mockito.verify; 59 import static org.mockito.Mockito.verifyNoMoreInteractions; 60 import static org.mockito.MockitoAnnotations.initMocks; 61 import static org.testng.Assert.assertThrows; 62 63 import android.content.Context; 64 import android.content.pm.PackageManager; 65 import android.content.res.Resources; 66 import android.location.ILocationCallback; 67 import android.location.ILocationListener; 68 import android.location.LastLocationRequest; 69 import android.location.Location; 70 import android.location.LocationManagerInternal; 71 import android.location.LocationManagerInternal.ProviderEnabledListener; 72 import android.location.LocationRequest; 73 import android.location.LocationResult; 74 import android.location.flags.Flags; 75 import android.location.provider.IProviderRequestListener; 76 import android.location.provider.IS2LevelCallback; 77 import android.location.provider.ProviderProperties; 78 import android.location.provider.ProviderRequest; 79 import android.location.util.identity.CallerIdentity; 80 import android.os.Bundle; 81 import android.os.ICancellationSignal; 82 import android.os.IRemoteCallback; 83 import android.os.PackageTagsList; 84 import android.os.PowerManager; 85 import android.os.Process; 86 import android.os.RemoteException; 87 import android.os.SystemClock; 88 import android.os.WorkSource; 89 import android.platform.test.annotations.Presubmit; 90 import android.platform.test.flag.junit.SetFlagsRule; 91 import android.provider.DeviceConfig; 92 import android.provider.Settings; 93 import android.util.Log; 94 95 import androidx.test.core.app.ApplicationProvider; 96 import androidx.test.filters.MediumTest; 97 import androidx.test.filters.SmallTest; 98 import androidx.test.runner.AndroidJUnit4; 99 100 import com.android.internal.R; 101 import com.android.server.FgThread; 102 import com.android.server.LocalServices; 103 import com.android.server.location.fudger.LocationFudgerCache; 104 import com.android.server.location.injector.FakeUserInfoHelper; 105 import com.android.server.location.injector.TestInjector; 106 import com.android.server.location.provider.proxy.ProxyPopulationDensityProvider; 107 108 import org.junit.After; 109 import org.junit.Before; 110 import org.junit.Rule; 111 import org.junit.Test; 112 import org.junit.runner.RunWith; 113 import org.mockito.ArgumentCaptor; 114 import org.mockito.InOrder; 115 import org.mockito.Mock; 116 117 import java.io.FileDescriptor; 118 import java.io.PrintWriter; 119 import java.util.ArrayList; 120 import java.util.Collection; 121 import java.util.Collections; 122 import java.util.List; 123 import java.util.Random; 124 import java.util.concurrent.CountDownLatch; 125 import java.util.concurrent.TimeUnit; 126 127 @Presubmit 128 @SmallTest 129 @RunWith(AndroidJUnit4.class) 130 public class LocationProviderManagerTest { 131 132 private static final String TAG = "LocationProviderManagerTest"; 133 134 private static final long TIMEOUT_MS = 1000; 135 136 private static final int CURRENT_USER = FakeUserInfoHelper.DEFAULT_USERID; 137 private static final int OTHER_USER = CURRENT_USER + 10; 138 139 private static final String NAME = "test"; 140 private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder() 141 .setHasAltitudeSupport(true) 142 .setHasSpeedSupport(true) 143 .setHasBearingSupport(true) 144 .setPowerUsage(POWER_USAGE_HIGH) 145 .setAccuracy(ProviderProperties.ACCURACY_FINE) 146 .build(); 147 private static final CallerIdentity PROVIDER_IDENTITY = CallerIdentity.forTest(CURRENT_USER, 1, 148 "mypackage", "attribution"); 149 private static final CallerIdentity IDENTITY = CallerIdentity.forTest(CURRENT_USER, 1, 150 "mypackage", "attribution", "listener"); 151 private static final WorkSource WORK_SOURCE = new WorkSource(IDENTITY.getUid()); 152 private static final String MISSING_PERMISSION = "missing_permission"; 153 154 @Rule 155 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 156 157 private Random mRandom; 158 159 @Mock 160 private LocationProviderManager.StateChangedListener mStateChangedListener; 161 @Mock 162 private LocationManagerInternal mInternal; 163 @Mock 164 private Context mContext; 165 @Mock 166 private Resources mResources; 167 @Mock 168 private PackageManager mPackageManager; 169 @Mock 170 private PowerManager mPowerManager; 171 @Mock 172 private PowerManager.WakeLock mWakeLock; 173 174 private TestInjector mInjector; 175 private PassiveLocationProviderManager mPassive; 176 private TestProvider mProvider; 177 178 private LocationProviderManager mManager; 179 180 @Before setUp()181 public void setUp() { 182 initMocks(this); 183 184 long seed = System.currentTimeMillis(); 185 Log.i(TAG, "location random seed: " + seed); 186 187 mRandom = new Random(seed); 188 189 LocalServices.addService(LocationManagerInternal.class, mInternal); 190 191 doReturn("android").when(mContext).getPackageName(); 192 doReturn(mResources).when(mContext).getResources(); 193 doReturn(mPackageManager).when(mContext).getPackageManager(); 194 doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class); 195 doReturn(ApplicationProvider.getApplicationContext()).when( 196 mContext).getApplicationContext(); 197 doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString()); 198 doReturn(PackageManager.PERMISSION_DENIED) 199 .when(mContext) 200 .checkCallingOrSelfPermission(MISSING_PERMISSION); 201 202 mInjector = new TestInjector(mContext); 203 mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true); 204 mInjector.getUserInfoHelper().startUser(OTHER_USER); 205 mInjector.getUserInfoHelper().setUserVisible(OTHER_USER, true); 206 207 mPassive = new PassiveLocationProviderManager(mContext, mInjector); 208 mPassive.startManager(null); 209 mPassive.setRealProvider(new PassiveLocationProvider(mContext)); 210 211 createManager(NAME); 212 } 213 createManager(String name)214 private void createManager(String name) { 215 createManager(name, Collections.emptyList()); 216 } 217 createManager(String name, Collection<String> requiredPermissions)218 private void createManager(String name, Collection<String> requiredPermissions) { 219 mStateChangedListener = mock(LocationProviderManager.StateChangedListener.class); 220 221 mProvider = new TestProvider(PROPERTIES, PROVIDER_IDENTITY); 222 mProvider.setProviderAllowed(true); 223 224 mManager = 225 new LocationProviderManager( 226 mContext, mInjector, name, mPassive, requiredPermissions); 227 mManager.startManager(mStateChangedListener); 228 mManager.setRealProvider(mProvider); 229 } 230 231 @After tearDown()232 public void tearDown() throws Exception { 233 DeviceConfig.resetToDefaults(Settings.RESET_MODE_PACKAGE_DEFAULTS, 234 DeviceConfig.NAMESPACE_LOCATION); 235 LocalServices.removeServiceForTest(LocationManagerInternal.class); 236 237 // some test failures may leave the fg thread stuck, interrupt until we get out of it 238 CountDownLatch latch = new CountDownLatch(1); 239 FgThread.getExecutor().execute(latch::countDown); 240 int count = 0; 241 while (++count < 10 && !latch.await(10, TimeUnit.MILLISECONDS)) { 242 FgThread.get().getLooper().getThread().interrupt(); 243 } 244 } 245 246 @Test testProperties()247 public void testProperties() { 248 assertThat(mManager.getName()).isEqualTo(NAME); 249 assertThat(mManager.getProperties()).isEqualTo(PROPERTIES); 250 assertThat(mManager.getProviderIdentity()).isEqualTo(IDENTITY); 251 assertThat(mManager.hasProvider()).isTrue(); 252 253 ProviderProperties newProperties = new ProviderProperties.Builder() 254 .setHasNetworkRequirement(true) 255 .setHasSatelliteRequirement(true) 256 .setHasCellRequirement(true) 257 .setHasMonetaryCost(true) 258 .setPowerUsage(POWER_USAGE_HIGH) 259 .setAccuracy(ProviderProperties.ACCURACY_COARSE) 260 .build(); 261 mProvider.setProperties(newProperties); 262 assertThat(mManager.getProperties()).isEqualTo(newProperties); 263 264 CallerIdentity newIdentity = CallerIdentity.forTest(OTHER_USER, 1, "otherpackage", 265 "otherattribution"); 266 mProvider.setIdentity(newIdentity); 267 assertThat(mManager.getProviderIdentity()).isEqualTo(newIdentity); 268 269 mManager.setRealProvider(null); 270 assertThat(mManager.hasProvider()).isFalse(); 271 } 272 273 @Test testStateChangedListener()274 public void testStateChangedListener() { 275 mProvider.setExtraAttributionTags(Collections.singleton("extra")); 276 277 ArgumentCaptor<AbstractLocationProvider.State> captorOld = ArgumentCaptor.forClass( 278 AbstractLocationProvider.State.class); 279 ArgumentCaptor<AbstractLocationProvider.State> captorNew = ArgumentCaptor.forClass( 280 AbstractLocationProvider.State.class); 281 verify(mStateChangedListener, timeout(TIMEOUT_MS).times(2)).onStateChanged(eq(NAME), 282 captorOld.capture(), captorNew.capture()); 283 284 assertThat(captorOld.getAllValues().get(1).extraAttributionTags).isEmpty(); 285 assertThat(captorNew.getAllValues().get(1).extraAttributionTags).containsExactly("extra"); 286 } 287 288 @Test testRemoveProvider()289 public void testRemoveProvider() { 290 mManager.setRealProvider(null); 291 assertThat(mManager.hasProvider()).isFalse(); 292 } 293 294 @Test testIsEnabled()295 public void testIsEnabled() { 296 assertThat(mManager.isEnabled(CURRENT_USER)).isTrue(); 297 assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); 298 299 mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER); 300 assertThat(mManager.isEnabled(CURRENT_USER)).isFalse(); 301 assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); 302 303 mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER); 304 mProvider.setAllowed(false); 305 assertThat(mManager.isEnabled(CURRENT_USER)).isFalse(); 306 assertThat(mManager.isEnabled(OTHER_USER)).isFalse(); 307 308 mProvider.setAllowed(true); 309 assertThat(mManager.isEnabled(CURRENT_USER)).isTrue(); 310 assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); 311 } 312 313 @Test testIsEnabledListener()314 public void testIsEnabledListener() { 315 ProviderEnabledListener listener = mock(ProviderEnabledListener.class); 316 mManager.addEnabledListener(listener); 317 verify(listener, never()).onProviderEnabledChanged(anyString(), anyInt(), anyBoolean()); 318 319 mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER); 320 verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, CURRENT_USER, 321 false); 322 323 mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER); 324 verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, CURRENT_USER, 325 true); 326 327 mProvider.setAllowed(false); 328 verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER, 329 false); 330 verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER, 331 false); 332 333 mProvider.setAllowed(true); 334 verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER, 335 true); 336 verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER, 337 true); 338 339 mManager.removeEnabledListener(listener); 340 mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER); 341 verifyNoMoreInteractions(listener); 342 } 343 344 @Test testGetLastLocation_Fine()345 public void testGetLastLocation_Fine() { 346 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 347 PERMISSION_FINE)).isNull(); 348 349 Location loc = createLocation(NAME, mRandom); 350 mProvider.setProviderLocation(loc); 351 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 352 PERMISSION_FINE)).isEqualTo(loc); 353 } 354 355 @Test testGetLastLocation_Coarse()356 public void testGetLastLocation_Coarse() { 357 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 358 PERMISSION_FINE)).isNull(); 359 360 Location loc = createLocation(NAME, mRandom); 361 mProvider.setProviderLocation(loc); 362 Location coarse = mManager.getLastLocation(new LastLocationRequest.Builder().build(), 363 IDENTITY, PERMISSION_COARSE); 364 assertThat(coarse).isNotEqualTo(loc); 365 assertThat(coarse).isNearby(loc, 5000); 366 } 367 368 @Test testGetLastLocation_InvisibleUser()369 public void testGetLastLocation_InvisibleUser() { 370 Location loc = createLocation(NAME, mRandom); 371 mProvider.setProviderLocation(loc); 372 373 mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false); 374 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 375 PERMISSION_FINE)).isNull(); 376 377 mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true); 378 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 379 PERMISSION_FINE)).isEqualTo(loc); 380 } 381 382 @Test testGetLastLocation_Bypass()383 public void testGetLastLocation_Bypass() { 384 mInjector.getSettingsHelper().setIgnoreSettingsAllowlist( 385 new PackageTagsList.Builder().add( 386 IDENTITY.getPackageName()).build()); 387 388 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 389 PERMISSION_FINE)).isNull(); 390 assertThat(mManager.getLastLocation( 391 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(), 392 IDENTITY, PERMISSION_FINE)).isNull(); 393 394 Location loc = createLocation(NAME, mRandom); 395 mProvider.setProviderLocation(loc); 396 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 397 PERMISSION_FINE)).isEqualTo(loc); 398 assertThat(mManager.getLastLocation( 399 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(), 400 IDENTITY, PERMISSION_FINE)).isEqualTo( 401 loc); 402 403 mProvider.setProviderAllowed(false); 404 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 405 PERMISSION_FINE)).isNull(); 406 assertThat(mManager.getLastLocation( 407 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(), 408 IDENTITY, PERMISSION_FINE)).isEqualTo( 409 loc); 410 411 loc = createLocation(NAME, mRandom); 412 mProvider.setProviderLocation(loc); 413 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 414 PERMISSION_FINE)).isNull(); 415 assertThat(mManager.getLastLocation( 416 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(), 417 IDENTITY, PERMISSION_FINE)).isEqualTo( 418 loc); 419 420 mProvider.setProviderAllowed(true); 421 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 422 PERMISSION_FINE)).isNull(); 423 assertThat(mManager.getLastLocation( 424 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(), 425 IDENTITY, PERMISSION_FINE)).isEqualTo( 426 loc); 427 428 loc = createLocation(NAME, mRandom); 429 mProvider.setProviderLocation(loc); 430 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 431 PERMISSION_FINE)).isEqualTo(loc); 432 assertThat(mManager.getLastLocation( 433 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(), 434 IDENTITY, PERMISSION_FINE)).isEqualTo( 435 loc); 436 437 mInjector.getSettingsHelper().setIgnoreSettingsAllowlist( 438 new PackageTagsList.Builder().build()); 439 mProvider.setProviderAllowed(false); 440 441 assertThat(mManager.getLastLocation( 442 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(), 443 IDENTITY, PERMISSION_FINE)).isNull(); 444 } 445 446 @Test testGetLastLocation_ClearOnMockRemoval()447 public void testGetLastLocation_ClearOnMockRemoval() { 448 MockLocationProvider mockProvider = new MockLocationProvider(PROPERTIES, PROVIDER_IDENTITY, 449 Collections.emptySet()); 450 mockProvider.setAllowed(true); 451 mManager.setMockProvider(mockProvider); 452 453 Location loc = createLocation(NAME, mRandom); 454 mockProvider.setProviderLocation(loc); 455 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 456 PERMISSION_FINE)).isEqualTo(loc); 457 458 mManager.setMockProvider(null); 459 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 460 PERMISSION_FINE)).isNull(); 461 } 462 463 @Test testInjectLastLocation()464 public void testInjectLastLocation() { 465 Location loc1 = createLocation(NAME, mRandom); 466 mManager.injectLastLocation(loc1, CURRENT_USER); 467 468 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 469 PERMISSION_FINE)).isEqualTo(loc1); 470 471 Location loc2 = createLocation(NAME, mRandom); 472 mManager.injectLastLocation(loc2, CURRENT_USER); 473 474 assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 475 PERMISSION_FINE)).isEqualTo(loc1); 476 } 477 478 @Test testPassive_Listener()479 public void testPassive_Listener() throws Exception { 480 ILocationListener listener = createMockLocationListener(); 481 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 482 mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 483 484 LocationResult loc = createLocationResult(NAME, mRandom); 485 mProvider.setProviderLocation(loc); 486 verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class)); 487 } 488 489 @Test testPassive_LastLocation()490 public void testPassive_LastLocation() { 491 Location loc = createLocation(NAME, mRandom); 492 mProvider.setProviderLocation(loc); 493 494 assertThat(mPassive.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 495 PERMISSION_FINE)).isEqualTo(loc); 496 } 497 498 @Test testRegisterListener()499 public void testRegisterListener() throws Exception { 500 ILocationListener listener = createMockLocationListener(); 501 mManager.registerLocationRequest( 502 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(), 503 IDENTITY, 504 PERMISSION_FINE, 505 listener); 506 507 LocationResult loc = createLocationResult(NAME, mRandom); 508 mProvider.setProviderLocation(loc); 509 verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class)); 510 511 mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER); 512 verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, false); 513 loc = createLocationResult(NAME, mRandom); 514 mProvider.setProviderLocation(loc); 515 verify(listener, times(1)).onLocationChanged(any(List.class), 516 nullable(IRemoteCallback.class)); 517 518 mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER); 519 verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, true); 520 521 mProvider.setAllowed(false); 522 verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, false); 523 loc = createLocationResult(NAME, mRandom); 524 mProvider.setProviderLocation(loc); 525 verify(listener, times(1)).onLocationChanged(any(List.class), 526 nullable(IRemoteCallback.class)); 527 528 mProvider.setAllowed(true); 529 verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, true); 530 531 loc = createLocationResult(NAME, mRandom); 532 mProvider.setProviderLocation(loc); 533 verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class)); 534 } 535 536 @Test testRegisterListener_SameProcess()537 public void testRegisterListener_SameProcess() throws Exception { 538 CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage", 539 "attribution", "listener"); 540 541 ILocationListener listener = createMockLocationListener(); 542 mManager.registerLocationRequest( 543 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(), 544 identity, 545 PERMISSION_FINE, 546 listener); 547 548 LocationResult loc = createLocationResult(NAME, mRandom); 549 mProvider.setProviderLocation(loc); 550 verify(listener, timeout(TIMEOUT_MS).times(1)).onLocationChanged(eq(loc.asList()), 551 nullable(IRemoteCallback.class)); 552 } 553 554 @Test testRegisterListener_Unregister()555 public void testRegisterListener_Unregister() throws Exception { 556 ILocationListener listener = createMockLocationListener(); 557 mManager.registerLocationRequest( 558 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(), 559 IDENTITY, 560 PERMISSION_FINE, 561 listener); 562 mManager.unregisterLocationRequest(listener); 563 564 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 565 verify(listener, never()).onLocationChanged(any(List.class), 566 nullable(IRemoteCallback.class)); 567 568 mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER); 569 verify(listener, after(TIMEOUT_MS).never()).onProviderEnabledChanged(NAME, false); 570 } 571 572 @Test testRegisterListener_Unregister_SameProcess()573 public void testRegisterListener_Unregister_SameProcess() throws Exception { 574 CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage", 575 "attribution", "listener"); 576 577 ILocationListener listener = createMockLocationListener(); 578 mManager.registerLocationRequest( 579 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(), 580 identity, 581 PERMISSION_FINE, 582 listener); 583 584 CountDownLatch blocker = new CountDownLatch(1); 585 FgThread.getExecutor().execute(() -> { 586 try { 587 blocker.await(); 588 } catch (InterruptedException e) { 589 // do nothing 590 } 591 }); 592 593 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 594 mManager.unregisterLocationRequest(listener); 595 blocker.countDown(); 596 verify(listener, after(TIMEOUT_MS).never()).onLocationChanged(any(List.class), 597 nullable(IRemoteCallback.class)); 598 } 599 600 @Test testRegisterListener_NumUpdates()601 public void testRegisterListener_NumUpdates() throws Exception { 602 ILocationListener listener = createMockLocationListener(); 603 LocationRequest request = new LocationRequest.Builder(0) 604 .setMaxUpdates(5) 605 .setWorkSource(WORK_SOURCE) 606 .build(); 607 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 608 609 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 610 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 611 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 612 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 613 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 614 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 615 616 verify(listener, times(5)).onLocationChanged(any(List.class), 617 nullable(IRemoteCallback.class)); 618 } 619 620 @Test testRegisterListener_InvisibleUser()621 public void testRegisterListener_InvisibleUser() throws Exception { 622 ILocationListener listener = createMockLocationListener(); 623 LocationRequest request = new LocationRequest.Builder(0) 624 .setWorkSource(WORK_SOURCE) 625 .build(); 626 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 627 628 mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false); 629 mProvider.setProviderLocation(createLocationResult(NAME, mRandom)); 630 verify(listener, never()).onLocationChanged(any(List.class), 631 nullable(IRemoteCallback.class)); 632 633 mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true); 634 LocationResult loc = createLocationResult(NAME, mRandom); 635 mProvider.setProviderLocation(loc); 636 verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class)); 637 } 638 639 @Test testRegisterListener_ExpiringAlarm()640 public void testRegisterListener_ExpiringAlarm() throws Exception { 641 ILocationListener listener = createMockLocationListener(); 642 LocationRequest request = new LocationRequest.Builder(0) 643 .setDurationMillis(5000) 644 .setWorkSource(WORK_SOURCE) 645 .build(); 646 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 647 648 mInjector.getAlarmHelper().incrementAlarmTime(5000); 649 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 650 verify(listener, never()).onLocationChanged(any(List.class), 651 nullable(IRemoteCallback.class)); 652 } 653 654 @Test testRegisterListener_ExpiringNoAlarm()655 public void testRegisterListener_ExpiringNoAlarm() throws Exception { 656 ILocationListener listener = createMockLocationListener(); 657 LocationRequest request = new LocationRequest.Builder(0) 658 .setDurationMillis(25) 659 .setWorkSource(WORK_SOURCE) 660 .build(); 661 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 662 663 Thread.sleep(25); 664 665 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 666 verify(listener, never()).onLocationChanged(any(List.class), 667 nullable(IRemoteCallback.class)); 668 } 669 670 @Test testRegisterListener_FastestInterval()671 public void testRegisterListener_FastestInterval() throws Exception { 672 ILocationListener listener = createMockLocationListener(); 673 LocationRequest request = new LocationRequest.Builder(5000) 674 .setMinUpdateIntervalMillis(5000) 675 .setWorkSource(WORK_SOURCE) 676 .build(); 677 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 678 679 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 680 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 681 682 verify(listener, times(1)).onLocationChanged( 683 any(List.class), nullable(IRemoteCallback.class)); 684 } 685 686 @Test testRegisterListener_SmallestDisplacement()687 public void testRegisterListener_SmallestDisplacement() throws Exception { 688 ILocationListener listener = createMockLocationListener(); 689 LocationRequest request = new LocationRequest.Builder(5000) 690 .setMinUpdateDistanceMeters(1f) 691 .setWorkSource(WORK_SOURCE) 692 .build(); 693 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 694 695 Location loc = createLocation(NAME, mRandom); 696 mProvider.setProviderLocation(loc); 697 mProvider.setProviderLocation(loc); 698 699 verify(listener, times(1)).onLocationChanged( 700 any(List.class), nullable(IRemoteCallback.class)); 701 } 702 703 @Test testRegisterListener_NoteOpFailure()704 public void testRegisterListener_NoteOpFailure() throws Exception { 705 ILocationListener listener = createMockLocationListener(); 706 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 707 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 708 709 mInjector.getAppOpsHelper().setAppOpAllowed(OP_FINE_LOCATION, IDENTITY.getPackageName(), 710 false); 711 712 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 713 714 verify(listener, never()).onLocationChanged(any(List.class), 715 nullable(IRemoteCallback.class)); 716 } 717 718 @Test testRegisterListener_Wakelock()719 public void testRegisterListener_Wakelock() throws Exception { 720 CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage", 721 "attribution", "listener"); 722 723 ILocationListener listener = createMockLocationListener(); 724 mManager.registerLocationRequest( 725 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(), 726 identity, 727 PERMISSION_FINE, 728 listener); 729 730 CountDownLatch blocker = new CountDownLatch(1); 731 FgThread.getExecutor().execute(() -> { 732 try { 733 blocker.await(); 734 } catch (InterruptedException e) { 735 // do nothing 736 } 737 }); 738 739 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 740 verify(mWakeLock).acquire(anyLong()); 741 verify(mWakeLock, never()).release(); 742 743 blocker.countDown(); 744 verify(listener, timeout(TIMEOUT_MS)).onLocationChanged(any(List.class), 745 nullable(IRemoteCallback.class)); 746 verify(mWakeLock).acquire(anyLong()); 747 verify(mWakeLock, timeout(TIMEOUT_MS)).release(); 748 } 749 750 @Test testRegisterListener_Coarse()751 public void testRegisterListener_Coarse() throws Exception { 752 ILocationListener listener = createMockLocationListener(); 753 mManager.registerLocationRequest( 754 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(), 755 IDENTITY, 756 PERMISSION_COARSE, 757 listener); 758 759 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 760 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 761 verify(listener, times(1)) 762 .onLocationChanged(any(List.class), nullable(IRemoteCallback.class)); 763 } 764 765 @Test testRegisterListener_Coarse_Passive()766 public void testRegisterListener_Coarse_Passive() throws Exception { 767 ILocationListener listener = createMockLocationListener(); 768 mManager.registerLocationRequest( 769 new LocationRequest.Builder(PASSIVE_INTERVAL) 770 .setMinUpdateIntervalMillis(0) 771 .setWorkSource(WORK_SOURCE).build(), 772 IDENTITY, 773 PERMISSION_COARSE, 774 listener); 775 776 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 777 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 778 verify(listener, times(1)) 779 .onLocationChanged(any(List.class), nullable(IRemoteCallback.class)); 780 } 781 782 @Test testProviderRequestListener()783 public void testProviderRequestListener() throws Exception { 784 IProviderRequestListener requestListener = mock(IProviderRequestListener.class); 785 mManager.addProviderRequestListener(requestListener); 786 787 ILocationListener locationListener = createMockLocationListener(); 788 LocationRequest request = new LocationRequest.Builder(1).setWorkSource( 789 WORK_SOURCE).build(); 790 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, locationListener); 791 792 verify(requestListener, timeout(TIMEOUT_MS).times(1)).onProviderRequestChanged(anyString(), 793 any(ProviderRequest.class)); 794 795 mManager.unregisterLocationRequest(locationListener); 796 mManager.removeProviderRequestListener(requestListener); 797 } 798 799 @Test testGetCurrentLocation()800 public void testGetCurrentLocation() throws Exception { 801 ILocationCallback listener = createMockGetCurrentLocationListener(); 802 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 803 mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener); 804 805 Location loc = createLocation(NAME, mRandom); 806 mProvider.setProviderLocation(loc); 807 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 808 verify(listener, times(1)).onLocation(loc); 809 } 810 811 @Test testGetCurrentLocation_Cancel()812 public void testGetCurrentLocation_Cancel() throws Exception { 813 ILocationCallback listener = createMockGetCurrentLocationListener(); 814 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 815 ICancellationSignal cancellationSignal = mManager.getCurrentLocation(request, 816 IDENTITY, PERMISSION_FINE, listener); 817 818 cancellationSignal.cancel(); 819 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 820 verify(listener, never()).onLocation(nullable(Location.class)); 821 } 822 823 @Test testGetCurrentLocation_ProviderDisabled()824 public void testGetCurrentLocation_ProviderDisabled() throws Exception { 825 ILocationCallback listener = createMockGetCurrentLocationListener(); 826 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 827 mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener); 828 829 mProvider.setProviderAllowed(false); 830 mProvider.setProviderAllowed(true); 831 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 832 verify(listener, times(1)).onLocation(isNull()); 833 } 834 835 @Test testGetCurrentLocation_ProviderAlreadyDisabled()836 public void testGetCurrentLocation_ProviderAlreadyDisabled() throws Exception { 837 mProvider.setProviderAllowed(false); 838 839 ILocationCallback listener = createMockGetCurrentLocationListener(); 840 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 841 mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener); 842 843 mProvider.setProviderAllowed(true); 844 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 845 verify(listener, times(1)).onLocation(isNull()); 846 } 847 848 @Test testGetCurrentLocation_LastLocation()849 public void testGetCurrentLocation_LastLocation() throws Exception { 850 Location loc = createLocation(NAME, mRandom); 851 mProvider.setProviderLocation(loc); 852 853 ILocationCallback listener = createMockGetCurrentLocationListener(); 854 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 855 mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener); 856 verify(listener, times(1)).onLocation(eq(loc)); 857 } 858 859 @Test testGetCurrentLocation_Timeout()860 public void testGetCurrentLocation_Timeout() throws Exception { 861 ILocationCallback listener = createMockGetCurrentLocationListener(); 862 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 863 mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener); 864 865 mInjector.getAlarmHelper().incrementAlarmTime(60000); 866 verify(listener, times(1)).onLocation(isNull()); 867 } 868 869 @Test testGetCurrentLocation_InvisibleUser()870 public void testGetCurrentLocation_InvisibleUser() throws Exception { 871 mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false); 872 873 ILocationCallback listener = createMockGetCurrentLocationListener(); 874 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 875 mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener); 876 877 verify(listener).onLocation(isNull()); 878 } 879 880 @Test testFlush()881 public void testFlush() throws Exception { 882 ILocationListener listener = createMockLocationListener(); 883 mManager.registerLocationRequest( 884 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(), 885 IDENTITY, 886 PERMISSION_FINE, 887 listener); 888 889 mManager.flush(listener, 99); 890 891 LocationResult loc = createLocationResult(NAME, mRandom); 892 mProvider.setProviderLocation(loc); 893 mProvider.completeFlushes(); 894 895 InOrder inOrder = inOrder(listener); 896 inOrder.verify(listener).onLocationChanged(eq(loc.asList()), any(IRemoteCallback.class)); 897 inOrder.verify(listener).onFlushComplete(99); 898 } 899 900 @Test testFlush_UnknownKey()901 public void testFlush_UnknownKey() { 902 assertThrows(IllegalArgumentException.class, 903 () -> mManager.flush(createMockLocationListener(), 0)); 904 } 905 906 @Test testLocationMonitoring()907 public void testLocationMonitoring() { 908 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION, 909 IDENTITY.getPackageName())).isFalse(); 910 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION, 911 IDENTITY.getPackageName())).isFalse(); 912 913 ILocationListener listener = createMockLocationListener(); 914 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 915 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 916 917 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION, 918 IDENTITY.getPackageName())).isTrue(); 919 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION, 920 IDENTITY.getPackageName())).isTrue(); 921 922 mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false); 923 924 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION, 925 IDENTITY.getPackageName())).isTrue(); 926 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION, 927 IDENTITY.getPackageName())).isFalse(); 928 929 mManager.unregisterLocationRequest(listener); 930 931 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION, 932 IDENTITY.getPackageName())).isFalse(); 933 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION, 934 IDENTITY.getPackageName())).isFalse(); 935 } 936 937 @Test testLocationMonitoring_multipleIdentities()938 public void testLocationMonitoring_multipleIdentities() { 939 CallerIdentity identity1 = CallerIdentity.forTest(CURRENT_USER, 1, 940 "mypackage", "attribution", "listener1"); 941 CallerIdentity identity2 = CallerIdentity.forTest(CURRENT_USER, 1, 942 "mypackage", "attribution", "listener2"); 943 944 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION, 945 IDENTITY.getPackageName())).isFalse(); 946 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION, 947 IDENTITY.getPackageName())).isFalse(); 948 949 ILocationListener listener1 = createMockLocationListener(); 950 LocationRequest request1 = new LocationRequest.Builder(0).setWorkSource( 951 WORK_SOURCE).build(); 952 mManager.registerLocationRequest(request1, identity1, PERMISSION_FINE, listener1); 953 954 ILocationListener listener2 = createMockLocationListener(); 955 LocationRequest request2 = new LocationRequest.Builder(0).setWorkSource( 956 WORK_SOURCE).build(); 957 mManager.registerLocationRequest(request2, identity2, PERMISSION_FINE, listener2); 958 959 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION, 960 "mypackage")).isTrue(); 961 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION, 962 "mypackage")).isTrue(); 963 964 mManager.unregisterLocationRequest(listener2); 965 966 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION, 967 "mypackage")).isTrue(); 968 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION, 969 "mypackage")).isTrue(); 970 971 mManager.unregisterLocationRequest(listener1); 972 973 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION, 974 "mypackage")).isFalse(); 975 assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION, 976 "mypackage")).isFalse(); 977 } 978 979 @Test testProviderRequest()980 public void testProviderRequest() { 981 assertThat(mProvider.getRequest().isActive()).isFalse(); 982 983 ILocationListener listener1 = createMockLocationListener(); 984 LocationRequest request1 = new LocationRequest.Builder(5).setWorkSource( 985 WORK_SOURCE).build(); 986 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 987 988 assertThat(mProvider.getRequest().isActive()).isTrue(); 989 assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse(); 990 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); 991 assertThat(mProvider.getRequest().isLowPower()).isFalse(); 992 assertThat(mProvider.getRequest().getWorkSource()).isNotNull(); 993 994 ILocationListener listener2 = createMockLocationListener(); 995 LocationRequest request2 = new LocationRequest.Builder(1) 996 .setLowPower(true) 997 .setWorkSource(WORK_SOURCE) 998 .build(); 999 mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); 1000 1001 assertThat(mProvider.getRequest().isActive()).isTrue(); 1002 assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse(); 1003 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1); 1004 assertThat(mProvider.getRequest().isLowPower()).isFalse(); 1005 assertThat(mProvider.getRequest().getWorkSource()).isNotNull(); 1006 1007 mManager.unregisterLocationRequest(listener1); 1008 1009 assertThat(mProvider.getRequest().isActive()).isTrue(); 1010 assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse(); 1011 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1); 1012 assertThat(mProvider.getRequest().isLowPower()).isTrue(); 1013 assertThat(mProvider.getRequest().getWorkSource()).isNotNull(); 1014 1015 mManager.unregisterLocationRequest(listener2); 1016 1017 assertThat(mProvider.getRequest().isActive()).isFalse(); 1018 } 1019 1020 @Test testProviderRequest_DelayedRequest()1021 public void testProviderRequest_DelayedRequest() throws Exception { 1022 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 1023 1024 ILocationListener listener1 = createMockLocationListener(); 1025 LocationRequest request1 = new LocationRequest.Builder(60000) 1026 .setWorkSource(WORK_SOURCE) 1027 .build(); 1028 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1029 1030 verify(listener1).onLocationChanged(any(List.class), 1031 nullable(IRemoteCallback.class)); 1032 1033 assertThat(mProvider.getRequest().isActive()).isFalse(); 1034 1035 mInjector.getAlarmHelper().incrementAlarmTime(60000); 1036 assertThat(mProvider.getRequest().isActive()).isTrue(); 1037 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(60000); 1038 } 1039 1040 @Test testProviderRequest_DelayedRequest_Remove()1041 public void testProviderRequest_DelayedRequest_Remove() { 1042 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 1043 1044 ILocationListener listener1 = createMockLocationListener(); 1045 LocationRequest request1 = new LocationRequest.Builder(60000) 1046 .setWorkSource(WORK_SOURCE) 1047 .build(); 1048 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1049 mManager.unregisterLocationRequest(listener1); 1050 1051 mInjector.getAlarmHelper().incrementAlarmTime(60000); 1052 assertThat(mProvider.getRequest().isActive()).isFalse(); 1053 } 1054 1055 @Test testProviderRequest_SpamRequesting()1056 public void testProviderRequest_SpamRequesting() { 1057 mProvider.setProviderLocation(createLocation(NAME, mRandom)); 1058 1059 ILocationListener listener1 = createMockLocationListener(); 1060 LocationRequest request1 = new LocationRequest.Builder(60000) 1061 .setWorkSource(WORK_SOURCE) 1062 .build(); 1063 1064 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1065 assertThat(mProvider.getRequest().isActive()).isFalse(); 1066 mManager.unregisterLocationRequest(listener1); 1067 assertThat(mProvider.getRequest().isActive()).isFalse(); 1068 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1069 assertThat(mProvider.getRequest().isActive()).isFalse(); 1070 mManager.unregisterLocationRequest(listener1); 1071 assertThat(mProvider.getRequest().isActive()).isFalse(); 1072 } 1073 1074 @Test testProviderRequest_BackgroundThrottle()1075 public void testProviderRequest_BackgroundThrottle() { 1076 ILocationListener listener1 = createMockLocationListener(); 1077 LocationRequest request1 = new LocationRequest.Builder(5) 1078 .setWorkSource(WORK_SOURCE) 1079 .build(); 1080 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1081 1082 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); 1083 1084 mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false); 1085 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo( 1086 mInjector.getSettingsHelper().getBackgroundThrottleIntervalMs()); 1087 } 1088 1089 @Test testProviderRequest_InvisibleUser()1090 public void testProviderRequest_InvisibleUser() { 1091 ILocationListener listener = createMockLocationListener(); 1092 LocationRequest request = new LocationRequest.Builder(5) 1093 .setWorkSource(WORK_SOURCE) 1094 .build(); 1095 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1096 1097 mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false); 1098 assertThat(mProvider.getRequest().isActive()).isFalse(); 1099 1100 mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true); 1101 assertThat(mProvider.getRequest().isActive()).isTrue(); 1102 } 1103 1104 @Test testProviderRequest_IgnoreLocationSettings()1105 public void testProviderRequest_IgnoreLocationSettings() { 1106 mInjector.getSettingsHelper().setIgnoreSettingsAllowlist( 1107 new PackageTagsList.Builder().add( 1108 IDENTITY.getPackageName()).build()); 1109 1110 ILocationListener listener1 = createMockLocationListener(); 1111 LocationRequest request1 = new LocationRequest.Builder(5) 1112 .setWorkSource(WORK_SOURCE) 1113 .build(); 1114 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1115 1116 assertThat(mProvider.getRequest().isActive()).isTrue(); 1117 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); 1118 assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse(); 1119 1120 ILocationListener listener2 = createMockLocationListener(); 1121 LocationRequest request2 = new LocationRequest.Builder(1) 1122 .setLocationSettingsIgnored(true) 1123 .setWorkSource(WORK_SOURCE) 1124 .build(); 1125 mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); 1126 1127 assertThat(mProvider.getRequest().isActive()).isTrue(); 1128 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1); 1129 assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue(); 1130 } 1131 1132 @Test testProviderRequest_IgnoreLocationSettings_ProviderDisabled()1133 public void testProviderRequest_IgnoreLocationSettings_ProviderDisabled() { 1134 mInjector.getSettingsHelper().setIgnoreSettingsAllowlist( 1135 new PackageTagsList.Builder().add( 1136 IDENTITY.getPackageName()).build()); 1137 1138 ILocationListener listener1 = createMockLocationListener(); 1139 LocationRequest request1 = new LocationRequest.Builder(1) 1140 .setWorkSource(WORK_SOURCE) 1141 .build(); 1142 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1143 1144 ILocationListener listener2 = createMockLocationListener(); 1145 LocationRequest request2 = new LocationRequest.Builder(5) 1146 .setLocationSettingsIgnored(true) 1147 .setWorkSource(WORK_SOURCE) 1148 .build(); 1149 mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); 1150 1151 mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId()); 1152 1153 assertThat(mProvider.getRequest().isActive()).isTrue(); 1154 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); 1155 assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue(); 1156 } 1157 1158 @Test testProviderRequest_IgnoreLocationSettings_NoAllowlist()1159 public void testProviderRequest_IgnoreLocationSettings_NoAllowlist() { 1160 mInjector.getSettingsHelper().setIgnoreSettingsAllowlist( 1161 new PackageTagsList.Builder().add( 1162 IDENTITY.getPackageName()).build()); 1163 1164 ILocationListener listener = createMockLocationListener(); 1165 LocationRequest request = new LocationRequest.Builder(1) 1166 .setLocationSettingsIgnored(true) 1167 .setWorkSource(WORK_SOURCE) 1168 .build(); 1169 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1170 1171 mInjector.getSettingsHelper().setIgnoreSettingsAllowlist( 1172 new PackageTagsList.Builder().build()); 1173 1174 assertThat(mProvider.getRequest().isActive()).isTrue(); 1175 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1); 1176 assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse(); 1177 } 1178 1179 @Test testProviderRequest_IgnoreLocationSettings_LocationBypass()1180 public void testProviderRequest_IgnoreLocationSettings_LocationBypass() { 1181 mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LOCATION_BYPASS); 1182 1183 doReturn(PackageManager.PERMISSION_GRANTED) 1184 .when(mContext) 1185 .checkPermission(LOCATION_BYPASS, IDENTITY.getPid(), IDENTITY.getUid()); 1186 mInjector.getLocationPermissionsHelper() 1187 .revokePermission(IDENTITY.getPackageName(), ACCESS_FINE_LOCATION); 1188 mInjector.getLocationPermissionsHelper() 1189 .revokePermission(IDENTITY.getPackageName(), ACCESS_COARSE_LOCATION); 1190 mInjector 1191 .getSettingsHelper() 1192 .setIgnoreSettingsAllowlist( 1193 new PackageTagsList.Builder().add(IDENTITY.getPackageName()).build()); 1194 1195 ILocationListener listener = createMockLocationListener(); 1196 LocationRequest request = 1197 new LocationRequest.Builder(1) 1198 .setLocationSettingsIgnored(true) 1199 .setWorkSource(WORK_SOURCE) 1200 .build(); 1201 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1202 1203 assertThat(mProvider.getRequest().isActive()).isFalse(); 1204 } 1205 1206 @Test testProviderRequest_IgnoreLocationSettings_LocationBypass_EmergencyCall()1207 public void testProviderRequest_IgnoreLocationSettings_LocationBypass_EmergencyCall() { 1208 mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LOCATION_BYPASS); 1209 1210 doReturn(PackageManager.PERMISSION_GRANTED) 1211 .when(mContext) 1212 .checkPermission(LOCATION_BYPASS, IDENTITY.getPid(), IDENTITY.getUid()); 1213 mInjector.getLocationPermissionsHelper() 1214 .revokePermission(IDENTITY.getPackageName(), ACCESS_FINE_LOCATION); 1215 mInjector.getLocationPermissionsHelper() 1216 .revokePermission(IDENTITY.getPackageName(), ACCESS_COARSE_LOCATION); 1217 mInjector.getEmergencyHelper().setInEmergency(true); 1218 mInjector 1219 .getSettingsHelper() 1220 .setIgnoreSettingsAllowlist( 1221 new PackageTagsList.Builder().add(IDENTITY.getPackageName()).build()); 1222 1223 ILocationListener listener = createMockLocationListener(); 1224 LocationRequest request = 1225 new LocationRequest.Builder(1) 1226 .setLocationSettingsIgnored(true) 1227 .setWorkSource(WORK_SOURCE) 1228 .build(); 1229 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1230 1231 assertThat(mProvider.getRequest().isActive()).isTrue(); 1232 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1); 1233 assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue(); 1234 } 1235 1236 @Test testProviderRequest_BackgroundThrottle_IgnoreLocationSettings()1237 public void testProviderRequest_BackgroundThrottle_IgnoreLocationSettings() { 1238 mInjector.getSettingsHelper().setIgnoreSettingsAllowlist( 1239 new PackageTagsList.Builder().add( 1240 IDENTITY.getPackageName()).build()); 1241 1242 ILocationListener listener1 = createMockLocationListener(); 1243 LocationRequest request1 = new LocationRequest.Builder(5) 1244 .setLocationSettingsIgnored(true) 1245 .setWorkSource(WORK_SOURCE) 1246 .build(); 1247 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1248 1249 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); 1250 1251 mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false); 1252 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); 1253 } 1254 1255 @Test testProviderRequest_AdasGnssBypass()1256 public void testProviderRequest_AdasGnssBypass() { 1257 doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE); 1258 doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); 1259 1260 mInjector.getSettingsHelper().setAdasSettingsAllowlist( 1261 new PackageTagsList.Builder().add( 1262 IDENTITY.getPackageName()).build()); 1263 1264 createManager(GPS_PROVIDER); 1265 1266 ILocationListener listener1 = createMockLocationListener(); 1267 LocationRequest request1 = new LocationRequest.Builder(5) 1268 .setWorkSource(WORK_SOURCE) 1269 .build(); 1270 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1271 1272 assertThat(mProvider.getRequest().isActive()).isTrue(); 1273 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); 1274 assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse(); 1275 1276 ILocationListener listener2 = createMockLocationListener(); 1277 LocationRequest request2 = new LocationRequest.Builder(1) 1278 .setAdasGnssBypass(true) 1279 .setWorkSource(WORK_SOURCE) 1280 .build(); 1281 mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); 1282 1283 assertThat(mProvider.getRequest().isActive()).isTrue(); 1284 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1); 1285 assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue(); 1286 } 1287 1288 @Test testProviderRequest_AdasGnssBypass_ProviderDisabled()1289 public void testProviderRequest_AdasGnssBypass_ProviderDisabled() { 1290 doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE); 1291 doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); 1292 1293 mInjector.getSettingsHelper().setAdasSettingsAllowlist( 1294 new PackageTagsList.Builder().add( 1295 IDENTITY.getPackageName()).build()); 1296 1297 createManager(GPS_PROVIDER); 1298 1299 ILocationListener listener1 = createMockLocationListener(); 1300 LocationRequest request1 = new LocationRequest.Builder(1) 1301 .setWorkSource(WORK_SOURCE) 1302 .build(); 1303 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1304 1305 ILocationListener listener2 = createMockLocationListener(); 1306 LocationRequest request2 = new LocationRequest.Builder(5) 1307 .setAdasGnssBypass(true) 1308 .setWorkSource(WORK_SOURCE) 1309 .build(); 1310 mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); 1311 1312 mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId()); 1313 1314 assertThat(mProvider.getRequest().isActive()).isTrue(); 1315 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); 1316 assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue(); 1317 } 1318 1319 @Test testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled()1320 public void testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled() { 1321 doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE); 1322 doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); 1323 1324 mInjector.getSettingsHelper().setIgnoreSettingsAllowlist( 1325 new PackageTagsList.Builder().add( 1326 IDENTITY.getPackageName()).build()); 1327 1328 mInjector.getSettingsHelper().setAdasSettingsAllowlist( 1329 new PackageTagsList.Builder().add( 1330 IDENTITY.getPackageName()).build()); 1331 1332 createManager(GPS_PROVIDER); 1333 1334 ILocationListener listener1 = createMockLocationListener(); 1335 LocationRequest request1 = new LocationRequest.Builder(5) 1336 .setLocationSettingsIgnored(true) 1337 .setWorkSource(WORK_SOURCE) 1338 .build(); 1339 mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); 1340 1341 ILocationListener listener2 = createMockLocationListener(); 1342 LocationRequest request2 = new LocationRequest.Builder(1) 1343 .setAdasGnssBypass(true) 1344 .setWorkSource(WORK_SOURCE) 1345 .build(); 1346 mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); 1347 1348 mInjector.getLocationSettings().updateUserSettings(IDENTITY.getUserId(), 1349 settings -> settings.withAdasGnssLocationEnabled(false)); 1350 mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId()); 1351 1352 assertThat(mProvider.getRequest().isActive()).isTrue(); 1353 assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); 1354 assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse(); 1355 } 1356 1357 @Test testProviderRequest_BatterySaver_ScreenOnOff()1358 public void testProviderRequest_BatterySaver_ScreenOnOff() { 1359 mInjector.getLocationPowerSaveModeHelper().setLocationPowerSaveMode( 1360 LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF); 1361 1362 ILocationListener listener = createMockLocationListener(); 1363 LocationRequest request = new LocationRequest.Builder(5).setWorkSource(WORK_SOURCE).build(); 1364 mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1365 1366 assertThat(mProvider.getRequest().isActive()).isTrue(); 1367 1368 mInjector.getScreenInteractiveHelper().setScreenInteractive(false); 1369 assertThat(mProvider.getRequest().isActive()).isFalse(); 1370 } 1371 1372 @Test testQueryPackageReset()1373 public void testQueryPackageReset() { 1374 assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isFalse(); 1375 1376 ILocationListener listener1 = createMockLocationListener(); 1377 mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource( 1378 WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener1); 1379 assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue(); 1380 1381 ILocationListener listener2 = createMockLocationListener(); 1382 mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource( 1383 WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener2); 1384 assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue(); 1385 1386 mManager.unregisterLocationRequest(listener1); 1387 assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue(); 1388 1389 mManager.unregisterLocationRequest(listener2); 1390 assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isFalse(); 1391 } 1392 1393 @Test testPackageReset()1394 public void testPackageReset() { 1395 ILocationListener listener1 = createMockLocationListener(); 1396 mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource( 1397 WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener1); 1398 ILocationListener listener2 = createMockLocationListener(); 1399 mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource( 1400 WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener2); 1401 1402 assertThat(mProvider.getRequest().isActive()).isTrue(); 1403 assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue(); 1404 1405 mInjector.getPackageResetHelper().reset("mypackage"); 1406 assertThat(mProvider.getRequest().isActive()).isFalse(); 1407 assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isFalse(); 1408 } 1409 1410 @Test testIsVisibleToCaller()1411 public void testIsVisibleToCaller() { 1412 assertThat(mManager.isVisibleToCaller()).isTrue(); 1413 } 1414 1415 @Test testIsVisibleToCaller_noPermissions()1416 public void testIsVisibleToCaller_noPermissions() { 1417 createManager("any_name", Collections.singletonList(MISSING_PERMISSION)); 1418 assertThat(mManager.isVisibleToCaller()).isFalse(); 1419 } 1420 1421 @Test testValidateLocation_futureLocation()1422 public void testValidateLocation_futureLocation() { 1423 mSetFlagsRule.enableFlags(Flags.FLAG_LOCATION_VALIDATION); 1424 Location location = createLocation(NAME, mRandom); 1425 mProvider.setProviderLocation(location); 1426 1427 assertThat(mPassive.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 1428 PERMISSION_FINE)).isEqualTo(location); 1429 1430 Location futureLocation = createLocation(NAME, mRandom); 1431 futureLocation.setElapsedRealtimeNanos( 1432 SystemClock.elapsedRealtimeNanos() + TimeUnit.SECONDS.toNanos(2)); 1433 mProvider.setProviderLocation(futureLocation); 1434 1435 assertThat(mPassive.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY, 1436 PERMISSION_FINE)).isEqualTo(location); 1437 } 1438 1439 @Test testLocationFudger_withFlagDisabled_cacheIsNotSetAndOldAlgoIsUsed()1440 public void testLocationFudger_withFlagDisabled_cacheIsNotSetAndOldAlgoIsUsed() { 1441 mSetFlagsRule.disableFlags(Flags.FLAG_DENSITY_BASED_COARSE_LOCATIONS); 1442 createManager("some-name"); 1443 ProxyPopulationDensityProvider provider = mock(ProxyPopulationDensityProvider.class); 1444 LocationFudgerCache cache = new LocationFudgerCache(provider); 1445 1446 mManager.setLocationFudgerCache(cache); 1447 1448 Location test = new Location("any-provider"); 1449 mManager.getPermittedLocation(test, PERMISSION_COARSE); 1450 1451 verify(provider, never()).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any()); 1452 } 1453 1454 @Test testLocationFudger_withFlagEnabledButNoDefaults_oldAlgoIsUsed()1455 public void testLocationFudger_withFlagEnabledButNoDefaults_oldAlgoIsUsed() 1456 throws RemoteException { 1457 mSetFlagsRule.enableFlags(Flags.FLAG_DENSITY_BASED_COARSE_LOCATIONS); 1458 createManager("some-other-name"); 1459 ProxyPopulationDensityProvider provider = mock(ProxyPopulationDensityProvider.class); 1460 LocationFudgerCache cache = new LocationFudgerCache(provider); 1461 1462 mManager.setLocationFudgerCache(cache); 1463 1464 ArgumentCaptor<IS2LevelCallback> captor = ArgumentCaptor.forClass(IS2LevelCallback.class); 1465 verify(provider).getDefaultCoarseningLevel(captor.capture()); 1466 1467 IS2LevelCallback cb = captor.getValue(); 1468 1469 // Act: the provider didn't provide a default 1470 cb.onError(); 1471 1472 Location test = new Location("any-provider"); 1473 mManager.getPermittedLocation(test, PERMISSION_COARSE); 1474 1475 verify(provider, never()).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any()); 1476 } 1477 1478 @Test testLocationFudger_withFlagEnabled_cacheIsSetAndNewAlgoIsUsed()1479 public void testLocationFudger_withFlagEnabled_cacheIsSetAndNewAlgoIsUsed() 1480 throws RemoteException { 1481 mSetFlagsRule.enableFlags(Flags.FLAG_DENSITY_BASED_COARSE_LOCATIONS); 1482 createManager("some-other-name"); 1483 ProxyPopulationDensityProvider provider = mock(ProxyPopulationDensityProvider.class); 1484 LocationFudgerCache cache = new LocationFudgerCache(provider); 1485 int defaultLevel = 2; 1486 1487 mManager.setLocationFudgerCache(cache); 1488 1489 ArgumentCaptor<IS2LevelCallback> captor = ArgumentCaptor.forClass(IS2LevelCallback.class); 1490 verify(provider).getDefaultCoarseningLevel(captor.capture()); 1491 1492 IS2LevelCallback cb = captor.getValue(); 1493 cb.onResult(defaultLevel); 1494 1495 Location test = new Location("any-provider"); 1496 test.setLatitude(10.0); 1497 test.setLongitude(20.0); 1498 mManager.getPermittedLocation(test, PERMISSION_COARSE); 1499 1500 // We can't test that 10.0, 20.0 was passed due to the offset. We only test that a call 1501 // happened. 1502 verify(provider).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any()); 1503 } 1504 1505 @MediumTest 1506 @Test testEnableMsl_expectedBehavior()1507 public void testEnableMsl_expectedBehavior() throws Exception { 1508 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION, 1509 "enable_location_provider_manager_msl", Boolean.toString(true), false); 1510 1511 // Create a random location and set provider location to cache necessary MSL assets. 1512 Location loc = createLocation(NAME, mRandom); 1513 loc.setAltitude(mRandom.nextDouble()); 1514 loc.setVerticalAccuracyMeters(mRandom.nextFloat()); 1515 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1516 Thread.sleep(1000); 1517 1518 // Register listener and reset provider location to capture. 1519 ILocationListener listener = createMockLocationListener(); 1520 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 1521 mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1522 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1523 ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class); 1524 verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class)); 1525 1526 // Assert that MSL fields are populated. 1527 Location actual = captor.getValue().get(0); 1528 assertThat(actual.hasMslAltitude()).isTrue(); 1529 assertThat(actual.hasMslAltitudeAccuracy()).isTrue(); 1530 } 1531 1532 @MediumTest 1533 @Test testEnableMsl_noVerticalAccuracy()1534 public void testEnableMsl_noVerticalAccuracy() throws Exception { 1535 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION, 1536 "enable_location_provider_manager_msl", Boolean.toString(true), false); 1537 1538 // Create a random location and set provider location to cache necessary MSL assets. 1539 Location loc = createLocation(NAME, mRandom); 1540 loc.setAltitude(mRandom.nextDouble()); 1541 loc.setVerticalAccuracyMeters(mRandom.nextFloat()); 1542 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1543 Thread.sleep(1000); 1544 1545 // Register listener and reset provider location with no vertical accuracy to capture. 1546 ILocationListener listener = createMockLocationListener(); 1547 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 1548 mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1549 loc.removeVerticalAccuracy(); 1550 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1551 ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class); 1552 verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class)); 1553 1554 // Assert that only the MSL accuracy field is populated. 1555 Location actual = captor.getValue().get(0); 1556 assertThat(actual.hasMslAltitude()).isTrue(); 1557 assertThat(actual.hasMslAltitudeAccuracy()).isFalse(); 1558 } 1559 1560 @MediumTest 1561 @Test testEnableMsl_noAltitude()1562 public void testEnableMsl_noAltitude() throws Exception { 1563 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION, 1564 "enable_location_provider_manager_msl", Boolean.toString(true), false); 1565 1566 // Create a random location and set provider location to cache necessary MSL assets. 1567 Location loc = createLocation(NAME, mRandom); 1568 loc.setAltitude(mRandom.nextDouble()); 1569 loc.setVerticalAccuracyMeters(mRandom.nextFloat()); 1570 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1571 Thread.sleep(1000); 1572 1573 // Register listener and reset provider location with no altitude to capture. 1574 ILocationListener listener = createMockLocationListener(); 1575 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 1576 mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1577 loc.removeAltitude(); 1578 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1579 ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class); 1580 verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class)); 1581 1582 // Assert that no MSL fields are populated. 1583 Location actual = captor.getValue().get(0); 1584 assertThat(actual.hasMslAltitude()).isFalse(); 1585 assertThat(actual.hasMslAltitudeAccuracy()).isFalse(); 1586 } 1587 1588 @MediumTest 1589 @Test testEnableMsl_invalidAltitude()1590 public void testEnableMsl_invalidAltitude() throws Exception { 1591 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION, 1592 "enable_location_provider_manager_msl", Boolean.toString(true), false); 1593 1594 // Create a random location and set provider location to cache necessary MSL assets. 1595 Location loc = createLocation(NAME, mRandom); 1596 loc.setAltitude(mRandom.nextDouble()); 1597 loc.setVerticalAccuracyMeters(mRandom.nextFloat()); 1598 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1599 Thread.sleep(1000); 1600 1601 // Register listener and reset provider location with invalid altitude to capture. 1602 ILocationListener listener = createMockLocationListener(); 1603 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 1604 mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1605 loc.setAltitude(Double.POSITIVE_INFINITY); 1606 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1607 ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class); 1608 verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class)); 1609 1610 // Assert that no MSL fields are populated. 1611 Location actual = captor.getValue().get(0); 1612 assertThat(actual.hasMslAltitude()).isFalse(); 1613 assertThat(actual.hasMslAltitudeAccuracy()).isFalse(); 1614 } 1615 1616 @MediumTest 1617 @Test testDisableMsl_expectedBehavior()1618 public void testDisableMsl_expectedBehavior() throws Exception { 1619 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION, 1620 "enable_location_provider_manager_msl", Boolean.toString(false), false); 1621 1622 // Create a random location and set provider location to cache necessary MSL assets. 1623 Location loc = createLocation(NAME, mRandom); 1624 loc.setAltitude(mRandom.nextDouble()); 1625 loc.setVerticalAccuracyMeters(mRandom.nextFloat()); 1626 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1627 Thread.sleep(1000); 1628 1629 // Register listener and reset provider location to capture. 1630 ILocationListener listener = createMockLocationListener(); 1631 LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(); 1632 mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener); 1633 mProvider.setProviderLocation(LocationResult.wrap(loc)); 1634 ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class); 1635 verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class)); 1636 1637 // Assert that no MSL fields are populated. 1638 Location actual = captor.getValue().get(0); 1639 assertThat(actual.hasMslAltitude()).isFalse(); 1640 assertThat(actual.hasMslAltitudeAccuracy()).isFalse(); 1641 } 1642 createMockLocationListener()1643 private ILocationListener createMockLocationListener() { 1644 return spy(new ILocationListener.Stub() { 1645 @Override 1646 public void onLocationChanged(List<Location> locations, 1647 IRemoteCallback onCompleteCallback) { 1648 if (onCompleteCallback != null) { 1649 try { 1650 onCompleteCallback.sendResult(null); 1651 } catch (RemoteException e) { 1652 e.rethrowFromSystemServer(); 1653 } 1654 } 1655 } 1656 1657 @Override 1658 public void onFlushComplete(int requestCode) { 1659 } 1660 1661 @Override 1662 public void onProviderEnabledChanged(String provider, boolean enabled) { 1663 } 1664 }); 1665 } 1666 1667 private ILocationCallback createMockGetCurrentLocationListener() { 1668 return spy(new ILocationCallback.Stub() { 1669 @Override 1670 public void onLocation(Location location) { 1671 } 1672 }); 1673 } 1674 1675 private static class TestProvider extends AbstractLocationProvider { 1676 1677 private ProviderRequest mProviderRequest = ProviderRequest.EMPTY_REQUEST; 1678 1679 private final ArrayList<Runnable> mFlushCallbacks = new ArrayList<>(); 1680 1681 TestProvider(ProviderProperties properties, CallerIdentity identity) { 1682 super(DIRECT_EXECUTOR, identity, properties, Collections.emptySet()); 1683 } 1684 1685 public void setProviderAllowed(boolean allowed) { 1686 setAllowed(allowed); 1687 } 1688 1689 public void setProviderLocation(Location l) { 1690 reportLocation(LocationResult.create(new Location(l))); 1691 } 1692 1693 public void setProviderLocation(LocationResult l) { 1694 reportLocation(l); 1695 } 1696 1697 public void completeFlushes() { 1698 for (Runnable r : mFlushCallbacks) { 1699 r.run(); 1700 } 1701 mFlushCallbacks.clear(); 1702 } 1703 1704 public ProviderRequest getRequest() { 1705 return mProviderRequest; 1706 } 1707 1708 @Override 1709 public void onSetRequest(ProviderRequest request) { 1710 mProviderRequest = request; 1711 } 1712 1713 @Override 1714 protected void onFlush(Runnable callback) { 1715 mFlushCallbacks.add(callback); 1716 } 1717 1718 @Override 1719 protected void onExtraCommand(int uid, int pid, String command, Bundle extras) { 1720 } 1721 1722 @Override 1723 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1724 } 1725 } 1726 } 1727