Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f20b5f03 authored by Soonil Nagarkar's avatar Soonil Nagarkar Committed by Android (Google) Code Review
Browse files

Merge "Fix background request throttling + jitter calculation"

parents 1dab7a7c 6e410506
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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.
     *
+24 −5
Original line number Diff line number Diff line
@@ -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.
@@ -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
@@ -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()}
+13 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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.
+0 −2
Original line number Diff line number Diff line
@@ -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;
+26 −24
Original line number Diff line number Diff line
@@ -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;

@@ -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;
@@ -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;
@@ -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;
@@ -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,
@@ -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,
@@ -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(
@@ -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);
@@ -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,
@@ -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;
            }
@@ -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;
@@ -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);
@@ -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