tools/gpx_replay.py: replay a GPX through the location pipeline #23

Closed
opened 2026-08-31 17:14:42 +02:00 by robert · 1 comment
robert commented 2026-08-31 17:14:42 +02:00 (Migrated from git.butzei.de)

Goal

Make the whole thing testable indoors and repeatably, which matters far more once navigation lands.

Acceptance criteria

  • Reads a GPX and emits positions at a configurable speed multiplier
  • Can drive the Android emulator via mock locations
  • Can drive the companion directly through a debug hook
  • Supports pausing, jumping to an offset and injecting a deliberate off-route excursion
  • Documented in docs/DEV.md

Files

  • tools/gpx_replay.py
## Goal Make the whole thing testable indoors and repeatably, which matters far more once navigation lands. ## Acceptance criteria - [ ] Reads a GPX and emits positions at a configurable speed multiplier - [ ] Can drive the Android emulator via mock locations - [ ] Can drive the companion directly through a debug hook - [ ] Supports pausing, jumping to an offset and injecting a deliberate off-route excursion - [ ] Documented in `docs/DEV.md` ## Files - `tools/gpx_replay.py`
Owner

Closed by PR #105 (merged). Correctly read the issue's actual acceptance criteria from the API rather than trusting the Python-file-path hint or an initial prediction \u2014 turned out to be about driving mock locations into a real emulator/device via a debug hook, not JVM-side algorithm verification, so building tools/gpx_replay.py literally (not a Kotlin harness) was the right call, explicitly justified in the PR.\n\nWhat shipped: a stdlib Python CLI (36 tests, cross-checked against the real ~119km fixture's established ground truth) with three sinks \u2014 print, adb emu geo fix (emulator), and a new debug-only broadcast path (DebugFixReceiver/DebugBridgeLocationSource) for injecting fixes into a real running ride on a real device. The broadcast receiver is registered RECEIVER_NOT_EXPORTED, gated on the real ApplicationInfo.FLAG_DEBUGGABLE platform flag (never true in a signed release build), fully additive alongside real GPS \u2014 zero surface added to production builds. Filled in the slow-lane/tag-lane CI placeholder jobs that were literally named after and hard-failing pending this issue.\n\nHonestly unverified (no adb device/emulator in this sandbox): the emulator and debug-broadcast sinks against a live target, and whether unprivileged adb shell am broadcast reaches a RECEIVER_NOT_EXPORTED receiver on this project's API levels \u2014 both flagged explicitly with a documented fallback (RECEIVER_EXPORTED, with Bastion's review called out as warranted first) if it doesn't work as assumed.\n\nVerified for real: gpx_replay.py's own 36 unit tests, :companion:location:test (14 new), :companion:core:test/:companion:pebble:test unaffected, :companion:assembleDebug clean, manual runs against every real fixture in the repo.

Closed by PR #105 (merged). Correctly read the issue's actual acceptance criteria from the API rather than trusting the Python-file-path hint or an initial prediction \u2014 turned out to be about driving mock locations into a real emulator/device via a debug hook, not JVM-side algorithm verification, so building `tools/gpx_replay.py` literally (not a Kotlin harness) was the right call, explicitly justified in the PR.\n\n**What shipped**: a stdlib Python CLI (36 tests, cross-checked against the real ~119km fixture's established ground truth) with three sinks \u2014 print, `adb emu geo fix` (emulator), and a new debug-only broadcast path (`DebugFixReceiver`/`DebugBridgeLocationSource`) for injecting fixes into a real running ride on a real device. The broadcast receiver is registered `RECEIVER_NOT_EXPORTED`, gated on the real `ApplicationInfo.FLAG_DEBUGGABLE` platform flag (never true in a signed release build), fully additive alongside real GPS \u2014 zero surface added to production builds. Filled in the slow-lane/tag-lane CI placeholder jobs that were literally named after and hard-failing pending this issue.\n\n**Honestly unverified** (no adb device/emulator in this sandbox): the emulator and debug-broadcast sinks against a live target, and whether unprivileged `adb shell am broadcast` reaches a RECEIVER_NOT_EXPORTED receiver on this project's API levels \u2014 both flagged explicitly with a documented fallback (RECEIVER_EXPORTED, with Bastion's review called out as warranted first) if it doesn't work as assumed.\n\nVerified for real: gpx_replay.py's own 36 unit tests, `:companion:location:test` (14 new), `:companion:core:test`/`:companion:pebble:test` unaffected, `:companion:assembleDebug` clean, manual runs against every real fixture in the repo.
Sign in to join this conversation.
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
robert/PedalPebble#23
No description provided.