From 958e8235dcbef8045aaae3f08c234ffa8df9a610 Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Wed, 25 Sep 2019 15:59:44 -0700 Subject: Reorder LocationManager methods Group LocationManager methods by function. No other changes beyond copy/pasting methods (and fixing lint error). Bug: 141644661 Test: builds Change-Id: I95e1297e37aa862cb9ff8fad9052079f056a2973 --- .../java/android/location/LocationManager.java | 1541 ++++++++++---------- 1 file changed, 769 insertions(+), 772 deletions(-) diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 7cf5bb80b654..6b47d1dff781 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -275,114 +275,391 @@ public class LocationManager { } } - private LocationProvider createProvider(String name, ProviderProperties properties) { - return new LocationProvider(name, properties); + /** + * Returns the extra location controller package on the device. + * + * @hide + */ + @SystemApi + public @Nullable String getExtraLocationControllerPackage() { + try { + return mService.getExtraLocationControllerPackage(); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return null; + } } /** - * Returns a list of the names of all known location providers. - *

All providers are returned, including ones that are not permitted to - * be accessed by the calling activity or are currently disabled. + * Set the extra location controller package for location services on the device. * - * @return list of Strings containing names of the provider + * @hide */ - public @NonNull List getAllProviders() { + @SystemApi + @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) + public void setExtraLocationControllerPackage(@Nullable String packageName) { try { - return mService.getAllProviders(); + mService.setExtraLocationControllerPackage(packageName); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + e.rethrowFromSystemServer(); } } /** - * Returns a list of the names of location providers. + * Set whether the extra location controller package is currently enabled on the device. * - * @param enabledOnly if true then only the providers which are currently - * enabled are returned. - * @return list of Strings containing names of the providers + * @hide */ - public @NonNull List getProviders(boolean enabledOnly) { + @SystemApi + @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) + public void setExtraLocationControllerPackageEnabled(boolean enabled) { try { - return mService.getProviders(null, enabledOnly); + mService.setExtraLocationControllerPackageEnabled(enabled); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Returns whether extra location controller package is currently enabled on the device. + * + * @hide + */ + @SystemApi + public boolean isExtraLocationControllerPackageEnabled() { + try { + return mService.isExtraLocationControllerPackageEnabled(); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return false; + } + } + + /** + * Set the extra location controller package for location services on the device. + * + * @removed + * @deprecated Use {@link #setExtraLocationControllerPackage} instead. + * @hide + */ + @Deprecated + @SystemApi + @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) + public void setLocationControllerExtraPackage(String packageName) { + try { + mService.setExtraLocationControllerPackage(packageName); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Set whether the extra location controller package is currently enabled on the device. + * + * @removed + * @deprecated Use {@link #setExtraLocationControllerPackageEnabled} instead. + * @hide + */ + @SystemApi + @Deprecated + @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) + public void setLocationControllerExtraPackageEnabled(boolean enabled) { + try { + mService.setExtraLocationControllerPackageEnabled(enabled); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Returns the current enabled/disabled state of location. To listen for changes, see + * {@link #MODE_CHANGED_ACTION}. + * + * @return true if location is enabled and false if location is disabled. + */ + public boolean isLocationEnabled() { + return isLocationEnabledForUser(Process.myUserHandle()); + } + + /** + * Returns the current enabled/disabled state of location. + * + * @param userHandle the user to query + * @return true if location is enabled and false if location is disabled. + * + * @hide + */ + @SystemApi + public boolean isLocationEnabledForUser(@NonNull UserHandle userHandle) { + try { + return mService.isLocationEnabledForUser(userHandle.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Returns the information associated with the location provider of the - * given name, or null if no provider exists by that name. + * Enables or disables the location setting. * - * @param name the provider name - * @return a LocationProvider, or null + * @param enabled true to enable location and false to disable location. + * @param userHandle the user to set * - * @throws IllegalArgumentException if name is null or does not exist - * @throws SecurityException if the caller is not permitted to access the - * given provider. + * @hide */ - public @Nullable LocationProvider getProvider(@NonNull String name) { - checkProvider(name); + @SystemApi + @TestApi + @RequiresPermission(WRITE_SECURE_SETTINGS) + public void setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle) { + Settings.Secure.putIntForUser( + mContext.getContentResolver(), + Settings.Secure.LOCATION_MODE, + enabled + ? Settings.Secure.LOCATION_MODE_ON + : Settings.Secure.LOCATION_MODE_OFF, + userHandle.getIdentifier()); + } + + /** + * Returns the current enabled/disabled status of the given provider. To listen for changes, see + * {@link #PROVIDERS_CHANGED_ACTION}. + * + * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw + * {@link SecurityException} if the location permissions were not sufficient to use the + * specified provider. + * + * @param provider the name of the provider + * @return true if the provider exists and is enabled + * + * @throws IllegalArgumentException if provider is null + */ + public boolean isProviderEnabled(@NonNull String provider) { + return isProviderEnabledForUser(provider, Process.myUserHandle()); + } + + /** + * Returns the current enabled/disabled status of the given provider and user. Callers should + * prefer {@link #isLocationEnabledForUser(UserHandle)} unless they depend on provider-specific + * APIs. + * + * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw + * {@link SecurityException} if the location permissions were not sufficient to use the + * specified provider. + * + * @param provider the name of the provider + * @param userHandle the user to query + * @return true if the provider exists and is enabled + * + * @throws IllegalArgumentException if provider is null + * @hide + */ + @SystemApi + public boolean isProviderEnabledForUser( + @NonNull String provider, @NonNull UserHandle userHandle) { + checkProvider(provider); + try { - ProviderProperties properties = mService.getProviderProperties(name); - if (properties == null) { - return null; - } - return createProvider(name, properties); + return mService.isProviderEnabledForUser(provider, userHandle.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Returns a list of the names of LocationProviders that satisfy the given - * criteria, or null if none do. Only providers that are permitted to be - * accessed by the calling activity will be returned. + * Method for enabling or disabling a single location provider. This method is deprecated and + * functions as a best effort. It should not be relied on in any meaningful sense as providers + * may no longer be enabled or disabled by clients. * - * @param criteria the criteria that the returned providers must match - * @param enabledOnly if true then only the providers which are currently - * enabled are returned. - * @return list of Strings containing names of the providers + * @param provider the name of the provider + * @param enabled true to enable the provider. false to disable the provider + * @param userHandle the user to set + * @return true if the value was set, false otherwise + * + * @throws IllegalArgumentException if provider is null + * @deprecated Do not manipulate providers individually, use + * {@link #setLocationEnabledForUser(boolean, UserHandle)} instead. + * @hide */ - public @NonNull List getProviders(@NonNull Criteria criteria, boolean enabledOnly) { - checkCriteria(criteria); + @Deprecated + @SystemApi + @RequiresPermission(WRITE_SECURE_SETTINGS) + public boolean setProviderEnabledForUser( + @NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) { + checkProvider(provider); + + return Settings.Secure.putStringForUser( + mContext.getContentResolver(), + Settings.Secure.LOCATION_PROVIDERS_ALLOWED, + (enabled ? "+" : "-") + provider, + userHandle.getIdentifier()); + } + + /** + * Get the last known location. + * + *

This location could be very old so use + * {@link Location#getElapsedRealtimeNanos} to calculate its age. It can + * also return null if no previous location is available. + * + *

Always returns immediately. + * + * @return The last known location, or null if not available + * @throws SecurityException if no suitable permission is present + * + * @hide + */ + @Nullable + public Location getLastLocation() { + String packageName = mContext.getPackageName(); + try { - return mService.getProviders(criteria, enabledOnly); + return mService.getLastLocation(null, packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Returns the name of the provider that best meets the given criteria. Only providers - * that are permitted to be accessed by the calling activity will be - * returned. If several providers meet the criteria, the one with the best - * accuracy is returned. If no provider meets the criteria, - * the criteria are loosened in the following sequence: + * Returns a Location indicating the data from the last known + * location fix obtained from the given provider. * - *

+ *

This can be done + * without starting the provider. Note that this location could + * be out-of-date, for example if the device was turned off and + * moved to another location. * - *

Note that the requirement on monetary cost is not removed - * in this process. + *

If the provider is currently disabled, null is returned. * - * @param criteria the criteria that need to be matched - * @param enabledOnly if true then only a provider that is currently enabled is returned - * @return name of the provider that best matches the requirements + * @param provider the name of the provider + * @return the last known location for the provider, or null + * + * @throws SecurityException if no suitable permission is present + * @throws IllegalArgumentException if provider is null or doesn't exist */ - public @Nullable String getBestProvider(@NonNull Criteria criteria, boolean enabledOnly) { - checkCriteria(criteria); + @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) + @Nullable + public Location getLastKnownLocation(@NonNull String provider) { + checkProvider(provider); + String packageName = mContext.getPackageName(); + LocationRequest request = LocationRequest.createFromDeprecatedProvider( + provider, 0, 0, true); + try { - return mService.getBestProvider(criteria, enabledOnly); + return mService.getLastLocation(request, packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } + /** + * Register for a single location update using the named provider and + * a callback. + * + *

See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} + * for more detail on how to use this method. + * + * @param provider the name of the provider with which to register + * @param listener a {@link LocationListener} whose + * {@link LocationListener#onLocationChanged} method will be called when + * the location update is available + * @param looper a Looper object whose message queue will be used to + * implement the callback mechanism, or null to make callbacks on the calling + * thread + * + * @throws IllegalArgumentException if provider is null or doesn't exist + * @throws IllegalArgumentException if listener is null + * @throws SecurityException if no suitable permission is present + */ + @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) + public void requestSingleUpdate( + @NonNull String provider, @NonNull LocationListener listener, @Nullable Looper looper) { + checkProvider(provider); + checkListener(listener); + + LocationRequest request = LocationRequest.createFromDeprecatedProvider( + provider, 0, 0, true); + requestLocationUpdates(request, listener, looper); + } + + /** + * Register for a single location update using a Criteria and + * a callback. + * + *

See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} + * for more detail on how to use this method. + * + * @param criteria contains parameters for the location manager to choose the + * appropriate provider and parameters to compute the location + * @param listener a {@link LocationListener} whose + * {@link LocationListener#onLocationChanged} method will be called when + * the location update is available + * @param looper a Looper object whose message queue will be used to + * implement the callback mechanism, or null to make callbacks on the calling + * thread + * + * @throws IllegalArgumentException if criteria is null + * @throws IllegalArgumentException if listener is null + * @throws SecurityException if no suitable permission is present + */ + @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) + public void requestSingleUpdate( + @NonNull Criteria criteria, + @NonNull LocationListener listener, + @Nullable Looper looper) { + checkCriteria(criteria); + checkListener(listener); + + LocationRequest request = LocationRequest.createFromDeprecatedCriteria( + criteria, 0, 0, true); + requestLocationUpdates(request, listener, looper); + } + + /** + * Register for a single location update using a named provider and pending intent. + * + *

See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} + * for more detail on how to use this method. + * + * @param provider the name of the provider with which to register + * @param intent a {@link PendingIntent} to be sent for the location update + * + * @throws IllegalArgumentException if provider is null or doesn't exist + * @throws IllegalArgumentException if intent is null + * @throws SecurityException if no suitable permission is present + */ + @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) + public void requestSingleUpdate(@NonNull String provider, @NonNull PendingIntent intent) { + checkProvider(provider); + checkPendingIntent(intent); + + LocationRequest request = LocationRequest.createFromDeprecatedProvider( + provider, 0, 0, true); + requestLocationUpdates(request, intent); + } + + /** + * Register for a single location update using a Criteria and pending intent. + * + *

See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} + * for more detail on how to use this method. + * + * @param criteria contains parameters for the location manager to choose the + * appropriate provider and parameters to compute the location + * @param intent a {@link PendingIntent} to be sent for the location update + * + * @throws IllegalArgumentException if provider is null or doesn't exist + * @throws IllegalArgumentException if intent is null + * @throws SecurityException if no suitable permission is present + */ + @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) + public void requestSingleUpdate(@NonNull Criteria criteria, @NonNull PendingIntent intent) { + checkCriteria(criteria); + checkPendingIntent(intent); + + LocationRequest request = LocationRequest.createFromDeprecatedCriteria( + criteria, 0, 0, true); + requestLocationUpdates(request, intent); + } + /** * Register for location updates using the named provider, and a * pending intent. @@ -624,158 +901,48 @@ public class LocationManager { * location updates will immediately resume and a provider availability * update sent. Providers can also send status updates, at any time, * with extra's specific to the provider. If a callback was supplied - * then status and availability updates are via - * {@link LocationListener#onProviderDisabled}, - * {@link LocationListener#onProviderEnabled} or - * {@link LocationListener#onStatusChanged}. Alternately, if a - * pending intent was supplied then status and availability updates - * are broadcast intents with extra keys of - * {@link #KEY_PROVIDER_ENABLED} or {@link #KEY_STATUS_CHANGED}. - * - *

If a {@link LocationListener} is used but with no Looper specified - * then the calling thread must already - * be a {@link android.os.Looper} thread such as the main thread of the - * calling Activity. If a Looper is specified with a {@link LocationListener} - * then callbacks are made on the supplied Looper thread. - * - *

When location callbacks are invoked, the system will hold a wakelock - * on your application's behalf for some period of time, but not - * indefinitely. If your application requires a long running wakelock - * within the location callback, you should acquire it yourself. - * - *

Prior to Jellybean, the minTime parameter was - * only a hint, and some location provider implementations ignored it. - * From Jellybean and onwards it is mandatory for Android compatible - * devices to observe both the minTime and minDistance parameters. - * - * @param minTime minimum time interval between location updates, in milliseconds - * @param minDistance minimum distance between location updates, in meters - * @param criteria contains parameters for the location manager to choose the - * appropriate provider and parameters to compute the location - * @param intent a {@link PendingIntent} to be sent for each location update - * - * @throws IllegalArgumentException if criteria is null - * @throws IllegalArgumentException if intent is null - * @throws SecurityException if no suitable permission is present - */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria, - @NonNull PendingIntent intent) { - checkCriteria(criteria); - checkPendingIntent(intent); - - LocationRequest request = LocationRequest.createFromDeprecatedCriteria( - criteria, minTime, minDistance, false); - requestLocationUpdates(request, intent); - } - - /** - * Register for a single location update using the named provider and - * a callback. - * - *

See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} - * for more detail on how to use this method. - * - * @param provider the name of the provider with which to register - * @param listener a {@link LocationListener} whose - * {@link LocationListener#onLocationChanged} method will be called when - * the location update is available - * @param looper a Looper object whose message queue will be used to - * implement the callback mechanism, or null to make callbacks on the calling - * thread - * - * @throws IllegalArgumentException if provider is null or doesn't exist - * @throws IllegalArgumentException if listener is null - * @throws SecurityException if no suitable permission is present - */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestSingleUpdate( - @NonNull String provider, @NonNull LocationListener listener, @Nullable Looper looper) { - checkProvider(provider); - checkListener(listener); - - LocationRequest request = LocationRequest.createFromDeprecatedProvider( - provider, 0, 0, true); - requestLocationUpdates(request, listener, looper); - } - - /** - * Register for a single location update using a Criteria and - * a callback. - * - *

See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} - * for more detail on how to use this method. - * - * @param criteria contains parameters for the location manager to choose the - * appropriate provider and parameters to compute the location - * @param listener a {@link LocationListener} whose - * {@link LocationListener#onLocationChanged} method will be called when - * the location update is available - * @param looper a Looper object whose message queue will be used to - * implement the callback mechanism, or null to make callbacks on the calling - * thread - * - * @throws IllegalArgumentException if criteria is null - * @throws IllegalArgumentException if listener is null - * @throws SecurityException if no suitable permission is present - */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestSingleUpdate( - @NonNull Criteria criteria, - @NonNull LocationListener listener, - @Nullable Looper looper) { - checkCriteria(criteria); - checkListener(listener); - - LocationRequest request = LocationRequest.createFromDeprecatedCriteria( - criteria, 0, 0, true); - requestLocationUpdates(request, listener, looper); - } - - /** - * Register for a single location update using a named provider and pending intent. - * - *

See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} - * for more detail on how to use this method. + * then status and availability updates are via + * {@link LocationListener#onProviderDisabled}, + * {@link LocationListener#onProviderEnabled} or + * {@link LocationListener#onStatusChanged}. Alternately, if a + * pending intent was supplied then status and availability updates + * are broadcast intents with extra keys of + * {@link #KEY_PROVIDER_ENABLED} or {@link #KEY_STATUS_CHANGED}. * - * @param provider the name of the provider with which to register - * @param intent a {@link PendingIntent} to be sent for the location update + *

If a {@link LocationListener} is used but with no Looper specified + * then the calling thread must already + * be a {@link android.os.Looper} thread such as the main thread of the + * calling Activity. If a Looper is specified with a {@link LocationListener} + * then callbacks are made on the supplied Looper thread. * - * @throws IllegalArgumentException if provider is null or doesn't exist - * @throws IllegalArgumentException if intent is null - * @throws SecurityException if no suitable permission is present - */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestSingleUpdate(@NonNull String provider, @NonNull PendingIntent intent) { - checkProvider(provider); - checkPendingIntent(intent); - - LocationRequest request = LocationRequest.createFromDeprecatedProvider( - provider, 0, 0, true); - requestLocationUpdates(request, intent); - } - - /** - * Register for a single location update using a Criteria and pending intent. + *

When location callbacks are invoked, the system will hold a wakelock + * on your application's behalf for some period of time, but not + * indefinitely. If your application requires a long running wakelock + * within the location callback, you should acquire it yourself. * - *

See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} - * for more detail on how to use this method. + *

Prior to Jellybean, the minTime parameter was + * only a hint, and some location provider implementations ignored it. + * From Jellybean and onwards it is mandatory for Android compatible + * devices to observe both the minTime and minDistance parameters. * + * @param minTime minimum time interval between location updates, in milliseconds + * @param minDistance minimum distance between location updates, in meters * @param criteria contains parameters for the location manager to choose the * appropriate provider and parameters to compute the location - * @param intent a {@link PendingIntent} to be sent for the location update + * @param intent a {@link PendingIntent} to be sent for each location update * - * @throws IllegalArgumentException if provider is null or doesn't exist + * @throws IllegalArgumentException if criteria is null * @throws IllegalArgumentException if intent is null * @throws SecurityException if no suitable permission is present */ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void requestSingleUpdate(@NonNull Criteria criteria, @NonNull PendingIntent intent) { + public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria, + @NonNull PendingIntent intent) { checkCriteria(criteria); checkPendingIntent(intent); LocationRequest request = LocationRequest.createFromDeprecatedCriteria( - criteria, 0, 0, true); + criteria, minTime, minDistance, false); requestLocationUpdates(request, intent); } @@ -937,433 +1104,206 @@ public class LocationManager { * the recent location is. This is especially useful when the device boots up and the GPS * chipset is in the process of getting the first fix. If the client has cached the location, * it can inject the {@link Location}, so if an app requests for a {@link Location} from {@link - * #getLastKnownLocation(String)}, the location information is still useful before getting - * the first fix.

- * - *

Useful in products like Auto. - * - * @param newLocation newly available {@link Location} object - * @return true if update was successful, false if not - * - * @throws SecurityException if no suitable permission is present - * - * @hide - */ - @RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION}) - public boolean injectLocation(@NonNull Location newLocation) { - try { - return mService.injectLocation(newLocation); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Removes location updates for the specified LocationListener. Following this call, updates - * will no longer occur for this listener. - * - * @param listener listener that no longer needs location updates - * @throws IllegalArgumentException if listener is null - */ - public void removeUpdates(@NonNull LocationListener listener) { - Preconditions.checkArgument(listener != null, "invalid null listener"); - - synchronized (mListeners) { - LocationListenerTransport transport = mListeners.remove(listener); - if (transport == null) { - return; - } - transport.unregisterListener(); - - try { - mService.removeUpdates(transport, null, mContext.getPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - } - - /** - * Removes all location updates for the specified pending intent. Following this call, updates - * will no longer occur for this pending intent. - * - * @param pendingIntent pending intent that no longer needs location updates - * @throws IllegalArgumentException if pendingIntent is null - */ - public void removeUpdates(@NonNull PendingIntent pendingIntent) { - Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); - - try { - mService.removeUpdates(null, pendingIntent, mContext.getPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Set a proximity alert for the location given by the position - * (latitude, longitude) and the given radius. - * - *

When the device - * detects that it has entered or exited the area surrounding the - * location, the given PendingIntent will be used to create an Intent - * to be fired. - * - *

The fired Intent will have a boolean extra added with key - * {@link #KEY_PROXIMITY_ENTERING}. If the value is true, the device is - * entering the proximity region; if false, it is exiting. - * - *

Due to the approximate nature of position estimation, if the - * device passes through the given area briefly, it is possible - * that no Intent will be fired. Similarly, an Intent could be - * fired if the device passes very close to the given area but - * does not actually enter it. - * - *

After the number of milliseconds given by the expiration - * parameter, the location manager will delete this proximity - * alert and no longer monitor it. A value of -1 indicates that - * there should be no expiration time. - * - *

Internally, this method uses both {@link #NETWORK_PROVIDER} - * and {@link #GPS_PROVIDER}. - * - *

Before API version 17, this method could be used with - * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or - * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. - * From API version 17 and onwards, this method requires - * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. - * - * @param latitude the latitude of the central point of the - * alert region - * @param longitude the longitude of the central point of the - * alert region - * @param radius the radius of the central point of the - * alert region, in meters - * @param expiration time for this proximity alert, in milliseconds, - * or -1 to indicate no expiration - * @param intent a PendingIntent that will be used to generate an Intent to - * fire when entry to or exit from the alert region is detected - * - * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} - * permission is not present - */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void addProximityAlert(double latitude, double longitude, float radius, long expiration, - @NonNull PendingIntent intent) { - checkPendingIntent(intent); - if (expiration < 0) expiration = Long.MAX_VALUE; - - Geofence fence = Geofence.createCircle(latitude, longitude, radius); - LocationRequest request = new LocationRequest().setExpireIn(expiration); - try { - mService.requestGeofence(request, fence, intent, mContext.getPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Add a geofence with the specified LocationRequest quality of service. - * - *

When the device - * detects that it has entered or exited the area surrounding the - * location, the given PendingIntent will be used to create an Intent - * to be fired. - * - *

The fired Intent will have a boolean extra added with key - * {@link #KEY_PROXIMITY_ENTERING}. If the value is true, the device is - * entering the proximity region; if false, it is exiting. - * - *

The geofence engine fuses results from all location providers to - * provide the best balance between accuracy and power. Applications - * can choose the quality of service required using the - * {@link LocationRequest} object. If it is null then a default, - * low power geo-fencing implementation is used. It is possible to cross - * a geo-fence without notification, but the system will do its best - * to detect, using {@link LocationRequest} as a hint to trade-off - * accuracy and power. - * - *

The power required by the geofence engine can depend on many factors, - * such as quality and interval requested in {@link LocationRequest}, - * distance to nearest geofence and current device velocity. - * - * @param request quality of service required, null for default low power - * @param fence a geographical description of the geofence area - * @param intent pending intent to receive geofence updates - * - * @throws IllegalArgumentException if fence is null - * @throws IllegalArgumentException if intent is null - * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} - * permission is not present - * - * @hide - */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void addGeofence( - @NonNull LocationRequest request, - @NonNull Geofence fence, - @NonNull PendingIntent intent) { - checkPendingIntent(intent); - checkGeofence(fence); - - try { - mService.requestGeofence(request, fence, intent, mContext.getPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Removes the proximity alert with the given PendingIntent. - * - *

Before API version 17, this method could be used with - * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or - * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. - * From API version 17 and onwards, this method requires - * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. - * - * @param intent the PendingIntent that no longer needs to be notified of - * proximity alerts - * - * @throws IllegalArgumentException if intent is null - * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} - * permission is not present - */ - public void removeProximityAlert(@NonNull PendingIntent intent) { - checkPendingIntent(intent); - String packageName = mContext.getPackageName(); - - try { - mService.removeGeofence(null, intent, packageName); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Remove a single geofence. + * #getLastKnownLocation(String)}, the location information is still useful before getting + * the first fix.

* - *

This removes only the specified geofence associated with the - * specified pending intent. All other geofences remain unchanged. + *

Useful in products like Auto. * - * @param fence a geofence previously passed to {@link #addGeofence} - * @param intent a pending intent previously passed to {@link #addGeofence} + * @param newLocation newly available {@link Location} object + * @return true if update was successful, false if not * - * @throws IllegalArgumentException if fence is null - * @throws IllegalArgumentException if intent is null - * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} - * permission is not present + * @throws SecurityException if no suitable permission is present * * @hide */ - public void removeGeofence(@NonNull Geofence fence, @NonNull PendingIntent intent) { - checkPendingIntent(intent); - checkGeofence(fence); - String packageName = mContext.getPackageName(); - + @RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION}) + public boolean injectLocation(@NonNull Location newLocation) { try { - mService.removeGeofence(fence, intent, packageName); + return mService.injectLocation(newLocation); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Remove all geofences registered to the specified pending intent. - * - * @param intent a pending intent previously passed to {@link #addGeofence} - * - * @throws IllegalArgumentException if intent is null - * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} - * permission is not present + * Removes location updates for the specified LocationListener. Following this call, updates + * will no longer occur for this listener. * - * @hide + * @param listener listener that no longer needs location updates + * @throws IllegalArgumentException if listener is null */ - public void removeAllGeofences(@NonNull PendingIntent intent) { - checkPendingIntent(intent); - String packageName = mContext.getPackageName(); + public void removeUpdates(@NonNull LocationListener listener) { + Preconditions.checkArgument(listener != null, "invalid null listener"); - try { - mService.removeGeofence(null, intent, packageName); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + synchronized (mListeners) { + LocationListenerTransport transport = mListeners.remove(listener); + if (transport == null) { + return; + } + transport.unregisterListener(); + + try { + mService.removeUpdates(transport, null, mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } } /** - * Returns the current enabled/disabled state of location. To listen for changes, see - * {@link #MODE_CHANGED_ACTION}. + * Removes all location updates for the specified pending intent. Following this call, updates + * will no longer occur for this pending intent. * - * @return true if location is enabled and false if location is disabled. + * @param pendingIntent pending intent that no longer needs location updates + * @throws IllegalArgumentException if pendingIntent is null */ - public boolean isLocationEnabled() { - return isLocationEnabledForUser(Process.myUserHandle()); + public void removeUpdates(@NonNull PendingIntent pendingIntent) { + Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); + + try { + mService.removeUpdates(null, pendingIntent, mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** - * Returns the current enabled/disabled state of location. - * - * @param userHandle the user to query - * @return true if location is enabled and false if location is disabled. + * Returns a list of the names of all known location providers. + *

All providers are returned, including ones that are not permitted to + * be accessed by the calling activity or are currently disabled. * - * @hide + * @return list of Strings containing names of the provider */ - @SystemApi - public boolean isLocationEnabledForUser(@NonNull UserHandle userHandle) { + public @NonNull List getAllProviders() { try { - return mService.isLocationEnabledForUser(userHandle.getIdentifier()); + return mService.getAllProviders(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Enables or disables the location setting. - * - * @param enabled true to enable location and false to disable location. - * @param userHandle the user to set + * Returns a list of the names of location providers. * - * @hide + * @param enabledOnly if true then only the providers which are currently + * enabled are returned. + * @return list of Strings containing names of the providers */ - @SystemApi - @TestApi - @RequiresPermission(WRITE_SECURE_SETTINGS) - public void setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle) { - Settings.Secure.putIntForUser( - mContext.getContentResolver(), - Settings.Secure.LOCATION_MODE, - enabled - ? Settings.Secure.LOCATION_MODE_ON - : Settings.Secure.LOCATION_MODE_OFF, - userHandle.getIdentifier()); + public @NonNull List getProviders(boolean enabledOnly) { + try { + return mService.getProviders(null, enabledOnly); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** - * Returns the current enabled/disabled status of the given provider. To listen for changes, see - * {@link #PROVIDERS_CHANGED_ACTION}. - * - * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw - * {@link SecurityException} if the location permissions were not sufficient to use the - * specified provider. - * - * @param provider the name of the provider - * @return true if the provider exists and is enabled + * Returns a list of the names of LocationProviders that satisfy the given + * criteria, or null if none do. Only providers that are permitted to be + * accessed by the calling activity will be returned. * - * @throws IllegalArgumentException if provider is null + * @param criteria the criteria that the returned providers must match + * @param enabledOnly if true then only the providers which are currently + * enabled are returned. + * @return list of Strings containing names of the providers */ - public boolean isProviderEnabled(@NonNull String provider) { - return isProviderEnabledForUser(provider, Process.myUserHandle()); + public @NonNull List getProviders(@NonNull Criteria criteria, boolean enabledOnly) { + checkCriteria(criteria); + try { + return mService.getProviders(criteria, enabledOnly); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** - * Returns the current enabled/disabled status of the given provider and user. Callers should - * prefer {@link #isLocationEnabledForUser(UserHandle)} unless they depend on provider-specific - * APIs. + * Returns the name of the provider that best meets the given criteria. Only providers + * that are permitted to be accessed by the calling activity will be + * returned. If several providers meet the criteria, the one with the best + * accuracy is returned. If no provider meets the criteria, + * the criteria are loosened in the following sequence: * - * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw - * {@link SecurityException} if the location permissions were not sufficient to use the - * specified provider. + *

* - * @param provider the name of the provider - * @param userHandle the user to query - * @return true if the provider exists and is enabled + *

Note that the requirement on monetary cost is not removed + * in this process. * - * @throws IllegalArgumentException if provider is null - * @hide + * @param criteria the criteria that need to be matched + * @param enabledOnly if true then only a provider that is currently enabled is returned + * @return name of the provider that best matches the requirements */ - @SystemApi - public boolean isProviderEnabledForUser( - @NonNull String provider, @NonNull UserHandle userHandle) { - checkProvider(provider); - + public @Nullable String getBestProvider(@NonNull Criteria criteria, boolean enabledOnly) { + checkCriteria(criteria); try { - return mService.isProviderEnabledForUser(provider, userHandle.getIdentifier()); + return mService.getBestProvider(criteria, enabledOnly); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Method for enabling or disabling a single location provider. This method is deprecated and - * functions as a best effort. It should not be relied on in any meaningful sense as providers - * may no longer be enabled or disabled by clients. + * Returns the information associated with the location provider of the + * given name, or null if no provider exists by that name. * - * @param provider the name of the provider - * @param enabled true to enable the provider. false to disable the provider - * @param userHandle the user to set - * @return true if the value was set, false otherwise + * @param name the provider name + * @return a LocationProvider, or null * - * @throws IllegalArgumentException if provider is null - * @deprecated Do not manipulate providers individually, use - * {@link #setLocationEnabledForUser(boolean, UserHandle)} instead. - * @hide + * @throws IllegalArgumentException if name is null or does not exist + * @throws SecurityException if the caller is not permitted to access the + * given provider. */ - @Deprecated - @SystemApi - @RequiresPermission(WRITE_SECURE_SETTINGS) - public boolean setProviderEnabledForUser( - @NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) { - checkProvider(provider); - - return Settings.Secure.putStringForUser( - mContext.getContentResolver(), - Settings.Secure.LOCATION_PROVIDERS_ALLOWED, - (enabled ? "+" : "-") + provider, - userHandle.getIdentifier()); + public @Nullable LocationProvider getProvider(@NonNull String name) { + checkProvider(name); + try { + ProviderProperties properties = mService.getProviderProperties(name); + if (properties == null) { + return null; + } + return new LocationProvider(name, properties); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** - * Get the last known location. - * - *

This location could be very old so use - * {@link Location#getElapsedRealtimeNanos} to calculate its age. It can - * also return null if no previous location is available. - * - *

Always returns immediately. - * - * @return The last known location, or null if not available - * @throws SecurityException if no suitable permission is present + * Returns true if the given package name matches a location provider package, and false + * otherwise. * * @hide */ - @Nullable - public Location getLastLocation() { - String packageName = mContext.getPackageName(); - + @SystemApi + @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) + public boolean isProviderPackage(@NonNull String packageName) { try { - return mService.getLastLocation(null, packageName); + return mService.isProviderPackage(packageName); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + e.rethrowFromSystemServer(); + return false; } } /** - * Returns a Location indicating the data from the last known - * location fix obtained from the given provider. - * - *

This can be done - * without starting the provider. Note that this location could - * be out-of-date, for example if the device was turned off and - * moved to another location. - * - *

If the provider is currently disabled, null is returned. - * - * @param provider the name of the provider - * @return the last known location for the provider, or null + * Sends additional commands to a location provider. Can be used to support provider specific + * extensions to the Location Manager API. * - * @throws SecurityException if no suitable permission is present - * @throws IllegalArgumentException if provider is null or doesn't exist + * @param provider name of the location provider. + * @param command name of the command to send to the provider. + * @param extras optional arguments for the command (or null). + * @return true always */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - @Nullable - public Location getLastKnownLocation(@NonNull String provider) { - checkProvider(provider); - String packageName = mContext.getPackageName(); - LocationRequest request = LocationRequest.createFromDeprecatedProvider( - provider, 0, 0, true); + public boolean sendExtraCommand( + @NonNull String provider, @NonNull String command, @Nullable Bundle extras) { + Preconditions.checkArgument(provider != null, "invalid null provider"); + Preconditions.checkArgument(command != null, "invalid null command"); try { - return mService.getLastLocation(request, packageName); + return mService.sendExtraCommand(provider, command, extras); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1522,22 +1462,294 @@ public class LocationManager { public void clearTestProviderStatus(@NonNull String provider) {} /** - * Get the last list of {@link LocationRequest}s sent to the provider. + * Get the last list of {@link LocationRequest}s sent to the provider. + * + * @hide + */ + @TestApi + @NonNull + public List getTestProviderCurrentRequests(String providerName) { + checkProvider(providerName); + try { + return mService.getTestProviderCurrentRequests(providerName, + mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Set a proximity alert for the location given by the position + * (latitude, longitude) and the given radius. + * + *

When the device + * detects that it has entered or exited the area surrounding the + * location, the given PendingIntent will be used to create an Intent + * to be fired. + * + *

The fired Intent will have a boolean extra added with key + * {@link #KEY_PROXIMITY_ENTERING}. If the value is true, the device is + * entering the proximity region; if false, it is exiting. + * + *

Due to the approximate nature of position estimation, if the + * device passes through the given area briefly, it is possible + * that no Intent will be fired. Similarly, an Intent could be + * fired if the device passes very close to the given area but + * does not actually enter it. + * + *

After the number of milliseconds given by the expiration + * parameter, the location manager will delete this proximity + * alert and no longer monitor it. A value of -1 indicates that + * there should be no expiration time. + * + *

Internally, this method uses both {@link #NETWORK_PROVIDER} + * and {@link #GPS_PROVIDER}. + * + *

Before API version 17, this method could be used with + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. + * From API version 17 and onwards, this method requires + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. + * + * @param latitude the latitude of the central point of the + * alert region + * @param longitude the longitude of the central point of the + * alert region + * @param radius the radius of the central point of the + * alert region, in meters + * @param expiration time for this proximity alert, in milliseconds, + * or -1 to indicate no expiration + * @param intent a PendingIntent that will be used to generate an Intent to + * fire when entry to or exit from the alert region is detected + * + * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} + * permission is not present + */ + @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) + public void addProximityAlert(double latitude, double longitude, float radius, long expiration, + @NonNull PendingIntent intent) { + checkPendingIntent(intent); + if (expiration < 0) expiration = Long.MAX_VALUE; + + Geofence fence = Geofence.createCircle(latitude, longitude, radius); + LocationRequest request = new LocationRequest().setExpireIn(expiration); + try { + mService.requestGeofence(request, fence, intent, mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Removes the proximity alert with the given PendingIntent. + * + *

Before API version 17, this method could be used with + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. + * From API version 17 and onwards, this method requires + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. + * + * @param intent the PendingIntent that no longer needs to be notified of + * proximity alerts + * + * @throws IllegalArgumentException if intent is null + * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} + * permission is not present + */ + public void removeProximityAlert(@NonNull PendingIntent intent) { + checkPendingIntent(intent); + String packageName = mContext.getPackageName(); + + try { + mService.removeGeofence(null, intent, packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Add a geofence with the specified LocationRequest quality of service. + * + *

When the device + * detects that it has entered or exited the area surrounding the + * location, the given PendingIntent will be used to create an Intent + * to be fired. + * + *

The fired Intent will have a boolean extra added with key + * {@link #KEY_PROXIMITY_ENTERING}. If the value is true, the device is + * entering the proximity region; if false, it is exiting. + * + *

The geofence engine fuses results from all location providers to + * provide the best balance between accuracy and power. Applications + * can choose the quality of service required using the + * {@link LocationRequest} object. If it is null then a default, + * low power geo-fencing implementation is used. It is possible to cross + * a geo-fence without notification, but the system will do its best + * to detect, using {@link LocationRequest} as a hint to trade-off + * accuracy and power. + * + *

The power required by the geofence engine can depend on many factors, + * such as quality and interval requested in {@link LocationRequest}, + * distance to nearest geofence and current device velocity. + * + * @param request quality of service required, null for default low power + * @param fence a geographical description of the geofence area + * @param intent pending intent to receive geofence updates + * + * @throws IllegalArgumentException if fence is null + * @throws IllegalArgumentException if intent is null + * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} + * permission is not present + * + * @hide + */ + @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) + public void addGeofence( + @NonNull LocationRequest request, + @NonNull Geofence fence, + @NonNull PendingIntent intent) { + checkPendingIntent(intent); + checkGeofence(fence); + + try { + mService.requestGeofence(request, fence, intent, mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Remove a single geofence. + * + *

This removes only the specified geofence associated with the + * specified pending intent. All other geofences remain unchanged. + * + * @param fence a geofence previously passed to {@link #addGeofence} + * @param intent a pending intent previously passed to {@link #addGeofence} + * + * @throws IllegalArgumentException if fence is null + * @throws IllegalArgumentException if intent is null + * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} + * permission is not present + * + * @hide + */ + public void removeGeofence(@NonNull Geofence fence, @NonNull PendingIntent intent) { + checkPendingIntent(intent); + checkGeofence(fence); + String packageName = mContext.getPackageName(); + + try { + mService.removeGeofence(fence, intent, packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Remove all geofences registered to the specified pending intent. + * + * @param intent a pending intent previously passed to {@link #addGeofence} + * + * @throws IllegalArgumentException if intent is null + * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} + * permission is not present + * + * @hide + */ + public void removeAllGeofences(@NonNull PendingIntent intent) { + checkPendingIntent(intent); + String packageName = mContext.getPackageName(); + + try { + mService.removeGeofence(null, intent, packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + // ================= GNSS APIs ================= + + /** + * Returns the supported capabilities of the GNSS chipset. + * + * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present. + * + * @hide + */ + @SystemApi + @RequiresPermission(ACCESS_FINE_LOCATION) + public @NonNull GnssCapabilities getGnssCapabilities() { + try { + long gnssCapabilities = mService.getGnssCapabilities(mContext.getPackageName()); + if (gnssCapabilities == GnssCapabilities.INVALID_CAPABILITIES) { + gnssCapabilities = 0L; + } + return GnssCapabilities.of(gnssCapabilities); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Returns the model year of the GNSS hardware and software build. More details, such as build + * date, may be available in {@link #getGnssHardwareModelName()}. May return 0 if the model year + * is less than 2016. + */ + public int getGnssYearOfHardware() { + try { + return mService.getGnssYearOfHardware(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Returns the Model Name (including Vendor and Hardware/Software Version) of the GNSS hardware + * driver. * - * @hide + *

No device-specific serial number or ID is returned from this API. + * + *

Will return null when the GNSS hardware abstraction layer does not support providing + * this value. */ - @TestApi - @NonNull - public List getTestProviderCurrentRequests(String providerName) { - checkProvider(providerName); + @Nullable + public String getGnssHardwareModelName() { try { - return mService.getTestProviderCurrentRequests(providerName, - mContext.getOpPackageName()); + return mService.getGnssHardwareModelName(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } + /** + * Retrieves information about the current status of the GPS engine. + * This should only be called from the {@link GpsStatus.Listener#onGpsStatusChanged} + * callback to ensure that the data is copied atomically. + * + * The caller may either pass in a {@link GpsStatus} object to set with the latest + * status information, or pass null to create a new {@link GpsStatus} object. + * + * @param status object containing GPS status details, or null. + * @return status object containing updated GPS status. + * @deprecated GpsStatus APIs are deprecated, use {@link GnssStatus} APIs instead. + */ + @Deprecated + @RequiresPermission(ACCESS_FINE_LOCATION) + public @Nullable GpsStatus getGpsStatus(@Nullable GpsStatus status) { + if (status == null) { + status = new GpsStatus(); + } + // When mGnssStatus is null, that means that this method is called outside + // onGpsStatusChanged(). Return an empty status to maintain backwards compatibility. + GnssStatus gnssStatus = mGnssStatusListenerManager.getGnssStatus(); + int ttff = mGnssStatusListenerManager.getTtff(); + if (gnssStatus != null) { + status.setStatus(gnssStatus, ttff); + } + return status; + } + /** * Adds a GPS status listener. * @@ -1853,27 +2065,6 @@ public class LocationManager { } } - /** - * Returns the supported capabilities of the GNSS chipset. - * - * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present. - * - * @hide - */ - @SystemApi - @RequiresPermission(ACCESS_FINE_LOCATION) - public @NonNull GnssCapabilities getGnssCapabilities() { - try { - long gnssCapabilities = mService.getGnssCapabilities(mContext.getPackageName()); - if (gnssCapabilities == GnssCapabilities.INVALID_CAPABILITIES) { - gnssCapabilities = 0L; - } - return GnssCapabilities.of(gnssCapabilities); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** * No-op method to keep backward-compatibility. * Don't use it. Use {@link #registerGnssNavigationMessageCallback} instead. @@ -1970,66 +2161,6 @@ public class LocationManager { } } - /** - * Retrieves information about the current status of the GPS engine. - * This should only be called from the {@link GpsStatus.Listener#onGpsStatusChanged} - * callback to ensure that the data is copied atomically. - * - * The caller may either pass in a {@link GpsStatus} object to set with the latest - * status information, or pass null to create a new {@link GpsStatus} object. - * - * @param status object containing GPS status details, or null. - * @return status object containing updated GPS status. - */ - @Deprecated - @RequiresPermission(ACCESS_FINE_LOCATION) - public @Nullable GpsStatus getGpsStatus(@Nullable GpsStatus status) { - if (status == null) { - status = new GpsStatus(); - } - // When mGnssStatus is null, that means that this method is called outside - // onGpsStatusChanged(). Return an empty status to maintain backwards compatibility. - GnssStatus gnssStatus = mGnssStatusListenerManager.getGnssStatus(); - int ttff = mGnssStatusListenerManager.getTtff(); - if (gnssStatus != null) { - status.setStatus(gnssStatus, ttff); - } - return status; - } - - /** - * Returns the model year of the GNSS hardware and software build. - * - *

More details, such as build date, may be available in {@link #getGnssHardwareModelName()}. - * - *

May return 0 if the model year is less than 2016. - */ - public int getGnssYearOfHardware() { - try { - return mService.getGnssYearOfHardware(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Returns the Model Name (including Vendor and Hardware/Software Version) of the GNSS hardware - * driver. - * - *

No device-specific serial number or ID is returned from this API. - * - *

Will return null when the GNSS hardware abstraction layer does not support providing - * this value. - */ - @Nullable - public String getGnssHardwareModelName() { - try { - return mService.getGnssHardwareModelName(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** * Returns the batch size (in number of Location objects) that are supported by the batching * interface. @@ -2130,27 +2261,6 @@ public class LocationManager { } } - /** - * Sends additional commands to a location provider. Can be used to support provider specific - * extensions to the Location Manager API. - * - * @param provider name of the location provider. - * @param command name of the command to send to the provider. - * @param extras optional arguments for the command (or null). - * @return true always - */ - public boolean sendExtraCommand( - @NonNull String provider, @NonNull String command, @Nullable Bundle extras) { - Preconditions.checkArgument(provider != null, "invalid null provider"); - Preconditions.checkArgument(command != null, "invalid null command"); - - try { - return mService.sendExtraCommand(provider, command, extras); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - /** * Used by NetInitiatedActivity to report user response * for network initiated GPS fix requests. @@ -2205,119 +2315,6 @@ public class LocationManager { } } - /** - * Returns true if the given package name matches a location provider package, and false - * otherwise. - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) - public boolean isProviderPackage(@NonNull String packageName) { - try { - return mService.isProviderPackage(packageName); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - return false; - } - } - - /** - * Set the extra location controller package for location services on the device. - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) - public void setExtraLocationControllerPackage(@Nullable String packageName) { - try { - mService.setExtraLocationControllerPackage(packageName); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } - - /** - * Set the extra location controller package for location services on the device. - * - * @removed - * @deprecated Use {@link #setExtraLocationControllerPackage} instead. - * @hide - */ - @Deprecated - @SystemApi - @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) - public void setLocationControllerExtraPackage(String packageName) { - try { - mService.setExtraLocationControllerPackage(packageName); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } - - /** - * Returns the extra location controller package on the device. - * - * @hide - */ - @SystemApi - public @Nullable String getExtraLocationControllerPackage() { - try { - return mService.getExtraLocationControllerPackage(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - return null; - } - } - - /** - * Set whether the extra location controller package is currently enabled on the device. - * - * @removed - * @deprecated Use {@link #setExtraLocationControllerPackageEnabled} instead. - * @hide - */ - @SystemApi - @Deprecated - @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) - public void setLocationControllerExtraPackageEnabled(boolean enabled) { - try { - mService.setExtraLocationControllerPackageEnabled(enabled); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } - - /** - * Set whether the extra location controller package is currently enabled on the device. - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) - public void setExtraLocationControllerPackageEnabled(boolean enabled) { - try { - mService.setExtraLocationControllerPackageEnabled(enabled); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } - - /** - * Returns whether extra location controller package is currently enabled on the device. - * - * @hide - */ - @SystemApi - public boolean isExtraLocationControllerPackageEnabled() { - try { - return mService.isExtraLocationControllerPackageEnabled(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - return false; - } - } - private class LocationListenerTransport extends ILocationListener.Stub { private final Executor mExecutor; -- cgit v1.2.3-59-g8ed1b