Loading location/java/android/location/Location.java +12 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.location; import static java.util.concurrent.TimeUnit.NANOSECONDS; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; Loading Loading @@ -585,6 +587,11 @@ public class Location implements Parcelable { return mElapsedRealtimeNanos; } /** @hide */ public long getElapsedRealtimeMillis() { return NANOSECONDS.toMillis(getElapsedRealtimeNanos()); } /** @hide */ public long getElapsedRealtimeAgeNanos(long referenceRealtimeNs) { return referenceRealtimeNs - mElapsedRealtimeNanos; Loading @@ -595,6 +602,11 @@ public class Location implements Parcelable { return getElapsedRealtimeAgeNanos(SystemClock.elapsedRealtimeNanos()); } /** @hide */ public long getElapsedRealtimeAgeMillis() { return NANOSECONDS.toMillis(getElapsedRealtimeAgeNanos()); } /** * Set the time of this fix, in elapsed real-time since system boot. * Loading location/java/android/location/LocationManager.java +24 −5 Original line number Diff line number Diff line Loading @@ -88,6 +88,16 @@ import java.util.function.Consumer; @RequiresFeature(PackageManager.FEATURE_LOCATION) public class LocationManager { /** * For apps targeting Android S and above, location clients may receive historical locations * (from before the present time) under some circumstances. * * @hide */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) public static final long DELIVER_HISTORICAL_LOCATIONS = 73144566L; /** * For apps targeting Android R and above, {@link #getProvider(String)} will no longer throw any * security exceptions. Loading Loading @@ -1256,13 +1266,15 @@ public class LocationManager { * arguments. The same listener may be used across multiple providers with different requests * for each provider. * * <p>It may take a while to receive the first location update. If an immediate location is * required, applications may use the {@link #getLastKnownLocation(String)} method. * <p>It may take some time to receive the first location update depending on the conditions the * device finds itself in. In order to take advantage of cached locations, application may * consider using {@link #getLastKnownLocation(String)} or {@link #getCurrentLocation(String, * LocationRequest, CancellationSignal, Executor, Consumer)} instead. * * <p>See {@link LocationRequest} documentation for an explanation of various request parameters * and how they can affect the received locations. * * <p> If your application wants to passively observe location updates from any provider, then * <p>If your application wants to passively observe location updates from all providers, then * use the {@link #PASSIVE_PROVIDER}. This provider does not turn on or modify active location * providers, so you do not need to be as careful about minimum time and minimum distance * parameters. However, if your application performs heavy work on a location update (such as Loading @@ -1271,13 +1283,20 @@ public class LocationManager { * * <p>In case the provider you have selected is disabled, location updates will cease, and a * provider availability update will be sent. As soon as the provider is enabled again, another * provider availability update will be sent and location updates will immediately resume. * provider availability update will be sent and location updates will resume. * * <p>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. * * <p>Spamming location requests is a drain on system resources, and the system has preventative * measures in place to ensure that this behavior will never result in more locations than could * be achieved with a single location request with an equivalent interval that is left in place * the whole time. As part of this amelioration, applications that target Android S and above * may receive cached or historical locations through their listener. These locations will never * be older than the interval of the location request. * * <p>To unregister for location updates, use {@link #removeUpdates(LocationListener)}. * * @param provider a provider listed by {@link #getAllProviders()} Loading location/java/android/location/LocationRequest.java +13 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; Loading @@ -44,6 +46,17 @@ import java.util.Objects; */ public final class LocationRequest implements Parcelable { /** * For apps targeting Android S and above, all LocationRequest objects marked as low power will * throw exceptions if the caller does not have the LOCATION_HARDWARE permission, instead of * silently dropping the low power part of the request. * * @hide */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) public static final long LOW_POWER_EXCEPTIONS = 168936375L; /** * Represents a passive only request. Such a request will not trigger any active locations or * power usage itself, but may receive locations generated in response to other requests. Loading packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java +0 −2 Original line number Diff line number Diff line Loading @@ -21,8 +21,6 @@ import static android.location.LocationManager.NETWORK_PROVIDER; import static androidx.test.ext.truth.location.LocationSubject.assertThat; import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.location.Criteria; import android.location.Location; Loading services/core/java/com/android/server/location/LocationManagerService.java +26 −24 Original line number Diff line number Diff line Loading @@ -23,10 +23,10 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.location.LocationManager.FUSED_PROVIDER; import static android.location.LocationManager.GPS_PROVIDER; import static android.location.LocationManager.NETWORK_PROVIDER; import static android.location.LocationRequest.LOW_POWER_EXCEPTIONS; import static com.android.server.location.LocationPermissions.PERMISSION_COARSE; import static com.android.server.location.LocationPermissions.PERMISSION_FINE; import static com.android.server.location.LocationProviderManager.FASTEST_COARSE_INTERVAL_MS; import static java.util.concurrent.TimeUnit.NANOSECONDS; Loading @@ -36,6 +36,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.content.Context; import android.content.Intent; import android.location.Criteria; Loading Loading @@ -82,12 +83,12 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.location.LocationPermissions.PermissionLevel; import com.android.server.location.LocationRequestStatistics.PackageProviderKey; import com.android.server.location.LocationRequestStatistics.PackageStatistics; import com.android.server.location.geofence.GeofenceManager; import com.android.server.location.geofence.GeofenceProxy; import com.android.server.location.gnss.GnssManagerService; import com.android.server.location.util.AlarmHelper; import com.android.server.location.util.AppForegroundHelper; import com.android.server.location.util.AppOpsHelper; import com.android.server.location.util.Injector; Loading @@ -97,6 +98,7 @@ import com.android.server.location.util.LocationPowerSaveModeHelper; import com.android.server.location.util.LocationUsageLogger; import com.android.server.location.util.ScreenInteractiveHelper; import com.android.server.location.util.SettingsHelper; import com.android.server.location.util.SystemAlarmHelper; import com.android.server.location.util.SystemAppForegroundHelper; import com.android.server.location.util.SystemAppOpsHelper; import com.android.server.location.util.SystemLocationPermissionsHelper; Loading Loading @@ -569,7 +571,7 @@ public class LocationManagerService extends ILocationManager.Stub { new IllegalArgumentException()); } request = validateAndSanitizeLocationRequest(request, permissionLevel); request = validateLocationRequest(request); LocationProviderManager manager = getLocationProviderManager(provider); Preconditions.checkArgument(manager != null, Loading @@ -591,7 +593,7 @@ public class LocationManagerService extends ILocationManager.Stub { // clients in the system process must have an attribution tag set Preconditions.checkArgument(identity.getPid() != Process.myPid() || attributionTag != null); request = validateAndSanitizeLocationRequest(request, permissionLevel); request = validateLocationRequest(request); LocationProviderManager manager = getLocationProviderManager(provider); Preconditions.checkArgument(manager != null, Loading @@ -600,8 +602,7 @@ public class LocationManagerService extends ILocationManager.Stub { manager.registerLocationRequest(request, identity, permissionLevel, pendingIntent); } private LocationRequest validateAndSanitizeLocationRequest(LocationRequest request, @PermissionLevel int permissionLevel) { private LocationRequest validateLocationRequest(LocationRequest request) { WorkSource workSource = request.getWorkSource(); if (workSource != null && !workSource.isEmpty()) { mContext.enforceCallingOrSelfPermission( Loading @@ -620,26 +621,20 @@ public class LocationManagerService extends ILocationManager.Stub { } LocationRequest.Builder sanitized = new LocationRequest.Builder(request); if (mContext.checkCallingPermission(permission.LOCATION_HARDWARE) != PERMISSION_GRANTED) { sanitized.setLowPower(false); } if (permissionLevel < PERMISSION_FINE) { switch (request.getQuality()) { case LocationRequest.ACCURACY_FINE: sanitized.setQuality(LocationRequest.ACCURACY_BLOCK); break; case LocationRequest.POWER_HIGH: sanitized.setQuality(LocationRequest.POWER_LOW); break; } if (request.getIntervalMillis() < FASTEST_COARSE_INTERVAL_MS) { sanitized.setIntervalMillis(FASTEST_COARSE_INTERVAL_MS); if (CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, Binder.getCallingUid())) { if (request.isLowPower()) { mContext.enforceCallingOrSelfPermission( permission.LOCATION_HARDWARE, "low power request requires " + permission.LOCATION_HARDWARE); } if (request.getMinUpdateIntervalMillis() < FASTEST_COARSE_INTERVAL_MS) { sanitized.clearMinUpdateIntervalMillis(); } else { if (mContext.checkCallingPermission(permission.LOCATION_HARDWARE) != PERMISSION_GRANTED) { sanitized.setLowPower(false); } } if (request.getWorkSource() != null) { if (request.getWorkSource().isEmpty()) { sanitized.setWorkSource(null); Loading Loading @@ -716,7 +711,7 @@ public class LocationManagerService extends ILocationManager.Stub { // clients in the system process must have an attribution tag set Preconditions.checkState(identity.getPid() != Process.myPid() || attributionTag != null); request = validateAndSanitizeLocationRequest(request, permissionLevel); request = validateLocationRequest(request); LocationProviderManager manager = getLocationProviderManager(provider); Preconditions.checkArgument(manager != null, Loading @@ -735,7 +730,7 @@ public class LocationManagerService extends ILocationManager.Stub { // use fine permission level to avoid creating unnecessary coarse locations Location location = gpsManager.getLastLocationUnsafe(UserHandle.USER_ALL, PERMISSION_FINE, false); PERMISSION_FINE, false, Long.MAX_VALUE); if (location == null) { return null; } Loading Loading @@ -1237,6 +1232,7 @@ public class LocationManagerService extends ILocationManager.Stub { private static class SystemInjector implements Injector { private final UserInfoHelper mUserInfoHelper; private final AlarmHelper mAlarmHelper; private final SystemAppOpsHelper mAppOpsHelper; private final SystemLocationPermissionsHelper mLocationPermissionsHelper; private final SystemSettingsHelper mSettingsHelper; Loading @@ -1249,6 +1245,7 @@ public class LocationManagerService extends ILocationManager.Stub { SystemInjector(Context context, UserInfoHelper userInfoHelper) { mUserInfoHelper = userInfoHelper; mAlarmHelper = new SystemAlarmHelper(context); mAppOpsHelper = new SystemAppOpsHelper(context); mLocationPermissionsHelper = new SystemLocationPermissionsHelper(context, mAppOpsHelper); Loading @@ -1275,6 +1272,11 @@ public class LocationManagerService extends ILocationManager.Stub { return mUserInfoHelper; } @Override public AlarmHelper getAlarmHelper() { return mAlarmHelper; } @Override public AppOpsHelper getAppOpsHelper() { return mAppOpsHelper; Loading Loading
location/java/android/location/Location.java +12 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.location; import static java.util.concurrent.TimeUnit.NANOSECONDS; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; Loading Loading @@ -585,6 +587,11 @@ public class Location implements Parcelable { return mElapsedRealtimeNanos; } /** @hide */ public long getElapsedRealtimeMillis() { return NANOSECONDS.toMillis(getElapsedRealtimeNanos()); } /** @hide */ public long getElapsedRealtimeAgeNanos(long referenceRealtimeNs) { return referenceRealtimeNs - mElapsedRealtimeNanos; Loading @@ -595,6 +602,11 @@ public class Location implements Parcelable { return getElapsedRealtimeAgeNanos(SystemClock.elapsedRealtimeNanos()); } /** @hide */ public long getElapsedRealtimeAgeMillis() { return NANOSECONDS.toMillis(getElapsedRealtimeAgeNanos()); } /** * Set the time of this fix, in elapsed real-time since system boot. * Loading
location/java/android/location/LocationManager.java +24 −5 Original line number Diff line number Diff line Loading @@ -88,6 +88,16 @@ import java.util.function.Consumer; @RequiresFeature(PackageManager.FEATURE_LOCATION) public class LocationManager { /** * For apps targeting Android S and above, location clients may receive historical locations * (from before the present time) under some circumstances. * * @hide */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) public static final long DELIVER_HISTORICAL_LOCATIONS = 73144566L; /** * For apps targeting Android R and above, {@link #getProvider(String)} will no longer throw any * security exceptions. Loading Loading @@ -1256,13 +1266,15 @@ public class LocationManager { * arguments. The same listener may be used across multiple providers with different requests * for each provider. * * <p>It may take a while to receive the first location update. If an immediate location is * required, applications may use the {@link #getLastKnownLocation(String)} method. * <p>It may take some time to receive the first location update depending on the conditions the * device finds itself in. In order to take advantage of cached locations, application may * consider using {@link #getLastKnownLocation(String)} or {@link #getCurrentLocation(String, * LocationRequest, CancellationSignal, Executor, Consumer)} instead. * * <p>See {@link LocationRequest} documentation for an explanation of various request parameters * and how they can affect the received locations. * * <p> If your application wants to passively observe location updates from any provider, then * <p>If your application wants to passively observe location updates from all providers, then * use the {@link #PASSIVE_PROVIDER}. This provider does not turn on or modify active location * providers, so you do not need to be as careful about minimum time and minimum distance * parameters. However, if your application performs heavy work on a location update (such as Loading @@ -1271,13 +1283,20 @@ public class LocationManager { * * <p>In case the provider you have selected is disabled, location updates will cease, and a * provider availability update will be sent. As soon as the provider is enabled again, another * provider availability update will be sent and location updates will immediately resume. * provider availability update will be sent and location updates will resume. * * <p>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. * * <p>Spamming location requests is a drain on system resources, and the system has preventative * measures in place to ensure that this behavior will never result in more locations than could * be achieved with a single location request with an equivalent interval that is left in place * the whole time. As part of this amelioration, applications that target Android S and above * may receive cached or historical locations through their listener. These locations will never * be older than the interval of the location request. * * <p>To unregister for location updates, use {@link #removeUpdates(LocationListener)}. * * @param provider a provider listed by {@link #getAllProviders()} Loading
location/java/android/location/LocationRequest.java +13 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; Loading @@ -44,6 +46,17 @@ import java.util.Objects; */ public final class LocationRequest implements Parcelable { /** * For apps targeting Android S and above, all LocationRequest objects marked as low power will * throw exceptions if the caller does not have the LOCATION_HARDWARE permission, instead of * silently dropping the low power part of the request. * * @hide */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) public static final long LOW_POWER_EXCEPTIONS = 168936375L; /** * Represents a passive only request. Such a request will not trigger any active locations or * power usage itself, but may receive locations generated in response to other requests. Loading
packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java +0 −2 Original line number Diff line number Diff line Loading @@ -21,8 +21,6 @@ import static android.location.LocationManager.NETWORK_PROVIDER; import static androidx.test.ext.truth.location.LocationSubject.assertThat; import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.location.Criteria; import android.location.Location; Loading
services/core/java/com/android/server/location/LocationManagerService.java +26 −24 Original line number Diff line number Diff line Loading @@ -23,10 +23,10 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.location.LocationManager.FUSED_PROVIDER; import static android.location.LocationManager.GPS_PROVIDER; import static android.location.LocationManager.NETWORK_PROVIDER; import static android.location.LocationRequest.LOW_POWER_EXCEPTIONS; import static com.android.server.location.LocationPermissions.PERMISSION_COARSE; import static com.android.server.location.LocationPermissions.PERMISSION_FINE; import static com.android.server.location.LocationProviderManager.FASTEST_COARSE_INTERVAL_MS; import static java.util.concurrent.TimeUnit.NANOSECONDS; Loading @@ -36,6 +36,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.content.Context; import android.content.Intent; import android.location.Criteria; Loading Loading @@ -82,12 +83,12 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.location.LocationPermissions.PermissionLevel; import com.android.server.location.LocationRequestStatistics.PackageProviderKey; import com.android.server.location.LocationRequestStatistics.PackageStatistics; import com.android.server.location.geofence.GeofenceManager; import com.android.server.location.geofence.GeofenceProxy; import com.android.server.location.gnss.GnssManagerService; import com.android.server.location.util.AlarmHelper; import com.android.server.location.util.AppForegroundHelper; import com.android.server.location.util.AppOpsHelper; import com.android.server.location.util.Injector; Loading @@ -97,6 +98,7 @@ import com.android.server.location.util.LocationPowerSaveModeHelper; import com.android.server.location.util.LocationUsageLogger; import com.android.server.location.util.ScreenInteractiveHelper; import com.android.server.location.util.SettingsHelper; import com.android.server.location.util.SystemAlarmHelper; import com.android.server.location.util.SystemAppForegroundHelper; import com.android.server.location.util.SystemAppOpsHelper; import com.android.server.location.util.SystemLocationPermissionsHelper; Loading Loading @@ -569,7 +571,7 @@ public class LocationManagerService extends ILocationManager.Stub { new IllegalArgumentException()); } request = validateAndSanitizeLocationRequest(request, permissionLevel); request = validateLocationRequest(request); LocationProviderManager manager = getLocationProviderManager(provider); Preconditions.checkArgument(manager != null, Loading @@ -591,7 +593,7 @@ public class LocationManagerService extends ILocationManager.Stub { // clients in the system process must have an attribution tag set Preconditions.checkArgument(identity.getPid() != Process.myPid() || attributionTag != null); request = validateAndSanitizeLocationRequest(request, permissionLevel); request = validateLocationRequest(request); LocationProviderManager manager = getLocationProviderManager(provider); Preconditions.checkArgument(manager != null, Loading @@ -600,8 +602,7 @@ public class LocationManagerService extends ILocationManager.Stub { manager.registerLocationRequest(request, identity, permissionLevel, pendingIntent); } private LocationRequest validateAndSanitizeLocationRequest(LocationRequest request, @PermissionLevel int permissionLevel) { private LocationRequest validateLocationRequest(LocationRequest request) { WorkSource workSource = request.getWorkSource(); if (workSource != null && !workSource.isEmpty()) { mContext.enforceCallingOrSelfPermission( Loading @@ -620,26 +621,20 @@ public class LocationManagerService extends ILocationManager.Stub { } LocationRequest.Builder sanitized = new LocationRequest.Builder(request); if (mContext.checkCallingPermission(permission.LOCATION_HARDWARE) != PERMISSION_GRANTED) { sanitized.setLowPower(false); } if (permissionLevel < PERMISSION_FINE) { switch (request.getQuality()) { case LocationRequest.ACCURACY_FINE: sanitized.setQuality(LocationRequest.ACCURACY_BLOCK); break; case LocationRequest.POWER_HIGH: sanitized.setQuality(LocationRequest.POWER_LOW); break; } if (request.getIntervalMillis() < FASTEST_COARSE_INTERVAL_MS) { sanitized.setIntervalMillis(FASTEST_COARSE_INTERVAL_MS); if (CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, Binder.getCallingUid())) { if (request.isLowPower()) { mContext.enforceCallingOrSelfPermission( permission.LOCATION_HARDWARE, "low power request requires " + permission.LOCATION_HARDWARE); } if (request.getMinUpdateIntervalMillis() < FASTEST_COARSE_INTERVAL_MS) { sanitized.clearMinUpdateIntervalMillis(); } else { if (mContext.checkCallingPermission(permission.LOCATION_HARDWARE) != PERMISSION_GRANTED) { sanitized.setLowPower(false); } } if (request.getWorkSource() != null) { if (request.getWorkSource().isEmpty()) { sanitized.setWorkSource(null); Loading Loading @@ -716,7 +711,7 @@ public class LocationManagerService extends ILocationManager.Stub { // clients in the system process must have an attribution tag set Preconditions.checkState(identity.getPid() != Process.myPid() || attributionTag != null); request = validateAndSanitizeLocationRequest(request, permissionLevel); request = validateLocationRequest(request); LocationProviderManager manager = getLocationProviderManager(provider); Preconditions.checkArgument(manager != null, Loading @@ -735,7 +730,7 @@ public class LocationManagerService extends ILocationManager.Stub { // use fine permission level to avoid creating unnecessary coarse locations Location location = gpsManager.getLastLocationUnsafe(UserHandle.USER_ALL, PERMISSION_FINE, false); PERMISSION_FINE, false, Long.MAX_VALUE); if (location == null) { return null; } Loading Loading @@ -1237,6 +1232,7 @@ public class LocationManagerService extends ILocationManager.Stub { private static class SystemInjector implements Injector { private final UserInfoHelper mUserInfoHelper; private final AlarmHelper mAlarmHelper; private final SystemAppOpsHelper mAppOpsHelper; private final SystemLocationPermissionsHelper mLocationPermissionsHelper; private final SystemSettingsHelper mSettingsHelper; Loading @@ -1249,6 +1245,7 @@ public class LocationManagerService extends ILocationManager.Stub { SystemInjector(Context context, UserInfoHelper userInfoHelper) { mUserInfoHelper = userInfoHelper; mAlarmHelper = new SystemAlarmHelper(context); mAppOpsHelper = new SystemAppOpsHelper(context); mLocationPermissionsHelper = new SystemLocationPermissionsHelper(context, mAppOpsHelper); Loading @@ -1275,6 +1272,11 @@ public class LocationManagerService extends ILocationManager.Stub { return mUserInfoHelper; } @Override public AlarmHelper getAlarmHelper() { return mAlarmHelper; } @Override public AppOpsHelper getAppOpsHelper() { return mAppOpsHelper; Loading