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