diff --git a/README.md b/README.md index 2c3aec8..94ba3d5 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,110 @@ -# Dasher-Android +# Dasher for Android -Official Android frontend for [Dasher v6](https://dasher.at), built on the -[DasherCore](https://github.com/dasher-project/DasherCore) **C API** via JNI. +[![Build](https://github.com/dasher-project/Dasher-Android/actions/workflows/build.yml/badge.svg)](https://github.com/dasher-project/Dasher-Android/actions/workflows/build.yml) +[![Release](https://img.shields.io/github/v/release/dasher-project/Dasher-Android?include_prereleases)](https://github.com/dasher-project/Dasher-Android/releases) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE) -> **Status:** Phase 0 (foundation scaffold). See [`PLAN.md`](./PLAN.md) for the -> full feature-parity roadmap against the cross-platform -> [feature matrix](https://dasher.at/status/). +Dasher is an information-efficient text-entry interface, driven by continuous +pointing gestures. It lets you write using eye gaze, a mouse, a switch, a +joystick, or touch — designed for accessibility and augmentative communication +(AAC). -## Architecture +This is the **Android** frontend, built on the shared +[DasherCore](https://github.com/dasher-project/DasherCore) engine. -DasherCore is consumed through its public C ABI (`dasher.h`) — the same -integration pattern as Dasher-Windows. A thin JNI shim marshals the frame -command buffer and engine callbacks to Kotlin; the UI is Jetpack Compose. +> **[dasher.at](https://dasher.at)** — downloads, user docs, and live demo +> **[Feature status](https://dasher.at/status/)** — what each platform supports +> **[All repos](https://github.com/dasher-project)** — engine, frontends, design guide -``` -Kotlin (Compose) ──JNI──▶ libdasher.so (DasherCore CAPI) + libdasher_jni.so (shim) -``` +## Status -## Build +> **Preview** — actively developed. Not on Google Play yet; download the latest +> signed APK from [Releases](../../releases) and sideload it. See the +> [feature matrix](https://dasher.at/status/) for what's implemented. -**Prerequisites:** Android Studio (Ladyfish or newer), which supplies JDK 17, -Android SDK 35, and NDK 27.0.12077973. +## Install -1. Open this directory in Android Studio. It will: - - install the required SDK/NDK/CMake, - - generate the Gradle wrapper jar (`gradle/wrapper/gradle-wrapper.jar`), - - initialize the `DasherCore` submodule. -2. From the CLI: - ``` - ./gradlew :app:assembleDebug - ./gradlew :app:installDebug - ``` +Download the latest APK from [Releases](../../releases) and install it +(Settings → Apps → allow unknown sources for your browser, then open the APK). +To use Dasher as the system keyboard, enable it in +**Settings → System → Keyboard → On-screen keyboard** and select it as the +default input method. -### Submodule +## Build + +### Prerequisites + +- Android Studio (Ladyfish or newer) — supplies JDK 17, the Android SDK, and the NDK +- Android SDK 35, NDK 27.0.12077973, CMake 3.22.1 (Android Studio offers to install these on first open) +- Git (with submodules) -DasherCore is pinned (not `main`) as a git submodule: +### Steps +```bash +git clone --recurse-submodules https://github.com/dasher-project/Dasher-Android.git +cd Dasher-Android +./gradlew :app:assembleDebug ``` -git submodule add https://github.com/dasher-project/DasherCore.git third_party/DasherCore + +Or open the project in Android Studio and run the `app` configuration on a +device or emulator (API 24+, x86_64 or arm64-v8a). On first open, Android +Studio installs the SDK/NDK/CMake and initialises the `DasherCore` submodule. + +## Architecture + +DasherCore is consumed through its public C ABI (`dasher.h`) — the same +integration pattern as Dasher-Windows. A thin JNI shim (`libdasher_jni.so`) +marshals the per-frame draw-command buffer, pointer input, and engine callbacks +(clipboard / speak / message / output / log) between Kotlin and `libdasher.so`. +The UI is Jetpack Compose; the same engine drives both the standalone app +(`MainActivity`) and the system keyboard (`DasherImeService`). + +```mermaid +graph LR + subgraph "Kotlin (Jetpack Compose)" + UI["MainActivity / DasherImeService
Compose shell + IME"] + ENG["DasherEngine.kt
Choreographer frame loop"] + NB["NativeBridge.kt
external funs, 1:1 with dasher.h"] + CV["DasherCanvasView
decodes the 6-int command buffer"] + UI --> ENG + ENG --> NB + ENG --> CV + end + subgraph "libdasher_jni.so (JNI shim)" + JNI["jni_bridge.cpp
pointer + frame buffer + callback trampolines"] + end + subgraph "libdasher.so (DasherCore CAPI)" + API["dasher.h
dasher_frame / dasher_mouse_* / callbacks"] + end + NB <-->|JNI| JNI + JNI <-->|dasher_* C ABI| API + API -.->|"draw commands: opcode, a, b, c, d, argb"| CV + API -.->|clipboard / speak / message / output / log| NB ``` +Each draw command is 6 ints: `[opcode, a, b, c, d, argb]` (clear / circle / line / +rect-outline / rect-fill / text). Pointer events flow the other way +(`DasherCanvasView` → `dasher_mouse_*`). See +[DasherCore's C API](https://github.com/dasher-project/DasherCore/blob/main/docs/C_API.md) +for the full engine contract. + ## Repository layout -``` -app/src/main/ -├── cpp/ Native layer -│ ├── CMakeLists.txt Builds DasherCore CAPI + JNI shim -│ ├── jni_bridge.cpp Thin JNI bindings over dasher.h -│ └── asset_copier.{h,cpp} Copies bundled Data/ to filesDir on first run -├── java/org/dasherproject/android/ -│ ├── NativeBridge.kt Kotlin external decls (1:1 with dasher.h) -│ ├── DasherEngine.kt Choreographer frame loop + input translation -│ ├── MainActivity.kt Compose app shell -│ └── ui/ -│ ├── DasherCanvasView.kt Decodes [op,a,b,c,d,argb] → Android Canvas -│ └── theme/ Compose theme from dasher-design-guide tokens -└── assets/ Symlink/srcDir to third_party/DasherCore/Data -``` +| Path | Purpose | +|---|---| +| `app/src/main/cpp/` | `CMakeLists.txt` + `jni_bridge.cpp` — JNI shim over `dasher.h`, produces `libdasher_jni.so` | +| `app/src/main/java/at/dasher/android/` | Kotlin: `NativeBridge` (CAPI decls), `DasherEngine` (frame loop), `MainActivity`, `DasherImeService` (keyboard), `SettingsScreen`, `AnalyticsService`, `DasherApp`, `LocaleHelper` | +| `app/src/main/java/at/dasher/android/ui/` | `DasherCanvasView` (command buffer → Canvas), Compose `theme/` | +| `app/src/main/res/` | Strings (incl. `values-de`), themes, `AndroidManifest.xml` | +| `third_party/DasherCore/` | DasherCore submodule (do not edit here — PR upstream) | + +## Contributing + +See [CONTRIBUTING.md](./CONTRIBUTING.md) for build details, code style, and DCO +sign-off. For project-wide conventions (code of conduct, RFCs, security), see +the +[org contributing guide](https://github.com/dasher-project/.github/blob/main/CONTRIBUTING.md). ## License -MIT. See [`LICENSE`](./LICENSE). +MIT — see [LICENSE](./LICENSE).