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