Commit Graph

17 Commits

Author SHA1 Message Date
subochev d4e1b66924 аудио UDP+Opus (очки→телефон), жесты дужки → гость, «убить всё лишнее» на очках
- shared/audio: вендорнут Concentus (libs/concentus.jar), OpusCodec/AudioDatagram/AudioConfig;
  захват на очках 48кГц стерео → Opus → UDP-датаграммы вместо сырого PCM по WebSocket
- glass.audio: AudioRecord 48кГц с минимальным буфером; UDP-сервер запоминает адрес пира из датаграммы
- glasses: жесты тач-сенсора дужки (cyttsp5_mt) через dispatchTouchEvent → DPAD/BACK гостю (TempleGesture*)
- glasses: forceStopAll — force-stop сторонних + xr.runtime, kill scrcpy-сирот через Shizuku UserService
- phone: AudioPlaybackManager на UDP+Opus+low-latency AudioTrack; кнопка «Убить всё лишнее» на вкладке очков
- deps: mercury transport 0.1.2-SNAPSHOT, shizuku-vd 0.1.1-SNAPSHOT
2026-10-01 05:54:54 +03:00
subochev 8cfd9192b3 mercury: синк часов очков после коннекта BLE (ble.response.set_time)
Как штатное приложение (OnConnected.startSyncTask): сразу после подъёма
BLE-сессии шлём очкам время телефона. Нужно очкам, когда они без сети —
иначе у них своё время и валятся TLS-проверки в гостевых приложениях.

Вызов идемпотентный, ставится и в connectInternal, и в Event.Connected
(внутренние переподключения библиотеки).
2026-09-28 02:27:12 +03:00
subochev 0f6f07782f UI: развести статусы каналов — сводка «Связь» (BLE / TCP/IP); transport 0.1.1-SNAPSHOT; BLOCKERS B-5
Обе строки назывались «Связь» (Канал 1 WebSocket и Канал 2 Mercury BLE), из-за чего
статус BLE читался как статус TCP: при выключенном Wi-Fi на очках телефон показывал
«подключено». Теперь вверху вкладки «Очки» сводка с отдельными строками BLE (Mercury)
и TCP/IP (Wi-Fi), в секциях — «BLE» и «TCP/IP».

mercuryTransport -> 0.1.1-SNAPSHOT (клиентский WS-пинг, см. BLOCKERS B-5).
2026-09-27 15:56:49 +03:00
subochev 3808281d42 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 проверен)
2026-09-27 12:49:05 +03:00
subochev ad4e458f5c #5 AccessibilityProvisioner: авто-включение VmAccessibilityService на очках при коннекте (по модели ShizukuProvisioner) 2026-09-27 11:22:04 +03:00
subochev 65f3f5d228 #1,#3,#4+#5 keyboards: Binocular Compose, cursor watchdog 3s, SetText + VmNoopIme + sendText 2026-09-27 11:18:52 +03:00
subochev b1efa3d462 feat(audio,#2): MediaProjection + AudioPlaybackCapture preview on glasses; AudioPath /vm-audio to phone; debug test tone; debug audio pipe; FGS mediaProjection type; AudioOutputSection UI toggle 2026-09-27 06:39:00 +03:00
subochev 9914488258 phone: AdbController — единственная точка входа для adb-команд; screen on/off через Канал 1
- AdbController: shell/push/ensureConnected/invalidate; перед каждой командой
  проверяет соединение (echo ok) и сам поднимает wireless-adb (Mercury -> mDNS ->
  connect). Мьютекс только на подъём, длинный бутстрап не блокирует команды.
- ShizukuProvisioner переведён на AdbController (adb-код вынесен).
- Убрана неработающая UI-консоль adb (нужен только программный API).
- ScreenControl(sleep) в shared: гашение/пробуждение экрана очков их же
  Shizuku-UserService (инжект 223/224 как shell), не зависит от Mercury/adb.
- VmPhoneController.setScreen + кнопки «Экран очков» на Канале 1.
- DebugReceiver: DEBUG_ADB_SHELL (+ SET_DEEP_SUSPEND) как отладочный инструмент.
- MercuryController/AdbClient: сопутствующие правки.
2026-09-27 04:55:47 +03:00
subochev 027e2efb9c phone: rewind/forward buttons in remote screen (DPAD left/right) 2026-09-27 04:01:22 +03:00
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
subochev 59069a741e phone: keep-alive foreground service + notification perm; glasses: clear NoConnection on reconnect
- ConnectionKeepAliveService (foreground, PARTIAL_WAKE_LOCK + WIFI_MODE_FULL_HIGH_PERF,
  started in PhoneVmApp.onCreate): without it HONOR deep-sleeps the phone process on
  screen-off and the glasses lose the WebSocket link. Same mechanic as view-mate.
- MainActivity: request POST_NOTIFICATIONS so the FGS notification is visible.
- VmGlassesController.onPhoneConnected(): drop a stuck NoConnection state when the
  phone (re)connects; returns to Running if a guest is active, else NoAppSelected.
- VmService: call it from onConnected.
- stopGuest/switch: force-stop the previous guest before releasing its display
  (releasing first migrates the guest task to display 0 full-screen); VirtualDisplay
  frame source now destroys its UserService on release.
- Mercury status: retry the first pullGeneralStatus until it lands, refresh every 15s
  and on tab open; GlassesStatusScreen shows 'Ждём статус от очков…' instead of fake zeros.
- MainActivity(glasses): HOME candidate flag + finish() on a non-default display (recursion guard).
- README: Home-launcher setup/rollback section.
- BOOTSTRAP_TEST.md: post-reboot Shizuku bootstrap investigation log.
2026-09-26 13:59:54 +03:00
subochev 94f0ed28fc glasses: ignore scroll drags shorter than 96px (guest counts them as item clicks); phone: skip centroid jump on finger-count change 2026-09-25 20:27:26 +03:00
subochev 05daf3fc7b phone: delay touchpad tap click by 100 ms; second finger cancels it 2026-09-25 20:20:39 +03:00
subochev c69e8a2e80 glasses: hold Mercury kill switch on hidden VirtualDisplay; phone: brightness/WiFi panel, two-finger touchpad scroll 2026-09-25 19:49:25 +03:00
subochev 3fce3eb3ca phone: third «Пульт» tab with on-glasses cursor; atomic click injection
- shared: VmDisplay (guest 640x480 coordinate space), CursorMove and
  CursorClick messages (CursorClick replaces the DOWN/UP pair — see below).
- glasses: cursor state + Canvas overlay drawn in both eyes, clickCursor
  injects one atomic tap at the cursor, sendKey for Back/Play/Pause.
- phone: RemoteScreen — touchpad (relative drag moves the cursor, tap
  clicks), «Назад»/«Плей»/«Пауза» buttons, «Клавиатура» stub (TODO).
- The old CursorButton(DOWN)/CursorButton(UP) pair was removed: the two
  messages were injected concurrently and could arrive out of order,
  breaking the guest's touch stream so clicks worked only once.
- tests: CursorMove/CursorClick roundtrips.
2026-09-25 18:20:56 +03:00
subochev 86bffed6ec phone: dynamic app list from glasses + two-channel GlassesStatusScreen
Phone app:
- VmPhoneController: collect appsOnGlasses from glasses (state flow), and
  requestAppList() sends VmMessage.GetAppList over WebSocket.
- AppsListScreen: rename to dynamic list from glasses, verticalScroll,
  tap → LaunchAppCommand(packageName). Tap calls onAppClick for parent
  nav (Glasses tab on the bottom NavigationBar).
- Shared VM message types (VmMessage.GetAppList / AppListResponse /
  AppEntry) move into :shared module so both phone and glasses can
  serialize/deserialize them through the existing VmMessage.Json

Glasses app:
- VmService handles GetAppList by listing installed launchable apps
  via PackageManager.queryIntentActivities (combined with Android 11+
  <queries> fix in the previous commit so 3rd-party apps appear) and
  replies with AppListResponse.
- GlassesScreen drives state from controller.state; no longer hardcodes
  any apps in the UI.

Tested end-to-end on A06B4AB933C4103: phone taps app on
AppsListScreen → glasses' VmService receives LaunchAppCommand →
controller.launchGuest(pkg) launches the activity via
PackageManager.getLaunchIntentForPackage + FLAG_ACTIVITY_NEW_TASK.
2026-09-25 15:21:14 +03:00
subochev 987f9e5547 init 2026-09-25 13:24:56 +03:00