1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.location; 18 19 import static android.Manifest.permission.ACCESS_COARSE_LOCATION; 20 import static android.Manifest.permission.ACCESS_FINE_LOCATION; 21 import static android.Manifest.permission.LOCATION_BYPASS; 22 import static android.Manifest.permission.LOCATION_HARDWARE; 23 import static android.Manifest.permission.WRITE_SECURE_SETTINGS; 24 import static android.location.LocationRequest.createFromDeprecatedCriteria; 25 import static android.location.LocationRequest.createFromDeprecatedProvider; 26 27 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; 28 29 import android.Manifest; 30 import android.annotation.CallbackExecutor; 31 import android.annotation.NonNull; 32 import android.annotation.Nullable; 33 import android.annotation.RequiresFeature; 34 import android.annotation.RequiresPermission; 35 import android.annotation.SdkConstant; 36 import android.annotation.SdkConstant.SdkConstantType; 37 import android.annotation.SuppressLint; 38 import android.annotation.SystemApi; 39 import android.annotation.SystemService; 40 import android.annotation.TestApi; 41 import android.app.AppOpsManager; 42 import android.app.PendingIntent; 43 import android.app.PropertyInvalidatedCache; 44 import android.compat.Compatibility; 45 import android.compat.annotation.ChangeId; 46 import android.compat.annotation.EnabledAfter; 47 import android.content.Context; 48 import android.content.Intent; 49 import android.content.pm.PackageManager; 50 import android.location.provider.IProviderRequestListener; 51 import android.location.provider.ProviderProperties; 52 import android.location.provider.ProviderRequest; 53 import android.location.provider.ProviderRequest.ChangedListener; 54 import android.os.Build; 55 import android.os.Bundle; 56 import android.os.CancellationSignal; 57 import android.os.Handler; 58 import android.os.HandlerExecutor; 59 import android.os.ICancellationSignal; 60 import android.os.IRemoteCallback; 61 import android.os.Looper; 62 import android.os.PackageTagsList; 63 import android.os.Process; 64 import android.os.RemoteException; 65 import android.os.ServiceManager; 66 import android.os.UserHandle; 67 68 import com.android.internal.annotations.GuardedBy; 69 import com.android.internal.listeners.ListenerExecutor; 70 import com.android.internal.listeners.ListenerTransport; 71 import com.android.internal.listeners.ListenerTransportManager; 72 import com.android.internal.util.Preconditions; 73 74 import java.lang.ref.WeakReference; 75 import java.util.ArrayList; 76 import java.util.Collections; 77 import java.util.List; 78 import java.util.Objects; 79 import java.util.Set; 80 import java.util.WeakHashMap; 81 import java.util.concurrent.Executor; 82 import java.util.function.Consumer; 83 84 /** 85 * This class provides access to the system location services. These services allow applications to 86 * obtain periodic updates of the device's geographical location, or to be notified when the device 87 * enters the proximity of a given geographical location. 88 * 89 * <p class="note">Unless otherwise noted, all Location API methods require the 90 * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} or 91 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permissions. If your application only 92 * has the coarse permission then providers will still return location results, but the exact 93 * location will be obfuscated to a coarse level of accuracy. 94 */ 95 @SuppressWarnings({"deprecation"}) 96 @SystemService(Context.LOCATION_SERVICE) 97 @RequiresFeature(PackageManager.FEATURE_LOCATION) 98 public class LocationManager { 99 100 /** 101 * For apps targeting Android S and above, immutable PendingIntents passed into location APIs 102 * will generate an IllegalArgumentException. 103 * 104 * @hide 105 */ 106 @ChangeId 107 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 108 public static final long BLOCK_IMMUTABLE_PENDING_INTENTS = 171317480L; 109 110 /** 111 * For apps targeting Android S and above, LocationRequest system APIs may not be used with 112 * PendingIntent location requests. 113 * 114 * @hide 115 */ 116 @ChangeId 117 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 118 public static final long BLOCK_PENDING_INTENT_SYSTEM_API_USAGE = 169887240L; 119 120 /** 121 * For apps targeting Android S and above, location clients may receive historical locations 122 * (from before the present time) under some circumstances. 123 * 124 * @hide 125 */ 126 @ChangeId 127 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 128 public static final long DELIVER_HISTORICAL_LOCATIONS = 73144566L; 129 130 /** 131 * For apps targeting Android R and above, {@link #getProvider(String)} will no longer throw any 132 * security exceptions. 133 * 134 * @hide 135 */ 136 @ChangeId 137 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) 138 public static final long GET_PROVIDER_SECURITY_EXCEPTIONS = 150935354L; 139 140 /** 141 * For apps targeting Android K and above, supplied {@link PendingIntent}s must be targeted to a 142 * specific package. 143 * 144 * @hide 145 */ 146 @ChangeId 147 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN) 148 public static final long BLOCK_UNTARGETED_PENDING_INTENTS = 148963590L; 149 150 /** 151 * For apps targeting Android K and above, incomplete locations may not be passed to 152 * {@link #setTestProviderLocation}. 153 * 154 * @hide 155 */ 156 @ChangeId 157 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN) 158 public static final long BLOCK_INCOMPLETE_LOCATIONS = 148964793L; 159 160 /** 161 * For apps targeting Android S and above, all {@link GpsStatus} API usage must be replaced with 162 * {@link GnssStatus} APIs. 163 * 164 * @hide 165 */ 166 @ChangeId 167 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 168 public static final long BLOCK_GPS_STATUS_USAGE = 144027538L; 169 170 /** 171 * Standard name of the network location provider. 172 * 173 * <p>If present, this provider determines location based on nearby of cell tower and WiFi 174 * access points. Operation of this provider may require a data connection. 175 */ 176 public static final String NETWORK_PROVIDER = "network"; 177 178 /** 179 * Standard name of the GNSS location provider. 180 * 181 * <p>If present, this provider determines location using GNSS satellites. The responsiveness 182 * and accuracy of location fixes may depend on GNSS signal conditions. 183 * 184 * <p>Locations returned from this provider are with respect to the primary GNSS antenna 185 * position within the device. {@link #getGnssAntennaInfos()} may be used to determine the GNSS 186 * antenna position with respect to the Android Coordinate System, and convert between them if 187 * necessary. This is generally only necessary for high accuracy applications. 188 * 189 * <p>The extras Bundle for locations derived by this location provider may contain the 190 * following key/value pairs: 191 * <ul> 192 * <li> satellites - the number of satellites used to derive the fix 193 * </ul> 194 */ 195 public static final String GPS_PROVIDER = "gps"; 196 197 /** 198 * Standard name of the GNSS hardware location provider. 199 * 200 * <p>This provider is similar to {@link LocationManager#GPS_PROVIDER}, but it directly uses the 201 * HAL GNSS implementation and doesn't go through any provider overrides that may exist. This 202 * provider will only be available when the GPS_PROVIDER is overridden with a proxy using {@link 203 * android.location.provider.LocationProviderBase#ACTION_GNSS_PROVIDER}, and is intended only 204 * for use internally by the location provider system. 205 * 206 * @hide 207 */ 208 @SystemApi 209 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) 210 public static final String GPS_HARDWARE_PROVIDER = "gps_hardware"; 211 212 /** 213 * A special location provider for receiving locations without actively initiating a location 214 * fix. This location provider is always present. 215 * 216 * <p>This provider can be used to passively receive location updates when other applications or 217 * services request them without actually requesting the locations yourself. This provider will 218 * only return locations generated by other providers. 219 */ 220 public static final String PASSIVE_PROVIDER = "passive"; 221 222 /** 223 * Standard name of the fused location provider. 224 * 225 * <p>If present, this provider may combine inputs from several other location providers to 226 * provide the best possible location fix. It is implicitly used for all requestLocationUpdates 227 * APIs that involve a {@link Criteria}. 228 */ 229 public static final String FUSED_PROVIDER = "fused"; 230 231 /** 232 * Key used for the Bundle extra holding a boolean indicating whether 233 * a proximity alert is entering (true) or exiting (false).. 234 */ 235 public static final String KEY_PROXIMITY_ENTERING = "entering"; 236 237 /** 238 * This key is no longer in use. 239 * 240 * <p>Key used for a Bundle extra holding an Integer status value when a status change is 241 * broadcast using a PendingIntent. 242 * 243 * @deprecated Status changes are deprecated and no longer broadcast from Android Q onwards. 244 */ 245 @Deprecated 246 public static final String KEY_STATUS_CHANGED = "status"; 247 248 /** 249 * Key used for an extra holding a boolean enabled/disabled status value when a provider 250 * enabled/disabled event is broadcast using a PendingIntent. 251 * 252 * @see #requestLocationUpdates(String, LocationRequest, PendingIntent) 253 */ 254 public static final String KEY_PROVIDER_ENABLED = "providerEnabled"; 255 256 /** 257 * Key used for an extra holding a {@link Location} value when a location change is sent using 258 * a PendingIntent. If the location change includes a list of batched locations via 259 * {@link #KEY_LOCATIONS} then this key will still be present, and will hold the last location 260 * in the batch. Use {@link Intent#getParcelableExtra(String)} to retrieve the location. 261 * 262 * @see #requestLocationUpdates(String, LocationRequest, PendingIntent) 263 */ 264 public static final String KEY_LOCATION_CHANGED = "location"; 265 266 /** 267 * Key used for an extra holding a array of {@link Location}s when a location change is sent 268 * using a PendingIntent. This key will only be present if the location change includes 269 * multiple (ie, batched) locations, otherwise only {@link #KEY_LOCATION_CHANGED} will be 270 * present. Use {@link Intent#getParcelableArrayExtra(String)} to retrieve the locations. 271 * 272 * <p>The array of locations will never be empty, and will ordered from earliest location to 273 * latest location, the same as with {@link LocationListener#onLocationChanged(List)}. 274 * 275 * @see #requestLocationUpdates(String, LocationRequest, PendingIntent) 276 */ 277 public static final String KEY_LOCATIONS = "locations"; 278 279 /** 280 * Key used for an extra holding an integer request code when location flush completion is sent 281 * using a PendingIntent. 282 * 283 * @see #requestFlush(String, PendingIntent, int) 284 */ 285 public static final String KEY_FLUSH_COMPLETE = "flushComplete"; 286 287 /** 288 * Broadcast intent action when the set of enabled location providers changes. To check the 289 * status of a provider, use {@link #isProviderEnabled(String)}. From Android Q and above, will 290 * include a string intent extra, {@link #EXTRA_PROVIDER_NAME}, with the name of the provider 291 * whose state has changed. From Android R and above, will include a boolean intent extra, 292 * {@link #EXTRA_PROVIDER_ENABLED}, with the enabled state of the provider. 293 * 294 * @see #EXTRA_PROVIDER_NAME 295 * @see #EXTRA_PROVIDER_ENABLED 296 * @see #isProviderEnabled(String) 297 */ 298 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 299 public static final String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED"; 300 301 /** 302 * Intent extra included with {@link #PROVIDERS_CHANGED_ACTION} broadcasts, containing the name 303 * of the location provider that has changed. 304 * 305 * @see #PROVIDERS_CHANGED_ACTION 306 * @see #EXTRA_PROVIDER_ENABLED 307 */ 308 public static final String EXTRA_PROVIDER_NAME = "android.location.extra.PROVIDER_NAME"; 309 310 /** 311 * Intent extra included with {@link #PROVIDERS_CHANGED_ACTION} broadcasts, containing the 312 * boolean enabled state of the location provider that has changed. 313 * 314 * @see #PROVIDERS_CHANGED_ACTION 315 * @see #EXTRA_PROVIDER_NAME 316 */ 317 public static final String EXTRA_PROVIDER_ENABLED = "android.location.extra.PROVIDER_ENABLED"; 318 319 /** 320 * Broadcast intent action when the device location enabled state changes. From Android R and 321 * above, will include a boolean intent extra, {@link #EXTRA_LOCATION_ENABLED}, with the enabled 322 * state of location. 323 * 324 * @see #EXTRA_LOCATION_ENABLED 325 * @see #isLocationEnabled() 326 */ 327 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 328 public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED"; 329 330 /** 331 * Intent extra included with {@link #MODE_CHANGED_ACTION} broadcasts, containing the boolean 332 * enabled state of location. 333 * 334 * @see #MODE_CHANGED_ACTION 335 */ 336 public static final String EXTRA_LOCATION_ENABLED = "android.location.extra.LOCATION_ENABLED"; 337 338 /** 339 * Broadcast intent action when the ADAS (Advanced Driving Assistance Systems) GNSS location 340 * enabled state changes. Includes a boolean intent extra, {@link #EXTRA_ADAS_GNSS_ENABLED}, 341 * with the enabled state of ADAS GNSS location. This broadcast only has meaning on automotive 342 * devices. 343 * 344 * @see #EXTRA_ADAS_GNSS_ENABLED 345 * @see #isAdasGnssLocationEnabled() 346 * 347 * @hide 348 */ 349 @SystemApi 350 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 351 public static final String ACTION_ADAS_GNSS_ENABLED_CHANGED = 352 "android.location.action.ADAS_GNSS_ENABLED_CHANGED"; 353 354 /** 355 * Intent extra included with {@link #ACTION_ADAS_GNSS_ENABLED_CHANGED} broadcasts, containing 356 * the boolean enabled state of ADAS GNSS location. 357 * 358 * @see #ACTION_ADAS_GNSS_ENABLED_CHANGED 359 * 360 * @hide 361 */ 362 @SystemApi 363 public static final String EXTRA_ADAS_GNSS_ENABLED = "android.location.extra.ADAS_GNSS_ENABLED"; 364 365 /** 366 * Broadcast intent action indicating that a high power location requests 367 * has either started or stopped being active. The current state of 368 * active location requests should be read from AppOpsManager using 369 * {@code OP_MONITOR_HIGH_POWER_LOCATION}. 370 * 371 * @hide 372 * @deprecated This action is unnecessary from Android S forward. 373 */ 374 @Deprecated 375 public static final String HIGH_POWER_REQUEST_CHANGE_ACTION = 376 "android.location.HIGH_POWER_REQUEST_CHANGE"; 377 378 /** 379 * Broadcast intent action when GNSS capabilities change. This is most common at boot time as 380 * GNSS capabilities are queried from the chipset. Includes an intent extra, 381 * {@link #EXTRA_GNSS_CAPABILITIES}, with the new {@link GnssCapabilities}. 382 * 383 * @see #EXTRA_GNSS_CAPABILITIES 384 * @see #getGnssCapabilities() 385 */ 386 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 387 public static final String ACTION_GNSS_CAPABILITIES_CHANGED = 388 "android.location.action.GNSS_CAPABILITIES_CHANGED"; 389 390 /** 391 * Intent extra included with {@link #ACTION_GNSS_CAPABILITIES_CHANGED} broadcasts, containing 392 * the new {@link GnssCapabilities}. 393 * 394 * @see #ACTION_GNSS_CAPABILITIES_CHANGED 395 */ 396 public static final String EXTRA_GNSS_CAPABILITIES = "android.location.extra.GNSS_CAPABILITIES"; 397 398 /** 399 * Broadcast intent action for Settings app to inject a footer at the bottom of location 400 * settings. This is for use only by apps that are included in the system image. 401 * 402 * <p>To inject a footer to location settings, you must declare a broadcast receiver for 403 * this action in the manifest: 404 * <pre> 405 * <receiver android:name="com.example.android.footer.MyFooterInjector"> 406 * <intent-filter> 407 * <action android:name="com.android.settings.location.INJECT_FOOTER" /> 408 * </intent-filter> 409 * <meta-data 410 * android:name="com.android.settings.location.FOOTER_STRING" 411 * android:resource="@string/my_injected_footer_string" /> 412 * </receiver> 413 * </pre> 414 * 415 * <p>This broadcast receiver will never actually be invoked. See also 416 * {#METADATA_SETTINGS_FOOTER_STRING}. 417 * 418 * @hide 419 */ 420 public static final String SETTINGS_FOOTER_DISPLAYED_ACTION = 421 "com.android.settings.location.DISPLAYED_FOOTER"; 422 423 /** 424 * Metadata name for {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast 425 * receivers to specify a string resource id as location settings footer text. This is for use 426 * only by apps that are included in the system image. 427 * 428 * <p>See {@link #SETTINGS_FOOTER_DISPLAYED_ACTION} for more detail on how to use. 429 * 430 * @hide 431 */ 432 public static final String METADATA_SETTINGS_FOOTER_STRING = 433 "com.android.settings.location.FOOTER_STRING"; 434 435 private static final long MAX_SINGLE_LOCATION_TIMEOUT_MS = 30 * 1000; 436 437 private static final String CACHE_KEY_LOCATION_ENABLED_PROPERTY = 438 "cache_key.location_enabled"; 439 getService()440 static ILocationManager getService() throws RemoteException { 441 try { 442 return ILocationManager.Stub.asInterface( 443 ServiceManager.getServiceOrThrow(Context.LOCATION_SERVICE)); 444 } catch (ServiceManager.ServiceNotFoundException e) { 445 throw new RemoteException(e); 446 } 447 } 448 449 private static volatile LocationEnabledCache sLocationEnabledCache = 450 new LocationEnabledCache(4); 451 452 @GuardedBy("sLocationListeners") 453 private static final WeakHashMap<LocationListener, WeakReference<LocationListenerTransport>> 454 sLocationListeners = new WeakHashMap<>(); 455 456 // allows lazy instantiation since most processes do not use GNSS APIs 457 private static class GnssLazyLoader { 458 static final GnssStatusTransportManager sGnssStatusListeners = 459 new GnssStatusTransportManager(); 460 static final GnssNmeaTransportManager sGnssNmeaListeners = 461 new GnssNmeaTransportManager(); 462 static final GnssMeasurementsTransportManager sGnssMeasurementsListeners = 463 new GnssMeasurementsTransportManager(); 464 static final GnssAntennaTransportManager sGnssAntennaInfoListeners = 465 new GnssAntennaTransportManager(); 466 static final GnssNavigationTransportManager sGnssNavigationListeners = 467 new GnssNavigationTransportManager(); 468 } 469 470 private static class ProviderRequestLazyLoader { 471 static final ProviderRequestTransportManager sProviderRequestListeners = 472 new ProviderRequestTransportManager(); 473 } 474 475 final Context mContext; 476 final ILocationManager mService; 477 478 /** 479 * @hide 480 */ LocationManager(@onNull Context context, @NonNull ILocationManager service)481 public LocationManager(@NonNull Context context, @NonNull ILocationManager service) { 482 mContext = Objects.requireNonNull(context); 483 mService = Objects.requireNonNull(service); 484 } 485 486 /** 487 * @hide 488 */ 489 @TestApi getBackgroundThrottlingWhitelist()490 public @NonNull String[] getBackgroundThrottlingWhitelist() { 491 try { 492 return mService.getBackgroundThrottlingWhitelist(); 493 } catch (RemoteException e) { 494 throw e.rethrowFromSystemServer(); 495 } 496 } 497 498 /** 499 * @deprecated Do not use. 500 * @hide 501 */ 502 @Deprecated 503 @TestApi getIgnoreSettingsWhitelist()504 public @NonNull String[] getIgnoreSettingsWhitelist() { 505 return new String[0]; 506 } 507 508 /** 509 * For testing purposes only. 510 * @hide 511 */ 512 @TestApi getIgnoreSettingsAllowlist()513 public @NonNull PackageTagsList getIgnoreSettingsAllowlist() { 514 try { 515 return mService.getIgnoreSettingsAllowlist(); 516 } catch (RemoteException e) { 517 throw e.rethrowFromSystemServer(); 518 } 519 } 520 521 /** 522 * Returns ADAS packages and their associated attribution tags. 523 * 524 * @hide 525 */ getAdasAllowlist()526 public @NonNull PackageTagsList getAdasAllowlist() { 527 try { 528 return mService.getAdasAllowlist(); 529 } catch (RemoteException e) { 530 throw e.rethrowFromSystemServer(); 531 } 532 } 533 534 /** 535 * Returns the extra location controller package on the device. 536 * 537 * @hide 538 */ 539 @SystemApi getExtraLocationControllerPackage()540 public @Nullable String getExtraLocationControllerPackage() { 541 try { 542 return mService.getExtraLocationControllerPackage(); 543 } catch (RemoteException e) { 544 throw e.rethrowFromSystemServer(); 545 } 546 } 547 548 /** 549 * Set the extra location controller package for location services on the device. 550 * 551 * @hide 552 */ 553 @SystemApi 554 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) setExtraLocationControllerPackage(@ullable String packageName)555 public void setExtraLocationControllerPackage(@Nullable String packageName) { 556 try { 557 mService.setExtraLocationControllerPackage(packageName); 558 } catch (RemoteException e) { 559 throw e.rethrowFromSystemServer(); 560 } 561 } 562 563 /** 564 * Set whether the extra location controller package is currently enabled on the device. 565 * 566 * @hide 567 */ 568 @SystemApi 569 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) setExtraLocationControllerPackageEnabled(boolean enabled)570 public void setExtraLocationControllerPackageEnabled(boolean enabled) { 571 try { 572 mService.setExtraLocationControllerPackageEnabled(enabled); 573 } catch (RemoteException e) { 574 throw e.rethrowFromSystemServer(); 575 } 576 } 577 578 /** 579 * Returns whether extra location controller package is currently enabled on the device. 580 * 581 * @hide 582 */ 583 @SystemApi isExtraLocationControllerPackageEnabled()584 public boolean isExtraLocationControllerPackageEnabled() { 585 try { 586 return mService.isExtraLocationControllerPackageEnabled(); 587 } catch (RemoteException e) { 588 throw e.rethrowFromSystemServer(); 589 } 590 } 591 592 /** 593 * Set the extra location controller package for location services on the device. 594 * 595 * @removed 596 * @deprecated Use {@link #setExtraLocationControllerPackage} instead. 597 * @hide 598 */ 599 @Deprecated 600 @SystemApi 601 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) setLocationControllerExtraPackage(String packageName)602 public void setLocationControllerExtraPackage(String packageName) { 603 try { 604 mService.setExtraLocationControllerPackage(packageName); 605 } catch (RemoteException e) { 606 throw e.rethrowFromSystemServer(); 607 } 608 } 609 610 /** 611 * Set whether the extra location controller package is currently enabled on the device. 612 * 613 * @removed 614 * @deprecated Use {@link #setExtraLocationControllerPackageEnabled} instead. 615 * @hide 616 */ 617 @SystemApi 618 @Deprecated 619 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) setLocationControllerExtraPackageEnabled(boolean enabled)620 public void setLocationControllerExtraPackageEnabled(boolean enabled) { 621 try { 622 mService.setExtraLocationControllerPackageEnabled(enabled); 623 } catch (RemoteException e) { 624 throw e.rethrowFromSystemServer(); 625 } 626 } 627 628 /** 629 * Returns the current enabled/disabled state of location. To listen for changes, see 630 * {@link #MODE_CHANGED_ACTION}. 631 * 632 * @return true if location is enabled and false if location is disabled. 633 */ isLocationEnabled()634 public boolean isLocationEnabled() { 635 return isLocationEnabledForUser(mContext.getUser()); 636 } 637 638 /** 639 * Returns the current enabled/disabled state of location for the given user. 640 * 641 * @param userHandle the user to query 642 * @return true if location is enabled and false if location is disabled. 643 * 644 * @hide 645 */ 646 @SystemApi isLocationEnabledForUser(@onNull UserHandle userHandle)647 public boolean isLocationEnabledForUser(@NonNull UserHandle userHandle) { 648 // skip the cache for any "special" user ids - special ids like CURRENT_USER may change 649 // their meaning over time and should never be in the cache. we could resolve the special 650 // user ids here, but that would require an x-process call anyways, and the whole point of 651 // the cache is to avoid x-process calls. 652 if (userHandle.getIdentifier() >= 0) { 653 PropertyInvalidatedCache<Integer, Boolean> cache = sLocationEnabledCache; 654 if (cache != null) { 655 return cache.query(userHandle.getIdentifier()); 656 } 657 } 658 659 try { 660 return mService.isLocationEnabledForUser(userHandle.getIdentifier()); 661 } catch (RemoteException e) { 662 throw e.rethrowFromSystemServer(); 663 } 664 } 665 666 /** 667 * Enables or disables location for the given user. 668 * 669 * @param enabled true to enable location and false to disable location. 670 * @param userHandle the user to set 671 * 672 * @hide 673 */ 674 @SystemApi 675 @RequiresPermission(WRITE_SECURE_SETTINGS) setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle)676 public void setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle) { 677 try { 678 mService.setLocationEnabledForUser(enabled, userHandle.getIdentifier()); 679 } catch (RemoteException e) { 680 throw e.rethrowFromSystemServer(); 681 } 682 } 683 684 /** 685 * Returns the current enabled/disabled state of ADAS (Advanced Driving Assistance Systems) 686 * GNSS location access for the given user. This controls safety critical automotive access to 687 * GNSS location. This only has meaning on automotive devices. 688 * 689 * @return true if ADAS location is enabled and false if ADAS location is disabled. 690 * 691 * @hide 692 */ 693 @SystemApi isAdasGnssLocationEnabled()694 public boolean isAdasGnssLocationEnabled() { 695 try { 696 return mService.isAdasGnssLocationEnabledForUser(mContext.getUser().getIdentifier()); 697 } catch (RemoteException e) { 698 throw e.rethrowFromSystemServer(); 699 } 700 } 701 702 /** 703 * Enables or disables ADAS (Advanced Driving Assistance Systems) GNSS location access for the 704 * given user. This only has meaning on automotive devices. 705 * 706 * @param enabled true to enable ADAS location and false to disable ADAS location. 707 * 708 * @hide 709 */ 710 @SystemApi 711 @RequiresPermission(LOCATION_BYPASS) 712 @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) setAdasGnssLocationEnabled(boolean enabled)713 public void setAdasGnssLocationEnabled(boolean enabled) { 714 try { 715 mService.setAdasGnssLocationEnabledForUser(enabled, mContext.getUser().getIdentifier()); 716 } catch (RemoteException e) { 717 throw e.rethrowFromSystemServer(); 718 } 719 } 720 721 /** 722 * Returns the current enabled/disabled status of the given provider. To listen for changes, see 723 * {@link #PROVIDERS_CHANGED_ACTION}. 724 * 725 * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw 726 * {@link SecurityException} if the location permissions were not sufficient to use the 727 * specified provider. 728 * 729 * @param provider a provider listed by {@link #getAllProviders()} 730 * @return true if the provider exists and is enabled 731 * 732 * @throws IllegalArgumentException if provider is null 733 */ isProviderEnabled(@onNull String provider)734 public boolean isProviderEnabled(@NonNull String provider) { 735 return isProviderEnabledForUser(provider, Process.myUserHandle()); 736 } 737 738 /** 739 * Returns the current enabled/disabled status of the given provider and user. Callers should 740 * prefer {@link #isLocationEnabledForUser(UserHandle)} unless they depend on provider-specific 741 * APIs. 742 * 743 * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw 744 * {@link SecurityException} if the location permissions were not sufficient to use the 745 * specified provider. 746 * 747 * @param provider a provider listed by {@link #getAllProviders()} 748 * @param userHandle the user to query 749 * @return true if the provider exists and is enabled 750 * 751 * @throws IllegalArgumentException if provider is null 752 * @hide 753 */ 754 @SystemApi isProviderEnabledForUser( @onNull String provider, @NonNull UserHandle userHandle)755 public boolean isProviderEnabledForUser( 756 @NonNull String provider, @NonNull UserHandle userHandle) { 757 Preconditions.checkArgument(provider != null, "invalid null provider"); 758 759 try { 760 return mService.isProviderEnabledForUser(provider, userHandle.getIdentifier()); 761 } catch (RemoteException e) { 762 throw e.rethrowFromSystemServer(); 763 } 764 } 765 766 /** 767 * Method for enabling or disabling a single location provider. This method is deprecated and 768 * functions as a best effort. It should not be relied on in any meaningful sense as providers 769 * may no longer be enabled or disabled by clients. 770 * 771 * @param provider a provider listed by {@link #getAllProviders()} 772 * @param enabled whether to enable or disable the provider 773 * @param userHandle the user to set 774 * @return true if the value was set, false otherwise 775 * 776 * @throws IllegalArgumentException if provider is null 777 * @deprecated Do not manipulate providers individually, use 778 * {@link #setLocationEnabledForUser(boolean, UserHandle)} instead. 779 * @hide 780 */ 781 @Deprecated 782 @SystemApi 783 @RequiresPermission(WRITE_SECURE_SETTINGS) setProviderEnabledForUser( @onNull String provider, boolean enabled, @NonNull UserHandle userHandle)784 public boolean setProviderEnabledForUser( 785 @NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) { 786 Preconditions.checkArgument(provider != null, "invalid null provider"); 787 return false; 788 } 789 790 /** 791 * Set whether GNSS requests are suspended on the automotive device. 792 * 793 * For devices where GNSS prevents the system from going into a low power state, GNSS should 794 * be suspended right before going into the lower power state and resumed right after the device 795 * wakes up. 796 * 797 * This method disables GNSS and should only be used for power management use cases such as 798 * suspend-to-RAM or suspend-to-disk. 799 * 800 * @hide 801 */ 802 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 803 @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) 804 @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) setAutomotiveGnssSuspended(boolean suspended)805 public void setAutomotiveGnssSuspended(boolean suspended) { 806 try { 807 mService.setAutomotiveGnssSuspended(suspended); 808 } catch (RemoteException e) { 809 throw e.rethrowFromSystemServer(); 810 } 811 } 812 813 /** 814 * Return whether GNSS requests are suspended on the automotive device. 815 * 816 * @return true if GNSS requests are suspended and false if they aren't. 817 * 818 * @hide 819 */ 820 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 821 @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) 822 @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) isAutomotiveGnssSuspended()823 public boolean isAutomotiveGnssSuspended() { 824 try { 825 return mService.isAutomotiveGnssSuspended(); 826 } catch (RemoteException e) { 827 throw e.rethrowFromSystemServer(); 828 } 829 } 830 831 /** 832 * Gets the last known location from the fused provider, or null if there is no last known 833 * location. The returned location may be quite old in some circumstances, so the age of the 834 * location should always be checked. 835 * 836 * @return the last known location, or null if not available 837 * 838 * @throws SecurityException if no suitable location permission is present 839 * 840 * @hide 841 */ 842 @Nullable 843 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) getLastLocation()844 public Location getLastLocation() { 845 return getLastKnownLocation(FUSED_PROVIDER); 846 } 847 848 /** 849 * Gets the last known location from the given provider, or null if there is no last known 850 * location. The returned location may be quite old in some circumstances, so the age of the 851 * location should always be checked. 852 * 853 * <p>This will never activate sensors to compute a new location, and will only ever return a 854 * cached location. 855 * 856 * <p>See also {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} which 857 * will always attempt to return a current location, but will potentially use additional power 858 * in the course of the attempt as compared to this method. 859 * 860 * @param provider a provider listed by {@link #getAllProviders()} 861 * 862 * @return the last known location for the given provider, or null if not available 863 * 864 * @throws SecurityException if no suitable permission is present 865 * @throws IllegalArgumentException if provider is null or doesn't exist 866 */ 867 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) 868 @Nullable getLastKnownLocation(@onNull String provider)869 public Location getLastKnownLocation(@NonNull String provider) { 870 return getLastKnownLocation(provider, new LastLocationRequest.Builder().build()); 871 } 872 873 /** 874 * Gets the last known location from the given provider, or null if there is no last known 875 * location. 876 * 877 * <p>See {@link LastLocationRequest} documentation for an explanation of various request 878 * parameters and how they can affect the returned location. 879 * 880 * <p>See {@link #getLastKnownLocation(String)} for more detail on how this method works. 881 * 882 * @param provider a provider listed by {@link #getAllProviders()} 883 * @param lastLocationRequest the last location request containing location parameters 884 * 885 * @return the last known location for the given provider, or null if not available 886 * 887 * @throws SecurityException if no suitable permission is present 888 * @throws IllegalArgumentException if provider is null or doesn't exist 889 * @throws IllegalArgumentException if lastLocationRequest is null 890 * 891 * @hide 892 */ 893 @SystemApi 894 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) 895 @Nullable getLastKnownLocation(@onNull String provider, @NonNull LastLocationRequest lastLocationRequest)896 public Location getLastKnownLocation(@NonNull String provider, 897 @NonNull LastLocationRequest lastLocationRequest) { 898 Preconditions.checkArgument(provider != null, "invalid null provider"); 899 Preconditions.checkArgument(lastLocationRequest != null, 900 "invalid null last location request"); 901 902 try { 903 return mService.getLastLocation(provider, lastLocationRequest, 904 mContext.getPackageName(), mContext.getAttributionTag()); 905 } catch (RemoteException e) { 906 throw e.rethrowFromSystemServer(); 907 } 908 } 909 910 /** 911 * Asynchronously returns a single current location fix from the given provider. 912 * 913 * <p>See 914 * {@link #getCurrentLocation(String, LocationRequest, CancellationSignal, Executor, Consumer)} 915 * for more information. 916 * 917 * @param provider a provider listed by {@link #getAllProviders()} 918 * @param cancellationSignal an optional signal that allows for cancelling this call 919 * @param executor the callback will take place on this {@link Executor} 920 * @param consumer the callback invoked with either a {@link Location} or null 921 * 922 * @throws IllegalArgumentException if provider is null or doesn't exist 923 * @throws IllegalArgumentException if executor is null 924 * @throws IllegalArgumentException if consumer is null 925 * @throws SecurityException if no suitable permission is present 926 */ 927 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) getCurrentLocation(@onNull String provider, @Nullable CancellationSignal cancellationSignal, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer)928 public void getCurrentLocation(@NonNull String provider, 929 @Nullable CancellationSignal cancellationSignal, 930 @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) { 931 getCurrentLocation( 932 provider, 933 new LocationRequest.Builder(0).build(), 934 cancellationSignal, executor, consumer); 935 } 936 937 /** 938 * Asynchronously returns a single current location fix from the given provider based on the 939 * given {@link LocationRequest}. 940 * 941 * <p>See 942 * {@link #getCurrentLocation(String, LocationRequest, CancellationSignal, Executor, Consumer)} 943 * for more information. 944 * 945 * @param locationRequest the location request containing location parameters 946 * @param cancellationSignal an optional signal that allows for cancelling this call 947 * @param executor the callback will take place on this {@link Executor} 948 * @param consumer the callback invoked with either a {@link Location} or null 949 * 950 * @throws IllegalArgumentException if provider is null or doesn't exist 951 * @throws IllegalArgumentException if executor is null 952 * @throws IllegalArgumentException if consumer is null 953 * @throws SecurityException if no suitable permission is present 954 * @hide 955 * @deprecated Use 956 * {@link #getCurrentLocation(String, LocationRequest, CancellationSignal, Executor, Consumer)} 957 * instead. 958 */ 959 @Deprecated 960 @SystemApi 961 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) getCurrentLocation(@onNull LocationRequest locationRequest, @Nullable CancellationSignal cancellationSignal, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer)962 public void getCurrentLocation(@NonNull LocationRequest locationRequest, 963 @Nullable CancellationSignal cancellationSignal, 964 @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) { 965 Preconditions.checkArgument(locationRequest.getProvider() != null); 966 getCurrentLocation(locationRequest.getProvider(), locationRequest, cancellationSignal, 967 executor, consumer); 968 } 969 970 /** 971 * Asynchronously returns a single current location fix from the given provider based on the 972 * given {@link LocationRequest}. This may activate sensors in order to compute a new location, 973 * unlike {@link #getLastKnownLocation(String)}, which will only return a cached fix if 974 * available. The given callback will be invoked once and only once, either with a valid 975 * location or with a null location if the provider was unable to generate a valid location. 976 * 977 * <p>A client may supply an optional {@link CancellationSignal}. If this is used to cancel the 978 * operation, no callback should be expected after the cancellation. 979 * 980 * <p>This method may return locations from the very recent past (on the order of several 981 * seconds), but will never return older locations (for example, several minutes old or older). 982 * Clients may rely upon the guarantee that if this method returns a location, it will represent 983 * the best estimation of the location of the device in the present moment. 984 * 985 * <p>Clients calling this method from the background may notice that the method fails to 986 * determine a valid location fix more often than while in the foreground. Background 987 * applications may be throttled in their location accesses to some degree. 988 * 989 * The given location request may be used to provide hints on how a fresh location is computed 990 * if necessary. In particular {@link LocationRequest#getDurationMillis()} can be used to 991 * provide maximum duration allowed before failing. The system will always cap the maximum 992 * amount of time a request for current location may run to some reasonable value (less than a 993 * minute for example) before the request is failed. 994 * 995 * @param provider a provider listed by {@link #getAllProviders()} 996 * @param locationRequest the location request containing location parameters 997 * @param cancellationSignal an optional signal that allows for cancelling this call 998 * @param executor the callback will take place on this {@link Executor} 999 * @param consumer the callback invoked with either a {@link Location} or null 1000 * 1001 * @throws IllegalArgumentException if provider is null or doesn't exist 1002 * @throws IllegalArgumentException if executor is null 1003 * @throws IllegalArgumentException if consumer is null 1004 * @throws SecurityException if no suitable permission is present 1005 */ 1006 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) getCurrentLocation(@onNull String provider, @NonNull LocationRequest locationRequest, @Nullable CancellationSignal cancellationSignal, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer)1007 public void getCurrentLocation(@NonNull String provider, 1008 @NonNull LocationRequest locationRequest, 1009 @Nullable CancellationSignal cancellationSignal, 1010 @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) { 1011 Preconditions.checkArgument(provider != null, "invalid null provider"); 1012 Preconditions.checkArgument(locationRequest != null, "invalid null location request"); 1013 1014 if (cancellationSignal != null) { 1015 cancellationSignal.throwIfCanceled(); 1016 } 1017 1018 GetCurrentLocationTransport transport = new GetCurrentLocationTransport(executor, consumer, 1019 cancellationSignal); 1020 1021 ICancellationSignal cancelRemote; 1022 try { 1023 cancelRemote = mService.getCurrentLocation(provider, 1024 locationRequest, transport, mContext.getPackageName(), 1025 mContext.getAttributionTag(), AppOpsManager.toReceiverId(consumer)); 1026 } catch (RemoteException e) { 1027 throw e.rethrowFromSystemServer(); 1028 } 1029 1030 if (cancellationSignal != null) { 1031 cancellationSignal.setRemote(cancelRemote); 1032 } 1033 } 1034 1035 /** 1036 * Register for a single location update using the named provider and a callback. 1037 * 1038 * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener, Looper)} for 1039 * more detail on how to use this method. 1040 * 1041 * @param provider a provider listed by {@link #getAllProviders()} 1042 * @param listener the listener to receive location updates 1043 * @param looper the looper handling listener callbacks, or null to use the looper of the 1044 * calling thread 1045 * 1046 * @throws IllegalArgumentException if provider is null or doesn't exist 1047 * @throws IllegalArgumentException if listener is null 1048 * @throws SecurityException if no suitable permission is present 1049 * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} 1050 * instead as it does not carry a risk of extreme battery drain. 1051 */ 1052 @Deprecated 1053 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestSingleUpdate( @onNull String provider, @NonNull LocationListener listener, @Nullable Looper looper)1054 public void requestSingleUpdate( 1055 @NonNull String provider, @NonNull LocationListener listener, @Nullable Looper looper) { 1056 Preconditions.checkArgument(provider != null, "invalid null provider"); 1057 1058 Handler handler = looper == null ? new Handler() : new Handler(looper); 1059 requestLocationUpdates( 1060 provider, 1061 new LocationRequest.Builder(0) 1062 .setMaxUpdates(1) 1063 .setDurationMillis(MAX_SINGLE_LOCATION_TIMEOUT_MS) 1064 .build(), 1065 new HandlerExecutor(handler), 1066 listener); 1067 } 1068 1069 /** 1070 * Register for a single location update using a Criteria and a callback. 1071 * 1072 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1073 * {@link #FUSED_PROVIDER}. 1074 * 1075 * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} for more detail 1076 * on how to use this method. 1077 * 1078 * @param criteria contains parameters to choose the appropriate provider for location updates 1079 * @param listener the listener to receive location updates 1080 * @param looper the looper handling listener callbacks, or null to use the looper of the 1081 * calling thread 1082 * 1083 * @throws IllegalArgumentException if criteria is null 1084 * @throws IllegalArgumentException if listener is null 1085 * @throws SecurityException if no suitable permission is present 1086 * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} 1087 * instead as it does not carry a risk of extreme battery drain. 1088 */ 1089 @Deprecated 1090 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestSingleUpdate( @onNull Criteria criteria, @NonNull LocationListener listener, @Nullable Looper looper)1091 public void requestSingleUpdate( 1092 @NonNull Criteria criteria, 1093 @NonNull LocationListener listener, 1094 @Nullable Looper looper) { 1095 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1096 1097 Handler handler = looper == null ? new Handler() : new Handler(looper); 1098 requestLocationUpdates( 1099 FUSED_PROVIDER, 1100 new LocationRequest.Builder(0) 1101 .setQuality(criteria) 1102 .setMaxUpdates(1) 1103 .setDurationMillis(MAX_SINGLE_LOCATION_TIMEOUT_MS) 1104 .build(), 1105 new HandlerExecutor(handler), 1106 listener); 1107 } 1108 1109 /** 1110 * Register for a single location update using a named provider and pending intent. 1111 * 1112 * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} for more detail 1113 * on how to use this method. 1114 * 1115 * @param provider a provider listed by {@link #getAllProviders()} 1116 * @param pendingIntent the pending intent to send location updates 1117 * 1118 * @throws IllegalArgumentException if provider is null or doesn't exist 1119 * @throws IllegalArgumentException if intent is null 1120 * @throws SecurityException if no suitable permission is present 1121 * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} 1122 * instead as it does not carry a risk of extreme battery drain. 1123 */ 1124 @Deprecated 1125 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestSingleUpdate(@onNull String provider, @NonNull PendingIntent pendingIntent)1126 public void requestSingleUpdate(@NonNull String provider, 1127 @NonNull PendingIntent pendingIntent) { 1128 Preconditions.checkArgument(provider != null, "invalid null provider"); 1129 1130 requestLocationUpdates( 1131 provider, 1132 new LocationRequest.Builder(0) 1133 .setMaxUpdates(1) 1134 .setDurationMillis(MAX_SINGLE_LOCATION_TIMEOUT_MS) 1135 .build(), 1136 pendingIntent); 1137 } 1138 1139 /** 1140 * Register for a single location update using a Criteria and pending intent. 1141 * 1142 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1143 * {@link #FUSED_PROVIDER}. 1144 * 1145 * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} for more detail 1146 * on how to use this method. 1147 * 1148 * @param criteria contains parameters to choose the appropriate provider for location 1149 * updates 1150 * @param pendingIntent the pending intent to send location updates 1151 * 1152 * @throws IllegalArgumentException if provider is null or doesn't exist 1153 * @throws IllegalArgumentException if intent is null 1154 * @throws SecurityException if no suitable permission is present 1155 * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} 1156 * instead as it does not carry a risk of extreme battery drain. 1157 */ 1158 @Deprecated 1159 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestSingleUpdate(@onNull Criteria criteria, @NonNull PendingIntent pendingIntent)1160 public void requestSingleUpdate(@NonNull Criteria criteria, 1161 @NonNull PendingIntent pendingIntent) { 1162 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1163 1164 requestLocationUpdates( 1165 FUSED_PROVIDER, 1166 new LocationRequest.Builder(0) 1167 .setQuality(criteria) 1168 .setMaxUpdates(1) 1169 .setDurationMillis(MAX_SINGLE_LOCATION_TIMEOUT_MS) 1170 .build(), 1171 pendingIntent); 1172 } 1173 1174 /** 1175 * Register for location updates from the given provider with the given arguments, and a 1176 * callback on the {@link Looper} of the calling thread. 1177 * 1178 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1179 * for more detail on how this method works. 1180 * 1181 * <p class="note"> Prior to Jellybean, the minTime parameter was only a hint, and some location 1182 * provider implementations ignored it. For Jellybean and onwards however, it is mandatory for 1183 * Android compatible devices to observe both the minTime and minDistance parameters. 1184 * 1185 * @param provider a provider listed by {@link #getAllProviders()} 1186 * @param minTimeMs minimum time interval between location updates in milliseconds 1187 * @param minDistanceM minimum distance between location updates in meters 1188 * @param listener the listener to receive location updates 1189 * 1190 * @throws IllegalArgumentException if provider is null or doesn't exist 1191 * @throws IllegalArgumentException if listener is null 1192 * @throws RuntimeException if the calling thread has no Looper 1193 * @throws SecurityException if no suitable permission is present 1194 */ 1195 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, long minTimeMs, float minDistanceM, @NonNull LocationListener listener)1196 public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM, 1197 @NonNull LocationListener listener) { 1198 requestLocationUpdates(provider, minTimeMs, minDistanceM, listener, null); 1199 } 1200 1201 /** 1202 * Register for location updates from the given provider with the given arguments, and a 1203 * callback on the specified {@link Looper}. 1204 * 1205 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1206 * for more detail on how this method works. 1207 * 1208 * <p class="note">Prior to Jellybean, the minTime parameter was only a hint, and some location 1209 * provider implementations ignored it. For Jellybean and onwards however, it is mandatory for 1210 * Android compatible devices to observe both the minTime and minDistance parameters. 1211 * 1212 * @param provider a provider listed by {@link #getAllProviders()} 1213 * @param minTimeMs minimum time interval between location updates in milliseconds 1214 * @param minDistanceM minimum distance between location updates in meters 1215 * @param listener the listener to receive location updates 1216 * @param looper the looper handling listener callbacks, or null to use the looper of the 1217 * calling thread 1218 * 1219 * @throws IllegalArgumentException if provider is null or doesn't exist 1220 * @throws IllegalArgumentException if listener is null 1221 * @throws SecurityException if no suitable permission is present 1222 */ 1223 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, long minTimeMs, float minDistanceM, @NonNull LocationListener listener, @Nullable Looper looper)1224 public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM, 1225 @NonNull LocationListener listener, @Nullable Looper looper) { 1226 Handler handler = looper == null ? new Handler() : new Handler(looper); 1227 requestLocationUpdates(provider, minTimeMs, minDistanceM, new HandlerExecutor(handler), 1228 listener); 1229 } 1230 1231 /** 1232 * Register for location updates using the named provider, and a callback on 1233 * the specified {@link Executor}. 1234 * 1235 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1236 * for more detail on how this method works. 1237 * 1238 * <p class="note">Prior to Jellybean, the minTime parameter was only a hint, and some location 1239 * provider implementations ignored it. For Jellybean and onwards however, it is mandatory for 1240 * Android compatible devices to observe both the minTime and minDistance parameters. 1241 * 1242 * @param provider a provider listed by {@link #getAllProviders()} 1243 * @param minTimeMs minimum time interval between location updates in milliseconds 1244 * @param minDistanceM minimum distance between location updates in meters 1245 * @param executor the executor handling listener callbacks 1246 * @param listener the listener to receive location updates 1247 * 1248 * @throws IllegalArgumentException if provider is null or doesn't exist 1249 * @throws IllegalArgumentException if executor is null 1250 * @throws IllegalArgumentException if listener is null 1251 * @throws SecurityException if no suitable permission is present 1252 */ 1253 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( @onNull String provider, long minTimeMs, float minDistanceM, @NonNull @CallbackExecutor Executor executor, @NonNull LocationListener listener)1254 public void requestLocationUpdates( 1255 @NonNull String provider, 1256 long minTimeMs, 1257 float minDistanceM, 1258 @NonNull @CallbackExecutor Executor executor, 1259 @NonNull LocationListener listener) { 1260 Preconditions.checkArgument(provider != null, "invalid null provider"); 1261 1262 requestLocationUpdates( 1263 provider, 1264 createFromDeprecatedProvider(provider, minTimeMs, minDistanceM, false), 1265 executor, 1266 listener); 1267 } 1268 1269 /** 1270 * Register for location updates using a provider selected through the given Criteria, and a 1271 * callback on the specified {@link Looper}. 1272 * 1273 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1274 * {@link #FUSED_PROVIDER}. 1275 * 1276 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1277 * for more detail on how this method works. 1278 * 1279 * @param minTimeMs minimum time interval between location updates in milliseconds 1280 * @param minDistanceM minimum distance between location updates in meters 1281 * @param criteria contains parameters to choose the appropriate provider for location updates 1282 * @param listener the listener to receive location updates 1283 * 1284 * @throws IllegalArgumentException if criteria is null 1285 * @throws IllegalArgumentException if listener is null 1286 * @throws SecurityException if no suitable permission is present 1287 * 1288 * @deprecated Use 1289 * {@link #requestLocationUpdates(String, long, float, LocationListener, Looper)} instead to 1290 * explicitly select a provider. 1291 */ 1292 @Deprecated 1293 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(long minTimeMs, float minDistanceM, @NonNull Criteria criteria, @NonNull LocationListener listener, @Nullable Looper looper)1294 public void requestLocationUpdates(long minTimeMs, float minDistanceM, 1295 @NonNull Criteria criteria, @NonNull LocationListener listener, 1296 @Nullable Looper looper) { 1297 Handler handler = looper == null ? new Handler() : new Handler(looper); 1298 requestLocationUpdates(minTimeMs, minDistanceM, criteria, new HandlerExecutor(handler), 1299 listener); 1300 } 1301 1302 /** 1303 * Register for location updates using a provider selected through the given Criteria, and a 1304 * callback on the specified {@link Executor}. 1305 * 1306 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1307 * {@link #FUSED_PROVIDER}. 1308 * 1309 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1310 * for more detail on how this method works. 1311 * 1312 * @param minTimeMs minimum time interval between location updates in milliseconds 1313 * @param minDistanceM minimum distance between location updates in meters 1314 * @param criteria contains parameters to choose the appropriate provider for location updates 1315 * @param executor the executor handling listener callbacks 1316 * @param listener the listener to receive location updates 1317 * 1318 * @throws IllegalArgumentException if criteria is null 1319 * @throws IllegalArgumentException if executor is null 1320 * @throws IllegalArgumentException if listener is null 1321 * @throws SecurityException if no suitable permission is present 1322 * 1323 * @deprecated Use 1324 * {@link #requestLocationUpdates(String, long, float, Executor, LocationListener)} instead to 1325 * explicitly select a provider. 1326 */ 1327 @Deprecated 1328 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( long minTimeMs, float minDistanceM, @NonNull Criteria criteria, @NonNull @CallbackExecutor Executor executor, @NonNull LocationListener listener)1329 public void requestLocationUpdates( 1330 long minTimeMs, 1331 float minDistanceM, 1332 @NonNull Criteria criteria, 1333 @NonNull @CallbackExecutor Executor executor, 1334 @NonNull LocationListener listener) { 1335 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1336 1337 requestLocationUpdates( 1338 FUSED_PROVIDER, 1339 createFromDeprecatedCriteria(criteria, minTimeMs, minDistanceM, false), 1340 executor, 1341 listener); 1342 } 1343 1344 /** 1345 * Register for location updates using the named provider, and callbacks delivered via the 1346 * provided {@link PendingIntent}. 1347 * 1348 * <p>See {@link #requestLocationUpdates(String, LocationRequest, PendingIntent)} for more 1349 * detail on how this method works. 1350 * 1351 * @param provider a provider listed by {@link #getAllProviders()} 1352 * @param minTimeMs minimum time interval between location updates in milliseconds 1353 * @param minDistanceM minimum distance between location updates in meters 1354 * @param pendingIntent the pending intent to send location updates 1355 * 1356 * @throws IllegalArgumentException if provider is null or doesn't exist 1357 * @throws IllegalArgumentException if pendingIntent is null 1358 * @throws SecurityException if no suitable permission is present 1359 */ 1360 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, long minTimeMs, float minDistanceM, @NonNull PendingIntent pendingIntent)1361 public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM, 1362 @NonNull PendingIntent pendingIntent) { 1363 Preconditions.checkArgument(provider != null, "invalid null provider"); 1364 1365 requestLocationUpdates( 1366 provider, 1367 createFromDeprecatedProvider(provider, minTimeMs, minDistanceM, false), 1368 pendingIntent); 1369 } 1370 1371 /** 1372 * Register for location updates using a provider selected through the given Criteria, and 1373 * callbacks delivered via the provided {@link PendingIntent}. 1374 * 1375 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1376 * {@link #FUSED_PROVIDER}. 1377 * 1378 * <p>See {@link #requestLocationUpdates(String, long, float, PendingIntent)} for more detail on 1379 * how this method works. 1380 * 1381 * @param minTimeMs minimum time interval between location updates in milliseconds 1382 * @param minDistanceM minimum distance between location updates in meters 1383 * @param criteria contains parameters to choose the appropriate provider for location updates 1384 * @param pendingIntent the pending intent to send location updates 1385 * 1386 * @throws IllegalArgumentException if provider is null or doesn't exist 1387 * @throws IllegalArgumentException if pendingIntent is null 1388 * @throws SecurityException if no suitable permission is present 1389 * 1390 * @deprecated Use {@link #requestLocationUpdates(String, long, float, PendingIntent)} instead 1391 * to explicitly select a provider. 1392 */ 1393 @Deprecated 1394 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(long minTimeMs, float minDistanceM, @NonNull Criteria criteria, @NonNull PendingIntent pendingIntent)1395 public void requestLocationUpdates(long minTimeMs, float minDistanceM, 1396 @NonNull Criteria criteria, @NonNull PendingIntent pendingIntent) { 1397 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1398 requestLocationUpdates( 1399 FUSED_PROVIDER, 1400 createFromDeprecatedCriteria(criteria, minTimeMs, minDistanceM, false), 1401 pendingIntent); 1402 } 1403 1404 /** 1405 * Register for location updates using a {@link LocationRequest}, and a callback on the 1406 * specified {@link Looper}. 1407 * 1408 * <p>The system will automatically select and enable the best provider based on the given 1409 * {@link LocationRequest}. The LocationRequest can be null, in which case the system will 1410 * choose default low power parameters for location updates, but this is heavily discouraged, 1411 * and an explicit LocationRequest should always be provided. 1412 * 1413 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1414 * for more detail on how this method works. 1415 * 1416 * @param locationRequest the location request containing location parameters 1417 * @param listener the listener to receive location updates 1418 * @param looper the looper handling listener callbacks, or null to use the looper of the 1419 * calling thread 1420 * 1421 * @throws IllegalArgumentException if listener is null 1422 * @throws SecurityException if no suitable permission is present 1423 * 1424 * @hide 1425 * @deprecated Use 1426 * {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} instead. 1427 */ 1428 @Deprecated 1429 @SystemApi 1430 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( @ullable LocationRequest locationRequest, @NonNull LocationListener listener, @Nullable Looper looper)1431 public void requestLocationUpdates( 1432 @Nullable LocationRequest locationRequest, 1433 @NonNull LocationListener listener, 1434 @Nullable Looper looper) { 1435 Handler handler = looper == null ? new Handler() : new Handler(looper); 1436 requestLocationUpdates(locationRequest, new HandlerExecutor(handler), listener); 1437 } 1438 1439 /** 1440 * Register for location updates using a {@link LocationRequest}, and a callback on the 1441 * specified {@link Executor}. 1442 * 1443 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1444 * for more detail on how this method works. 1445 * 1446 * @param locationRequest the location request containing location parameters 1447 * @param executor the executor handling listener callbacks 1448 * @param listener the listener to receive location updates 1449 * 1450 * @throws IllegalArgumentException if executor is null 1451 * @throws IllegalArgumentException if listener is null 1452 * @throws SecurityException if no suitable permission is present 1453 * 1454 * @hide 1455 * @deprecated Use 1456 * {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} instead. 1457 */ 1458 @Deprecated 1459 @SystemApi 1460 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( @ullable LocationRequest locationRequest, @NonNull @CallbackExecutor Executor executor, @NonNull LocationListener listener)1461 public void requestLocationUpdates( 1462 @Nullable LocationRequest locationRequest, 1463 @NonNull @CallbackExecutor Executor executor, 1464 @NonNull LocationListener listener) { 1465 if (locationRequest == null) { 1466 locationRequest = LocationRequest.create(); 1467 } 1468 Preconditions.checkArgument(locationRequest.getProvider() != null); 1469 requestLocationUpdates(locationRequest.getProvider(), locationRequest, executor, listener); 1470 } 1471 1472 /** 1473 * Register for location updates using a {@link LocationRequest}, and callbacks delivered via 1474 * the provided {@link PendingIntent}. 1475 * 1476 * <p>See {@link #requestLocationUpdates(String, LocationRequest, PendingIntent)} for more 1477 * detail on how this method works. 1478 * 1479 * @param locationRequest the location request containing location parameters 1480 * @param pendingIntent the pending intent to send location updates 1481 * 1482 * @throws IllegalArgumentException if pendingIntent is null 1483 * @throws SecurityException if no suitable permission is present 1484 * 1485 * @hide 1486 * @deprecated Use {@link #requestLocationUpdates(String, LocationRequest, PendingIntent)} 1487 * instead. 1488 */ 1489 @Deprecated 1490 @SystemApi 1491 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( @ullable LocationRequest locationRequest, @NonNull PendingIntent pendingIntent)1492 public void requestLocationUpdates( 1493 @Nullable LocationRequest locationRequest, 1494 @NonNull PendingIntent pendingIntent) { 1495 if (locationRequest == null) { 1496 locationRequest = LocationRequest.create(); 1497 } 1498 Preconditions.checkArgument(locationRequest.getProvider() != null); 1499 requestLocationUpdates(locationRequest.getProvider(), locationRequest, pendingIntent); 1500 } 1501 1502 /** 1503 * Register for location updates from the specified provider, using a {@link LocationRequest}, 1504 * and a callback on the specified {@link Executor}. 1505 * 1506 * <p>Only one request can be registered for each unique listener/provider pair, so any 1507 * subsequent requests with the same provider and listener will overwrite all associated 1508 * arguments. The same listener may be used across multiple providers with different requests 1509 * for each provider. 1510 * 1511 * <p>It may take some time to receive the first location update depending on the conditions the 1512 * device finds itself in. In order to take advantage of cached locations, application may 1513 * consider using {@link #getLastKnownLocation(String)} or {@link #getCurrentLocation(String, 1514 * LocationRequest, CancellationSignal, Executor, Consumer)} instead. 1515 * 1516 * <p>See {@link LocationRequest} documentation for an explanation of various request parameters 1517 * and how they can affect the received locations. 1518 * 1519 * <p>If your application wants to passively observe location updates from all providers, then 1520 * use the {@link #PASSIVE_PROVIDER}. This provider does not turn on or modify active location 1521 * providers, so you do not need to be as careful about minimum time and minimum distance 1522 * parameters. However, if your application performs heavy work on a location update (such as 1523 * network activity) then you should set an explicit fastest interval on your location request 1524 * in case another application enables a location provider with extremely fast updates. 1525 * 1526 * <p>In case the provider you have selected is disabled, location updates will cease, and a 1527 * provider availability update will be sent. As soon as the provider is enabled again, another 1528 * provider availability update will be sent and location updates will resume. 1529 * 1530 * <p>Locations returned from {@link #GPS_PROVIDER} are with respect to the primary GNSS antenna 1531 * position within the device. {@link #getGnssAntennaInfos()} may be used to determine the GNSS 1532 * antenna position with respect to the Android Coordinate System, and convert between them if 1533 * necessary. This is generally only necessary for high accuracy applications. 1534 * 1535 * <p>When location callbacks are invoked, the system will hold a wakelock on your 1536 * application's behalf for some period of time, but not indefinitely. If your application 1537 * requires a long running wakelock within the location callback, you should acquire it 1538 * yourself. 1539 * 1540 * <p>Spamming location requests is a drain on system resources, and the system has preventative 1541 * measures in place to ensure that this behavior will never result in more locations than could 1542 * be achieved with a single location request with an equivalent interval that is left in place 1543 * the whole time. As part of this amelioration, applications that target Android S and above 1544 * may receive cached or historical locations through their listener. These locations will never 1545 * be older than the interval of the location request. 1546 * 1547 * <p>To unregister for location updates, use {@link #removeUpdates(LocationListener)}. 1548 * 1549 * @param provider a provider listed by {@link #getAllProviders()} 1550 * @param locationRequest the location request containing location parameters 1551 * @param executor the executor handling listener callbacks 1552 * @param listener the listener to receive location updates 1553 * 1554 * @throws IllegalArgumentException if provider is null or doesn't exist 1555 * @throws IllegalArgumentException if locationRequest is null 1556 * @throws IllegalArgumentException if listener is null 1557 * @throws SecurityException if no suitable permission is present 1558 */ 1559 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, @NonNull LocationRequest locationRequest, @NonNull @CallbackExecutor Executor executor, @NonNull LocationListener listener)1560 public void requestLocationUpdates(@NonNull String provider, 1561 @NonNull LocationRequest locationRequest, 1562 @NonNull @CallbackExecutor Executor executor, 1563 @NonNull LocationListener listener) { 1564 Preconditions.checkArgument(provider != null, "invalid null provider"); 1565 Preconditions.checkArgument(locationRequest != null, "invalid null location request"); 1566 1567 try { 1568 synchronized (sLocationListeners) { 1569 WeakReference<LocationListenerTransport> reference = sLocationListeners.get( 1570 listener); 1571 LocationListenerTransport transport = reference != null ? reference.get() : null; 1572 if (transport == null) { 1573 transport = new LocationListenerTransport(listener, executor); 1574 } else { 1575 Preconditions.checkState(transport.isRegistered()); 1576 transport.setExecutor(executor); 1577 } 1578 1579 mService.registerLocationListener(provider, locationRequest, transport, 1580 mContext.getPackageName(), mContext.getAttributionTag(), 1581 AppOpsManager.toReceiverId(listener)); 1582 1583 sLocationListeners.put(listener, new WeakReference<>(transport)); 1584 } 1585 } catch (RemoteException e) { 1586 throw e.rethrowFromSystemServer(); 1587 } 1588 } 1589 1590 /** 1591 * Register for location updates from the specified provider, using a {@link LocationRequest}, 1592 * and callbacks delivered via the provided {@link PendingIntent}. 1593 * 1594 * <p>The delivered pending intents will contain extras with the callback information. The keys 1595 * used for the extras are {@link #KEY_LOCATION_CHANGED} and {@link #KEY_PROVIDER_ENABLED}. See 1596 * the documentation for each respective extra key for information on the values. 1597 * 1598 * <p>To unregister for location updates, use {@link #removeUpdates(PendingIntent)}. 1599 * 1600 * @param provider a provider listed by {@link #getAllProviders()} 1601 * @param locationRequest the location request containing location parameters 1602 * @param pendingIntent the pending intent to send location updates 1603 * 1604 * @throws IllegalArgumentException if provider is null or doesn't exist 1605 * @throws IllegalArgumentException if locationRequest is null 1606 * @throws IllegalArgumentException if pendingIntent is null 1607 * @throws SecurityException if no suitable permission is present 1608 */ 1609 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, @NonNull LocationRequest locationRequest, @NonNull PendingIntent pendingIntent)1610 public void requestLocationUpdates(@NonNull String provider, 1611 @NonNull LocationRequest locationRequest, 1612 @NonNull PendingIntent pendingIntent) { 1613 Preconditions.checkArgument(provider != null, "invalid null provider"); 1614 Preconditions.checkArgument(locationRequest != null, "invalid null location request"); 1615 Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); 1616 1617 if (Compatibility.isChangeEnabled(BLOCK_UNTARGETED_PENDING_INTENTS)) { 1618 Preconditions.checkArgument(pendingIntent.isTargetedToPackage(), 1619 "pending intent must be targeted to a package"); 1620 } 1621 1622 if (Compatibility.isChangeEnabled(BLOCK_IMMUTABLE_PENDING_INTENTS)) { 1623 Preconditions.checkArgument(!pendingIntent.isImmutable(), 1624 "pending intent must be mutable"); 1625 } 1626 1627 try { 1628 mService.registerLocationPendingIntent(provider, locationRequest, pendingIntent, 1629 mContext.getPackageName(), mContext.getAttributionTag()); 1630 } catch (RemoteException e) { 1631 throw e.rethrowFromSystemServer(); 1632 } 1633 } 1634 1635 /** 1636 * Set the last known location with a new location. 1637 * 1638 * <p>A privileged client can inject a {@link Location} if it has a better estimate of what 1639 * the recent location is. This is especially useful when the device boots up and the GPS 1640 * chipset is in the process of getting the first fix. If the client has cached the location, 1641 * it can inject the {@link Location}, so if an app requests for a {@link Location} from {@link 1642 * #getLastKnownLocation(String)}, the location information is still useful before getting 1643 * the first fix. 1644 * 1645 * @param location newly available {@link Location} object 1646 * @return true if the location was injected, false otherwise 1647 * 1648 * @throws IllegalArgumentException if location is null 1649 * @throws SecurityException if permissions are not present 1650 * 1651 * @hide 1652 */ 1653 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 1654 @RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION}) injectLocation(@onNull Location location)1655 public boolean injectLocation(@NonNull Location location) { 1656 Preconditions.checkArgument(location != null, "invalid null location"); 1657 Preconditions.checkArgument(location.isComplete(), 1658 "incomplete location object, missing timestamp or accuracy?"); 1659 1660 try { 1661 mService.injectLocation(location); 1662 return true; 1663 } catch (RemoteException e) { 1664 throw e.rethrowFromSystemServer(); 1665 } 1666 } 1667 1668 /** 1669 * Requests that the given provider flush any batched locations to listeners. The given listener 1670 * (registered with the provider) will have {@link LocationListener#onFlushComplete(int)} 1671 * invoked with the given result code after any locations that were flushed have been delivered. 1672 * If {@link #removeUpdates(LocationListener)} is invoked before the flush callback is executed, 1673 * then the flush callback will never be executed. 1674 * 1675 * @param provider a provider listed by {@link #getAllProviders()} 1676 * @param listener a listener registered under the provider 1677 * @param requestCode an arbitrary integer passed through to 1678 * {@link LocationListener#onFlushComplete(int)} 1679 * 1680 * @throws IllegalArgumentException if provider is null or doesn't exist 1681 * @throws IllegalArgumentException if listener is null or is not registered under the provider 1682 */ 1683 @SuppressLint("SamShouldBeLast") requestFlush(@onNull String provider, @NonNull LocationListener listener, @SuppressLint(R) int requestCode)1684 public void requestFlush(@NonNull String provider, @NonNull LocationListener listener, 1685 @SuppressLint("ListenerLast") int requestCode) { 1686 Preconditions.checkArgument(provider != null, "invalid null provider"); 1687 Preconditions.checkArgument(listener != null, "invalid null listener"); 1688 1689 synchronized (sLocationListeners) { 1690 WeakReference<LocationListenerTransport> ref = sLocationListeners.get(listener); 1691 LocationListenerTransport transport = ref != null ? ref.get() : null; 1692 1693 Preconditions.checkArgument(transport != null, 1694 "unregistered listener cannot be flushed"); 1695 1696 try { 1697 mService.requestListenerFlush(provider, transport, requestCode); 1698 } catch (RemoteException e) { 1699 throw e.rethrowFromSystemServer(); 1700 } 1701 } 1702 } 1703 1704 /** 1705 * Requests that the given provider flush any batched locations to listeners. The given 1706 * PendingIntent (registered with the provider) will be sent with {@link #KEY_FLUSH_COMPLETE} 1707 * present in the extra keys, and {@code requestCode} as the corresponding value. 1708 * 1709 * @param provider a provider listed by {@link #getAllProviders()} 1710 * @param pendingIntent a pendingIntent registered under the provider 1711 * @param requestCode an arbitrary integer that will be passed back as the extra value for 1712 * {@link #KEY_FLUSH_COMPLETE} 1713 * 1714 * @throws IllegalArgumentException if provider is null or doesn't exist 1715 * @throws IllegalArgumentException if pending intent is null or is not registered under the 1716 * provider 1717 */ requestFlush(@onNull String provider, @NonNull PendingIntent pendingIntent, int requestCode)1718 public void requestFlush(@NonNull String provider, @NonNull PendingIntent pendingIntent, 1719 int requestCode) { 1720 Preconditions.checkArgument(provider != null, "invalid null provider"); 1721 Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); 1722 1723 try { 1724 mService.requestPendingIntentFlush(provider, pendingIntent, requestCode); 1725 } catch (RemoteException e) { 1726 throw e.rethrowFromSystemServer(); 1727 } 1728 } 1729 1730 /** 1731 * Removes all location updates for the specified {@link LocationListener}. The given listener 1732 * is guaranteed not to receive any invocations that <b>happens-after</b> this method is 1733 * invoked. 1734 * 1735 * <p>If the given listener has any batched requests, this method will not flush any incomplete 1736 * location batches before stopping location updates. If you wish to flush any pending locations 1737 * before stopping, you must first call {@link #requestFlush(String, LocationListener, int)} and 1738 * then call this method once the flush is complete. If this method is invoked before the flush 1739 * is complete, you may not receive the flushed locations. 1740 * 1741 * @param listener listener that no longer needs location updates 1742 * 1743 * @throws IllegalArgumentException if listener is null 1744 */ removeUpdates(@onNull LocationListener listener)1745 public void removeUpdates(@NonNull LocationListener listener) { 1746 Preconditions.checkArgument(listener != null, "invalid null listener"); 1747 1748 try { 1749 synchronized (sLocationListeners) { 1750 WeakReference<LocationListenerTransport> ref = sLocationListeners.remove(listener); 1751 LocationListenerTransport transport = ref != null ? ref.get() : null; 1752 if (transport != null) { 1753 transport.unregister(); 1754 mService.unregisterLocationListener(transport); 1755 } 1756 } 1757 } catch (RemoteException e) { 1758 throw e.rethrowFromSystemServer(); 1759 } 1760 } 1761 1762 /** 1763 * Removes location updates for the specified {@link PendingIntent}. Following this call, the 1764 * PendingIntent will no longer receive location updates. 1765 * 1766 * <p>See {@link #removeUpdates(LocationListener)} for more detail on how this method works. 1767 * 1768 * @param pendingIntent pending intent that no longer needs location updates 1769 * 1770 * @throws IllegalArgumentException if pendingIntent is null 1771 */ removeUpdates(@onNull PendingIntent pendingIntent)1772 public void removeUpdates(@NonNull PendingIntent pendingIntent) { 1773 Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); 1774 1775 try { 1776 mService.unregisterLocationPendingIntent(pendingIntent); 1777 } catch (RemoteException e) { 1778 throw e.rethrowFromSystemServer(); 1779 } 1780 } 1781 1782 /** 1783 * Returns true if the given location provider exists on this device, irrespective of whether 1784 * it is currently enabled or not. 1785 * 1786 * @param provider a potential location provider 1787 * @return true if the location provider exists, false otherwise 1788 * 1789 * @throws IllegalArgumentException if provider is null 1790 */ hasProvider(@onNull String provider)1791 public boolean hasProvider(@NonNull String provider) { 1792 Preconditions.checkArgument(provider != null, "invalid null provider"); 1793 1794 try { 1795 return mService.hasProvider(provider); 1796 } catch (RemoteException e) { 1797 throw e.rethrowFromSystemServer(); 1798 } 1799 } 1800 1801 /** 1802 * Returns a list of the names of all available location providers. All providers are returned, 1803 * including those that are currently disabled. 1804 * 1805 * @return list of provider names 1806 */ getAllProviders()1807 public @NonNull List<String> getAllProviders() { 1808 try { 1809 return mService.getAllProviders(); 1810 } catch (RemoteException e) { 1811 throw e.rethrowFromSystemServer(); 1812 } 1813 } 1814 1815 /** 1816 * Returns a list of the names of available location providers. If {@code enabledOnly} is false, 1817 * this is functionally the same as {@link #getAllProviders()}. 1818 * 1819 * @param enabledOnly if true then only enabled providers are included 1820 * @return list of provider names 1821 */ getProviders(boolean enabledOnly)1822 public @NonNull List<String> getProviders(boolean enabledOnly) { 1823 try { 1824 return mService.getProviders(null, enabledOnly); 1825 } catch (RemoteException e) { 1826 throw e.rethrowFromSystemServer(); 1827 } 1828 } 1829 1830 /** 1831 * Returns a list of the names of available location providers that satisfy the given criteria. 1832 * 1833 * @param criteria the criteria that providers must match 1834 * @param enabledOnly if true then only enabled providers are included 1835 * @return list of provider names 1836 * 1837 * @throws IllegalArgumentException if criteria is null 1838 * 1839 * @deprecated Criteria based APIs are deprecated, prefer to select a provider explicitly. 1840 */ 1841 @Deprecated getProviders(@onNull Criteria criteria, boolean enabledOnly)1842 public @NonNull List<String> getProviders(@NonNull Criteria criteria, boolean enabledOnly) { 1843 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1844 1845 try { 1846 return mService.getProviders(criteria, enabledOnly); 1847 } catch (RemoteException e) { 1848 throw e.rethrowFromSystemServer(); 1849 } 1850 } 1851 1852 /** 1853 * Returns the name of the provider that best meets the given criteria. Only providers that are 1854 * permitted to be accessed by the caller will be returned. If several providers meet the 1855 * criteria, the one with the best accuracy is returned. If no provider meets the criteria, the 1856 * criteria are loosened in the following order: 1857 * 1858 * <ul> 1859 * <li> power requirement 1860 * <li> accuracy 1861 * <li> bearing 1862 * <li> speed 1863 * <li> altitude 1864 * </ul> 1865 * 1866 * <p> Note that the requirement on monetary cost is not removed in this process. 1867 * 1868 * @param criteria the criteria that need to be matched 1869 * @param enabledOnly if true then only enabled providers are included 1870 * @return name of the provider that best matches the criteria, or null if none match 1871 * 1872 * @throws IllegalArgumentException if criteria is null 1873 * 1874 * @deprecated Criteria based APIs are deprecated, prefer to select a provider explicitly. 1875 */ 1876 @Deprecated getBestProvider(@onNull Criteria criteria, boolean enabledOnly)1877 public @Nullable String getBestProvider(@NonNull Criteria criteria, boolean enabledOnly) { 1878 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1879 1880 try { 1881 return mService.getBestProvider(criteria, enabledOnly); 1882 } catch (RemoteException e) { 1883 throw e.rethrowFromSystemServer(); 1884 } 1885 } 1886 1887 /** 1888 * Returns the information about the location provider with the given name, or null if no 1889 * provider exists by that name. 1890 * 1891 * @param provider a provider listed by {@link #getAllProviders()} 1892 * @return location provider information, or null if provider does not exist 1893 * 1894 * @throws IllegalArgumentException if provider is null 1895 * 1896 * @deprecated This method has no way to indicate that a provider's properties are unknown, and 1897 * so may return incorrect results on rare occasions. Use {@link #getProviderProperties(String)} 1898 * instead. 1899 */ 1900 @Deprecated getProvider(@onNull String provider)1901 public @Nullable LocationProvider getProvider(@NonNull String provider) { 1902 Preconditions.checkArgument(provider != null, "invalid null provider"); 1903 1904 if (!Compatibility.isChangeEnabled(GET_PROVIDER_SECURITY_EXCEPTIONS)) { 1905 if (NETWORK_PROVIDER.equals(provider) || FUSED_PROVIDER.equals(provider)) { 1906 try { 1907 mContext.enforcePermission(ACCESS_FINE_LOCATION, Process.myPid(), 1908 Process.myUid(), null); 1909 } catch (SecurityException e) { 1910 mContext.enforcePermission(ACCESS_COARSE_LOCATION, Process.myPid(), 1911 Process.myUid(), null); 1912 } 1913 } else { 1914 mContext.enforcePermission(ACCESS_FINE_LOCATION, Process.myPid(), Process.myUid(), 1915 null); 1916 } 1917 } 1918 1919 try { 1920 ProviderProperties properties = mService.getProviderProperties(provider); 1921 return new LocationProvider(provider, properties); 1922 } catch (IllegalArgumentException e) { 1923 // provider does not exist 1924 return null; 1925 } catch (RemoteException e) { 1926 throw e.rethrowFromSystemServer(); 1927 } 1928 } 1929 1930 /** 1931 * Returns the properties of the given provider, or null if the properties are currently 1932 * unknown. Provider properties may change over time, although this is discouraged, and should 1933 * be rare. The most common transition is when provider properties go from being unknown to 1934 * known, which is most common near boot time. 1935 * 1936 * @param provider a provider listed by {@link #getAllProviders()} 1937 * @return location provider properties, or null if properties are currently unknown 1938 * 1939 * @throws IllegalArgumentException if provider is null or does not exist 1940 */ getProviderProperties(@onNull String provider)1941 public @Nullable ProviderProperties getProviderProperties(@NonNull String provider) { 1942 Preconditions.checkArgument(provider != null, "invalid null provider"); 1943 1944 try { 1945 return mService.getProviderProperties(provider); 1946 } catch (RemoteException e) { 1947 throw e.rethrowFromSystemServer(); 1948 } 1949 } 1950 1951 /** 1952 * Returns true if the given package name matches a location provider package, and false 1953 * otherwise. 1954 * 1955 * @hide 1956 * @deprecated Prefer {@link #isProviderPackage(String, String, String)} instead. 1957 */ 1958 @Deprecated 1959 @SystemApi 1960 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) isProviderPackage(@onNull String packageName)1961 public boolean isProviderPackage(@NonNull String packageName) { 1962 return isProviderPackage(null, packageName, null); 1963 } 1964 1965 /** 1966 * Returns true if the given provider corresponds to the given package name. If the given 1967 * provider is null, this will return true if any provider corresponds to the given package 1968 * name. 1969 * 1970 * @param provider a provider listed by {@link #getAllProviders()} or null 1971 * @param packageName the package name to test if it is a provider 1972 * @return true if the given arguments correspond to a provider 1973 * 1974 * @deprecated Use {@link #isProviderPackage(String, String, String)} instead. 1975 * 1976 * @hide 1977 * @removed 1978 */ 1979 @Deprecated 1980 @SystemApi 1981 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) isProviderPackage(@ullable String provider, @NonNull String packageName)1982 public boolean isProviderPackage(@Nullable String provider, @NonNull String packageName) { 1983 return isProviderPackage(provider, packageName, null); 1984 } 1985 1986 /** 1987 * Returns true if the given provider corresponds to the given package name. If the given 1988 * provider is null, this will return true if any provider corresponds to the given package 1989 * name and/or attribution tag. If attribution tag is non-null, the provider identity must match 1990 * both the given package name and attribution tag. 1991 * 1992 * @param provider a provider listed by {@link #getAllProviders()} or null 1993 * @param packageName the package name to test if it is a provider 1994 * @param attributionTag an optional attribution tag within the given package 1995 * @return true if the given arguments correspond to a provider 1996 * @hide 1997 */ 1998 @SystemApi 1999 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) isProviderPackage(@ullable String provider, @NonNull String packageName, @Nullable String attributionTag)2000 public boolean isProviderPackage(@Nullable String provider, @NonNull String packageName, 2001 @Nullable String attributionTag) { 2002 try { 2003 return mService.isProviderPackage(provider, Objects.requireNonNull(packageName), 2004 attributionTag); 2005 } catch (RemoteException e) { 2006 throw e.rethrowFromSystemServer(); 2007 } 2008 } 2009 2010 /** 2011 * Returns a list of packages associated with the given provider, 2012 * and an empty list if no package is associated with the provider. 2013 * 2014 * @hide 2015 * @deprecated Prefer {@link #isProviderPackage(String, String, String)} instead. 2016 */ 2017 @TestApi 2018 @Deprecated 2019 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) 2020 @Nullable 2021 @SuppressWarnings("NullableCollection") getProviderPackages(@onNull String provider)2022 public List<String> getProviderPackages(@NonNull String provider) { 2023 try { 2024 return mService.getProviderPackages(provider); 2025 } catch (RemoteException e) { 2026 throw e.rethrowFromSystemServer(); 2027 } 2028 } 2029 2030 /** 2031 * Sends additional commands to a location provider. Can be used to support provider specific 2032 * extensions to the Location Manager API. 2033 * 2034 * @param provider a provider listed by {@link #getAllProviders()} 2035 * @param command name of the command to send to the provider 2036 * @param extras optional arguments for the command, or null 2037 * @return true always, the return value may be ignored 2038 */ sendExtraCommand( @onNull String provider, @NonNull String command, @Nullable Bundle extras)2039 public boolean sendExtraCommand( 2040 @NonNull String provider, @NonNull String command, @Nullable Bundle extras) { 2041 Preconditions.checkArgument(provider != null, "invalid null provider"); 2042 Preconditions.checkArgument(command != null, "invalid null command"); 2043 2044 try { 2045 mService.sendExtraCommand(provider, command, extras); 2046 return true; 2047 } catch (RemoteException e) { 2048 throw e.rethrowFromSystemServer(); 2049 } 2050 } 2051 2052 /** 2053 * Creates a test location provider and adds it to the set of active providers. This provider 2054 * will replace any provider with the same name that exists prior to this call. 2055 * 2056 * @param provider the provider name 2057 * 2058 * @throws IllegalArgumentException if provider is null 2059 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2060 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2061 * allowed} for your app. 2062 */ addTestProvider( @onNull String provider, boolean requiresNetwork, boolean requiresSatellite, boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, boolean supportsSpeed, boolean supportsBearing, @ProviderProperties.PowerUsage int powerUsage, @ProviderProperties.Accuracy int accuracy)2063 public void addTestProvider( 2064 @NonNull String provider, boolean requiresNetwork, boolean requiresSatellite, 2065 boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, 2066 boolean supportsSpeed, boolean supportsBearing, 2067 @ProviderProperties.PowerUsage int powerUsage, 2068 @ProviderProperties.Accuracy int accuracy) { 2069 addTestProvider(provider, new ProviderProperties.Builder() 2070 .setHasNetworkRequirement(requiresNetwork) 2071 .setHasSatelliteRequirement(requiresSatellite) 2072 .setHasCellRequirement(requiresCell) 2073 .setHasMonetaryCost(hasMonetaryCost) 2074 .setHasAltitudeSupport(supportsAltitude) 2075 .setHasSpeedSupport(supportsSpeed) 2076 .setHasBearingSupport(supportsBearing) 2077 .setPowerUsage(powerUsage) 2078 .setAccuracy(accuracy) 2079 .build()); 2080 } 2081 2082 /** 2083 * Creates a test location provider and adds it to the set of active providers. This provider 2084 * will replace any provider with the same name that exists prior to this call. 2085 * 2086 * @param provider the provider name 2087 * 2088 * @throws IllegalArgumentException if provider is null 2089 * @throws IllegalArgumentException if properties is null 2090 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2091 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2092 * allowed} for your app. 2093 */ addTestProvider(@onNull String provider, @NonNull ProviderProperties properties)2094 public void addTestProvider(@NonNull String provider, @NonNull ProviderProperties properties) { 2095 addTestProvider(provider, properties, Collections.emptySet()); 2096 } 2097 2098 /** 2099 * Creates a test location provider and adds it to the set of active providers. This provider 2100 * will replace any provider with the same name that exists prior to this call. 2101 * 2102 * @param provider the provider name 2103 * @param properties the provider properties 2104 * @param extraAttributionTags additional attribution tags associated with this provider 2105 * 2106 * @throws IllegalArgumentException if provider is null 2107 * @throws IllegalArgumentException if properties is null 2108 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2109 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2110 * allowed} for your app. 2111 */ addTestProvider(@onNull String provider, @NonNull ProviderProperties properties, @NonNull Set<String> extraAttributionTags)2112 public void addTestProvider(@NonNull String provider, @NonNull ProviderProperties properties, 2113 @NonNull Set<String> extraAttributionTags) { 2114 Preconditions.checkArgument(provider != null, "invalid null provider"); 2115 Preconditions.checkArgument(properties != null, "invalid null properties"); 2116 Preconditions.checkArgument(extraAttributionTags != null, 2117 "invalid null extra attribution tags"); 2118 2119 try { 2120 mService.addTestProvider(provider, properties, new ArrayList<>(extraAttributionTags), 2121 mContext.getOpPackageName(), mContext.getAttributionTag()); 2122 } catch (RemoteException e) { 2123 throw e.rethrowFromSystemServer(); 2124 } 2125 } 2126 2127 /** 2128 * Removes the test location provider with the given name or does nothing if no such test 2129 * location provider exists. 2130 * 2131 * @param provider the provider name 2132 * 2133 * @throws IllegalArgumentException if provider is null 2134 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2135 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2136 * allowed} for your app. 2137 */ removeTestProvider(@onNull String provider)2138 public void removeTestProvider(@NonNull String provider) { 2139 Preconditions.checkArgument(provider != null, "invalid null provider"); 2140 2141 try { 2142 mService.removeTestProvider(provider, mContext.getOpPackageName(), 2143 mContext.getAttributionTag()); 2144 } catch (RemoteException e) { 2145 throw e.rethrowFromSystemServer(); 2146 } 2147 } 2148 2149 /** 2150 * Sets a new location for the given test provider. This location will be identiable as a mock 2151 * location to all clients via {@link Location#isMock()}. 2152 * 2153 * <p>The location object must have a minimum number of fields set to be considered valid, as 2154 * per documentation on {@link Location} class. 2155 * 2156 * @param provider the provider name 2157 * @param location the mock location 2158 * 2159 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2160 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2161 * allowed} for your app. 2162 * @throws IllegalArgumentException if the provider is null or not a test provider 2163 * @throws IllegalArgumentException if the location is null or incomplete 2164 */ setTestProviderLocation(@onNull String provider, @NonNull Location location)2165 public void setTestProviderLocation(@NonNull String provider, @NonNull Location location) { 2166 Preconditions.checkArgument(provider != null, "invalid null provider"); 2167 Preconditions.checkArgument(location != null, "invalid null location"); 2168 2169 if (Compatibility.isChangeEnabled(BLOCK_INCOMPLETE_LOCATIONS)) { 2170 Preconditions.checkArgument(location.isComplete(), 2171 "incomplete location object, missing timestamp or accuracy?"); 2172 } else { 2173 location.makeComplete(); 2174 } 2175 2176 try { 2177 mService.setTestProviderLocation(provider, location, mContext.getOpPackageName(), 2178 mContext.getAttributionTag()); 2179 } catch (RemoteException e) { 2180 throw e.rethrowFromSystemServer(); 2181 } 2182 } 2183 2184 /** 2185 * Does nothing. 2186 * 2187 * @deprecated This method has always been a no-op, and may be removed in the future. 2188 */ 2189 @Deprecated clearTestProviderLocation(@onNull String provider)2190 public void clearTestProviderLocation(@NonNull String provider) {} 2191 2192 /** 2193 * Sets the given test provider to be enabled or disabled. 2194 * 2195 * @param provider the provider name 2196 * @param enabled the mock enabled value 2197 * 2198 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2199 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2200 * allowed} for your app. 2201 * @throws IllegalArgumentException if provider is null or not a test provider 2202 */ setTestProviderEnabled(@onNull String provider, boolean enabled)2203 public void setTestProviderEnabled(@NonNull String provider, boolean enabled) { 2204 Preconditions.checkArgument(provider != null, "invalid null provider"); 2205 2206 try { 2207 mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName(), 2208 mContext.getAttributionTag()); 2209 } catch (RemoteException e) { 2210 throw e.rethrowFromSystemServer(); 2211 } 2212 } 2213 2214 /** 2215 * Equivalent to calling {@link #setTestProviderEnabled(String, boolean)} to disable a test 2216 * provider. 2217 * 2218 * @deprecated Use {@link #setTestProviderEnabled(String, boolean)} instead. 2219 */ 2220 @Deprecated clearTestProviderEnabled(@onNull String provider)2221 public void clearTestProviderEnabled(@NonNull String provider) { 2222 setTestProviderEnabled(provider, false); 2223 } 2224 2225 /** 2226 * This method has no effect as provider status has been deprecated and is no longer supported. 2227 * 2228 * @deprecated This method has no effect. 2229 */ 2230 @Deprecated setTestProviderStatus( @onNull String provider, int status, @Nullable Bundle extras, long updateTime)2231 public void setTestProviderStatus( 2232 @NonNull String provider, int status, @Nullable Bundle extras, long updateTime) {} 2233 2234 /** 2235 * This method has no effect as provider status has been deprecated and is no longer supported. 2236 * 2237 * @deprecated This method has no effect. 2238 */ 2239 @Deprecated clearTestProviderStatus(@onNull String provider)2240 public void clearTestProviderStatus(@NonNull String provider) {} 2241 2242 /** 2243 * Sets a proximity alert for the location given by the position (latitude, longitude) and the 2244 * given radius. 2245 * 2246 * <p>When the device detects that it has entered or exited the area surrounding the location, 2247 * the given PendingIntent will be fired. 2248 * 2249 * <p>The fired intent will have a boolean extra added with key {@link #KEY_PROXIMITY_ENTERING}. 2250 * If the value is true, the device is entering the proximity region; if false, it is exiting. 2251 * 2252 * <p>Due to the approximate nature of position estimation, if the device passes through the 2253 * given area briefly, it is possible that no Intent will be fired. Similarly, an intent could 2254 * be fired if the device passes very close to the given area but does not actually enter it. 2255 * 2256 * <p>Before API version 17, this method could be used with 2257 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or 2258 * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. From API version 17 and onwards, 2259 * this method requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. 2260 * 2261 * @param latitude the latitude of the central point of the alert region 2262 * @param longitude the longitude of the central point of the alert region 2263 * @param radius the radius of the central point of the alert region in meters 2264 * @param expiration expiration realtime for this proximity alert in milliseconds, or -1 to 2265 * indicate no expiration 2266 * @param pendingIntent a {@link PendingIntent} that will sent when entry to or exit from the 2267 * alert region is detected 2268 * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} 2269 * permission is not present 2270 */ 2271 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) addProximityAlert(double latitude, double longitude, float radius, long expiration, @NonNull PendingIntent pendingIntent)2272 public void addProximityAlert(double latitude, double longitude, float radius, long expiration, 2273 @NonNull PendingIntent pendingIntent) { 2274 Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); 2275 2276 if (Compatibility.isChangeEnabled(BLOCK_UNTARGETED_PENDING_INTENTS)) { 2277 Preconditions.checkArgument(pendingIntent.isTargetedToPackage(), 2278 "pending intent must be targeted to a package"); 2279 } 2280 2281 if (Compatibility.isChangeEnabled(BLOCK_IMMUTABLE_PENDING_INTENTS)) { 2282 Preconditions.checkArgument(!pendingIntent.isImmutable(), 2283 "pending intent must be mutable"); 2284 } 2285 2286 if (expiration < 0) { 2287 expiration = Long.MAX_VALUE; 2288 } 2289 2290 try { 2291 Geofence fence = Geofence.createCircle(latitude, longitude, radius, expiration); 2292 mService.requestGeofence(fence, pendingIntent, mContext.getPackageName(), 2293 mContext.getAttributionTag()); 2294 } catch (RemoteException e) { 2295 throw e.rethrowFromSystemServer(); 2296 } 2297 } 2298 2299 /** 2300 * Removes the proximity alert with the given PendingIntent. 2301 * 2302 * <p>Before API version 17, this method could be used with 2303 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or 2304 * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. 2305 * From API version 17 and onwards, this method requires 2306 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. 2307 * 2308 * @param intent the PendingIntent that no longer needs to be notified of 2309 * proximity alerts 2310 * 2311 * @throws IllegalArgumentException if intent is null 2312 * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} 2313 * permission is not present 2314 */ removeProximityAlert(@onNull PendingIntent intent)2315 public void removeProximityAlert(@NonNull PendingIntent intent) { 2316 Preconditions.checkArgument(intent != null, "invalid null pending intent"); 2317 2318 try { 2319 mService.removeGeofence(intent); 2320 } catch (RemoteException e) { 2321 throw e.rethrowFromSystemServer(); 2322 } 2323 } 2324 2325 // ================= GNSS APIs ================= 2326 2327 /** 2328 * Returns the supported capabilities of the GNSS chipset. 2329 */ getGnssCapabilities()2330 public @NonNull GnssCapabilities getGnssCapabilities() { 2331 try { 2332 return mService.getGnssCapabilities(); 2333 } catch (RemoteException e) { 2334 throw e.rethrowFromSystemServer(); 2335 } 2336 } 2337 2338 /** 2339 * Returns the model year of the GNSS hardware and software build, or 0 if the model year 2340 * is before 2016. 2341 */ getGnssYearOfHardware()2342 public int getGnssYearOfHardware() { 2343 try { 2344 return mService.getGnssYearOfHardware(); 2345 } catch (RemoteException e) { 2346 throw e.rethrowFromSystemServer(); 2347 } 2348 } 2349 2350 /** 2351 * Returns the model name (including vendor and hardware/software version) of the GNSS hardware 2352 * driver, or null if this information is not available. 2353 * 2354 * <p>No device-specific serial number or ID is returned from this API. 2355 */ 2356 @Nullable getGnssHardwareModelName()2357 public String getGnssHardwareModelName() { 2358 try { 2359 return mService.getGnssHardwareModelName(); 2360 } catch (RemoteException e) { 2361 throw e.rethrowFromSystemServer(); 2362 } 2363 } 2364 2365 /** 2366 * Returns the current list of GNSS antenna infos, or null if unknown or unsupported. 2367 * 2368 * @see #getGnssCapabilities() 2369 */ 2370 @Nullable 2371 @SuppressLint("NullableCollection") getGnssAntennaInfos()2372 public List<GnssAntennaInfo> getGnssAntennaInfos() { 2373 try { 2374 return mService.getGnssAntennaInfos(); 2375 } catch (RemoteException e) { 2376 throw e.rethrowFromSystemServer(); 2377 } 2378 } 2379 2380 /** 2381 * Retrieves information about the current status of the GPS engine. This should only be called 2382 * from within the {@link GpsStatus.Listener#onGpsStatusChanged} callback to ensure that the 2383 * data is copied atomically. 2384 * 2385 * The caller may either pass in an existing {@link GpsStatus} object to be overwritten, or pass 2386 * null to create a new {@link GpsStatus} object. 2387 * 2388 * @param status object containing GPS status details, or null. 2389 * @return status object containing updated GPS status. 2390 * 2391 * @deprecated GpsStatus APIs are deprecated, use {@link GnssStatus} APIs instead. No longer 2392 * supported in apps targeting S and above. 2393 */ 2394 @Deprecated 2395 @RequiresPermission(ACCESS_FINE_LOCATION) getGpsStatus(@ullable GpsStatus status)2396 public @Nullable GpsStatus getGpsStatus(@Nullable GpsStatus status) { 2397 if (Compatibility.isChangeEnabled(BLOCK_GPS_STATUS_USAGE)) { 2398 throw new UnsupportedOperationException( 2399 "GpsStatus APIs not supported, please use GnssStatus APIs instead"); 2400 } 2401 2402 GnssStatus gnssStatus = GpsStatusTransport.sGnssStatus; 2403 int ttff = GpsStatusTransport.sTtff; 2404 if (gnssStatus != null) { 2405 if (status == null) { 2406 status = GpsStatus.create(gnssStatus, ttff); 2407 } else { 2408 status.setStatus(gnssStatus, ttff); 2409 } 2410 } else if (status == null) { 2411 // even though this method is marked as nullable, legacy behavior was to never return 2412 // a null result, and there are applications that rely on this behavior. 2413 status = GpsStatus.createEmpty(); 2414 } 2415 return status; 2416 } 2417 2418 /** 2419 * Adds a GPS status listener. 2420 * 2421 * @param listener GPS status listener object to register 2422 * @return true if the listener was successfully added 2423 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2424 * 2425 * @deprecated Use {@link #registerGnssStatusCallback(GnssStatus.Callback, Handler)} or {@link 2426 * #registerGnssStatusCallback(Executor, GnssStatus.Callback)} instead. 2427 */ 2428 @Deprecated 2429 @RequiresPermission(ACCESS_FINE_LOCATION) addGpsStatusListener(GpsStatus.Listener listener)2430 public boolean addGpsStatusListener(GpsStatus.Listener listener) { 2431 if (Compatibility.isChangeEnabled(BLOCK_GPS_STATUS_USAGE)) { 2432 throw new UnsupportedOperationException( 2433 "GpsStatus APIs not supported, please use GnssStatus APIs instead"); 2434 } 2435 2436 GnssLazyLoader.sGnssStatusListeners.addListener(listener, 2437 new GpsStatusTransport(new HandlerExecutor(new Handler()), mContext, listener)); 2438 return true; 2439 } 2440 2441 /** 2442 * Removes a GPS status listener. 2443 * 2444 * @param listener GPS status listener object to remove 2445 * 2446 * @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead. No longer 2447 * supported in apps targeting S and above. 2448 */ 2449 @Deprecated removeGpsStatusListener(GpsStatus.Listener listener)2450 public void removeGpsStatusListener(GpsStatus.Listener listener) { 2451 if (Compatibility.isChangeEnabled(BLOCK_GPS_STATUS_USAGE)) { 2452 throw new UnsupportedOperationException( 2453 "GpsStatus APIs not supported, please use GnssStatus APIs instead"); 2454 } 2455 2456 GnssLazyLoader.sGnssStatusListeners.removeListener(listener); 2457 } 2458 2459 /** 2460 * Registers a GNSS status callback. This method must be called from a {@link Looper} thread, 2461 * and callbacks will occur on that looper. 2462 * 2463 * <p>See {@link #registerGnssStatusCallback(Executor, GnssStatus.Callback)} for more detail on 2464 * how this method works. 2465 * 2466 * @param callback the callback to register 2467 * @return {@code true} always 2468 * 2469 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2470 * 2471 * @deprecated Use {@link #registerGnssStatusCallback(GnssStatus.Callback, Handler)} or {@link 2472 * #registerGnssStatusCallback(Executor, GnssStatus.Callback)} instead. 2473 */ 2474 @Deprecated 2475 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssStatusCallback(@onNull GnssStatus.Callback callback)2476 public boolean registerGnssStatusCallback(@NonNull GnssStatus.Callback callback) { 2477 return registerGnssStatusCallback(callback, null); 2478 } 2479 2480 /** 2481 * Registers a GNSS status callback. 2482 * 2483 * <p>See {@link #registerGnssStatusCallback(Executor, GnssStatus.Callback)} for more detail on 2484 * how this method works. 2485 * 2486 * @param callback the callback to register 2487 * @param handler the handler the callback runs on 2488 * @return {@code true} always 2489 * 2490 * @throws IllegalArgumentException if callback is null 2491 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2492 */ 2493 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssStatusCallback( @onNull GnssStatus.Callback callback, @Nullable Handler handler)2494 public boolean registerGnssStatusCallback( 2495 @NonNull GnssStatus.Callback callback, @Nullable Handler handler) { 2496 if (handler == null) { 2497 handler = new Handler(); 2498 } 2499 2500 return registerGnssStatusCallback(new HandlerExecutor(handler), callback); 2501 } 2502 2503 /** 2504 * Registers a GNSS status callback. GNSS status information will only be received while the 2505 * {@link #GPS_PROVIDER} is enabled, and while the client app is in the foreground. 2506 * 2507 * @param executor the executor that the callback runs on 2508 * @param callback the callback to register 2509 * @return {@code true} always 2510 * 2511 * @throws IllegalArgumentException if executor is null 2512 * @throws IllegalArgumentException if callback is null 2513 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2514 */ 2515 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssStatusCallback( @onNull @allbackExecutor Executor executor, @NonNull GnssStatus.Callback callback)2516 public boolean registerGnssStatusCallback( 2517 @NonNull @CallbackExecutor Executor executor, 2518 @NonNull GnssStatus.Callback callback) { 2519 GnssLazyLoader.sGnssStatusListeners.addListener(callback, 2520 new GnssStatusTransport(executor, mContext, callback)); 2521 return true; 2522 } 2523 2524 /** 2525 * Removes a GNSS status callback. 2526 * 2527 * @param callback GNSS status callback object to remove 2528 */ unregisterGnssStatusCallback(@onNull GnssStatus.Callback callback)2529 public void unregisterGnssStatusCallback(@NonNull GnssStatus.Callback callback) { 2530 GnssLazyLoader.sGnssStatusListeners.removeListener(callback); 2531 } 2532 2533 /** 2534 * No-op method to keep backward-compatibility. 2535 * 2536 * @deprecated Use {@link #addNmeaListener(OnNmeaMessageListener, Handler)} or {@link 2537 * #addNmeaListener(Executor, OnNmeaMessageListener)} instead. 2538 */ 2539 @Deprecated 2540 @RequiresPermission(ACCESS_FINE_LOCATION) addNmeaListener(@onNull GpsStatus.NmeaListener listener)2541 public boolean addNmeaListener(@NonNull GpsStatus.NmeaListener listener) { 2542 return false; 2543 } 2544 2545 /** 2546 * No-op method to keep backward-compatibility. 2547 * 2548 * @deprecated Use {@link #removeNmeaListener(OnNmeaMessageListener)} instead. 2549 */ 2550 @Deprecated removeNmeaListener(@onNull GpsStatus.NmeaListener listener)2551 public void removeNmeaListener(@NonNull GpsStatus.NmeaListener listener) {} 2552 2553 /** 2554 * Adds an NMEA listener. 2555 * 2556 * <p>See {@link #addNmeaListener(Executor, OnNmeaMessageListener)} for more detail on how this 2557 * method works. 2558 * 2559 * @param listener the listener to register 2560 * @return {@code true} always 2561 * 2562 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2563 * @deprecated Use {@link #addNmeaListener(OnNmeaMessageListener, Handler)} or {@link 2564 * #addNmeaListener(Executor, OnNmeaMessageListener)} instead. 2565 */ 2566 @Deprecated 2567 @RequiresPermission(ACCESS_FINE_LOCATION) addNmeaListener(@onNull OnNmeaMessageListener listener)2568 public boolean addNmeaListener(@NonNull OnNmeaMessageListener listener) { 2569 return addNmeaListener(listener, null); 2570 } 2571 2572 /** 2573 * Adds an NMEA listener. 2574 * 2575 * <p>See {@link #addNmeaListener(Executor, OnNmeaMessageListener)} for more detail on how this 2576 * method works. 2577 * 2578 * @param listener the listener to register 2579 * @param handler the handler that the listener runs on 2580 * @return {@code true} always 2581 * 2582 * @throws IllegalArgumentException if listener is null 2583 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2584 */ 2585 @RequiresPermission(ACCESS_FINE_LOCATION) addNmeaListener( @onNull OnNmeaMessageListener listener, @Nullable Handler handler)2586 public boolean addNmeaListener( 2587 @NonNull OnNmeaMessageListener listener, @Nullable Handler handler) { 2588 if (handler == null) { 2589 handler = new Handler(); 2590 } 2591 2592 return addNmeaListener(new HandlerExecutor(handler), listener); 2593 } 2594 2595 /** 2596 * Adds an NMEA listener. GNSS NMEA information will only be received while the 2597 * {@link #GPS_PROVIDER} is enabled, and while the client app is in the foreground. 2598 * 2599 * @param listener the listener to register 2600 * @param executor the executor that the listener runs on 2601 * @return {@code true} always 2602 * 2603 * @throws IllegalArgumentException if executor is null 2604 * @throws IllegalArgumentException if listener is null 2605 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2606 */ 2607 @RequiresPermission(ACCESS_FINE_LOCATION) addNmeaListener( @onNull @allbackExecutor Executor executor, @NonNull OnNmeaMessageListener listener)2608 public boolean addNmeaListener( 2609 @NonNull @CallbackExecutor Executor executor, 2610 @NonNull OnNmeaMessageListener listener) { 2611 GnssLazyLoader.sGnssNmeaListeners.addListener(listener, 2612 new GnssNmeaTransport(executor, mContext, listener)); 2613 return true; 2614 } 2615 2616 /** 2617 * Removes an NMEA listener. 2618 * 2619 * @param listener a {@link OnNmeaMessageListener} object to remove 2620 */ removeNmeaListener(@onNull OnNmeaMessageListener listener)2621 public void removeNmeaListener(@NonNull OnNmeaMessageListener listener) { 2622 GnssLazyLoader.sGnssNmeaListeners.removeListener(listener); 2623 } 2624 2625 /** 2626 * No-op method to keep backward-compatibility. 2627 * 2628 * @hide 2629 * @deprecated Use {@link #registerGnssMeasurementsCallback} instead. 2630 * @removed 2631 */ 2632 @Deprecated 2633 @SystemApi addGpsMeasurementListener(GpsMeasurementsEvent.Listener listener)2634 public boolean addGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) { 2635 return false; 2636 } 2637 2638 /** 2639 * No-op method to keep backward-compatibility. 2640 * 2641 * @hide 2642 * @deprecated Use {@link #unregisterGnssMeasurementsCallback} instead. 2643 * @removed 2644 */ 2645 @Deprecated 2646 @SystemApi removeGpsMeasurementListener(GpsMeasurementsEvent.Listener listener)2647 public void removeGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) {} 2648 2649 /** 2650 * Registers a GNSS measurements callback which will run on a binder thread. 2651 * 2652 * <p>See {@link #registerGnssMeasurementsCallback(Executor, GnssMeasurementsEvent.Callback) 2653 * for more detail on how this method works. 2654 * 2655 * @param callback a {@link GnssMeasurementsEvent.Callback} object to register 2656 * @return {@code true} always 2657 * 2658 * @deprecated Use {@link 2659 * #registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback, Handler)} or {@link 2660 * #registerGnssMeasurementsCallback(Executor, GnssMeasurementsEvent.Callback)} instead. 2661 */ 2662 @Deprecated 2663 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull GnssMeasurementsEvent.Callback callback)2664 public boolean registerGnssMeasurementsCallback( 2665 @NonNull GnssMeasurementsEvent.Callback callback) { 2666 return registerGnssMeasurementsCallback(DIRECT_EXECUTOR, callback); 2667 } 2668 2669 /** 2670 * Registers a GNSS measurements callback. 2671 * 2672 * <p>See {@link #registerGnssMeasurementsCallback(Executor, GnssMeasurementsEvent.Callback) 2673 * for more detail on how this method works. 2674 * 2675 * @param callback a {@link GnssMeasurementsEvent.Callback} object to register 2676 * @param handler the handler that the callback runs on 2677 * @return {@code true} always 2678 * 2679 * @throws IllegalArgumentException if callback is null 2680 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2681 */ 2682 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull GnssMeasurementsEvent.Callback callback, @Nullable Handler handler)2683 public boolean registerGnssMeasurementsCallback( 2684 @NonNull GnssMeasurementsEvent.Callback callback, @Nullable Handler handler) { 2685 if (handler == null) { 2686 handler = new Handler(); 2687 } 2688 2689 return registerGnssMeasurementsCallback(new GnssMeasurementRequest.Builder().build(), 2690 new HandlerExecutor(handler), callback); 2691 } 2692 2693 /** 2694 * Registers a GNSS measurements callback. GNSS measurements information will only be received 2695 * while the {@link #GPS_PROVIDER} is enabled, and while the client app is in the foreground. 2696 * 2697 * <p>Not all GNSS chipsets support measurements updates, see {@link #getGnssCapabilities()}. 2698 * 2699 * <p class="caution">On Android R devices that have not yet upgraded to Android R QPR1, using 2700 * this API will cause unavoidable crashes in the client application when GNSS measurements 2701 * are received. If a client needs to receive GNSS measurements on Android R devices that have 2702 * not been upgraded to QPR1, clients are instead encouraged to use 2703 * <a href="https://developer.android.com/reference/androidx/core/location/LocationManagerCompat#registerGnssMeasurementsCallback(android.location.LocationManager,java.util.concurrent.Executor,android.location.GnssMeasurementsEvent.Callback)">LocationManagerCompat.registerGnssMeasurementsCallback()</a> 2704 * from the compat libraries instead to avoid this crash. 2705 * 2706 * @param executor the executor that the callback runs on 2707 * @param callback the callback to register 2708 * @return {@code true} always 2709 * 2710 * @throws IllegalArgumentException if executor is null 2711 * @throws IllegalArgumentException if callback is null 2712 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2713 */ 2714 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull @allbackExecutor Executor executor, @NonNull GnssMeasurementsEvent.Callback callback)2715 public boolean registerGnssMeasurementsCallback( 2716 @NonNull @CallbackExecutor Executor executor, 2717 @NonNull GnssMeasurementsEvent.Callback callback) { 2718 return registerGnssMeasurementsCallback(new GnssMeasurementRequest.Builder().build(), 2719 executor, callback); 2720 } 2721 2722 /** 2723 * Registers a GNSS Measurement callback. 2724 * 2725 * @param request the gnss measurement request containgin measurement parameters 2726 * @param executor the executor that the callback runs on 2727 * @param callback the callack to register 2728 * @return {@code true} always 2729 * 2730 * @throws IllegalArgumentException if request is null 2731 * @throws IllegalArgumentException if executor is null 2732 * @throws IllegalArgumentException if callback is null 2733 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2734 * @hide 2735 * @deprecated Use {@link #registerGnssMeasurementsCallback(GnssMeasurementRequest, Executor, 2736 * GnssMeasurementsEvent.Callback)} instead. 2737 */ 2738 @Deprecated 2739 @SystemApi 2740 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull GnssRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull GnssMeasurementsEvent.Callback callback)2741 public boolean registerGnssMeasurementsCallback( 2742 @NonNull GnssRequest request, 2743 @NonNull @CallbackExecutor Executor executor, 2744 @NonNull GnssMeasurementsEvent.Callback callback) { 2745 return registerGnssMeasurementsCallback(request.toGnssMeasurementRequest(), executor, 2746 callback); 2747 } 2748 2749 /** 2750 * Registers a GNSS measurement callback. 2751 * 2752 * @param request extra parameters to pass to GNSS measurement provider. For example, if {@link 2753 * GnssMeasurementRequest#isFullTracking()} is true, GNSS chipset switches off 2754 * duty cycling. 2755 * @param executor the executor that the callback runs on 2756 * @param callback a {@link GnssMeasurementsEvent.Callback} object to register. 2757 * @return {@code true} always if the callback was added successfully, {@code false} otherwise. 2758 * @throws IllegalArgumentException if request is null 2759 * @throws IllegalArgumentException if executor is null 2760 * @throws IllegalArgumentException if callback is null 2761 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2762 */ 2763 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull GnssMeasurementRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull GnssMeasurementsEvent.Callback callback)2764 public boolean registerGnssMeasurementsCallback( 2765 @NonNull GnssMeasurementRequest request, 2766 @NonNull @CallbackExecutor Executor executor, 2767 @NonNull GnssMeasurementsEvent.Callback callback) { 2768 GnssLazyLoader.sGnssMeasurementsListeners.addListener(callback, 2769 new GnssMeasurementsTransport(executor, mContext, request, callback)); 2770 return true; 2771 } 2772 2773 /** 2774 * Injects GNSS measurement corrections into the GNSS chipset. 2775 * 2776 * @param measurementCorrections measurement corrections to be injected into the chipset 2777 * 2778 * @throws IllegalArgumentException if measurementCorrections is null 2779 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2780 * @hide 2781 */ 2782 @SystemApi 2783 @RequiresPermission(ACCESS_FINE_LOCATION) injectGnssMeasurementCorrections( @onNull GnssMeasurementCorrections measurementCorrections)2784 public void injectGnssMeasurementCorrections( 2785 @NonNull GnssMeasurementCorrections measurementCorrections) { 2786 Preconditions.checkArgument(measurementCorrections != null); 2787 try { 2788 mService.injectGnssMeasurementCorrections(measurementCorrections); 2789 } catch (RemoteException e) { 2790 throw e.rethrowFromSystemServer(); 2791 } 2792 } 2793 2794 /** 2795 * Unregisters a GPS Measurement callback. 2796 * 2797 * @param callback a {@link GnssMeasurementsEvent.Callback} object to remove. 2798 */ unregisterGnssMeasurementsCallback( @onNull GnssMeasurementsEvent.Callback callback)2799 public void unregisterGnssMeasurementsCallback( 2800 @NonNull GnssMeasurementsEvent.Callback callback) { 2801 GnssLazyLoader.sGnssMeasurementsListeners.removeListener(callback); 2802 } 2803 2804 /** 2805 * Registers a GNSS antenna info listener that will receive all changes to antenna info. Use 2806 * {@link #getGnssAntennaInfos()} to get current antenna info. 2807 * 2808 * <p>Not all GNSS chipsets support antenna info updates, see {@link #getGnssCapabilities()}. If 2809 * unsupported, the listener will never be invoked. 2810 * 2811 * <p>Prior to Android S, this requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} 2812 * permission. 2813 * 2814 * @param executor the executor that the listener runs on 2815 * @param listener the listener to register 2816 * @return {@code true} always 2817 * 2818 * @throws IllegalArgumentException if executor is null 2819 * @throws IllegalArgumentException if listener is null 2820 */ registerAntennaInfoListener( @onNull @allbackExecutor Executor executor, @NonNull GnssAntennaInfo.Listener listener)2821 public boolean registerAntennaInfoListener( 2822 @NonNull @CallbackExecutor Executor executor, 2823 @NonNull GnssAntennaInfo.Listener listener) { 2824 GnssLazyLoader.sGnssAntennaInfoListeners.addListener(listener, 2825 new GnssAntennaInfoTransport(executor, mContext, listener)); 2826 return true; 2827 } 2828 2829 /** 2830 * Unregisters a GNSS antenna info listener. 2831 * 2832 * @param listener a {@link GnssAntennaInfo.Listener} object to remove 2833 */ unregisterAntennaInfoListener(@onNull GnssAntennaInfo.Listener listener)2834 public void unregisterAntennaInfoListener(@NonNull GnssAntennaInfo.Listener listener) { 2835 GnssLazyLoader.sGnssAntennaInfoListeners.removeListener(listener); 2836 } 2837 2838 /** 2839 * No-op method to keep backward-compatibility. 2840 * 2841 * @hide 2842 * @deprecated Use {@link #registerGnssNavigationMessageCallback} instead. 2843 * @removed 2844 */ 2845 @Deprecated 2846 @SystemApi addGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener)2847 public boolean addGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) { 2848 return false; 2849 } 2850 2851 /** 2852 * No-op method to keep backward-compatibility. 2853 * 2854 * @hide 2855 * @deprecated Use {@link #unregisterGnssNavigationMessageCallback} instead. 2856 * @removed 2857 */ 2858 @Deprecated 2859 @SystemApi removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener)2860 public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {} 2861 2862 /** 2863 * Registers a GNSS navigation message callback which will run on a binder thread. 2864 * 2865 * <p>See 2866 * {@link #registerGnssNavigationMessageCallback(Executor, GnssNavigationMessage.Callback)} for 2867 * more detail on how this method works. 2868 * 2869 * @param callback the callback to register 2870 * @return {@code true} always 2871 * 2872 * @deprecated Use {@link 2873 * #registerGnssNavigationMessageCallback(GnssNavigationMessage.Callback, Handler)} or {@link 2874 * #registerGnssNavigationMessageCallback(Executor, GnssNavigationMessage.Callback)} instead. 2875 */ 2876 @Deprecated registerGnssNavigationMessageCallback( @onNull GnssNavigationMessage.Callback callback)2877 public boolean registerGnssNavigationMessageCallback( 2878 @NonNull GnssNavigationMessage.Callback callback) { 2879 return registerGnssNavigationMessageCallback(DIRECT_EXECUTOR, callback); 2880 } 2881 2882 /** 2883 * Registers a GNSS navigation message callback. 2884 * 2885 * <p>See 2886 * {@link #registerGnssNavigationMessageCallback(Executor, GnssNavigationMessage.Callback)} for 2887 * more detail on how this method works. 2888 * 2889 * @param callback the callback to register 2890 * @param handler the handler that the callback runs on 2891 * @return {@code true} always 2892 * 2893 * @throws IllegalArgumentException if callback is null 2894 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2895 */ 2896 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssNavigationMessageCallback( @onNull GnssNavigationMessage.Callback callback, @Nullable Handler handler)2897 public boolean registerGnssNavigationMessageCallback( 2898 @NonNull GnssNavigationMessage.Callback callback, @Nullable Handler handler) { 2899 if (handler == null) { 2900 handler = new Handler(); 2901 } 2902 2903 return registerGnssNavigationMessageCallback(new HandlerExecutor(handler), callback); 2904 } 2905 2906 /** 2907 * Registers a GNSS navigation message callback. GNSS navigation messages will only be received 2908 * while the {@link #GPS_PROVIDER} is enabled, and while the client app is in the foreground. 2909 * 2910 * <p>Not all GNSS chipsets support navigation message updates, see 2911 * {@link #getGnssCapabilities()}. 2912 * 2913 * @param executor the executor that the callback runs on 2914 * @param callback the callback to register 2915 * @return {@code true} always 2916 * 2917 * @throws IllegalArgumentException if executor is null 2918 * @throws IllegalArgumentException if callback is null 2919 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2920 */ 2921 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssNavigationMessageCallback( @onNull @allbackExecutor Executor executor, @NonNull GnssNavigationMessage.Callback callback)2922 public boolean registerGnssNavigationMessageCallback( 2923 @NonNull @CallbackExecutor Executor executor, 2924 @NonNull GnssNavigationMessage.Callback callback) { 2925 GnssLazyLoader.sGnssNavigationListeners.addListener(callback, 2926 new GnssNavigationTransport(executor, mContext, callback)); 2927 return true; 2928 } 2929 2930 /** 2931 * Unregisters a GNSS Navigation Message callback. 2932 * 2933 * @param callback a {@link GnssNavigationMessage.Callback} object to remove. 2934 */ unregisterGnssNavigationMessageCallback( @onNull GnssNavigationMessage.Callback callback)2935 public void unregisterGnssNavigationMessageCallback( 2936 @NonNull GnssNavigationMessage.Callback callback) { 2937 GnssLazyLoader.sGnssNavigationListeners.removeListener(callback); 2938 } 2939 2940 /** 2941 * Adds a {@link ProviderRequest.ChangedListener} for listening to all providers' 2942 * {@link ProviderRequest} changed events. 2943 * 2944 * @param executor the executor that the callback runs on 2945 * @param listener the listener to register 2946 * @hide 2947 */ 2948 @SystemApi 2949 @RequiresPermission(allOf = {Manifest.permission.LOCATION_HARDWARE, 2950 Manifest.permission.INTERACT_ACROSS_USERS}) addProviderRequestChangedListener( @onNull @allbackExecutor Executor executor, @NonNull ChangedListener listener)2951 public void addProviderRequestChangedListener( 2952 @NonNull @CallbackExecutor Executor executor, 2953 @NonNull ChangedListener listener) { 2954 ProviderRequestLazyLoader.sProviderRequestListeners.addListener(listener, 2955 new ProviderRequestTransport(executor, listener)); 2956 } 2957 2958 /** 2959 * Removes a {@link ProviderRequest.ChangedListener} that has been added. 2960 * 2961 * @param listener the listener to remove. 2962 * @hide 2963 */ 2964 @SystemApi 2965 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) removeProviderRequestChangedListener( @onNull ProviderRequest.ChangedListener listener)2966 public void removeProviderRequestChangedListener( 2967 @NonNull ProviderRequest.ChangedListener listener) { 2968 ProviderRequestLazyLoader.sProviderRequestListeners.removeListener(listener); 2969 } 2970 2971 /** 2972 * Returns the batch size (in number of Location objects) that are supported by the batching 2973 * interface. 2974 * 2975 * Prior to Android S this call requires the {@link Manifest.permission#LOCATION_HARDWARE} 2976 * permission. 2977 * 2978 * @return Maximum number of location objects that can be returned 2979 * @deprecated Do not use 2980 * @hide 2981 */ 2982 @Deprecated 2983 @SystemApi getGnssBatchSize()2984 public int getGnssBatchSize() { 2985 try { 2986 return mService.getGnssBatchSize(); 2987 } catch (RemoteException e) { 2988 throw e.rethrowFromSystemServer(); 2989 } 2990 } 2991 2992 /** 2993 * Start hardware-batching of GNSS locations. This API is primarily used when the AP is 2994 * asleep and the device can batch GNSS locations in the hardware. 2995 * 2996 * Note this is designed (as was the fused location interface before it) for a single user 2997 * SystemApi - requests are not consolidated. Care should be taken when the System switches 2998 * users that may have different batching requests, to stop hardware batching for one user, and 2999 * restart it for the next. 3000 * 3001 * @param periodNanos Time interval, in nanoseconds, that the GNSS locations are requested 3002 * within the batch 3003 * @param wakeOnFifoFull ignored 3004 * @param callback The listener on which to return the batched locations 3005 * @param handler The handler on which to process the callback 3006 * 3007 * @return True always 3008 * @deprecated Use {@link LocationRequest.Builder#setMaxUpdateDelayMillis(long)} instead. 3009 * @hide 3010 */ 3011 @Deprecated 3012 @SystemApi 3013 @RequiresPermission(allOf = {Manifest.permission.LOCATION_HARDWARE, 3014 Manifest.permission.UPDATE_APP_OPS_STATS}) registerGnssBatchedLocationCallback(long periodNanos, boolean wakeOnFifoFull, @NonNull BatchedLocationCallback callback, @Nullable Handler handler)3015 public boolean registerGnssBatchedLocationCallback(long periodNanos, boolean wakeOnFifoFull, 3016 @NonNull BatchedLocationCallback callback, @Nullable Handler handler) { 3017 if (handler == null) { 3018 handler = new Handler(); 3019 } 3020 3021 try { 3022 mService.startGnssBatch( 3023 periodNanos, 3024 new BatchedLocationCallbackTransport(callback, handler), 3025 mContext.getPackageName(), 3026 mContext.getAttributionTag(), 3027 AppOpsManager.toReceiverId(callback)); 3028 return true; 3029 } catch (RemoteException e) { 3030 throw e.rethrowFromSystemServer(); 3031 } 3032 } 3033 3034 /** 3035 * Flush the batched GNSS locations. All GNSS locations currently ready in the batch are 3036 * returned via the callback sent in startGnssBatch(), and the buffer containing the batched 3037 * locations is cleared. 3038 * 3039 * @hide 3040 * @deprecated Use {@link #requestFlush(String, LocationListener, int)} or 3041 * {@link #requestFlush(String, PendingIntent, int)} instead. 3042 */ 3043 @Deprecated 3044 @SystemApi 3045 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) flushGnssBatch()3046 public void flushGnssBatch() { 3047 try { 3048 mService.flushGnssBatch(); 3049 } catch (RemoteException e) { 3050 throw e.rethrowFromSystemServer(); 3051 } 3052 } 3053 3054 /** 3055 * Stop batching locations. This API is primarily used when the AP is asleep and the device can 3056 * batch locations in the hardware. 3057 * 3058 * @param callback ignored 3059 * 3060 * @return True always 3061 * @deprecated Use {@link LocationRequest.Builder#setMaxUpdateDelayMillis(long)} instead. 3062 * @hide 3063 */ 3064 @Deprecated 3065 @SystemApi 3066 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) unregisterGnssBatchedLocationCallback( @onNull BatchedLocationCallback callback)3067 public boolean unregisterGnssBatchedLocationCallback( 3068 @NonNull BatchedLocationCallback callback) { 3069 try { 3070 mService.stopGnssBatch(); 3071 return true; 3072 } catch (RemoteException e) { 3073 throw e.rethrowFromSystemServer(); 3074 } 3075 } 3076 3077 private static class GnssStatusTransportManager extends 3078 ListenerTransportManager<GnssStatusTransport> { 3079 GnssStatusTransportManager()3080 GnssStatusTransportManager() { 3081 super(false); 3082 } 3083 3084 @Override registerTransport(GnssStatusTransport transport)3085 protected void registerTransport(GnssStatusTransport transport) 3086 throws RemoteException { 3087 getService().registerGnssStatusCallback(transport, transport.getPackage(), 3088 transport.getAttributionTag(), 3089 AppOpsManager.toReceiverId(transport.getListener())); 3090 } 3091 3092 @Override unregisterTransport(GnssStatusTransport transport)3093 protected void unregisterTransport(GnssStatusTransport transport) 3094 throws RemoteException { 3095 getService().unregisterGnssStatusCallback(transport); 3096 } 3097 } 3098 3099 private static class GnssNmeaTransportManager extends 3100 ListenerTransportManager<GnssNmeaTransport> { 3101 GnssNmeaTransportManager()3102 GnssNmeaTransportManager() { 3103 super(false); 3104 } 3105 3106 @Override registerTransport(GnssNmeaTransport transport)3107 protected void registerTransport(GnssNmeaTransport transport) 3108 throws RemoteException { 3109 getService().registerGnssNmeaCallback(transport, transport.getPackage(), 3110 transport.getAttributionTag(), 3111 AppOpsManager.toReceiverId(transport.getListener())); 3112 } 3113 3114 @Override unregisterTransport(GnssNmeaTransport transport)3115 protected void unregisterTransport(GnssNmeaTransport transport) 3116 throws RemoteException { 3117 getService().unregisterGnssNmeaCallback(transport); 3118 } 3119 } 3120 3121 private static class GnssMeasurementsTransportManager extends 3122 ListenerTransportManager<GnssMeasurementsTransport> { 3123 GnssMeasurementsTransportManager()3124 GnssMeasurementsTransportManager() { 3125 super(false); 3126 } 3127 3128 @Override registerTransport(GnssMeasurementsTransport transport)3129 protected void registerTransport(GnssMeasurementsTransport transport) 3130 throws RemoteException { 3131 getService().addGnssMeasurementsListener(transport.getRequest(), transport, 3132 transport.getPackage(), transport.getAttributionTag(), 3133 AppOpsManager.toReceiverId(transport.getListener())); 3134 } 3135 3136 @Override unregisterTransport(GnssMeasurementsTransport transport)3137 protected void unregisterTransport(GnssMeasurementsTransport transport) 3138 throws RemoteException { 3139 getService().removeGnssMeasurementsListener(transport); 3140 } 3141 } 3142 3143 private static class GnssAntennaTransportManager extends 3144 ListenerTransportManager<GnssAntennaInfoTransport> { 3145 GnssAntennaTransportManager()3146 GnssAntennaTransportManager() { 3147 super(false); 3148 } 3149 3150 @Override registerTransport(GnssAntennaInfoTransport transport)3151 protected void registerTransport(GnssAntennaInfoTransport transport) 3152 throws RemoteException { 3153 getService().addGnssAntennaInfoListener(transport, transport.getPackage(), 3154 transport.getAttributionTag(), 3155 AppOpsManager.toReceiverId(transport.getListener())); 3156 } 3157 3158 @Override unregisterTransport(GnssAntennaInfoTransport transport)3159 protected void unregisterTransport(GnssAntennaInfoTransport transport) 3160 throws RemoteException { 3161 getService().removeGnssAntennaInfoListener(transport); 3162 } 3163 } 3164 3165 private static class GnssNavigationTransportManager extends 3166 ListenerTransportManager<GnssNavigationTransport> { 3167 GnssNavigationTransportManager()3168 GnssNavigationTransportManager() { 3169 super(false); 3170 } 3171 3172 @Override registerTransport(GnssNavigationTransport transport)3173 protected void registerTransport(GnssNavigationTransport transport) 3174 throws RemoteException { 3175 getService().addGnssNavigationMessageListener(transport, 3176 transport.getPackage(), transport.getAttributionTag(), 3177 AppOpsManager.toReceiverId(transport.getListener())); 3178 } 3179 3180 @Override unregisterTransport(GnssNavigationTransport transport)3181 protected void unregisterTransport(GnssNavigationTransport transport) 3182 throws RemoteException { 3183 getService().removeGnssNavigationMessageListener(transport); 3184 } 3185 } 3186 3187 private static class ProviderRequestTransportManager extends 3188 ListenerTransportManager<ProviderRequestTransport> { 3189 ProviderRequestTransportManager()3190 ProviderRequestTransportManager() { 3191 super(false); 3192 } 3193 3194 @Override registerTransport(ProviderRequestTransport transport)3195 protected void registerTransport(ProviderRequestTransport transport) 3196 throws RemoteException { 3197 getService().addProviderRequestListener(transport); 3198 } 3199 3200 @Override unregisterTransport(ProviderRequestTransport transport)3201 protected void unregisterTransport(ProviderRequestTransport transport) 3202 throws RemoteException { 3203 getService().removeProviderRequestListener(transport); 3204 } 3205 } 3206 3207 private static class GetCurrentLocationTransport extends ILocationCallback.Stub implements 3208 ListenerExecutor, CancellationSignal.OnCancelListener { 3209 3210 private final Executor mExecutor; 3211 volatile @Nullable Consumer<Location> mConsumer; 3212 GetCurrentLocationTransport(Executor executor, Consumer<Location> consumer, @Nullable CancellationSignal cancellationSignal)3213 GetCurrentLocationTransport(Executor executor, Consumer<Location> consumer, 3214 @Nullable CancellationSignal cancellationSignal) { 3215 Preconditions.checkArgument(executor != null, "illegal null executor"); 3216 Preconditions.checkArgument(consumer != null, "illegal null consumer"); 3217 mExecutor = executor; 3218 mConsumer = consumer; 3219 3220 if (cancellationSignal != null) { 3221 cancellationSignal.setOnCancelListener(this); 3222 } 3223 } 3224 3225 @Override onCancel()3226 public void onCancel() { 3227 mConsumer = null; 3228 } 3229 3230 @Override onLocation(@ullable Location location)3231 public void onLocation(@Nullable Location location) { 3232 executeSafely(mExecutor, () -> mConsumer, new ListenerOperation<Consumer<Location>>() { 3233 @Override 3234 public void operate(Consumer<Location> consumer) { 3235 consumer.accept(location); 3236 } 3237 3238 @Override 3239 public void onPostExecute(boolean success) { 3240 mConsumer = null; 3241 } 3242 }); 3243 } 3244 } 3245 3246 private static class LocationListenerTransport extends ILocationListener.Stub implements 3247 ListenerExecutor { 3248 3249 private Executor mExecutor; 3250 private volatile @Nullable LocationListener mListener; 3251 LocationListenerTransport(LocationListener listener, Executor executor)3252 LocationListenerTransport(LocationListener listener, Executor executor) { 3253 Preconditions.checkArgument(listener != null, "invalid null listener"); 3254 mListener = listener; 3255 setExecutor(executor); 3256 } 3257 setExecutor(Executor executor)3258 void setExecutor(Executor executor) { 3259 Preconditions.checkArgument(executor != null, "invalid null executor"); 3260 mExecutor = executor; 3261 } 3262 isRegistered()3263 boolean isRegistered() { 3264 return mListener != null; 3265 } 3266 unregister()3267 void unregister() { 3268 mListener = null; 3269 } 3270 3271 @Override onLocationChanged(List<Location> locations, @Nullable IRemoteCallback onCompleteCallback)3272 public void onLocationChanged(List<Location> locations, 3273 @Nullable IRemoteCallback onCompleteCallback) { 3274 executeSafely(mExecutor, () -> mListener, new ListenerOperation<LocationListener>() { 3275 @Override 3276 public void operate(LocationListener listener) { 3277 listener.onLocationChanged(locations); 3278 } 3279 3280 @Override 3281 public void onComplete(boolean success) { 3282 if (onCompleteCallback != null) { 3283 try { 3284 onCompleteCallback.sendResult(null); 3285 } catch (RemoteException e) { 3286 throw e.rethrowFromSystemServer(); 3287 } 3288 } 3289 } 3290 }); 3291 } 3292 3293 @Override onFlushComplete(int requestCode)3294 public void onFlushComplete(int requestCode) { 3295 executeSafely(mExecutor, () -> mListener, 3296 listener -> listener.onFlushComplete(requestCode)); 3297 } 3298 3299 @Override onProviderEnabledChanged(String provider, boolean enabled)3300 public void onProviderEnabledChanged(String provider, boolean enabled) { 3301 executeSafely(mExecutor, () -> mListener, listener -> { 3302 if (enabled) { 3303 listener.onProviderEnabled(provider); 3304 } else { 3305 listener.onProviderDisabled(provider); 3306 } 3307 }); 3308 } 3309 } 3310 3311 /** @deprecated */ 3312 @Deprecated 3313 private static class GpsAdapter extends GnssStatus.Callback { 3314 3315 private final GpsStatus.Listener mGpsListener; 3316 GpsAdapter(GpsStatus.Listener gpsListener)3317 GpsAdapter(GpsStatus.Listener gpsListener) { 3318 mGpsListener = gpsListener; 3319 } 3320 3321 @Override onStarted()3322 public void onStarted() { 3323 mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED); 3324 } 3325 3326 @Override onStopped()3327 public void onStopped() { 3328 mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STOPPED); 3329 } 3330 3331 @Override onFirstFix(int ttffMillis)3332 public void onFirstFix(int ttffMillis) { 3333 mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_FIRST_FIX); 3334 } 3335 3336 @Override onSatelliteStatusChanged(GnssStatus status)3337 public void onSatelliteStatusChanged(GnssStatus status) { 3338 mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS); 3339 } 3340 } 3341 3342 private static class GnssStatusTransport extends IGnssStatusListener.Stub implements 3343 ListenerTransport<GnssStatus.Callback> { 3344 3345 private final Executor mExecutor; 3346 private final String mPackageName; 3347 private final String mAttributionTag; 3348 3349 private volatile @Nullable GnssStatus.Callback mListener; 3350 GnssStatusTransport(Executor executor, Context context, GnssStatus.Callback listener)3351 GnssStatusTransport(Executor executor, Context context, GnssStatus.Callback listener) { 3352 Preconditions.checkArgument(executor != null, "invalid null executor"); 3353 Preconditions.checkArgument(listener != null, "invalid null callback"); 3354 mExecutor = executor; 3355 mPackageName = context.getPackageName(); 3356 mAttributionTag = context.getAttributionTag(); 3357 mListener = listener; 3358 } 3359 getPackage()3360 public String getPackage() { 3361 return mPackageName; 3362 } 3363 getAttributionTag()3364 public String getAttributionTag() { 3365 return mAttributionTag; 3366 } 3367 3368 @Override unregister()3369 public void unregister() { 3370 mListener = null; 3371 } 3372 3373 @Override getListener()3374 public @Nullable GnssStatus.Callback getListener() { 3375 return mListener; 3376 } 3377 3378 @Override onGnssStarted()3379 public void onGnssStarted() { 3380 execute(mExecutor, GnssStatus.Callback::onStarted); 3381 } 3382 3383 @Override onGnssStopped()3384 public void onGnssStopped() { 3385 execute(mExecutor, GnssStatus.Callback::onStopped); 3386 } 3387 3388 @Override onFirstFix(int ttff)3389 public void onFirstFix(int ttff) { 3390 execute(mExecutor, listener -> listener.onFirstFix(ttff)); 3391 3392 } 3393 3394 @Override onSvStatusChanged(GnssStatus gnssStatus)3395 public void onSvStatusChanged(GnssStatus gnssStatus) { 3396 execute(mExecutor, listener -> listener.onSatelliteStatusChanged(gnssStatus)); 3397 } 3398 } 3399 3400 /** @deprecated */ 3401 @Deprecated 3402 private static class GpsStatusTransport extends GnssStatusTransport { 3403 3404 static volatile int sTtff; 3405 static volatile GnssStatus sGnssStatus; 3406 GpsStatusTransport(Executor executor, Context context, GpsStatus.Listener listener)3407 GpsStatusTransport(Executor executor, Context context, GpsStatus.Listener listener) { 3408 super(executor, context, new GpsAdapter(listener)); 3409 } 3410 3411 @Override onFirstFix(int ttff)3412 public void onFirstFix(int ttff) { 3413 sTtff = ttff; 3414 super.onFirstFix(ttff); 3415 } 3416 3417 @Override onSvStatusChanged(GnssStatus gnssStatus)3418 public void onSvStatusChanged(GnssStatus gnssStatus) { 3419 sGnssStatus = gnssStatus; 3420 super.onSvStatusChanged(gnssStatus); 3421 } 3422 } 3423 3424 private static class GnssNmeaTransport extends IGnssNmeaListener.Stub implements 3425 ListenerTransport<OnNmeaMessageListener> { 3426 3427 private final Executor mExecutor; 3428 private final String mPackageName; 3429 private final String mAttributionTag; 3430 3431 private volatile @Nullable OnNmeaMessageListener mListener; 3432 GnssNmeaTransport(Executor executor, Context context, OnNmeaMessageListener listener)3433 GnssNmeaTransport(Executor executor, Context context, OnNmeaMessageListener listener) { 3434 Preconditions.checkArgument(executor != null, "invalid null executor"); 3435 Preconditions.checkArgument(listener != null, "invalid null listener"); 3436 mExecutor = executor; 3437 mPackageName = context.getPackageName(); 3438 mAttributionTag = context.getAttributionTag(); 3439 mListener = listener; 3440 } 3441 getPackage()3442 public String getPackage() { 3443 return mPackageName; 3444 } 3445 getAttributionTag()3446 public String getAttributionTag() { 3447 return mAttributionTag; 3448 } 3449 3450 @Override unregister()3451 public void unregister() { 3452 mListener = null; 3453 } 3454 3455 @Override getListener()3456 public @Nullable OnNmeaMessageListener getListener() { 3457 return mListener; 3458 } 3459 3460 @Override onNmeaReceived(long timestamp, String nmea)3461 public void onNmeaReceived(long timestamp, String nmea) { 3462 execute(mExecutor, callback -> callback.onNmeaMessage(nmea, timestamp)); 3463 } 3464 } 3465 3466 private static class GnssMeasurementsTransport extends IGnssMeasurementsListener.Stub implements 3467 ListenerTransport<GnssMeasurementsEvent.Callback> { 3468 3469 private final Executor mExecutor; 3470 private final String mPackageName; 3471 private final String mAttributionTag; 3472 private final GnssMeasurementRequest mRequest; 3473 3474 private volatile @Nullable GnssMeasurementsEvent.Callback mListener; 3475 GnssMeasurementsTransport(Executor executor, Context context, GnssMeasurementRequest request, GnssMeasurementsEvent.Callback listener)3476 GnssMeasurementsTransport(Executor executor, Context context, 3477 GnssMeasurementRequest request, GnssMeasurementsEvent.Callback listener) { 3478 Preconditions.checkArgument(executor != null, "invalid null executor"); 3479 Preconditions.checkArgument(listener != null, "invalid null callback"); 3480 Preconditions.checkArgument(request != null, "invalid null request"); 3481 mExecutor = executor; 3482 mPackageName = context.getPackageName(); 3483 mAttributionTag = context.getAttributionTag(); 3484 mRequest = request; 3485 mListener = listener; 3486 } 3487 getPackage()3488 public String getPackage() { 3489 return mPackageName; 3490 } 3491 getAttributionTag()3492 public String getAttributionTag() { 3493 return mAttributionTag; 3494 } 3495 getRequest()3496 public GnssMeasurementRequest getRequest() { 3497 return mRequest; 3498 } 3499 3500 @Override unregister()3501 public void unregister() { 3502 mListener = null; 3503 } 3504 3505 @Override getListener()3506 public @Nullable GnssMeasurementsEvent.Callback getListener() { 3507 return mListener; 3508 } 3509 3510 @Override onGnssMeasurementsReceived(GnssMeasurementsEvent event)3511 public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) { 3512 execute(mExecutor, callback -> callback.onGnssMeasurementsReceived(event)); 3513 } 3514 3515 @Override onStatusChanged(int status)3516 public void onStatusChanged(int status) { 3517 execute(mExecutor, callback -> callback.onStatusChanged(status)); 3518 } 3519 } 3520 3521 private static class GnssAntennaInfoTransport extends IGnssAntennaInfoListener.Stub implements 3522 ListenerTransport<GnssAntennaInfo.Listener> { 3523 3524 private final Executor mExecutor; 3525 private final String mPackageName; 3526 private final String mAttributionTag; 3527 3528 private volatile @Nullable GnssAntennaInfo.Listener mListener; 3529 GnssAntennaInfoTransport(Executor executor, Context context, GnssAntennaInfo.Listener listener)3530 GnssAntennaInfoTransport(Executor executor, Context context, 3531 GnssAntennaInfo.Listener listener) { 3532 Preconditions.checkArgument(executor != null, "invalid null executor"); 3533 Preconditions.checkArgument(listener != null, "invalid null listener"); 3534 mExecutor = executor; 3535 mPackageName = context.getPackageName(); 3536 mAttributionTag = context.getAttributionTag(); 3537 mListener = listener; 3538 } 3539 getPackage()3540 public String getPackage() { 3541 return mPackageName; 3542 } 3543 getAttributionTag()3544 public String getAttributionTag() { 3545 return mAttributionTag; 3546 } 3547 3548 @Override unregister()3549 public void unregister() { 3550 mListener = null; 3551 } 3552 3553 @Override getListener()3554 public @Nullable GnssAntennaInfo.Listener getListener() { 3555 return mListener; 3556 } 3557 3558 @Override onGnssAntennaInfoChanged(List<GnssAntennaInfo> antennaInfos)3559 public void onGnssAntennaInfoChanged(List<GnssAntennaInfo> antennaInfos) { 3560 execute(mExecutor, callback -> callback.onGnssAntennaInfoReceived(antennaInfos)); 3561 } 3562 } 3563 3564 private static class GnssNavigationTransport extends IGnssNavigationMessageListener.Stub 3565 implements ListenerTransport<GnssNavigationMessage.Callback> { 3566 3567 private final Executor mExecutor; 3568 private final String mPackageName; 3569 private final String mAttributionTag; 3570 3571 private volatile @Nullable GnssNavigationMessage.Callback mListener; 3572 GnssNavigationTransport(Executor executor, Context context, GnssNavigationMessage.Callback listener)3573 GnssNavigationTransport(Executor executor, Context context, 3574 GnssNavigationMessage.Callback listener) { 3575 Preconditions.checkArgument(executor != null, "invalid null executor"); 3576 Preconditions.checkArgument(listener != null, "invalid null callback"); 3577 mExecutor = executor; 3578 mPackageName = context.getPackageName(); 3579 mAttributionTag = context.getAttributionTag(); 3580 mListener = listener; 3581 } 3582 getPackage()3583 public String getPackage() { 3584 return mPackageName; 3585 } 3586 getAttributionTag()3587 public String getAttributionTag() { 3588 return mAttributionTag; 3589 } 3590 3591 @Override unregister()3592 public void unregister() { 3593 mListener = null; 3594 } 3595 3596 @Override getListener()3597 public @Nullable GnssNavigationMessage.Callback getListener() { 3598 return mListener; 3599 } 3600 3601 @Override onGnssNavigationMessageReceived(GnssNavigationMessage event)3602 public void onGnssNavigationMessageReceived(GnssNavigationMessage event) { 3603 execute(mExecutor, listener -> listener.onGnssNavigationMessageReceived(event)); 3604 } 3605 3606 @Override onStatusChanged(int status)3607 public void onStatusChanged(int status) { 3608 execute(mExecutor, listener -> listener.onStatusChanged(status)); 3609 } 3610 } 3611 3612 private static class ProviderRequestTransport extends IProviderRequestListener.Stub 3613 implements ListenerTransport<ChangedListener> { 3614 3615 private final Executor mExecutor; 3616 3617 private volatile @Nullable ProviderRequest.ChangedListener mListener; 3618 ProviderRequestTransport(Executor executor, ChangedListener listener)3619 ProviderRequestTransport(Executor executor, ChangedListener listener) { 3620 Preconditions.checkArgument(executor != null, "invalid null executor"); 3621 Preconditions.checkArgument(listener != null, "invalid null callback"); 3622 mExecutor = executor; 3623 mListener = listener; 3624 } 3625 3626 @Override unregister()3627 public void unregister() { 3628 mListener = null; 3629 } 3630 3631 @Override getListener()3632 public @Nullable ProviderRequest.ChangedListener getListener() { 3633 return mListener; 3634 } 3635 3636 @Override onProviderRequestChanged(String provider, ProviderRequest request)3637 public void onProviderRequestChanged(String provider, ProviderRequest request) { 3638 execute(mExecutor, listener -> listener.onProviderRequestChanged(provider, request)); 3639 } 3640 } 3641 3642 /** @deprecated */ 3643 @Deprecated 3644 private static class BatchedLocationCallbackWrapper implements LocationListener { 3645 3646 private final BatchedLocationCallback mCallback; 3647 BatchedLocationCallbackWrapper(BatchedLocationCallback callback)3648 BatchedLocationCallbackWrapper(BatchedLocationCallback callback) { 3649 mCallback = callback; 3650 } 3651 3652 @Override onLocationChanged(@onNull Location location)3653 public void onLocationChanged(@NonNull Location location) { 3654 mCallback.onLocationBatch(Collections.singletonList(location)); 3655 } 3656 3657 @Override onLocationChanged(@onNull List<Location> locations)3658 public void onLocationChanged(@NonNull List<Location> locations) { 3659 mCallback.onLocationBatch(locations); 3660 } 3661 } 3662 3663 /** @deprecated */ 3664 @Deprecated 3665 private static class BatchedLocationCallbackTransport extends LocationListenerTransport { 3666 BatchedLocationCallbackTransport(BatchedLocationCallback callback, Handler handler)3667 BatchedLocationCallbackTransport(BatchedLocationCallback callback, Handler handler) { 3668 super(new BatchedLocationCallbackWrapper(callback), new HandlerExecutor(handler)); 3669 } 3670 } 3671 3672 private static class LocationEnabledCache extends PropertyInvalidatedCache<Integer, Boolean> { 3673 3674 // this is not loaded immediately because this class is created as soon as LocationManager 3675 // is referenced for the first time, and within the system server, the ILocationManager 3676 // service may not have been loaded yet at that time. 3677 private @Nullable ILocationManager mManager; 3678 LocationEnabledCache(int numEntries)3679 LocationEnabledCache(int numEntries) { 3680 super(numEntries, CACHE_KEY_LOCATION_ENABLED_PROPERTY); 3681 } 3682 3683 @Override recompute(Integer userId)3684 public Boolean recompute(Integer userId) { 3685 Preconditions.checkArgument(userId >= 0); 3686 3687 if (mManager == null) { 3688 try { 3689 mManager = getService(); 3690 } catch (RemoteException e) { 3691 e.rethrowFromSystemServer(); 3692 } 3693 } 3694 3695 try { 3696 return mManager.isLocationEnabledForUser(userId); 3697 } catch (RemoteException e) { 3698 throw e.rethrowFromSystemServer(); 3699 } 3700 } 3701 } 3702 3703 /** 3704 * @hide 3705 */ invalidateLocalLocationEnabledCaches()3706 public static void invalidateLocalLocationEnabledCaches() { 3707 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_LOCATION_ENABLED_PROPERTY); 3708 } 3709 3710 /** 3711 * @hide 3712 */ disableLocalLocationEnabledCaches()3713 public static void disableLocalLocationEnabledCaches() { 3714 sLocationEnabledCache = null; 3715 } 3716 } 3717