S11
Development emulator image (userdebug)Validated
On a debuggable Google APIs emulator, the emulator skip for bootloader_unlocked holds and root_rw_system fires — but root_dangerous_props can't see the debuggable flags.
How to read this page
A scenario is one test case: prepare the environment, run the steps, then compare the expected result (written before the run) with the observed result (copied from the run, with screenshots).
- S11 · S
- Run on a simulator or emulator — a virtual device on a computer.
- Validated
- Run, and the result matched what was expected.
Why it matters
Development images are where several root checks should fire, and where the emulator skip for bootloader_unlocked actually matters.
Environment
- App
- Example app, release build from the v0.3.0 tag (debug build of the same tag for run-as reads)
- Device
- Google APIs emulator, Android 16 (sdk_gphone64_arm64, BE2A.250530.026.F3), userdebug, dev-keys
- Tools
- adb root, setprop, -writable-system + adb remount, nsenter
Setup
Prepare the environment.Then run the steps.
- 01Create an emulator from system-images;android-36;google_apis;arm64-v8a and install the example app.
- 02adb root (works on userdebug images).
Steps
What to run.What to read.
- 01Run with defaults.
- 02setprop ro.boot.verifiedbootstate orange (plus flash.locked 0, vbmeta.device_state unlocked — unset on this image, so settable once) and run again.
- 03Restart with -writable-system, adb remount, then remount /system read-write inside the running app's own mount namespace (nsenter -t <pid> -m) and let the app re-check.
Expected result · written before the run
No single pass/fail status.3 signals.
bootloader_unlocked must stay absent (emulator skip). root_dangerous_props was expected on a userdebug build; root_rw_system once /system is writable.
Observed result · copied from the run
No single pass/fail status.Observed 2026-10-06.
Three findings. (1) The emulator skip for bootloader_unlocked works: the app could read the unlocked boot state, emulator fired, bootloader_unlocked did not. (2) root_rw_system reads the app's own /proc/mounts. adb remount changes the shell's view only — zygote and every app still see /system read-only — so it fires only when /system is writable in the app's namespace, as here. (3) root_dangerous_props did not fire on this debuggable build: ro.debuggable and ro.secure carry the userdebug_or_eng_prop label, which apps can't read, so the app sees them empty (the shell sees 1). ro.build.type (userdebug) stays readable — a candidate replacement. Also: /system/xbin/su exists here but root_su_binary stayed quiet, so the app itself can't see it. root_test_keys can't be exercised on this image (dev-keys, not test-keys).
Defaults: clean, Signals (1) emulator (91 ms) · boot state set to orange: clean, Signals (1) emulator (39 ms) — the app reads orange / 0 / unlocked, bootloader_unlocked is skipped · after adb remount only: clean, emulator · /system rw in the app's namespace: compromised, Signals (2) emulator, root_rw_system (23 ms)


Limitations
root_dangerous_props is blind to apps wherever ro.debuggable / ro.secure are labelled userdebug_or_eng_prop (seen on Android 16). A library fix is needed for it to fire.
root_test_keys still unobserved: Google's emulator images are dev-keys.
Checks this scenario covers
Every check this test case touches — including ones that aren't expected to fire here. The expected and observed results above say which ones should and did. Each links to how the check works.