Android simulator shell for the Kern LVGL UI.
Research and development only. Kern is a research and development project, not a product. This repository is a simulator shell for exploring Kern and air-gapped Bitcoin transactions on a phone. A phone cannot fully isolate keys from the OS, libraries, or peripherals, so do not use it for wallets holding real funds or important mnemonics.
- Kotlin
SurfaceViewAndroid app at packagecom.odudex.kern - JNI/native bridge in
app/src/main/cpp - Android LVGL display/input driver using
ANativeWindow - Kern simulator shims reused from
third_party/Kern/simulator - Submodule-style dependencies:
third_party/Kernfromhttps://github.com/odudex/Kernthird_party/lvglpinned to LVGLv9.5.0
- Additional native crypto dependency:
third_party/mbedtlspinned tombedtls-3.6.2
- Android SDK with NDK
30.0.14904198and CMake4.1.2installed viasdkmanager(or Android Studio's SDK Manager). Both versions are pinned inapp/build.gradle.kts. - The build needs to know where the SDK lives. Either:
- export
ANDROID_HOME(orANDROID_SDK_ROOT) to point at the SDK, or - create a
local.propertiesat the repo root with:Only addsdk.dir=/absolute/path/to/Android/sdkcmake.dir=...if your CMake 4.1.2 lives outside the standard$ANDROID_SDK_ROOT/cmake/4.1.2/.
- export
local.properties is per-machine — it's gitignored and must not be committed.
./gradlew :app:assembleDebugThe debug APK is written to:
app/build/outputs/apk/debug/app-debug.apk
The default build produces both arm64-v8a (real phones) and x86_64
(emulator). Pass -Pkern.abi to limit the native build to one ABI —
roughly halves clean-build time and skips the unused-architecture
recompiles during inner-loop work:
./gradlew :app:assembleDebug -Pkern.abi=arm64-v8a # phone only
./gradlew :app:assembleDebug -Pkern.abi=x86_64 # emulator onlyMultiple ABIs can be comma-separated (-Pkern.abi=arm64-v8a,x86_64).
For a persistent per-machine default, add the property to your user
Gradle config — this keeps the repo's defaults untouched:
echo 'kern.abi=arm64-v8a' >> ~/.gradle/gradle.propertiesUnset the property (or remove the line) to restore the full release matrix.
emulator -avd kern_test -no-window -no-audio -no-snapshot -gpu swiftshader_indirect
adb wait-for-device
adb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n com.odudex.kern/.MainActivityEnable Developer options and USB debugging on the phone, connect it over USB, then accept the debugging prompt.
./gradlew :app:assembleDebug
adb devices
adb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n com.odudex.kern/.MainActivity- The QR scanner and entropy capture flows run against the phone's real rear camera via Camera2; the simulator's mock camera shims are only used as a fallback when no camera is available (e.g. emulator without a virtual webcam).
- A research-and-development notice is shown on every launch; the Kern surface is only initialised once it is acknowledged. Kern shows its own R&D disclaimer as well, once per version, so the first run of a newly built version shows both.
- The About page shows a version of the form
<kern>-sim-dev, where<kern>is read at configure time fromthird_party/Kern/version.txt. - Kern and LVGL sources are not modified; Android-specific glue lives under
app/src/main/cpp. - Android simulates the
wave_5board at its LVGL logical resolution (720x1280) and scales that frame into the phone/emulatorSurfaceViewas large as possible without changing the aspect ratio.
MIT — see LICENSE. Bundled dependencies keep their own licenses: Kern (MIT), LVGL (MIT), mbedtls (Apache-2.0).