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

GrapheneOS always returns "gps" location, even if it’s a passive or network location? #1194

Open
op3 opened this issue Jan 25, 2025 · 1 comment

Comments

@op3
Copy link

op3 commented Jan 25, 2025

I am using GrapheneOS on a Google Pixel 8 device. By default, location services are severely limited. Only GPS location data is provided, unless you install Google Play services. More information.

As I understand it, I can take advantage of Google Play geolocation services (but in turn transmit data to Google) if I do the following:

  • Install sandboxed Google Play
  • Enable (precise) location permissions and nearby devices permission for the Google Play services app
  • In the Sandboxed Google Play settings > Location Accuracy, enable “Improve Location Accuracy”
  • In Settings > Location > Location services, enable ”Wi-Fi scanning“ (on) and “Bluetooth scanning” (on).
  • GPSLogger also has precise location permissions (all the time)

I did all of that, so I would assume that GPSLogger is now able to obtain a network location.

“Log GPS/GNSS locations” always works, regardless of the aforementioned steps, as expected. “Log passive locations” also seems to work. However, when I try to use “Log network locations”, GPSlogger never records a position. I checked the log, and encountered the following message:

01-25 15:52:38.449 10712 10712 D GpsLoggingService: onLocationChanged:894 - Received location, but it's not from a selected listener. Ignoring.

I am aware that this is probably a somewhat obscure issue, and might be difficult to debug without a GrapheneOS device. I will try to provide as much information as possible, and I realize that this issue is probably not the most urgent.

I have no experience in Android app development, but to me, it looks like GpsLoggingService.isFromSelectedListener discards events that are returned by the system when requesting network locations. I started a debugger and was able to obtain the following information:

When enabling network locations, this is what the resulting Location object loc looks like:

Location[
  gps
  49.000070,8.000070
  hAcc=1.9628069
  et=+8d7h37m5s261ms
  alt=200.7278070339645
  vAcc=185.53226
  mslAlt=152.57094428886646
  mslAltAcc=185.53246
  vel=0.0
  sAcc=10.684022
  {Bundle[{AGEOFDGPSDATA=null, PASSIVE=false, HDOP=, PDOP=, VDOP=, GEOIDHEIGHT=null, SATELLITES_FIX=0, DGPSID=null, LISTENER=CELL}]}
]

loc.mProvider == "gps", and loc.getProvider() returns gps. Obviously, this is not equal to network, so it is no surprise that isFromSelectedListener will return false. Maybe this is a weirdness of GrapheneOS due to the way location services are implemented? Let me know if it would be appropriate to create an issue with the GrapheneOS project.

I am not sure if I can confidently exclude that this location data was nevertheless determined by GNSS internally by GrapheneOS? Interestingly, mExtras specifies that LISTENER=CELL.

For comparison, this is what a proper GNSS/GPS Location looks like:

Location[
  gps
  49.000068,8.000026
  hAcc=10.705652
  et=+8d7h48m5s694ms
  alt=226.2114116305497
  vAcc=43.343197
  mslAlt=178.05454888545165
  mslAltAcc=43.344036
  {Bundle[{AGEOFDGPSDATA=null, PASSIVE=false, HDOP=6.1, PDOP=6.2, VDOP=1.0, GEOIDHEIGHT=47.9, SATELLITES_FIX=7, DGPSID=null, LISTENER=GPS}]}
]

You can see that xDOP and the number of satellites are available.

For completeness, I also had a look at passive locations. This is what Location loc looks like for a passive GNSS location:

Location[
  gps
  49.000051,8.000094
  hAcc=33.029816
  et=+8d8h32m24s817ms
  alt=200.32551767419048
  vAcc=46.640938
  mslAlt=152.16865492909244
  mslAltAcc=46.64172
  vel=0.0
  sAcc=1.3822131
  {Bundle[{AGEOFDGPSDATA=null, PASSIVE=true, HDOP=null, PDOP=null, VDOP=null, GEOIDHEIGHT=null, SATELLITES_FIX=0, DGPSID=null, LISTENER=PASSIVE}]}
]

I am not sure why xDOP or the number of satellites are missing or zero. They were displayed in the other app (Network Survey) that I used to request the location data.

And finally, (I assume), a passive network event:

Location[
  gps
  49.000000,8.000075
  hAcc=7.0
  et=+8d8h34m33s90ms
  alt=271.0
  vAcc=118.0
  mslAlt=232.84313725490196
  mslAltAcc=128.000305
  vel=0.0
  sAcc=1.140625
  {Bundle[{AGEOFDGPSDATA=null, PASSIVE=true, HDOP=, PDOP=, VDOP=, GEOIDHEIGHT=null, SATELLITES_FIX=0, DGPSID=null, LISTENER=PASSIVE}]}
]

I am not sure if this is universally applicable, but at least in my case, the GPSlogger settings seem to align with the loc.mExtras.LISTENER value, and not loc.mProvider. Maybe it would be better to check loc.getExtras().getString(BundleConstants.LISTENER) instead?

@mendhak
Copy link
Owner

mendhak commented Feb 4, 2025

That's quite a good bit of troubleshooting and honing in on the problem, it helped me look at my codebase to see where all of this is coming from. It's an old codebase now so I need reminders and hints.

Bad news, that LISTENER field is something being added in this app, it's only there for troubleshooting but not necessarily something to rely on.

I tried to find out if there's something going on with Graphene and network, and I did find this comment:

https://discuss.grapheneos.org/d/79-location-not-working/6

which says

Yes that is making the difference, the OS does not have a network location provider service integrated into the OS.
Also in so far as having a configurable network location provider the really big problem and reason they are blocked is because they can ALSO be used to lie to apps, even though your use might be "normal".
We aren't going to add support for something like UnifiedNLP into the system, which would undermine the security model, bypassing the signature enforcement model, for location providers. It is simply antithetical to the projects aims.

So assuming that statement is still true, I think the network bit might be a bit of a red herring, in that it's still actually GPS being reported and GrapheneOS is doing some kind of 'fill' to make the app think that there is a network provider. In turn that would mean that the Provider = GPS value that GrapheneOS is giving is actually correct!

I haven't used GrapheneOS in several years and unfortunately no spare device to test with. But probably it's worth trying to verify and make sure that statement is still true?

I'm leaning towards it might still be true, because I found this other thread which is talking about collecting beacon information to help with a Network Location Provider implementation. https://discuss.grapheneos.org/d/17089-users-contribute-location-data-for-future-network-location-usage

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

No branches or pull requests

2 participants