lomiri-location-service GPS reliability patches (navius branch, v3.4.1+navius5)
-
lomiri-location-service GPS reliability patches (navius branch, v3.4.1+navius5)
While building Navius (a GPS navigator for Ubuntu Touch) I ran into several GPS reliability issues in
lomiri-location-service, particularly on devices that run Waydroid alongside UT.I have collected the fixes in a branch called navius (currently at navius5). All patches are tested on a Xiaomi Redmi Note 9 Pro (HALIUM_10, arm64) running Ubuntu Touch Noble (24.04), but they address generic race conditions and watchdog issues that should benefit any device.
I would like to share them here and eventually propose the relevant ones upstream.
Bugs fixed
1. Waydroid GPS callback race → SIGSEGV
navius1On HALIUM_10, Waydroid and Ubuntu Touch both access the GPS HAL via
host_hwbinder. Waydroid can callregister_callbacks()at any time; that function doesu_hardware_gps_delete()+u_hardware_gps_new(). If a GPS callback fires between those two calls it dereferences the freed handle — SIGSEGV, daemon crash.Fix:
std::shared_mutex callback_mutexinImpl. All seven GPS callbacks hold a shared lock (run concurrently with each other).register_callbacks()holds an exclusive lock only while deleting/installing the handle — callbacks complete first, then the swap happens safely.2. EDEADLK at service start
navius1The initial mutex fix held the exclusive lock across the whole delete → new sequence.
u_hardware_gps_new()fireson_set_capabilitiessynchronously on the calling thread, which tries to take a shared lock on the same mutex: EDEADLK, daemon aborts at start-up.Fix: Three-phase lock:
- Exclusive lock → delete old handle → release.
- Create new handle without any lock (re-entrant callbacks are now safe).
- Exclusive lock → install new handle → dispatch position mode → release.
3.
start_positioning()blocking the daemon forevernavius2start_positioning()was called from a D-Bus handler thread. Its internalQEventLoopblocked that thread indefinitely. LLS started, satellites were tracked, but no position fix ever arrived.Fix:
start_positioning()dispatched to the main thread viaQt::QueuedConnection/QMetaObject::invokeMethod.4. GPS stops after Waydroid closes and never restarts
navius4When Waydroid shuts down it calls
u_hardware_gps_stop()on the shared HAL, halting GPS globally. LLS's handle remained valid so it never detected the stall — GPS frozen until LLS was manually restarted.Fix — watchdog thread: a detached thread ticks every 5 s and reads
last_gps_ms(updated byon_location_updateandon_sv_status_update). If no GPS data for 10 s, it re-runsregister_callbacks()and restarts the chipset automatically.5. No fixes despite 37+ satellites in view
navius4dispatch_updated_modes_to_driver()(which sends the position mode to the chipset viau_hardware_gps_set_position_mode()) was called inregister_callbacks()but not in the fast path insidestart_positioning(). The chipset tracked satellites but never computed fixes.Fix: call
dispatch_updated_modes_to_driver()beforeu_hardware_gps_start()in the fast path.Result after navius4: Waydroid and Ubuntu Touch GPS now work simultaneously. After Waydroid opens and steals the HAL, the watchdog reclaims callbacks within 10 s; accuracy converges to ~4 m while Waydroid keeps positioning.
Feature additions
GetVisibleSpaceVehiclesD-Bus methodnavius2QML clients that cannot subscribe to D-Bus property-change signals have no way to get a satellite snapshot without keeping a persistent session. Added a synchronous method and read-only property
VisibleSpaceVehiclesto the service interface:dbus-send --system --dest=com.lomiri.location.Service \ --print-reply \ /com/lomiri/location/Service \ com.lomiri.location.Service.Interface.GetVisibleSpaceVehiclesCompile-time debug traces (
LLS_DEBUG)navius5All GPS trace logging is gated behind
LLS_DEBUG(defaultfalse) ininclude/…/lls_trace.h. Zero runtime cost when disabled; set totrueand rebuild for full per-fix traces in journald.
Build & install
The branch ships a
build-deb.shscript that produces a.debinside an isolated Docker container (Ubuntu 24.04 + UBports repo). No host modifications needed. Requires Docker on an ARM64 host.git clone https://github.com/woodyst/lomiri-location-service -b navius cd lomiri-location-service bash build-deb.sh # output to ./debs/# Deploy to device scp debs/liblomiri-location-service3_*_arm64.deb phablet@<device>:/tmp/ ssh root@<device> "mount -o remount,rw / && \ dpkg -i /tmp/liblomiri-location-service3_*_arm64.deb && \ systemctl restart lomiri-location-service"
Upstream proposal
I intend to open two MRs on gitlab.com/ubports/…/lomiri-location-service:
MR What Status MR 1 Bug fix: mutex/EDEADLK race in register_callbacks()Ready to propose MR 2 Feature: GetVisibleSpaceVehiclesD-Bus methodReady, needs API discussion — Watchdog thread, LLS_DEBUG, build script Navius-specific; not proposing upstream Before opening the MRs I wanted to share the work here and get feedback, especially on whether there is already upstream work addressing the Waydroid race condition or the
GetVisibleSpaceVehiclesAPI.Any review or testing on other devices is very welcome. Full patch documentation: doc/navius-patches.md.
-
I misstyped the patch documentation link. Te correct one is: https://github.com/woodyst/lomiri-location-service/blob/main/doc/navius-patches.md
-
What is the Navius app, exactly?
-
@projectmoon A GPS Navigator. I was a lot of time searching for a GPS navigator with the functionality I like for me, but I didn't found anyone. So I decided to code my own. I'm reviewing it now for publishing it.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login