GrapheneOS always returns "gps" location, even if it’s a passive or network location?
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?
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