glasses: launch guest on Shizuku VirtualDisplay + binocular render
- VmShizukuService is a Shizuku UserService only; remove its <service> manifest entry (ServiceStarter instantiates it reflectively, an Android service entry causes ClassCastException) - VirtualDisplayFrameSource: await binder via ShizukuVdClient.bindForResult(5s), expose virtualDisplayId + shizukuBinder, stop the UserService on release - VmGlassesController: serialize acquire via Mutex, use double-buffered SurfaceTexture (DisplayManagerService rejects single-buffer), launch the guest on the VD with ShizukuVdBinder.launchActivity - GlassesScreen: render controller.frameSource (Running) directly; drop the LaunchedEffect acquire - DebugTestReceiver: register at runtime from MainActivity (background manifest receivers are blocked on Android 12+)
This commit is contained in:
+14
-5
@@ -25,14 +25,23 @@ class VirtualDisplayFrameSource private constructor(
|
||||
private val surface: Surface,
|
||||
private val binder: IBinder,
|
||||
private val displayId: Int,
|
||||
private val client: ShizukuVdClient,
|
||||
width: Int,
|
||||
height: Int,
|
||||
) : SurfaceTextureFrameSource(source, width, height) {
|
||||
|
||||
/** ID виртуального дисплея (нужен для запуска Activity через ActivityOptions.setLaunchDisplayId). */
|
||||
val virtualDisplayId: Int get() = displayId
|
||||
|
||||
/** Binder к ShizukuVdService (для последующих вызовов launchActivity / injectInputEvent). */
|
||||
val shizukuBinder: IBinder get() = binder
|
||||
|
||||
override fun release() {
|
||||
runCatching { ShizukuVdBinder.releaseDisplay(binder, displayId) }
|
||||
runCatching { surface.release() }
|
||||
super.release()
|
||||
// Отвязываем UserService — держим его живым ровно на время жизни дисплея.
|
||||
runCatching { client.stop() }
|
||||
Log.i(TAG, "VirtualDisplayFrameSource released: displayId=$displayId")
|
||||
}
|
||||
|
||||
@@ -60,10 +69,10 @@ class VirtualDisplayFrameSource private constructor(
|
||||
val surface = Surface(surfaceTexture)
|
||||
val client = ShizukuVdClient(context, serviceClass)
|
||||
return try {
|
||||
var binder: IBinder? = null
|
||||
client.start { b -> binder = b }
|
||||
val b = binder ?: run {
|
||||
Log.w(TAG, "Shizuku binder not ready, returning null")
|
||||
// bindUserService асинхронен — ждём Binder через suspend-обёртку (5с таймаут).
|
||||
val b = client.bindForResult(timeoutMs = 5000)
|
||||
if (b == null) {
|
||||
Log.w(TAG, "Shizuku binder not ready (timeout или pingBinder=false), returning null")
|
||||
surface.release()
|
||||
client.stop()
|
||||
return null
|
||||
@@ -78,7 +87,7 @@ class VirtualDisplayFrameSource private constructor(
|
||||
return null
|
||||
}
|
||||
Log.i(TAG, "Acquired VirtualDisplay id=$displayId ${width}x${height}")
|
||||
VirtualDisplayFrameSource(surfaceTexture, surface, b, displayId, width, height)
|
||||
VirtualDisplayFrameSource(surfaceTexture, surface, b, displayId, client, width, height)
|
||||
} catch (t: Throwable) {
|
||||
Log.e(TAG, "acquire failed", t)
|
||||
runCatching { surface.release() }
|
||||
|
||||
Reference in New Issue
Block a user