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).
This commit is contained in:
@@ -2,8 +2,17 @@ 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.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
|
||||
|
||||
@@ -13,10 +22,15 @@ import pw.binom.rayneovm.phone.protocol.VmPhoneController
|
||||
* При старте подготавливает контроллер [VmPhoneController] (auto-reconnect к очкам через mDNS)
|
||||
* и [MercuryController] (второй канал — RayNeo Mercury BLE).
|
||||
*/
|
||||
class PhoneVmApp : Application(), ControllerProvider, MercuryControllerProvider {
|
||||
class PhoneVmApp : Application(), ControllerProvider, MercuryControllerProvider, ShizukuProvisionerProvider {
|
||||
|
||||
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 provisioner: ShizukuProvisioner by lazy {
|
||||
ShizukuProvisioner(this, mercuryController, controller)
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
@@ -32,19 +46,58 @@ class PhoneVmApp : Application(), ControllerProvider, MercuryControllerProvider
|
||||
// Запуск отложен до первого обращения — в 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
|
||||
|
||||
companion object {
|
||||
private const val TAG = "PhoneVmApp"
|
||||
private const val PROVISION_RETRY_MS = 30_000L
|
||||
}
|
||||
}
|
||||
|
||||
/** Провайдер автономного бутстрапа Shizuku для UI. */
|
||||
interface ShizukuProvisionerProvider {
|
||||
fun provideShizukuProvisioner(): ShizukuProvisioner
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user