- MainActivity: requestTick собирается в repeatOnLifecycle(RESUMED) + флаг AudioBridge.activityResumed - requestProjection(): не дёргает startActivity(MainActivity), пока Activity RESUMED (гонка с grant) - ensureAudioCaptureLoop(): запрос проекции один раз, повтор не чаще 20 c (было 2.5 c) - AudioBridge/GlassesAudioCapture: проекция одна на процесс и не гасится, переиспользуется - ShizukuProvisioner: PROJECT_MEDIA per-UID (на Android 12 package-level = no-op) - отладочные логи phone-side audio; BLOCKERS.md B-3 закрыт (E2E проверен)
8.8 KiB
Blockers
Сюда пишутся только те задачи/проблемы, в которых застряли. Каждая запись — задача,
что сделано, в чём стена, что проверено, варианты обхода. Записи ведутся по правилам
ночной сессии (см. TASKS.md, секция «Правила ночной сессии»).
B-1 · Периодический лаунч Mercury/.NetConfigActivity — ПОДТВЕРЖДЁН, источник не найден
Когда замечено: 2026-09-27, во время тестов запуска Zona через DEBUG_LAUNCH.
Что я видел в логах: ShizukuVdService: launchActivity pkg=com.ffalconxr.mercury.launcher cls=com.ffalconxr.mercury.launcher.wizard.netconfig.NetConfigActivity displayId=2 повторялось
каждые 5 секунд, постоянно.
Что это на самом деле: Непонятно. Это мог быть мой собственный GlassesDebugReceiver,
который я перепосылал несколько раз и он где-то зациклился; мог быть артефакт system-job’а;
мог быть какой-то fallback в VmGlassesController.ensureNetworking().
Повторно замечено: 2026-09-27 12:28:40, START ... NetConfigActivity from uid 2000 (shell)
в логах очков во время отладки звука. uid 2000 = shell ⇒ запускает Shizuku UserService
(наш код через Shizuku). Значит источник — где-то в нашем Shizuku-пути (не Mercury BLE).
На аудио-grant влияния не оказал (график grant сломался по другой причине — см. B-3).
Что НЕ сделано: не остановил очки в момент пика, не нашёл источник цикла. Пользователь утром сказал «сейчас вижу наше приложение», значит цикл или закончился, или не повторяется.
Следующий шаг: если повторится — переписать GlassesDebugReceiver с rate-limit + проверить
нет ли в VmService/VmGlassesController периодического launchActivity(Mercury) для
Wi-Fi/network fallback.
B-2 · rayneo-mercury: enableWirelessAdb через BLE на X3 Pro не возвращает адрес
Когда выяснено: 2026-09-27, аудит прошивки RayNeoLauncher по smali
(adb pull /system/app/RayNeoLauncher).
Что происходит (по smali + логам):
- Телефон шлёт BLE-команду
ble.request.debugсpayload.cmd="enableWirelessAdb". - Очки принимают команду и реально поднимают беспроводной adb (мы видим
adb_wifi_enabled=1иservice.adb.tcp.portпосле). Это работает. - Очки должны прислать событие
WirelessAdbAddressобратно. Это не происходит. - В smali
BleResponseестьRESPONSE_MAP, в котором зарегистрированы Wi-Fi / media / netconfig ответы — ноDebugResponseотсутствует. Поэтому маршрутизация ответа по URIble.request.debugне настроена, и событие теряется. - Телефон вечно ждёт
Event.WirelessAdbAddress, не получает его и уходит в таймаут.
Что это значит для provisioning:
- Команда
enableWirelessAdbчерез BLE включает adb — но адресip:portмы узнать не можем. - Provisioning сейчас работает только потому, что adb уже был включён раньше (например,
руками или через shizuku) и не выключился после ребута. После ребута очков — если
adb_wifi_enabledсбросится в 0 — provisioning сломается, потому что новый адрес мы узнать не сможем.
Обходной путь (уже работает):
# Через shizuku shell на очках:
service call adb 4 i32 1 s16 'Caffeine Portable' # включить adb
settings put global adb_wifi_enabled 1 # не дать ему автоотключиться
После этого adb_wifi_enabled остаётся 1, телефон через mDNS _adb-tls-connect._tcp
находит ip:port и подключается. Это уже используется как fallback в AdbController.
Следующий шаг: при первом удобном случае — поднять через shizuku-shell и убедиться, что provisioning пройдёт полностью через этот путь.
B-3 · Звук end-to-end — РЕШЕНО
Когда замечено: 2026-09-27, E2E-проверка после восстановления общей сети «O2 5».
Симптом: звук на телефон работал только в первый раз; после ON_GLASSES → ON_PHONE тишина
и на очках, и на телефоне.
Корень (найден по логам 2026-09-27): не сеть и не телефон, а grant MediaProjection на очках.
ensureAudioCaptureLoop ре-запрашивал проекцию каждые 2.5 c, а requestProjection() каждый раз
дёргал startActivity(MainActivity, NEW_TASK|SINGLE_TOP). Система:
START com.android.systemui/.media.MediaProjectionPermissionActivity from uid 10090
→ UsageStats event :23 (ACTIVITY_STOPPED) через ~30 мс
→ MainActivity: MediaProjection не выдан: resultCode=0
то есть grant-активити гасится, если её запускает только что перезапущенная Activity. Ручной
KEYCODE_HOME (уводит нашу Activity с переднего плана) «разблокировал» grant — подтверждало
гипотезу гонки.
Фикс (вариант A):
MainActivityсобираетrequestTickвrepeatOnLifecycle(**RESUMED**)(былSTARTED) и флагомAudioBridge.activityResumedсообщает сервису, что она наверху.requestProjection()больше не вызываетstartActivity(MainActivity), пока Activity ужеRESUMED(убрана гонка с запуском consent-активити).ensureAudioCaptureLoopзапрашивает проекцию один раз; повтор — не чащеAUDIO_RETRY_MS=20 c.- Проекция одна на процесс и не гасится:
GlassesAudioCapture.stop()останавливает толькоAudioRecord, аAudioBridge.onProjectionGrantedне трогает уже имеющуюся. СледующийON_PHONEпереиспользует ту же проекцию — новый grant не нужен вовсе.
Проверено вживую 2026-09-27 (очки A06B4AB933C4103 → телефон AXGL024B05001337):
[1] ON_PHONE→MediaProjection полученбез HOME → захват запущен.[2] ON_GLASSES→остановлен (проекцию сохраняю).[3] ON_PHONE→аудио-захват поднят, без нового grant (переиспользование).- Тестовый тон 440 Гц: очки
rms=5673, телефонplaying ... rms=5620..5698, байты совпали (bytes=4751360с обеих сторон). PCM реально дошёл по/vm-audio.
Проверено с руки пользователя 2026-09-27: полный сценарий с Zona — ON_PHONE → ON_GLASSES
→ ON_PHONE — звук корректно переключается, повторный ON_PHONE больше не ломается.
B-3 закрыт полностью.
B-4 · Финал: гашение экрана обязательно в конце
По ночным правилам — на завершении всех задач ИЛИ при невозможности продолжать — выполняется:
adb -s A06B4AB933C4103 shell input keyevent 223
и проверка mWakefulness=Dozing/Asleep. Если не работает — через ScreenControl (Канал 1) /
Shizuku SET_SCREEN.
Статус: выполнено (mWakefulness=Dozing подтверждён в конце ночной сессии).