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

Commit f1be6861 authored by Nick Pelly's avatar Nick Pelly
Browse files

Enforce the minTime parameter in LocationManager#requestLocationUpdates

There is a long history in Android, on both GED and non GED devices
of GPS providers ignoring the minTime parameter making location updates
every second. The problem is usually poor GPS drivers that claim to
do scheduling but then do not.

By making the minTime parameter strict (instead of a hint) we can add
a CTS test to ensure that udpates to not occur too frequently. I believe
this is the desired behavior from apps. If apps want to take advantage
of more frequent updates when another application asks for those updates
then it can use the passive provider.

The CTS test for GPS has already been submitted (as part of CTS Verifier).

Bug: 6424983
Change-Id: I163b9e44ea7ab71530b86fc2282614e0150e90f1
parent c1c14065
Loading
Loading
Loading
Loading
+259 −134

File changed.

Preview size limit exceeded, changes collapsed.

+20 −11
Original line number Diff line number Diff line
@@ -105,6 +105,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    private static final String INSTALL_LOCATION_PROVIDER =
        android.Manifest.permission.INSTALL_LOCATION_PROVIDER;

    // Location Providers may sometimes deliver location updates
    // slightly faster that requested - provide grace period so
    // we don't unnecessarily filter events that are otherwise on
    // time
    private static final int MAX_PROVIDER_SCHEDULING_JITTER = 100;

    // Set of providers that are explicitly enabled
    private final Set<String> mEnabledProviders = new HashSet<String>();

@@ -194,8 +200,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        final PendingIntent mPendingIntent;
        final Object mKey;
        final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>();

        int mPendingBroadcasts;
        String requiredPermissions;
        String mRequiredPermissions;

        Receiver(ILocationListener listener) {
            mListener = listener;
@@ -286,7 +293,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                        // synchronize to ensure incrementPendingBroadcastsLocked()
                        // is called before decrementPendingBroadcasts()
                        mPendingIntent.send(mContext, 0, statusChanged, this, mLocationHandler,
                                requiredPermissions);
                                mRequiredPermissions);
                        // call this after broadcasting so we do not increment
                        // if we throw an exeption.
                        incrementPendingBroadcastsLocked();
@@ -322,7 +329,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                        // synchronize to ensure incrementPendingBroadcastsLocked()
                        // is called before decrementPendingBroadcasts()
                        mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler,
                                requiredPermissions);
                                mRequiredPermissions);
                        // call this after broadcasting so we do not increment
                        // if we throw an exeption.
                        incrementPendingBroadcastsLocked();
@@ -362,7 +369,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                        // synchronize to ensure incrementPendingBroadcastsLocked()
                        // is called before decrementPendingBroadcasts()
                        mPendingIntent.send(mContext, 0, providerIntent, this, mLocationHandler,
                                requiredPermissions);
                                mRequiredPermissions);
                        // call this after broadcasting so we do not increment
                        // if we throw an exeption.
                        incrementPendingBroadcastsLocked();
@@ -374,6 +381,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
            return true;
        }

        @Override
        public void binderDied() {
            if (LOCAL_LOGV) {
                Slog.v(TAG, "Location listener died");
@@ -1155,10 +1163,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run

        LocationProviderInterface p = mProvidersByName.get(provider);
        if (p == null) {
            throw new IllegalArgumentException("provider=" + provider);
            throw new IllegalArgumentException("requested provider " + provider +
                    " doesn't exisit");
        }
        receiver.requiredPermissions = checkPermissionsSafe(provider,
                receiver.requiredPermissions);
        receiver.mRequiredPermissions = checkPermissionsSafe(provider,
                receiver.mRequiredPermissions);

        // so wakelock calls will succeed
        final int callingPid = Binder.getCallingPid();
@@ -1752,9 +1761,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
            return true;
        }

        // Don't broadcast same location again regardless of condition
        // TODO - we should probably still rebroadcast if user explicitly sets a minTime > 0
        if (loc.getTime() == lastLoc.getTime()) {
        // Check whether sufficient time has passed
        long minTime = record.mMinTime;
        if (loc.getTime() - lastLoc.getTime() < minTime - MAX_PROVIDER_SCHEDULING_JITTER) {
            return false;
        }