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

10 KiB
Raw Permalink Blame History

Тест автономного автозапуска 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 сам.