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).
10 KiB
Тест автономного автозапуска GlassesApp (HOME + adb-бутстрап Shizuku) — ВЫВОДЫ
Цель: доказать, что GlassesApp может подниматься и оживлять Shizuku после холодной перезагрузки без Mercury-лаунчера и без USB-компьютера.
Устройство: RayNeo X3 Pro, adb serial A06B4AB933C4103.
Дата экспериментов: 2026-09-25/26.
ИТОГОВЫЙ ВЫВОД (кратко)
-
Автозапуск через 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. -
Mercury-лаунчер убрать нельзя.
pm disable-user com.ffalconxr.mercury.launcherприменяется (enabled=0), но system_server всё равно стартует Mercury при буте (PID uid system), и его BLE продолжает работать (телефон по Bluetooth соединяется). Значит: убийцаBackgroundAppManagerприсутствует всегда → стража NetConfigActivity-на-скрытом-дисплее обязательна. Отключение лаунчера проблему не решает. -
BLE жив всегда. Раз Mercury стартует при буте в любом случае, Channel 2 (BLE: запуск приложения, яркость, WiFi, статус) доступен всегда. Это надёжный канал.
-
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 SDKMirroringView(правый); - использует проприетарный 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-сервер не поднимается):
IAdbManager.allowWirelessDebugging(true, ssid)— транзакция binderadb№4, добавляет доверенную сеть (adb_temp_keys.xml+ запись wifiAP/bssid).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. Поэтому при каждом бутстрапе его надо перевключать (через MercuryenableWirelessAdb, который и вызывает оба шага).
Авторизация без сопряжения
- Встроенный 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→ pushassets/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 сам.