Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stale location reported when backend calls report(null) #75

Closed
mvglasow opened this issue Mar 15, 2016 · 8 comments · Fixed by #77
Closed

Stale location reported when backend calls report(null) #75

mvglasow opened this issue Mar 15, 2016 · 8 comments · Fixed by #77

Comments

@mvglasow
Copy link

This came out of an issue in the openBmap backend, openbmap/radiocells-nlp-android#13: After getting stale locations under some circumstances, I did some investigations and introduced some modifications into the backend.

The backend does a combined cell/wifi lookup, either online or using an offline DB (all my tests were done with the offline DB).

Steps to reproduce:

  1. Fire up an appropriate app in an environment with known wifis. I used SatStat, available on F-Droid, which visualizes both GPS and network location along with their accuracies. Check location, then return to home screen making sure no other app requests location updates).
  2. Move to a location with no known cells and wifis at all, and fire up the app again.

The first step behaved as I expected: the modified backend gave me a crisp (+/- 20 m) location. The second step was performed some 5 minutes after leaving the previous location. SatStat claimed I was still within 20 meters of the old location, even after I killed and restarted it (to rule out any caching in SatStat).

Analyzing the logcat, I find that I originally had 26 wifis in range, from which the backend calculated a location and reported it. In the metro station, the backend reported that no wifis were in range and the only visible cell was not in the DB. It reported a null location, resulting in a call to report() with a null argument. Then, however, UnifiedNLP (specifically NlpLocationBackendFuser) reports the same location it has given out 5 minutes before, with the same et=+15d21h34m50s905ms (which I suppose is the timestamp) and the same accuracy acc=20.

Are backends supposed to call report(null) when they are unable to determine the current location, or should they simply not call report() at all? This should probably be documented in the API README.

In any case, the fuser probably should not give out old locations unmodified: when processing any location, its accuracy should be penalized based on its age (if you're interested, I can provide a link to my branch of the openBmap backend for an example on how to fuse locations of different ages) and the resulting location should have a recent timestamp.

@n76
Copy link
Contributor

n76 commented Mar 15, 2016

FWIW, on my local WiFi backend I ran into this or at least a very similar same issue: If no WiFi position was available (backend returns null) the last known position was being given to apps rather than a current location with a worse accuracy value from a mobile/cell based backend. I "fixed" that by always reporting a position but increasing the uncertainty based on time since last good fix (IIRC, I assumed a speed of 100 K/h to grow the uncertainty).

@mvglasow
Copy link
Author

Yep, that's how I'm dealing with it as well when I get stale data – the thing is that Android wifi scan results can also be several seconds old at times, and I penalize them in the same way. Currently I assume 20 m/s (72 km/h) for speed. That's what I meant by penalizing.

Update: looking at the backend code in detail, I realize report() never gets called when we can't determine the location. update() always returns null.

In the end, reporting an old location but "tweaking" its accuracy is just a workaround. When the backend can't determine a reliable location, it should honestly say so by reporting a null location (or no location at all), and the fuser should ultimately do the same. Android has separate API calls to get the last known location of a location provider. Apps which just need a location, no matter how old, can use that call, while apps registering for periodic updates likely expect up-to-date information. IMHO UnifiedNLP should play nicely with that assumption (the GPS provider works that way as well).

@mar-v-in
Copy link
Member

report(null) effectively does nothing. It's not possible to remove the location from UnifiedNlp as it is required to report last location. However you are right that old locations should not be published. I will check how the behavior for this is with Google's provider - it might also be that it's not possible to not report a location at all as Google always knows at least something very inaccurate about your current location ;)

@n76
Copy link
Contributor

n76 commented Mar 16, 2016

". . .as Google always knows at least something very inaccurate about your current location ;)" Bonus points for UnifiedNlp for having backends that can work with no data connection!

@mvglasow
Copy link
Author

it might also be that it's not possible to not report a location at all

I have yet to look at the source code, but the API calls I was referring to are the various forms of LocationManager.requestLocationUpdates() and LocationManager.getLastKnownLocation().

For the latter of the two, it is totally OK to give a previously reported location, no matter how old. Apps using this call should be aware of its implications and take into account the possibility of the device having moved since.

The former of the calls registers a listener for periodic updates. Making that call alone won't retrieve any location updates yet. Sending these updates is then the job of the location provider, which should thus have control over when to send an update.

Google always knows at least something very inaccurate about your current location

Are you referring to GApps? They might just be using LocationManager.getLastKnownLocation(). Or do you mean that Google's network location provider always seems to know where you are? If you were to wipe a device and then boot it without a SIM card, it would have no previous location, no way to reach its cloud backend and thus no way to report any remotely valid location. They must have covered that case somehow...

@mvglasow
Copy link
Author

I've had a look at the code. mvglasow@e8158cb (not yet tested) should modify the behavior to send out updates only when at least one backend has reported a non-null location.

What I didn't find is any processing for getLastKnownLocation() – do location providers have to implement logic for that, or does Android simply cache the last location delivered? In the latter case, we should be good.

@mvglasow
Copy link
Author

I successfully built and installed my modified version. Note that swapping an installed APK against one with a different signature requires a reboot before the new version will work.

"Results are encouraging" (as in: starts without crashing and even delivers location updates which look correct), I still need to test what happens when the backend stops supplying location updates.

@mvglasow
Copy link
Author

Ran a test in a tunnel: a certain distance into the tunnel, UnifiedNLP stops supplying location updates and resumes around the exit. Backend used was openBmap in offline mode, with a wifi-only catalog. This is the behavior I would expect from a location provider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants