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: сопутствующие правки.
This commit is contained in:
2026-09-27 04:55:47 +03:00
parent 027e2efb9c
commit 9914488258
13 changed files with 493 additions and 169 deletions
@@ -36,6 +36,7 @@ import pw.binom.rayneovm.shared.CursorScroll
import pw.binom.rayneovm.shared.CursorClick
import pw.binom.rayneovm.shared.CursorMove
import pw.binom.rayneovm.shared.RequestShizukuStatus
import pw.binom.rayneovm.shared.ScreenControl
import pw.binom.rayneovm.shared.ShizukuStatus
/**
@@ -167,6 +168,10 @@ class VmService : LifecycleService() {
controller.sendKey(msg.keyCode, msg.action)
}
is SetAudioMode -> Log.d(TAG, "SetAudioMode: ${msg.mode}")
is ScreenControl -> {
Log.i(TAG, "ScreenControl: sleep=${msg.sleep}")
controller.setScreen(msg.sleep)
}
is Shutdown -> {
Log.i(TAG, "Shutdown")
controller.stopGuest()
@@ -245,6 +245,27 @@ class VmGlassesController {
}
}
/**
* Гасит/будит экран самих очков (дисплей 0) через Shizuku-UserService.
*
* Идёт через инжект `KEYCODE_SLEEP`/`KEYCODE_WAKEUP` от shell UID, поэтому не зависит
* ни от Mercury BLE, ни от wireless-adb. Биндер берём у «стража» (он всегда поднят, пока
* живёт приложение), иначе — у активного гостевого дисплея.
*/
fun setScreen(sleep: Boolean) {
val binder = guardBinder ?: activeSource?.shizukuBinder
if (binder == null) {
Log.w(TAG, "setScreen(sleep=$sleep): нет Shizuku-биндера (Shizuku не поднят?)")
return
}
testScope.launch {
val ok = runCatching { ShizukuVdBinder.setScreen(binder, !sleep) }
.onFailure { Log.w(TAG, "setScreen: binder мёртв", it) }
.getOrDefault(false)
Log.i(TAG, "setScreen(sleep=$sleep) -> $ok")
}
}
/** Клавиатурное/медиа-событие гостю на его VirtualDisplay (Back, Play, Pause, ...). */
fun sendKey(keyCode: Int, action: Int) {
val src = activeSource ?: return