agentsclimarketplace

Android emulator mask testing

Skill simiancraft/simiancraft-skills/skills/android-emulator-mask-testing

Specialization of android-emulator-harness for CAMERA / segmentation testing: get a real PERSON in front of the emulator camera so MediaPipe / ML Kit selfie segmentation produces an actual mask, then verify background-replacement / blur / shader effects and tune mask threshold by vision. Use when the task is "test the mask", "verify segmentation", "tune mask threshold", "check a camera/background effect on Android", or any time an app must SEE a human through the emulator camera without a physical device. Read android-emulator-harness FIRST for bring-up, drive, and assert; this skill only overrides the camera-specific pieces. Validated on Linux/WSL with a 32-bit x86 emulator image and MediaPipe/ML Kit segmentation.From its SKILL.md

Install
npx -y skills add simiancraft/simiancraft-skills --skill android-emulator-mask-testing

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
  • runs commandsInstructs the agent to run 7 commands, including `unzip -l app.apk | grep mediapipe` and 6 more.

SKILL.md

6.4 KB, ~1.5k tokens by cl100k_base, as published. Nobody here has run it

Camera / Mask Testing: specialization of android-emulator-harness

Read android-emulator-harness first. That base covers KVM, AVD creation, headless boot, app install/launch, Maestro driving, logcat/screenshot assertion, and teardown. This skill changes only what's needed to put a segmentable human in the camera and run GPU segmentation. Everything else (drive with Maestro, assert on logcat + screenshot) is identical to the base.

This skill ships one fixture: fixtures/person-framed.png, a full-body subject pre-positioned for the emulator's camera-feed crop (see override 3). Feed it directly, or swap in your own subject framed the same way.

The three camera-specific overrides (each cost real debugging time)

  1. Use a 32-bit x86 system image, NOT the base's x86_64. MediaPipe Tasks Vision ships libmediapipe_tasks_vision_jni.so for arm64-v8a, armeabi-v7a, and x86, not x86_64. On x86_64 it fails with UnsatisfiedLinkError and segmentation silently falls through to the raw frame. API 30 is the highest 32-bit x86 google_apis image. Verify in the APK: unzip -l app.apk | grep mediapipe (expect a lib/x86/… entry).

    yes | "$SDKMGR" "system-images;android-30;google_apis;x86"
    echo no | "$AVDMGR" create avd -n harness_x86 -k "system-images;android-30;google_apis;x86" -d pixel_3 --force
    
  2. Boot with -gpu swangle_indirect, NOT the base's swiftshader_indirect. MediaPipe runs through TFLite's GPU delegate, which needs GLES 3.1 compute shaders. Raw SwiftShader is only GLES 3.0 → [GL_INVALID_ENUM] glCreateShader in TensorsToSegmentationCalculator. swangle (ANGLE over SwiftShader-Vulkan) exposes GLES 3.1. Confirm after boot; this is the make-or-break check:

    adb shell dumpsys SurfaceFlinger | grep -m1 "GLES:"   # MUST say "OpenGL ES 3.1 ... ANGLE"
    
  3. Feed the framed subject straight into the camera (-camera-back imagefile:). A recent emulator presents a still image as the back camera. Confirm support first ("$EMU" -help-camera-back lists imagefile: / videofile:); upgrade if missing (yes | "$SDKMGR" emulator). Feed the pre-framed image, not a bare cutout: the imagefile-to-sensor path does not present the image 1:1; it crops and shifts, so a subject centered in the source lands off to the right with the head clipped. fixtures/person-framed.png is pre-compensated. The framing that lands the subject centered and fully in frame:

    • Frame: 9:16 portrait (e.g. 1080 x 1920).
    • Subject height: ~0.42 of the frame height (full body, not a close-up).
    • Subject center: x = 0.25 W, y = 0.58 H. The left-quarter x is deliberate; it cancels the sensor path's rightward shift so the subject reads centered on screen.
    • Background: opaque and contrasting (a light neutral gray works); segmentation needs a clean figure/ground split, and the background is what gets replaced.

    These offsets are emulator/AVD/version specific. Calibrate once: feed the image, select no effect to see the raw camera preview, screenshot it, and nudge the subject's x-center until it reads centered before trusting a run. To re-frame for a different crop, recompose from your own transparent subject using the offsets above.

Full launch (base boot + the three overrides)

sg kvm -c "nohup $EMU -avd harness_x86 \
  -no-window -no-audio -no-boot-anim -no-snapshot \
  -gpu swangle_indirect \
  -camera-back imagefile:$PWD/fixtures/person-framed.png \
  -accel on -port 5554 > /tmp/emulator.log 2>&1 &"
# then base boot-wait, then dumpsys SurfaceFlinger GLES check MUST be 3.1/ANGLE

-no-snapshot forces a clean boot so the camera feed takes effect. Pass an absolute path to the imagefile; the example uses $PWD assuming you launch from the skill dir.

Asserting the mask (beyond the base's logcat gate)

Add these to the base's HARD logcat gate (all must be ABSENT): UnsatisfiedLink, GL_INVALID_ENUM, glCreateShader, CalculatorGraph::Run() failed.

Then drive an effect (Maestro: tapOn: "Dark Office") and Read the screenshot. A working mask shows the person kept and the background replaced. Failure modes: unchanged room (segmentation fell through) or person gone (empty mask). For threshold tuning, iterate the app's maskThreshold/hardness controls and re-Read.

What this adds to the base's scope

  • CAN now also validate: mask SHAPE + compositing (person carved, bg swapped).
  • Still CANNOT: temporal mask quality (flicker/edge stability) from a STATIC image; that needs motion. Use -camera-back videofile:<abs>/subject.mp4 for a full-frame moving subject when you need to test edge stability over time.

Older emulators without imagefile:

Builds whose -help-camera-back lacks imagefile: can still put a subject in view via the virtualscene wall poster. The headless camera pose is not settable (telnet sensor set is ignored; only the gRPC physical model moves it), so move the poster into the camera's fixed view (camera sits near origin looking down −Z): feed your own transparent full-body cutout as -camera-back virtualscene -virtualscene-poster wall=<subject.png> and set geometry in $SDK/emulator/resources/Toren1BD.posters (back it up first; the wall anchor is guaranteed to render). Upgrading the emulator to get imagefile: is simpler; prefer that.

Teardown

adb -s emulator-5554 emu kill
# only if you used the virtualscene fallback and edited resources:
# cp "$SDK/emulator/resources/Toren1BD.posters.bak" "$SDK/emulator/resources/Toren1BD.posters" 2>/dev/null || true

What ships with it: 2 files

211.2 KB alongside SKILL.md

fixtures/

Gives 0 of the 12 instructions most quality gates skills give in ~1.5k tokens

Counted across 1,524 of the 2,830 authors here whose files we hold, read 2026-09-06

  • Read full output and check exit codein 45 of 1524, across 40 files
  • Verify output confirms the claimin 44 of 1524, across 39 files
  • Identify the command that proves the claimin 43 of 1524, across 39 files
  • Execute the full verification commandin 36 of 1524, across 30 files
  • Produce a verification reportin 34 of 1524, across 18 files
  • Review git diff changesin 30 of 1524, across 16 files
  • Fix build failures immediatelyin 29 of 1524, across 9 files
  • Group findings by severityin 28 of 1524
  • State claim only with evidencein 27 of 1524, across 22 files
  • Verify regression tests with red-green cyclein 26 of 1524, across 22 files
  • Run the full test suitein 26 of 1524, across 25 files
  • Run test suite with coveragein 25 of 1524, across 10 files

Said here and by no other author read

  • use a 32-bit x86 system image
  • boot with gpu swangle_indirect
  • feed a pre-framed image into the camera
  • verify GLES 3.1 ANGLE support after boot
  • use absolute paths for camera image files
  • force a clean boot without snapshots

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.