fix(audio,#2): переиспользование одного MediaProjection — устранён слом повторного ON_PHONE
- 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 проверен)
This commit is contained in:
+40
-20
@@ -6,7 +6,7 @@
|
||||
|
||||
---
|
||||
|
||||
## B-1 · Периодический лаунч `Mercury/.NetConfigActivity` — НЕ ПОДТВЕРЖДЁН
|
||||
## B-1 · Периодический лаунч `Mercury/.NetConfigActivity` — ПОДТВЕРЖДЁН, источник не найден
|
||||
|
||||
**Когда замечено:** 2026-09-27, во время тестов запуска Zona через `DEBUG_LAUNCH`.
|
||||
|
||||
@@ -16,7 +16,12 @@ cls=com.ffalconxr.mercury.launcher.wizard.netconfig.NetConfigActivity displayId=
|
||||
|
||||
**Что это на самом деле:** Непонятно. Это мог быть мой собственный `GlassesDebugReceiver`,
|
||||
который я перепосылал несколько раз и он где-то зациклился; мог быть артефакт system-job’а;
|
||||
мог быть какой-то fallback в `VmGlassesController.ensureNetworking()`. **Не блокер.**
|
||||
мог быть какой-то 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).
|
||||
|
||||
**Что НЕ сделано:** не остановил очки в момент пика, не нашёл источник цикла. Пользователь
|
||||
утром сказал «сейчас вижу наше приложение», значит цикл или закончился, или не повторяется.
|
||||
@@ -63,30 +68,45 @@ settings put global adb_wifi_enabled 1 # не дать ему ав
|
||||
|
||||
---
|
||||
|
||||
## B-3 · Звук end-to-end — РЕШЕНО на стороне очков
|
||||
## B-3 · Звук end-to-end — РЕШЕНО
|
||||
|
||||
**Когда замечено:** 2026-09-27, E2E-проверка после восстановления общей сети «O2 5».
|
||||
|
||||
**Что доказано работающим на очках:**
|
||||
- `MediaProjection` получается без диалога (`PROJECT_MEDIA: allow` уже стоит с ночи).
|
||||
- `AudioPlaybackCapture` стартует, читает PCM: `GlassesAudioCapture: capture: bytes=... rms=...`.
|
||||
- 440 Гц TestTone → RMS=5674 (теория ~5657). **Реальный звук захвачен, не тишина**.
|
||||
- Динамик очков мутится (`STREAM_MUSIC: mute`).
|
||||
- Поток PCM по 4 КБ фреймам идёт в `Channel<ByteArray>(capacity=16)`, готов к WebSocket.
|
||||
- TCP-порт `8081` на очках (`192.168.76.248:8081/vm-audio`) отвечает с телефона.
|
||||
**Симптом:** звук на телефон работал только в первый раз; после `ON_GLASSES` → `ON_PHONE` тишина
|
||||
и на очках, и на телефоне.
|
||||
|
||||
**Что не проверено вживую:** воспроизведение на телефоне. AudioPlaybackManager код опубликован,
|
||||
но не вызван (`controller.setAudioMode(ON_PHONE)` никто не дёрнул). UI-переключатель на
|
||||
телефоне готов, но нажать его можно только с руки (в этой сессии PhoneDebugReceiver я не
|
||||
реализовал, broadcast дропается HONOR).
|
||||
**Корень (найден по логам 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 — подтверждало
|
||||
гипотезу гонки.
|
||||
|
||||
**Известный race-condition:** `MainActivity.handledTick` при двойном `requestProjection`
|
||||
с коротким интервалом пересоздаёт projection → `AudioRecord.read -2`. Не блокирует нормальную
|
||||
работу (UI нажимается один раз → один tick), но при отладке DEBUG_AUDIO_PIPE после уже
|
||||
активного захвата ломает capture. Чиню при случае.
|
||||
**Фикс (вариант A):**
|
||||
1. `MainActivity` собирает `requestTick` в `repeatOnLifecycle(**RESUMED**)` (был `STARTED`) и флагом
|
||||
`AudioBridge.activityResumed` сообщает сервису, что она наверху.
|
||||
2. `requestProjection()` больше **не** вызывает `startActivity(MainActivity)`, пока Activity уже
|
||||
`RESUMED` (убрана гонка с запуском consent-активити).
|
||||
3. `ensureAudioCaptureLoop` запрашивает проекцию **один раз**; повтор — не чаще `AUDIO_RETRY_MS=20 c`.
|
||||
4. Проекция **одна на процесс и не гасится**: `GlassesAudioCapture.stop()` останавливает только
|
||||
`AudioRecord`, а `AudioBridge.onProjectionGranted` не трогает уже имеющуюся. Следующий `ON_PHONE`
|
||||
переиспользует ту же проекцию — новый grant не нужен вовсе.
|
||||
|
||||
**Следующий шаг:** нажать в UI телефона переключатель «Звук на телефоне» — должно
|
||||
зазвучать. Если нет — проверить `adb -s AXGL024B05001337 logcat -s AudioPlaybackManager:V`.
|
||||
**Проверено вживую 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 закрыт полностью.**
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user