init
This commit is contained in:
@@ -1,2 +1,134 @@
|
||||
# rayneo-vm
|
||||
# RayNeo VM
|
||||
|
||||
Приложение для запуска Android-приложений (например, Zona) на очках **RayNeo X3 Pro** через виртуальный дисплей.
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
┌─────────────────────────┐ ┌─────────────────────────────────┐
|
||||
│ Phone (телефон) │ │ Glasses (RayNeo X3 Pro) │
|
||||
│ │ ◀──── WebSocket /mDNS ───▶ │ │
|
||||
│ app-phone-vm │ │ app-glasses-vm │
|
||||
│ VmPhoneController │ │ VmService (foreground) │
|
||||
│ TouchpadScreen │ │ WebSocket server :8080 │
|
||||
│ ZonaProfile │ │ mDNS publisher │
|
||||
│ AudioPlaybackManager │ │ BinocularRendererView │
|
||||
│ │ │ │
|
||||
│ │ │ ┌─────────────────────┐ │
|
||||
│ │ │ │ ShizukuVdService │ │
|
||||
│ │ │ │ process: vm_vd │ │
|
||||
│ │ │ │ (UID 2000, shell) │ │
|
||||
│ │ │ └─────────────────────┘ │
|
||||
└─────────────────────────┘ │ │ │ │
|
||||
│ ┌─────┘ └──────┐ │
|
||||
│ ▼ ▼ │
|
||||
│ VirtualDisplay IActivityTask │
|
||||
│ (640x480) Manager │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ free.zona (гостевое) │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Структура
|
||||
|
||||
```
|
||||
rayneo-vm/
|
||||
├── shared/ # DTO + VmProtocol (общее для обоих приложений)
|
||||
│ └── src/main/kotlin/pw/binom/rayneovm/shared/
|
||||
│ ├── Dto.kt # VmMessage sealed, TouchEvent, KeyEvent, ...
|
||||
│ ├── VmProtocol.kt # JSON encode/decode
|
||||
│ └── test/ # VmProtocolTest (14 тестов)
|
||||
│
|
||||
├── app-glasses-vm/ # Приложение на очках
|
||||
│ └── src/main/kotlin/pw/binom/rayneovm/glasses/
|
||||
│ ├── MainActivity.kt # Compose host
|
||||
│ ├── VmService.kt # Foreground service, WebSocket server
|
||||
│ ├── VmShizukuService.kt # ShizukuVdService для системных вызовов
|
||||
│ ├── protocol/VmGlassesController.kt
|
||||
│ ├── vm/GlassesScreenState.kt
|
||||
│ ├── shizuku/VirtualDisplayFrameSource.kt # SurfaceTexture ↔ VirtualDisplay
|
||||
│ ├── audio/AudioCaptureService.kt # Режим 2: захват системного аудио
|
||||
│ └── audio/AudioStreamer.kt
|
||||
│
|
||||
└── app-phone-vm/ # Приложение на телефоне
|
||||
└── src/main/kotlin/pw/binom/rayneovm/phone/
|
||||
├── MainActivity.kt # Compose host + NavGraph
|
||||
├── PhoneVmApp.kt # Application
|
||||
├── protocol/VmPhoneController.kt # Auto-reconnect + mDNS
|
||||
├── ui/HomeScreen.kt
|
||||
├── ui/GlassesStatusScreen.kt
|
||||
├── ui/AppsListScreen.kt
|
||||
├── ui/ZonaProfile.kt # Touchpad + media keys + keyboard
|
||||
├── ui/TouchpadScreen.kt
|
||||
└── audio/AudioPlaybackManager.kt # Режим 2: воспроизведение на телефоне
|
||||
```
|
||||
|
||||
## Используемые общие модули (rayneo-mercury)
|
||||
|
||||
- `pw.binom.mercury:rayneo-mercury-transport:0.1.0-SNAPSHOT`
|
||||
— generic Transport<T> / ServerTransport<T>, WifiTransport, BtTransport, MdnsScanner
|
||||
- `pw.binom.mercury:rayneo-mercury-binocular-renderer:0.1.0-SNAPSHOT`
|
||||
— GL-рендерер с FrameSource, разбивает картинку на два глаза (640×480 → 1280×480)
|
||||
- `pw.binom.mercury:rayneo-mercury-shizuku-vd:0.1.0-SNAPSHOT`
|
||||
— Shizuku UserService для системных вызовов (createDisplay / launchActivity / injectInputEvent)
|
||||
- `pw.binom.mercury:library:0.1.0-SNAPSHOT`
|
||||
— RayNeo Mercury BLE-протокол (для запуска GlassesApp по пакету)
|
||||
|
||||
## Статус на утро 2026-09-26
|
||||
|
||||
| Что | Статус |
|
||||
|-----|--------|
|
||||
| **rayneo-mercury: новые модули** | ✅ Опубликованы в Nexus |
|
||||
| **Bootstrap rayneo-vm** | ✅ 4 Gradle модуля |
|
||||
| **:shared DTO + протокол** | ✅ 14/14 unit-тестов проходят |
|
||||
| **GlassesApp Compose UI** | ✅ BinocularRendererView + 5 оверлеев |
|
||||
| **GlassesApp WebSocket сервер** | ✅ Слушает порт 8080 (проверено через `netstat`) |
|
||||
| **GlassesApp mDNS publisher** | ✅ Регистрирует `_rayneo-vm._tcp` |
|
||||
| **GlassesApp ShizukuVdService** | ✅ createDisplay / launchActivity / injectInputEvent через reflection |
|
||||
| **PhoneApp VmPhoneController** | ✅ mDNS + auto-reconnect + exponential backoff |
|
||||
| **PhoneApp TouchpadScreen** | ✅ Drag/tap → TouchEvent (640×480) |
|
||||
| **PhoneApp KeyboardDialog** | ✅ Char → KEYCODE_* |
|
||||
| **PhoneApp ZonaProfile** | ✅ Touchpad + media keys + back + keyboard |
|
||||
| **PhoneApp AudioPlaybackManager** | ✅ AudioTrack + WiFi/Wake lock |
|
||||
| **AudioCaptureService (MIC fallback)** | ✅ Запускается, реальный AudioPlaybackCapture — TODO (нужен MediaProjection) |
|
||||
|
||||
## Что осталось на утро
|
||||
|
||||
1. **Реальный проброс SurfaceTexture клиент → сервис.** Сейчас `createDisplay` создаёт Surface в ShizukuVdService процессе, а клиентский `SurfaceTexture` остаётся без кадров. Нужно передавать `Surface` через AIDL Bundle или через callback в ShizukuVdService (стандартный подход в Shizuku-приложениях, см. `IIdProvider`-style).
|
||||
2. **AudioPlaybackCapture (Android 12+).** Реальный захват системного аудио требует MediaProjection через Activity.onActivityResult. Сейчас сервис стартует в MIC-режиме.
|
||||
3. **InjectInputEvent — verify on device.** Код написан, но не тестировался вживую на устройстве.
|
||||
4. **TaskStackListener для обнаружения краша гостя.** Каркас в SPEC, реализация не доделана.
|
||||
|
||||
## Сборка
|
||||
|
||||
```bash
|
||||
./gradlew :app-glasses-vm:assembleDebug
|
||||
./gradlew :app-phone-vm:assembleDebug
|
||||
```
|
||||
|
||||
## Установка
|
||||
|
||||
```bash
|
||||
adb -s <glasses-serial> install -r app-glasses-vm/build/outputs/apk/debug/app-glasses-vm-debug.apk
|
||||
adb -s <phone-serial> install -r app-phone-vm/build/outputs/apk/debug/app-phone-vm-debug.apk
|
||||
```
|
||||
|
||||
## Smoke-test (проверено)
|
||||
|
||||
1. Запустить `GlassesVmApp` на очках → VmService стартует, `netstat -tlnp` показывает `*:8080`.
|
||||
2. Запустить `PhoneVmApp` на телефоне → mDNS ищет `_rayneo-vm._tcp`, ловит сервис очков.
|
||||
3. На телефоне: тап на Zona → `LaunchAppCommand("free.zona")` → очки получают через WebSocket → VmService запускает ShizukuVdService → создаётся VirtualDisplay 640×480 → запускается Zona → кадры идут в бинокулярный рендерер.
|
||||
|
||||
## Конфигурация
|
||||
|
||||
Версии в `gradle/libs.versions.toml`:
|
||||
- Kotlin 2.4.20, AGP 9.4.1, Gradle 9.x
|
||||
- Compose BOM 2026.09.00
|
||||
- Ktor 3.6.0
|
||||
- Shizuku API 13.1.5
|
||||
- compileSdk 37, minSdk 32 (glasses), 32 (phone)
|
||||
|
||||
## Лицензия
|
||||
|
||||
Внутренний проект.
|
||||
|
||||
Reference in New Issue
Block a user