ShizukuShellBackend
ShellBackend backed by Shizuku's newProcess binder. Runs commands as the shell UID — broader than the host app but narrower than root.
Activation is the user's responsibility: install the Shizuku app, activate it via wireless debugging (Android 11+) or ADB, grant the permission. The backend reports isAvailable() == false until both the binder is reachable and the host has permission. See docs/SHELL.md.
Bounds. Each exec is limited to execTimeoutMs of wall-clock time and maxOutputBytes of captured stdout / stderr each (execBinary uses the larger maxBinaryOutputBytes for stdout, since screencap -p PNGs are multi-MB). The spawned process's stdin is closed immediately, so a command that reads stdin sees EOF instead of hanging. On timeout, caller cancellation, or an exceeded output cap the remote process is destroyed and its pipes closed. A timeout surfaces as ShellException.SpawnFailed; an exceeded cap returns the captured prefix with ShellResult.outputTruncated set and exitCode = -1.
Binder death. A RemoteException (Shizuku server killed, device re-locked, etc.) from spawn / wait / destroy surfaces as ShellException.NotAvailable, i.e. shell_unavailable.
Implementation note (Shizuku v13): Shizuku.newProcess(...) is private in v13. We reflectively access it because the alternative (a full AIDL UserService pattern) is substantially more code for the same effective behaviour. Migrating to a proper UserService is tracked for a follow-up release; reflection is the documented pragmatic path used by other Shizuku consumers in the v13 era. The module ships consumer ProGuard rules keeping that member so R8-minified hosts keep working.
Parameters
wall-clock limit per call. Note the core ToolRegistry applies its own (longer) per-tool timeout on top.
per-stream capture cap for exec (and stderr of execBinary).
stdout capture cap for execBinary.