Skip to content

Device validation and runnable probes ​

Last reviewed: September 30, 2026.

Evidence levels ​

LevelMeaningExamples in this catalog
Observed locallyCommand/probe ran on connected physical hardwarePad AVF info, protected Microdroid boot, real app-domain probes
Contributor observedPhysical-device collector output supplied and reviewedPixel 7 Pro AVF capabilities and live NNS app/session/daemon views
Upstream demonstratedSource author records execution on a stated setupRooted Lenovo Gunyah guide; NNS Android harness
Source inspectedMechanism verified in pinned implementationAVF permission checks, NNS launcher, custom bootstrap
Proposed / inferredIntegration could follow but has not passed locallyNo-DEX AVF owner, custom NixOS on Pad, Pixel/MediaTek compatibility

A feature bit, device node, guest boot, app permission and complete development workflow are different achievements. The tests below do not claim a working local NixOS backend or quantify performance.

Stored device transcripts normalize carriage returns, NUL separators and trailing whitespace for repository text checks. They retain command output, including interleaved console lines and error messages; they are not byte-identical terminal captures. Implementation source snapshots remain byte-identical.

Physical inventory ​

PropertyXiaomi 11T ProXiaomi Pad 8 Pro
Model / device2107113SG / vili25091RP04G / piano
SoC evidenceSM8350 (Snapdragon 888)getprop ro.soc.model: SM8750P; user identifies Snapdragon 8 Elite
Android / API14 / 3416 / 36
FirmwareV816.0.20.0.UKDEUXMOS3.0.303.0.WPYEUXM
Kernel5.4.289-qgki-g7dd106e6c8476.6.77-android15-8-g4a507830d890-ab13636293-4k
Boot/securityLocked, green verified boot, SELinux enforcingLocked, green verified boot, SELinux enforcing
AVF featureAbsentPresent
Hypervisor nodes/dev/kvm, /dev/gunyah, /dev/gzvm absent/dev/gunyah present; KVM/GZ nodes absent
AVF toolAbsent/apex/com.android.virt/bin/vm present
App namespace routeRejectedRejected
Independent shell-owned guest bootNot available through observed stackProtected Microdroid payload ready

The Pixel 10 Pro is deferred at the user's request. A contributor supplied Pixel 7 Pro evidence from a provisioned Android 16 device: both AVF guest modes are reported, and a live NNS Zsh session has canonical store paths, the app UID and separate user/mount namespaces. The Pixel was not connected to this research workstation; no Pixel guest was launched by the collector. No MediaTek hardware was tested. These are exact deployment observations, not enduring support guarantees for the model names.

A separate getconf PAGESIZE query on the Pad returned 4096 bytes. Future device inventories should record page size and apply the native compatibility checks before attributing a launch failure to the execution backend.

The original phone was disconnected when the Pad was connected. Its initial results were recorded from live tool output; the Pad has raw inventory, capability output, guest boot log and app probe output. The phone was subsequently reconnected: its captured app probe output was retrieved and its disposable files/android-research probe directory and /data/local/tmp/sparkles-android-app-probe removed. No system policy or existing application data was changed.

Reproduce the inventory ​

The inventory program requires an explicit serial and performs read-only queries. Without arguments it prints SKIP: for CI. With a device:

bash
dub docs/research/android-dev-env/device-validation/examples/inventory.d --serial SERIAL --adb /path/to/adb

It captures identity, shell security state, feature/node presence, resource snapshot and relevant app/process names. A shell UID of 2000 with seccomp disabled is not the app's execution context.

App-domain probe ​

The libc-only probe compiles with -betterC against the Android Bionic toolchain. Run it from the terminal UI's actual session. run-as can copy the binary and retrieve output, but must not be used to execute the evidence-producing probe: its SELinux domain differs from the application session.

Successful cross-compilation used LDC Android 1.42.0 and NDK 28.1.13356709's aarch64-linux-android29-clang:

bash
ldc2 -betterC -mtriple=aarch64--linux-android \
  -gcc=/path/to/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang \
  docs/research/android-dev-env/device-validation/examples/app-probe.d \
  -of=/tmp/sparkles-android-app-probe

The custom terminal's existing no-DEX APK was installed on the Pad because it was not present. The binary was copied into an app-private research directory, executed through short typed shell commands and its output retrieved afterward. This proves the test inherited the zygote-born application's policy; it is not a standalone ADB shell executable result.

ProbeXiaomi 11T Pro app sessionPad 8 Pro app session
UID/GID10488 / 1048810413 / 10413
SELinux domainuntrusted_app_27untrusted_app_27
Seccomp22
CapEffZeroZero
unshare(CLONE_NEWUSER)-1, errno 22 (EINVAL)-1, errno 22 (EINVAL)
unshare(CLONE_NEWNS)-1, errno 1 (EPERM)-1, errno 1 (EPERM)
Combined namespaces-1, errno 22-1, errno 22
socket(AF_VSOCK)-1, errno 13 (EACCES)-1, errno 13 (EACCES)

Neither device exposes the NNS seccomp-bypass sysctl or max_user_namespaces at the probed paths. These observations reject direct app namespace entry on the tested configurations, but do not uniquely identify the cause of every rejected syscall. AF_VSOCK rejection does not exclude a framework-brokered descriptor or service-mediated transport.

The full D namespace example separately demonstrates disposable-child namespace behavior on a capable Linux host. It is not substituted for the Android app result.

Pad AVF and protected guest ​

vm info reported “Only protected VMs are supported.” The world-readable/writable Gunyah node carries SELinux type vendor_gunyah_dev; the mode bits alone do not grant an ordinary app access. Android Terminal is preinstalled with management/custom permissions, but it was not used as the VM owner.

The installed permission definitions report MANAGE_VIRTUAL_MACHINE as signature|development|preinstalled and USE_CUSTOM_VIRTUAL_MACHINE as signature|development. This supports investigating explicit development grants on this firmware. The existing terminal APK does not request them; no grant or no-DEX framework ownership test was performed.

A bounded shell-owned test ran:

bash
adb -s SERIAL shell 'mkdir -p /data/local/tmp/sparkles-research-microdroid; timeout 20 /apex/com.android.virt/bin/vm run-microdroid --protected --mem 256 --work-dir /data/local/tmp/sparkles-research-microdroid'

The complete log records pvmfw, successful verification of a debuggable payload, Microdroid initialization, Hello Microdroid, and payload is ready. Early initrd_normal AVB error messages are followed by firmware's explicit instruction to disregard them after successful debug-payload verification. The run ended with timeout exit status 124; subsequent VM listing was empty. This was a stock signed Microdroid payload, not a custom NixOS image, an app-owned VM or a successful arbitrary guest signing experiment.

An initial invocation without creating the work directory failed before guest creation. The recorded successful command includes that prerequisite. The VM tool also created an empty temporary directory under /data/local/tmp/microdroid; it was removed after the run, together with the explicit instance/idsig files and app probe files. The custom terminal installation remains available on the Pad; existing Termux/nix-on-droid and Android Terminal data were untouched.

Workload and resource limits ​

The phone snapshot had roughly 7 GiB total RAM, about 1.4 GiB available, 15% battery and a battery temperature reading of 50°C. The Pad snapshot had MemTotal=7544184 kB, MemAvailable=1736308 kB, 31% battery, 32.9°C and 126 GiB available on the reported data filesystem. These are transient pre-test snapshots, not performance characteristics.

Only one relevant VM mode was boot-tested, and the custom app's full PRoot bootstrap was not completed as part of this research. A same-device backend benchmark would therefore give misleading coverage. Follow the proposed workload protocol after two backends meet functional gates.

The Pixel report is an existing-process observation, not a workload benchmark. Its active NNS shell supplies new functional evidence, but signed substitution/build, DNS/TTY behavior, app-store-write rejection, independent terminal ownership and AVF custom-image boot remain acceptance gates. The report's seven nonzero process statuses reflect missing canonical paths outside NNS views, not seven failed NNS sessions.

CI scope ​

The examples are registered in apps/ci's standalone defaults. CI parses an actual ELF, exercises real disposable namespace calls where permitted, runs the libc probe on Linux, and checks that device collectors skip without an explicit serial. CI does not silently contact hardware or prove AVF/NNS support. Device results remain dated evidence that must be rerun when firmware changes.

For a packaged collector and an agent prompt covering rooted Pixel/NNS contributions, see Contributor device probes.

Sources ​