Files
rayneo-vm/app-phone-vm/src/main/kotlin/pw/binom/rayneovm/phone/PhoneVmApp.kt
T
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

113 lines
5.4 KiB
Kotlin

package pw.binom.rayneovm.phone
import android.app.Application
import android.util.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import pw.binom.rayneovm.phone.adb.AdbController
import pw.binom.rayneovm.phone.bootstrap.ShizukuProvisioner
import pw.binom.rayneovm.phone.mercury.MercuryController
import pw.binom.rayneovm.phone.mercury.MercuryControllerProvider
import pw.binom.rayneovm.phone.mercury.MercuryState
import pw.binom.rayneovm.phone.protocol.ConnectionState
import pw.binom.rayneovm.phone.protocol.ControllerProvider
import pw.binom.rayneovm.phone.protocol.VmPhoneController
/**
* Application-класс PhoneApp.
*
* При старте подготавливает контроллер [VmPhoneController] (auto-reconnect к очкам через mDNS)
* и [MercuryController] (второй канал — RayNeo Mercury BLE).
*/
class PhoneVmApp : Application(), ControllerProvider, MercuryControllerProvider,
ShizukuProvisionerProvider, AdbControllerProvider {
private val appScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
private val controller: VmPhoneController by lazy { VmPhoneController(this) }
private val mercuryController: MercuryController by lazy { MercuryController(this) }
private val adbController: AdbController by lazy { AdbController(this, mercuryController) }
private val provisioner: ShizukuProvisioner by lazy {
ShizukuProvisioner(this, mercuryController, controller, adbController)
}
override fun onCreate() {
super.onCreate()
Log.i(TAG, "PhoneVmApp onCreate, uid=${android.os.Process.myUid()}")
// Хранитель связи: держит процесс живым при выключенном экране, иначе HONOR усыпляет
// его и очки теряют WebSocket-связь. Может быть запрещён системой при старте из фона —
// тогда связь просто отвалится по экрану, как раньше; приложение не падает.
try {
ConnectionKeepAliveService.start(this)
} catch (t: Throwable) {
Log.w(TAG, "ConnectionKeepAliveService start failed", t)
}
// Запуск отложен до первого обращения — в lazy.
controller.start()
mercuryController.refresh()
// Автономный подъём Shizuku. Условие: есть и WiFi-канал (наша WebSocket-связь
// с очками), и BLE (Канал 2, через который очки включают ADB over WiFi).
// Проверяем при каждом появлении связи и периодически, пока BLE жив, —
// если Shizuku не запущен, поднимаем его.
appScope.launch {
controller.state.collect { st ->
if (st is ConnectionState.Connected && mercuryController.state.value is MercuryState.Connected) {
Log.i(TAG, "WiFi подключение к очкам — проверяю Shizuku")
provisioner.ensure()
}
}
}
// Периодический дешёвый дозвон, пока BLE жив. Полный adb-цикл гоняется не чаще
// одного раза за BLE-сессию (см. ShizukuProvisioner.provisionedInSession), поэтому
// это не дёргает очки; зато так мы подхватываем случай, когда Shizuku упал и очки
// прислали явный статус running=false.
appScope.launch {
while (true) {
delay(PROVISION_RETRY_MS)
if (mercuryController.state.value is MercuryState.Connected) {
provisioner.ensure()
}
}
}
// Разрыв BLE — новая сессия: при следующем подключении проверяем Shizuku заново.
appScope.launch {
mercuryController.state.collect { st ->
if (st !is MercuryState.Connected) provisioner.onBleDisconnected()
}
}
}
override fun onTerminate() {
super.onTerminate()
ConnectionKeepAliveService.stop(this)
provisioner.close()
controller.stop()
mercuryController.close()
}
override fun provideController(): VmPhoneController = controller
override fun provideMercuryController(): MercuryController = mercuryController
override fun provideShizukuProvisioner(): ShizukuProvisioner = provisioner
override fun provideAdbController(): AdbController = adbController
companion object {
private const val TAG = "PhoneVmApp"
private const val PROVISION_RETRY_MS = 30_000L
}
}
/** Провайдер автономного бутстрапа Shizuku для UI. */
interface ShizukuProvisionerProvider {
fun provideShizukuProvisioner(): ShizukuProvisioner
}
/** Провайдер adb-контроллера (единая точка входа для adb-команд) для UI. */
interface AdbControllerProvider {
fun provideAdbController(): AdbController
}