This directory contains the native Termux build workflow used to exercise OpenRoadCode directly on Android hardware.
The current target combines:
8766;proot-distro;~/.local/share/openroadcode.CarUi keeps the shared runtime composition in config/runtime.toml and selects config/applications.termux.toml for Termux-specific application behavior. config/runtime.termux.toml is the explicit Android/Termux navigation and sensor-service profile through OPENROAD_RUNTIME_CONFIG.
Android devices do not share one GPU architecture, so OpenRoadCode does not assume a particular video driver. development/termux/configure_graphics.sh inspects the device and selects only a graphics backend that the installed Termux repositories can support.
Run detection without changing packages:
Install the packages selected for the detected device:
The first validated native Termux hardware path is Qualcomm/Adreno. On a device exposing the KGSL interface, when the Termux repository supplies mesa-vulkan-icd-freedreno, the selected stack is:
For that native Termux backend, OpenGL applications should be launched with:
Validate each layer independently when bringing up a new device. When the corresponding diagnostic packages are installed, useful probes are:
Do not install every Mesa Vulkan ICD indiscriminately and do not assume Freedreno on Mali, PowerVR, or other GPU families. Unknown devices retain the basic/software graphics path until a hardware backend has been validated. Application launchers should consume the selected graphics environment rather than hard-coding a GPU vendor.
Chromium launched under Termux:X11 should use --password-store=basic so it does not depend on a desktop password-keyring service. GPU-specific Chromium flags should remain platform/runtime configuration rather than UI code.
For the native Chromium/WebGL alternative-map experiment, see Google Earth navigation.
Debian applications running under proot-distro use glibc and cannot safely load Termux/Bionic Turnip libraries directly. For graphical Debian games, OpenRoadCode instead supports Mesa virpipe with Termux virglrenderer-android:
Install the Android VirGL server package when using this path:
The Debian command runner starts virgl_test_server_android on demand when it is installed and exposes the shared socket to Debian with proot-distro --shared-tmp. It sets GALLIUM_DRIVER=virpipe for that Debian process only. This is intentionally separate from the native Termux Zink/Turnip environment.
SuperTuxKart is configured to use its OpenGL renderer rather than Vulkan on this path. Debian Vulkan may otherwise select a software renderer even when OpenGL through VirGL is accelerated.
GNOME 2048, GNOME Nibbles, and GNOME Sudoku are enabled for a Termux/X11 trial. Their proot configuration uses rendering = "auto" and GSK_RENDERER=gl to select GTK OpenGL through the same VirGL bridge. Live device rendering, input, embedding, and exit behavior remain unverified. GTK versions that do not use GSK may ignore this renderer setting.
On the device, switch to the branch containing this trial before pulling or testing. Close ORC, run ./development/termux/install_games.sh, then restart ORC in the usual Termux/X11 session. Install each game through the Games panel and test one at a time:
To inspect the Debian OpenGL renderer after launching a game has started the bridge, install mesa-utils inside Debian if needed and run in Termux:
Record the renderer string and any game errors. virgl indicates the bridge; llvmpipe or softpipe indicates software rendering. This probe alone does not prove that an individual game uses GPU rendering or performs well. Compare failures with the previous software configuration by setting that game's rendering = "software" and GSK_RENDERER = "cairo" in config/games.toml, then restarting ORC. Set enabled = false to hide a failing game again.
The ORC UI Games panel reads config/games.toml, discovers installed/available packages asynchronously, and supports both Termux packages and Debian packages. Install the Termux-side game prerequisites with:
The Games frontend requires xdotool for X11 embedding. When a Debian game is selected, the controller chooses the Debian backend without exposing whether Debian is native or hosted through proot-distro to the UI.
The game browser adapts its columns to the window size and font metrics. Narrow Termux/X11 windows show one column. Each full page keeps six games; short windows scroll vertically instead of hiding games or stretching cards. Use PREV/NEXT to navigate between pages. Titles and descriptions wrap above the action button, and installation status appears below the wrapping filters.
While a game is active, ORC replaces the category browser with an EXIT GAME control and reparents the game's X11 window into the Games content area. Closing a game through its own menu is also detected and returns the panel to the game browser. Window embedding is best effort because third-party games can create helper processes or reposition their own top-level windows; the X11 frontend searches the launched process tree and reasserts the ORC host geometry during startup.
Navigation data is intentionally separated by responsibility:
Position does not conceptually own speed or course. A physical provider may deliver those values with a location sample, but normalized OpenRoadCode consumers remain insulated from the provider-specific transport.
The current Termux navigation profile uses the Android bridge as its physical position source and keeps IMU simulation available so navigation remains usable when Android motion integration is unavailable. The map consumes the normalized navigation position contract rather than talking directly to Android.
Simulate on an active route now generates positions inside ORC's navigation service. The Android bridge stays on real GPS. Stop simulation, End route, arrival, or a service restart restores normal position input. This Python change requires restarting openroadcode-navigation, but no renderer rebuild. After updating, test a short route through playback, stop, arrival, and restart; verify that live position returns. The full native renderer/theme-toggle test and live weather-provider probes still need device verification; CI does not prove GPU rendering. See Weather component probes.
PySerial is intentionally not a Termux dependency. Android/Termux automotive hardware uses the Android bridge and TCP transport rather than opening a serial device directly from Termux.
The ELM327 stack keeps transport selection behind the common stream-transport interface. Physical Linux targets may select the serial backend when PySerial is installed, while Android/Termux injects the TCP transport exposed by the bridge. Importing the OBD-II controller stack or running transport-injected/simulated tests must not require PySerial merely to collect or import the modules.
For the validated KONNWEI/ELM327 Android path, the bridge exposes the Bluetooth SPP connection through localhost TCP. This keeps Bluetooth ownership in Android while OpenRoadCode consumes the same ELM327 protocol through a platform-neutral byte stream.
The script installs/builds native dependencies and prints the resulting paths. Termux:X11 normally uses display :1; override it with X11_DISPLAY when needed.
With the openroadcode-android-bridge application running:
A healthy /location response is consumed by AndroidPositionSource and published by the normal navigation service. This keeps map-follow and other consumers independent of the Android bridge API.
Install Termux service supervision once:
Restart the Termux shell after first installing termux-services, then from the repository root run:
Start and inspect the supervised services with:
Stop them with:
The runit definitions call the same runtime wrappers used by the Linux service installation where applicable. Termux-specific service definitions live under scripts/runit/. Runtime-generated supervise/ directories are state, not source, and must never be committed to the repository.
Valhalla runs as the supervised openroadcode-valhalla runit service when the core stack is requested; it remains down after installation. The navigation build installs its service definition along with the core services. The Termux build installs it under $PREFIX/opt/openroadcode/navigation/valhalla/bin/valhalla_service, while deployed routing data lives under ~/.local/share/openroadcode/valhalla.
For an existing installation, register the new service once (stop any manually launched Valhalla first):
The wrapper detects Termux, reads the installed valhalla.json, and writes a prepared copy under $PREFIX/tmp/openroadcode-valhalla. It relocates IPC sockets, standard routing data, optional data paths, and Linux log paths into writable Termux locations. The downloaded source configuration stays unchanged. Run the wrapper again after pulling new routing data; no manual JSON edits are needed. VALHALLA_CONFIG, VALHALLA_BIN, VALHALLA_DATA_ROOT, and VALHALLA_RUNTIME_ROOT can override the defaults. Runit owns startup, crash restarts, and shutdown; no dedicated terminal is needed. Rotating logs for every supervised service are available under ~/.local/state/openroadcode/log/<service>/current. The service-manager core start/stop operations include Valhalla. For foreground debugging only, stop the supervised service before running ./scripts/runtime/start_valhalla.sh.
Verify the service with:
The Termux application profile uses the ADS-B producer source simulation. This keeps presentation testing independent of RTL-SDR hardware and Linux readsb/systemd service management.
Install the tar1090 presentation files once:
The setup uses the tar1090 revision pinned in scripts/installers/toolchain.lock; set TAR1090_REF only for an intentional test of another revision.
After scripts/runit/install_termux_services.sh has installed the service, openroadcode-adsb owns the local tar1090 web server on port 8081.
The native MapLibre renderer uses offline vector tiles under ~/.local/share/openroadcode/maps/vector/openroadcode.mbtiles. Map commands are published on the OpenRoadCode message bus using the map.command topic. Position telemetry and camera control remain separate so a manual pan does not move the vehicle marker.
The active navigation/map path is:
Route planning uses the local Valhalla HTTP service on port 8002. The route-to-map component test can use the real Valhalla service while recording renderer commands:
To publish the resulting route to a running renderer through the normal broker path, add --external-renderer.
Start Termux:X11/XFCE first. When X11 is managed by runit, do not start a duplicate server on the same display.
Then launch the ORC UI from a Termux/X11 shell with the broker and navigation service already running:
The current ORC UI navigation map supports shared camera state between Home and Navigation views, follow/recenter behavior, screen-relative panning, route overlays, live vehicle position, and focused POI categories. The Games panel can launch installed native/hosted Linux games into its X11 content host. Browser-backed launchers use the selected X11 display and Chromium is started with --password-store=basic.
The runtime target pulls validated map/routing data from a map-build machine. The map-build machine publishes a validated dataset; the target decides when to update itself. The Termux-native target stores deployed navigation data under ~/.local/share/openroadcode. Use development/termux/pull_navigation_data.sh for the Android/Termux path where applicable.
Vector-map content and routing data are generated from source datasets and should not be assumed to contain every real-world business. UI POI highlighting operates on features present in the deployed vector tiles.
The broad Python suite runs under Termux with platform-specific hardware tests skipped when their Linux-only dependencies are unavailable. Component tests supplement automated tests where real hardware, native services, X11, Android integration, or game packages are required.
Close ORC, then update the native renderer without rebuilding MapLibre or Valhalla:
The renderer-only option installs renderer build dependencies, including libspdlog for structured logging, before compiling. It requires the existing apps/map_renderer/build-termux directory configured by build_navigation_stack.sh. Compilation must succeed before the installed executable is replaced. No map-data download is needed.