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