Native Wayland Compositor for Android
Winland Server is a full-featured Wayland compositor that runs natively on Android devices, enabling Linux GUI applications to run directly on phones and tablets. Built with the Smithay compositor library in Rust with a Kotlin/Compose Multiplatform UI.
- Native Wayland compositor built with Smithay — no VNC/RDP/streaming overhead
- Vulkan hardware acceleration via Zink (OpenGL-on-Vulkan) using Turnip driver on Adreno GPUs, fully integrated with LabWC for desktop-wide GPU compositing
- GPU acceleration per-app: Type
gpuin the terminal followed by the game/app name to launch it with the Zink accelerator enabled - OpenGL ES path via Android HardwareBuffers for devices without Vulkan
- XWayland support for legacy X11 applications
- Dynamic resolution with persistent scale locking across Android lifecycle events
- Screen rotation support — seamless landscape/portrait switching with correct input coordinate mapping and pointer icon management
- Multi-display ready architecture
- Touch — Direct touch-to-Wayland-touch translation with gesture support (window move/resize, 3-finger swipe to cycle windows)
- Trackpad — Relative pointer motion with acceleration, two-finger tap for click, pinch-to-zoom
- Bluetooth & wired mouse — full desktop-grade pointer support with left-click, right-click, hover, and orientation-aware coordinates
- Bluetooth & USB keyboard — complete keymap handling with XKB, multi-key shortcuts, physical keyboard input via Android
- Install, setup, run, stop, and restart Linux distributions
- Root filesystem download and extraction
- Chroot-based isolation with bind-mount management
- Clean unmount on shutdown/reboot
- Native audio playback — Zero-copy PCM audio routed via Oboe (AAudio) between chroot PulseAudio and Android audio hardware through a named FIFO pipe
- Native microphone input — Android mic captured via Oboe (AAudio) at 44.1kHz mono 16-bit and streamed into chroot PulseAudio through a dedicated FIFO pipe
- Clipboard sync — Full copy/paste between Android and Linux applications (X11 and Wayland)
- Live log panel with search, copy, and pause
- Real-time compositor diagnostics (FPS, surface count, input events)
- Runtime stats overlay
- Debug logging via Android logcat
- Ubuntu 24.04 (Noble) and Kali Nethunter rootfs support
- XFCE desktop session running on LabWC (Wayland compositor) with GPU-accelerated compositing via Zink+Turnip
- Automatic rootfs download, extraction, and dependency installation
- BusyBox-based bootstrap for reliable chroot setup
| Requirement | Minimum | Recommended |
|---|---|---|
| OS | Android 8.0 (API 26) | Android 10+ |
| Architecture | ARM64 (arm64-v8a) | ARM64 |
| RAM | 3 GB | 6 GB+ |
| Storage | 2 GB free | 8 GB+ |
| GPU | Adreno 650+ (Vulkan 1.1+ for Turnip) | OpenGL ES 3.0+ |
- Download the latest APK from Releases
- Enable Install from Unknown Sources in Android Settings
- Install the APK and launch Winland Server
- Select a Linux distribution from the Home tab and tap Install
- Once installed, tap Run to start the compositor
Prerequisites:
- Android Studio Hedgehog (2023.1.1+) or newer
- Android NDK r26+ (set path in
.cargo/config.toml) - Rust toolchain with
aarch64-linux-androidtarget - JDK 17+
git clone https://github.com/anomalyco/winland-android.git
cd winland-android
# Install dependencies
make setup
# Full build (Rust + bindings + APK)
make build
# Or build individually:
make build-rust # Build Rust library only
make generate-bindings # Generate UniFFI bindings
make build-app # Build Android APK
# Build release with LTO/NEON optimizations
make build-release
# Install on connected device
make installManual build:
# Build Rust native library
cargo build --release --target aarch64-linux-android --features smithay_android
# Copy library
cp native/target/aarch64-linux-android/release/libuniffi_winland_core.so \
app/src/main/jniLibs/arm64-v8a/
# Build APK
./gradlew clean assembleDebugSee BUILD_ARM64.md for detailed ARM64 build instructions.
-
Bootstrapping: The app downloads a compressed Linux rootfs (Ubuntu or Kali) and extracts it into the app's private data directory.
-
Chroot Setup: With root privileges, the app mounts
/proc,/sys,/dev, and bind-mounts the Wayland socket and audio FIFO into the chroot. -
Compositor: The Rust-based Smithay compositor creates a Wayland socket inside the app's data directory. This socket is bind-mounted into the chroot so Linux GUI apps can connect to it.
-
Desktop Launch: Inside the chroot, LabWC (a Wayland compositor) starts as the window manager with GPU-accelerated compositing via Zink+Turnip, XFCE as the desktop environment, and XWayland for X11 app compatibility.
-
Input Routing: Touch events, keyboard input, and mouse events from Android are forwarded through UniFFI to the Rust compositor, which injects them into the Wayland protocol.
-
Audio Bridge (Native): PulseAudio inside the chroot writes PCM audio to a named FIFO; the Rust audio bridge reads it via Oboe (AAudio) for zero-copy playback on Android speakers. For microphone input, Oboe captures 44.1kHz mono 16-bit audio from the Android mic and writes to a second FIFO, which PulseAudio reads as the
AndroidMicsource — all natively with no streaming overhead. -
Rendering: The compositor renders directly onto an Android
SurfaceViewusing Vulkan (Zink/Turnip) or OpenGL ES via HardwareBuffers.
The main dashboard has three tabs:
| Tab | Description |
|---|---|
| Home | Distro management (install/setup/run/stop/restart), live logs, connection instructions |
| Terminal | Embedded Android terminal via Termux emulator library |
| Settings | Display (resolution), input mode (Touch/Trackpad/Mouse), scroll sensitivity, refresh rate, theme, runtime controls |
| Mode | Best For | Behavior |
|---|---|---|
| Touch | General navigation | Direct touch input, window move/resize by titlebar/edges, 3-finger swipe to cycle windows |
| Trackpad | Precise cursor control | Smooth relative motion with acceleration, one-finger drag, two-finger tap for click |
| Mouse | Gaming / pointer-lock | Absolute pointer positioning, constrained-relative mode for pointer lock |
- 1080p (scale 1.0) — Native resolution, sharper text
- 720p (scale 1.5) — Larger UI elements, better readability on small screens
Once the compositor is running (tap Run), Linux applications connect to the Wayland socket:
export WAYLAND_DISPLAY=wayland-0
export XDG_RUNTIME_DIR=/data/data/com.winland.server/files
your-linux-app| Shortcut | Action |
|---|---|
Alt + Tab |
Cycle through windows forward |
Alt + Shift + Tab |
Cycle through windows backward |
| Titlebar ✕ button | Close window |
┌─────────────────────────────────────────────────────┐
│ Android Device │
│ ┌───────────────────────────────────────────┐ │
│ │ Kotlin/Compose UI │ │
│ │ ┌────────┐ ┌──────────┐ ┌───────────┐ │ │
│ │ │Dashboard│ │ Display │ │ Terminal │ │ │
│ │ │ Screen │ │ Activity │ │ Activity │ │ │
│ │ └────────┘ └──────────┘ └───────────┘ │ │
│ └───────────────────────────────────────────┘ │
│ │ JNI / UniFFI │
│ ┌───────────────────────────────────────────┐ │
│ │ Rust Native Library │ │
│ │ ┌────────────┐ ┌──────────────────┐ │ │
│ │ │ JNI Bridge │ │ Wayland Server │ │ │
│ │ │ (input, │ │ (Smithay-based) │ │ │
│ │ │ surface, │ │ ┌────────────┐ │ │ │
│ │ │ lifecycle)│ │ │ Seat/Input │ │ │ │
│ │ └────────────┘ │ ├────────────┤ │ │ │
│ │ │ │ Shell (XDG)│ │ │ │
│ │ ┌────────────┐ │ ├────────────┤ │ │ │
│ │ │ Audio / │ │ │ Renderer │ │ │ │
│ │ │ USB / │ │ │ (OpenGL ES)│ │ │ │
│ │ │ Distro │ │ └────────────┘ │ │ │
│ │ └────────────┘ └──────────────────┘ │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
| Layer | Technology | Purpose |
|---|---|---|
| UI | Kotlin + Compose | Dashboard, settings, live logs |
| Display | SurfaceView + EGL | Full-screen compositor output, touch input routing |
| Bridge | JNI + UniFFI | Kotlin↔Rust communication |
| Compositor | Rust (Smithay) | Wayland protocol, input routing, shell management |
| Rendering | OpenGL ES 2.0 / Vulkan (Zink+Turnip) | Surface compositing, texture upload, NDC mapping |
| Audio | Oboe (AAudio) | Native zero-copy audio playback + mic capture via FIFO pipes |
| Distro | Rust bindings | Rootfs management, chroot lifecycle |
| Target | Description |
|---|---|
make setup |
Install Rust ARM64 target, create cargo config |
make build-rust |
Build Rust library for ARM64, copy .so to jniLibs |
make generate-bindings |
Generate UniFFI Kotlin bindings from UDL |
make build-app |
Build APK (requires built Rust library) |
make build |
Full build (Rust → bindings → APK) |
make build-release |
Release build with LTO/NEON |
make install |
Build + install APK via adb |
make clean |
Clean Gradle + Cargo artifacts |
make test |
Run Rust + Gradle tests |
make lint |
Run Clippy + Android lint |
make docs |
Generate Rust documentation |
# Filter Winland logs
adb logcat -s WinlandServer,NativeBridge,SmithayRuntime,Compositor
# Full dump with memory info
adb logcat -d > winland-logs.txt
adb shell dumpsys meminfo com.winland.server >> winland-logs.txtThe compositor exposes real-time diagnostics via getWaylandRuntimeStats() (accessible from the Dashboard debug panel).
| Symptom | Likely Cause | Solution |
|---|---|---|
| Black screen | EGL init failure / Surface not bound | Restart the compositor |
| Input not working | Wrong input mode | Switch mode in Settings tab |
| Apps crash on connect | XDG_RUNTIME_DIR permissions | Ensure directory is accessible |
| Low FPS | Missing GPU acceleration | Verify OpenGL ES / Vulkan support |
Contributions are welcome! Please read CONTRIBUTING.md for our contribution guidelines, code of conduct, and development workflow.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes following Conventional Commits
- Push and open a Pull Request
See ARCHITECTURE.md for detailed system architecture documentation.
Distributed under the MIT License. See LICENSE for more information.
Copyright (c) 2024 Winland Server Contributors
- Smithay — Rust Wayland compositor library
- Wayland — Display server protocol
- The Turnip driver team for Vulkan-on-Adreno support
- Termux — Android terminal emulator (terminal-view/terminal-emulator modules)
- UniFFI — Rust-to-Kotlin bindings generator
- Android NDK — Native development kit
Made with ❤️ for the Linux on Android community