Skip to content

Repository files navigation

Denza Lab

Android apps, remote tooling, and field research for Denza / BYD head units.

Android 8+ Kotlin 2.3.21 Go Gradle 9.4.1 Project status: active lab

A working lab for Denza / BYD head-unit apps, remote access, and the reverse-engineering notes behind them. Product code, infrastructure, and experiments live in separate parts of the repository.

Important

Compatibility and responsibility. All research, development, and live validation in this repository has been performed exclusively on the author's Denza Z9GT, using the particular firmware builds installed at the time of each test. Compatibility with other vehicles, model years, regional configurations, head-unit revisions, or firmware versions has not been established and is not guaranteed. A vehicle or firmware update may change or disable previously verified behavior.

Denza Lab is an independent hobby and research project, not an official Denza or BYD product. The software interacts with undocumented vehicle services and is provided without warranties of functionality, compatibility, reliability, or safety. You are solely responsible for evaluating the risks, keeping a recovery path available, and using the software only when it is safe to do so. Use this project and its applications entirely at your own risk.

Portfolio

Lifecycle Component Purpose
Active apps/car-adb-gateway/ Generic, relay-only remote ADB gateway with one trusted computer and a self-healing Android service.
Active apps/denza-apps/ Simulcast, side-camera mirrors, navigation and HUD guidance, Shortcuts default-app roles, explicit stock split-screen sessions, trip/spectrum display, native weather adaptation, and passenger-screen app installation.
Legacy legacy/denza-mirrors/ Frozen hardware-verified camera reference. Its working behavior has moved into Denza Apps and it is no longer in the root Gradle build.
Legacy legacy/denza-gateway/ Original LAN-only SSH-to-ADB gateway. Kept for maintenance and reference; superseded for new remote-access work.
Library libraries/dishare-bridge/ Shared raw DiShare binder integration used by Denza Apps.
Platform platform/cli/, platform/relay/, ops/ansible/ Developer CLI, restricted relay control plane, and reproducible server provisioning.

The rest of the tree is straightforward:

  • docs/ — durable architecture, decisions, and verified findings;
  • experiments/ — isolated on-device probes included in the root build;
  • tools/ — host-side probes and live-car utilities;
  • research/ — parked or non-built experiments;
  • reverse/ — ignored local workspace for extracted artifacts and captures.

How it fits together

flowchart LR
    Dev["Developer computer"] --> CLI["cag CLI"]
    CLI --> Relay["Restricted SSH relay"]
    Relay --> CAG["Car ADB Gateway"]
    CAG --> ADB["Head-unit ADB"]

    Apps["Denza Apps"] --> Bridge["DiShare bridge"]
    Bridge --> Car["Denza / BYD services"]
    Apps --> Scene["Shared instrument scene"]
    Scene --> Cluster["Map base + camera overlay"]
    Apps --> Guidance["HUD guidance"]
    Guidance --> HUD["Windshield projection"]
    Apps --> FSE["Passenger-screen installer"]
    FSE --> Passenger["Passenger FSE"]
Loading

Car ADB Gateway never exposes ADB or SSH on the vehicle network. The vehicle opens the outbound relay connection, while the developer's SSH connection stays end-to-end encrypted to the Android app. See the architecture and decision log for the security model.

Repository layout

The repository is called Denza Lab. Older checkouts may still use the historical directory name denza-gateway.

Active apps live under apps/, shared code under libraries/, and frozen products under legacy/. The migrated Mirrors and navigation paths now live in Denza Apps behind one instrument-display resolver and scene. The standalone Denza Mirrors source is retained only as reference and is not a root Gradle module.

The repository shape is:

apps/
  car-adb-gateway/
  denza-apps/
libraries/
  dishare-bridge/
platform/
  cli/
  relay/
ops/
experiments/
legacy/
  denza-gateway/
  denza-mirrors/
docs/  research/  tools/

Build

Requirements:

  • JDK 17;
  • Android SDK platform 37;
  • Android Platform Tools;
  • Go for the cag CLI.

On a Homebrew-based macOS setup:

export JAVA_HOME=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home
export ANDROID_HOME=/opt/homebrew/share/android-commandlinetools

./gradlew :car-adb-gateway:testDebugUnitTest :car-adb-gateway:assembleDebug
./gradlew :denza-apps:testDebugUnitTest :denza-apps:assembleDebug

Build the legacy gateway only when working on it:

./gradlew :denza-gateway:testDebugUnitTest :denza-gateway:assembleDebug

Build and test the developer CLI:

cd platform/cli
go test ./...
go build -o cag ./cmd/cag

Git ignores generated APKs and reverse-engineered binaries. Keep them out of the repository.

Car ADB Gateway in 30 seconds

After an administrator enrolls the vehicle, a person at the head unit can issue a ten-minute pairing code for one trusted computer:

cag pair XXXX-XXXX
cag connect -- adb devices
cag connect -- adb shell
cag status
cag disconnect

The relay must be deployed through ops/ansible/, not by copying scripts manually. This keeps SSH, PAM, account, filesystem, and verification rules consistent.

Car ADB Gateway field guide

Car ADB Gateway uses two different short-lived codes:

Code Created by Used for Lifetime
Enrollment code Relay administrator Register one fresh APK installation with the relay. 60 minutes
Pairing code A person at the enrolled head unit Connect or replace the one trusted computer. 10 minutes

Share either code only with the person who is setting up or operating the vehicle. A pairing code grants full remote ADB access after the vehicle confirms the computer.

1. Install or update the APK

Build from the repository root, then use the serial shown by adb devices -l:

./gradlew :car-adb-gateway:assembleDebug
adb devices -l
adb -s <serial> install -r apps/car-adb-gateway/build/outputs/apk/debug/car-adb-gateway.apk
adb -s <serial> shell am start -n ru.adbgw.gateway/.MainActivity

Keep -r when updating an enrolled installation so its private keys and relay identity remain intact. Uninstalling the APK removes that state and requires a new enrollment code.

2. Enroll the vehicle once

  1. Open Car ADB Gateway on the head unit.
  2. If Android shows an ADB authorization dialog, approve the app key and press «Проверить снова».
  3. Ask the relay administrator for a current enrollment code. Administrators create it using the procedure in ops/ansible/README.md.
  4. Enter the code, press «Подключить автомобиль», read the full-access warning, and confirm.
  5. Wait until the main screen reports that the vehicle is connected to the relay. The «Поддержка» dialog shows the relay, device ID, ADB endpoint, connection state, and recent events when diagnosis is needed.

3. Pair or replace the trusted computer

The computer needs the cag CLI, OpenSSH, and Android Platform Tools on PATH. Build/install instructions are in platform/cli/README.md.

  1. On the head unit, press «Подключить компьютер» or «Заменить компьютер».

  2. Read the warning and press «Показать код».

  3. On the trusted computer, run the displayed command before the code expires:

    cag pair XXXX-XXXX
  4. Wait for Paired with .... A successful replacement revokes the previous computer. If replacement fails or expires, the previous computer keeps its access.

4. Use ADB remotely

cag opens the protected tunnel and selects the correct smart-socket or raw-ADB mode automatically:

cag connect -- adb devices
cag connect -- adb shell
cag status

Use the same prefix for other ADB commands, for example:

cag connect -- adb shell getprop ro.build.version.release
cag connect -- adb logcat

Some raw-ADB head units show a second Android authorization dialog for the computer's normal ADB key. Approve it at the vehicle before retrying the command.

5. Disconnect safely

  • cag disconnect closes only this computer's local tunnel. It does not disable remote access on the vehicle.
  • «Отключить удалённый доступ» in the vehicle app closes current sessions, disables the relay grant, and keeps access disabled after reboot.
  • «Включить удалённый доступ» in the vehicle app re-enables it.

Quick diagnosis

  • no car is paired — create a fresh pairing code at the vehicle and run cag pair.
  • Pairing code rejected — create another code; pairing codes expire after ten minutes.
  • Enrollment code rejected — ask the relay administrator for another code; enrollment codes expire after 60 minutes and are single-use.
  • Vehicle is reconnecting — check network access and the «Поддержка» events; transient network, relay, and ADB failures are retried automatically.
  • App was force-stopped — open Car ADB Gateway manually. Android does not allow an ordinary APK to restart itself after Force Stop.
  • Identity or host-key error — stop and inspect the support details. Resolve the mismatch instead of bypassing the check.

Documentation

When a page disagrees with the code, manifest, or Gradle configuration, follow the implementation and update that page.

License

The original work in this repository is released under the MIT License — use, modify, and redistribute it freely, including commercially, as long as the copyright notice and the license text travel with it.

The license covers this project's own source, documentation, and tooling. It does not grant rights to third-party material this repository merely describes or analyzes: Denza and BYD firmware, their applications, and their trademarks remain the property of their owners. Nothing here is redistributed from them.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages