This document provides technical information about how AndroidDisplay works and its architecture.
AndroidDisplay consists of two main components:
- Fedora Component: Creates a virtual display, captures its contents, and streams it to the Android tablet
- Android App: Receives the video stream and displays it, while sending touch events back to the Fedora system
+---------------+ +----------------+
| | Video Stream (UDP) | |
| Fedora | -------------------> | Android |
| System | | Tablet |
| (KDE/X11) | | |
| | <------------------- | |
| | Touch Events (TCP) | |
+---------------+ +----------------+
The virtual display is created using the xrandr utility and the X11 dummy driver. The virtual-display.sh script:
- Finds the primary display
- Locates an available virtual output
- Creates a new mode with the desired resolution
- Enables the virtual output with the new mode
- Positions it relative to the primary display
The stream-display.sh script:
- Captures the virtual display using FFmpeg's x11grab
- Compresses it using H.264 encoding (hardware-accelerated via VA-API when available)
- Streams the compressed video over UDP to the Android tablet
- Adaptive quality settings based on network conditions
The input-handler.py script:
- Listens for touch events from the Android tablet over TCP
- Maps touch coordinates based on the virtual display's position
- Injects mouse events into X11 using
xdotool - Supports basic touch gestures (down, up, move)
The system uses udev rules to detect when the tablet is connected:
- The rule matches the specific USB vendor and product IDs of the tablet
- When connected, it automatically starts the AndroidDisplay service
- When disconnected, it stops the service
The Android app:
- Sets up a SurfaceView to display the video
- Creates a MediaCodec decoder for H.264 video
- Listens for UDP packets containing the video stream
- Feeds the packets to the decoder
- Renders the decoded frames to the SurfaceView
The app captures touch events and sends them to the Fedora system:
- The SurfaceView captures MotionEvents (DOWN, UP, MOVE)
- These events are packaged into a compact binary format:
- 1 byte for action type
- 4 bytes for X coordinate (int)
- 4 bytes for Y coordinate (int)
- The packaged events are sent over TCP to the input handler on Fedora
The app uses USB tethering for optimal performance:
- When the tablet is connected via USB and tethering is enabled, it creates a direct network connection
- The Fedora system typically has the IP address 192.168.42.1
- The tablet typically has the IP address 192.168.42.129
- This direct connection minimizes latency compared to going through Wi-Fi
The video streaming uses standard MPEG-TS over UDP:
- Port: 5000
- Transport: UDP (for lower latency)
- Codec: H.264 (hardware accelerated when possible)
- Container: MPEG-TS
- Resolution: Configurable (default 1600x1200)
- Framerate: Configurable (default 30fps)
- Bitrate: Adaptive based on quality setting (1.5-5 Mbps)
Touch events use a custom binary protocol over TCP:
- Port: 5001
- Transport: TCP (for reliability)
- Message format:
- Byte 0: Event type (0=DOWN, 1=UP, 2=MOVE)
- Bytes 1-4: X coordinate (32-bit integer, big-endian)
- Bytes 5-8: Y coordinate (32-bit integer, big-endian)
To minimize latency:
- Video encoding uses low-latency presets
- Hardware acceleration is used when available
- UDP is used for video to minimize overhead
- The USB connection provides higher bandwidth and lower latency than Wi-Fi
- Frame buffer is kept small to reduce delay
The system balances quality and performance:
- Default resolution is 1600x1200 (Lenovo P11 native is 2000x1200)
- Three quality presets available (low, medium, high)
- Bitrate is adjusted based on the quality setting
- Hardware accelerated encoding/decoding reduces CPU load
- The service only runs when the tablet is connected via USB
- The video and input services only listen on the USB network interface
- No authentication is currently implemented since the connection is direct via USB
- Future versions could implement TLS encryption for the TCP connection