Files
rayneo-vm/BOOTSTRAP_TEST.md
subochev 8a0b7832c0 phone: autonomous Shizuku revive over wireless-adb; glasses screen on/off buttons
AdbClient wraps the bundled libadb.so (useLegacyPackaging -> exec from nativeLibraryDir, HOME/TMPDIR overridden, adb key injected into BuildConfig from ~/.android at build time and never committed). ShizukuProvisioner: on each BLE+WiFi connect it enables ADB-over-WiFi via Mercury, connects with mDNS fallback, pushes the Shizuku starter and runs it; runs once per BLE session, does not relaunch GlassesApp when the WS channel is already up, and exposes runShell() for arbitrary commands. DebugReceiver (DUMP) + am start --ez provision for diagnostics.

Protocol: ShizukuStatus(running/granted) + RequestShizukuStatus; glasses push it on connect and on Shizuku state change, using a passive probe() that never shows a permission dialog. Glasses kill-guard now recreates its UserService when the Shizuku binder dies instead of spamming DeadObjectException. Mercury: brightness disables auto-brightness first (was silently ignored), BLE auto-connect loop retries every 6s (fixes 'searches then stops'). New phone section 'Экран очков' with wake/sleep via adb (input keyevent 224/223).
2026-09-27 03:52:05 +03:00

141 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Тест автономного автозапуска GlassesApp (HOME + adb-бутстрап Shizuku) — ВЫВОДЫ
Цель: доказать, что GlassesApp может подниматься и оживлять Shizuku после холодной
перезагрузки **без Mercury-лаунчера и без USB-компьютера**.
Устройство: RayNeo X3 Pro, adb serial `A06B4AB933C4103`.
Дата экспериментов: 2026-09-25/26.
---
## ИТОГОВЫЙ ВЫВОД (кратко)
1. **Автозапуск через HOME не работает.** Наш пакет можно назначить дефолтным HOME
(`cmd package set-home-activity pw.binom.rayneovm.glasses/.MainActivity`, `isDefault=true`),
но при загрузке ROM-патч system_server всё равно поднимает **свою**
`com.ffalconxr.mercury.launcher/.home.LauncherHomeActivity`. Ручной HOME-intent
(`am start -a MAIN -c HOME`) открывает наш `MainActivity` правильно — то есть наш
домашний экран рабочий, но boot-резолв перехвачен Mercury.
2. **Mercury-лаунчер убрать нельзя.** `pm disable-user com.ffalconxr.mercury.launcher`
применяется (`enabled=0`), но system_server всё равно стартует Mercury при буте
(PID uid system), и **его BLE продолжает работать** (телефон по Bluetooth соединяется).
Значит: убийца `BackgroundAppManager` присутствует всегда → стража
NetConfigActivity-на-скрытом-дисплее **обязательна**. Отключение лаунчера проблему не решает.
3. **BLE жив всегда.** Раз Mercury стартует при буте в любом случае, Channel 2 (BLE:
запуск приложения, яркость, WiFi, статус) доступен всегда. Это надёжный канал.
4. **`com.rayneo.mercury.app=true`** у нас уже стоит в манифесте, но **иммунитета от
убийцы не даёт** — нас всё равно убивало.
## Про adb-бутстрап Shizuku после ребута
| Способ | Результат |
|--------|-----------|
| legacy plain-TCP `persist.adb.tcp.port` / `service.adb.tcp.port` из shell (uid 2000) | ❌ SELinux запрещает (`Unable to set property ... adbd_config_prop, u:r:shell:s0`) |
| Wireless-ADB `settings put global adb_wifi_enabled 1` | ⚠️ включается, но сбрасывается ребутом и требует подключённого WiFi; при выключенном WiFi очки полностью пропадают из сети |
| «Второй adbd» на `127.0.0.1:8872` | ❌ это не adbd, а Bluetooth HCI-snoop (`btsnoop`), uid android.uid.bluetooth |
| Единственный настоящий adbd | штатный `adbd --root_seclabel=u:r:su:s0` (uid shell), слушает USB/WiFi |
**Вывод:** автономного сетевого бутстрапа Shizuku без WiFi у нас нет. После ребута
очки оживают либо через USB, либо через WiFi+wireless-adb (если сеть есть).
Self-bootstrap (встроенный adb-клиент в приложении + авторизованный ключ) возможен,
но только когда сеть уже поднята, т.е. холодный старт им не закрыть.
## RayDesk (github.com/Quad-Labs/RayDesk) — почему «без приседаний»
RayDesk — Moonlight-клиент: стримит рабочий стол ПК в **свой** GL-рендер. Он:
- НЕ создаёт VirtualDisplay, НЕ использует Shizuku, НЕ запускает чужие Activity;
- «оба глаза» = свой `TextureView` (левый) + Mercury SDK `MirroringView` (правый);
- использует проприетарный Mercury SDK (`BaseMirrorActivity`, `TempleAction`), нужен
developer access от RayNeo.
Их подход **неприменим** к нашей задаче: мы запускаем чужие приложения на VD — это
принципиально другой сценарий. Заимствовать нечего (наш meta-data уже стоит).
## Остаётся рабочих варианта
- **A (текущий):** Mercury живёт как сервис (BLE + убийца), стража NetConfigActivity
держит гостя, Shizuku держим (USB / wireless-adb при наличии WiFi).
- **B:** встроить в приложение adb-клиент (dadb) + один раз авторизовать наш ключ —
поднимает Shizuku по сети, когда WiFi есть (не закрывает холодный старт без сети).
---
## Журнал (детали по этапам)
### Этап A/B — HOME после ребута
- Назначили наш пакет дефолтным HOME. После ребута `topResumedActivity=`
`com.ffalconxr.mercury.launcher/.home.LauncherHomeActivity` — нас система не подняла.
- `resolve-activity` при этом указывает на нас (`isDefault=true`) — то есть boot идёт
мимо обычного HOME-резолва (ROM-патч).
### Этап C — adb после ребута
- `settings put global adb_wifi_enabled 1` ✅ (запись из shell проходит).
- `setprop service.adb.tcp.port` / `persist.adb.tcp.port` ❌ SELinux.
- boot-лог: `AdbDebuggingManager: Not connected to any wireless network. Not enabling adbwifi.`
- Wireless-adb поднялся по WiFi: `adb connect 192.168.76.248:40481` → `device`.
### Этап D — WiFi off (ложная «тыква»)
- При `svc wifi disable` очки пропали из сети полностью (ping unreachable) — wireless-adb
живёт на WiFi-интерфейсе, loopback снаружи недоступен. Внутренний loopback не проверялся.
### Этап E — отключение Mercury
- `pm disable-user` → `enabled=0`, но после ребута Mercury запущен и держит стол;
телефон по BLE соединился. Откат: `pm enable --user 0 com.ffalconxr.mercury.launcher`
выполнен (`enabled=1`).
### Ложная зацепка
- `127.0.0.1:8872` (uid 1002) — при коннекте отдаёт поток с магией `btsnoop` → это
Bluetooth HCI-логгер, не adbd. ADB-хендшейк не проходит.
---
## Этап F — автономный подъём Shizuku С ТЕЛЕФОНА (успех)
### Механизм включения wireless-adb на очках
- Нужно **два** действия (иначе TLS-сервер не поднимается):
1. `IAdbManager.allowWirelessDebugging(true, ssid)` — транзакция binder `adb` №4,
добавляет доверенную сеть (`adb_temp_keys.xml` + запись wifiAP/bssid).
2. `settings put global adb_wifi_enabled 1` — adbd стартует
`TlsServer running on port <random>` и публикует mDNS `_adb-tls-connect._tcp`.
- Порт — **случайный**; узнать: binder-транзакция `adb` №10 (`getAdbWirelessPort`).
- Shell (uid 2000) вправе делать оба вызова — root не нужен.
### Критично: wireless-adb сам гаснет
- Как только очки теряют ту WiFi-сеть, к которой были привязаны, `adb_wifi_enabled`
сбрасывается в 0, порт становится `-1`. Поэтому при каждом бутстрапе его надо
перевключать (через Mercury `enableWirelessAdb`, который и вызывает оба шага).
### Авторизация без сопряжения
- Встроенный adb-ключ рабочей машины уже лежит в `/data/misc/adb/adb_keys` очков.
`AdbDebuggingManager.addUserKeysToKeyStore()` подмешивает user-ключи в wireless-keystore,
поэтому при connect по TLS ключ принимается без pairing-кода. Проверено.
### Реализация в PhoneApp
- `jniLibs/arm64-v8a/libadb.so` — AOSP adb (префилд LADB, Apache-2.0);
`useLegacyPackaging = true` → распаковывается в `nativeLibraryDir`, откуда
разрешён `exec` (W^X запрещает exec из filesDir/cacheDir — первая ошибка была `EACCES`).
- Ключ `~/.android/adbkey` зашивается в `BuildConfig` на сборке (в репо не коммитится).
- `AdbClient`: HOME=filesDir/.android (ключ кладём и в `.android/.android`),
TMPDIR=cacheDir, `ANDROID_USER_CONFIG`=HOME.
- `ShizukuProvisioner`: Mercury адрес → mDNS fallback → `start-server` → `connect` →
`pidof shizuku_server` → push `assets/shizuku/starter` → `chmod` →
`starter --apk=$(pm path moe.shizuku.privileged.api)` → проверка `pidof` → `appMarketLaunch`.
### Проверено на устройстве (через TCP-релей ПК, т.к. телефон и очки были в разных сетях)
```
forceWithAddress(192.168.76.142:39998)
exec: -s ... shell /data/local/tmp/shizuku_starter --apk=.../base.apk
info: shizuku_server pid is 4342
pidof shizuku_server -> '4342'
Shizuku поднят
```
Диагностика: `am broadcast -a pw.binom.rayneovm.phone.DEBUG_PROVISION [--es address ip:port]`
или `am start -n pw.binom.rayneovm.phone/.MainActivity --ez provision true [--es address ip:port]`.
### Остаётся проверить «в бою»
- Реальный сценарий: телефон держит хотспот, очки к нему подключены, BLE соединён →
`enableWirelessAdb` отдаёт адрес (или mDNS), телефон поднимает Shizuku сам.