9914488258
- 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: сопутствующие правки.
113 lines
5.4 KiB
Kotlin
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
|
|
}
|