2026-04-09 03:29:37 +00:00
s''
2026-04-03 23:22:27 -05:00
2026-04-09 02:33:32 +00:00
's'
2026-04-04 15:42:13 -05:00
's'
2026-04-04 16:18:52 -05:00
's'
2026-04-04 15:26:33 -05:00
s''
2026-04-03 23:22:27 -05:00
's'
2026-04-04 16:24:48 -05:00
2026-04-09 03:29:37 +00:00
's'
2026-04-04 16:18:52 -05:00
's'
2026-04-04 16:24:48 -05:00

redroid-android13

This repo is the minimal Android 13 redroid bundle that matches the optimized 5570 instance.

It keeps only the parts that were actually used:

  • redroid/redroid:13.0.0
  • MindTheGapps
  • libhoudini
  • Kitsune Mask / Magisk Delta
  • Pixel 7 Pro device profile
  • the post-fs-data fix that keeps Magisk Installed and the settings page healthy

Included files

  • redroid.py
  • run_redroid.py
  • bootstrap_redroid.py
  • verify_offline_bundle.py
  • tools/compat.py (host / GPU / runtime checks)
  • tools/ssh_remote.py (Paramiko SSH: remote docker / adb diagnostics)
  • offline/README.md
  • offline/manifest.json
  • stuff/mindthegapps.py
  • stuff/houdini.py
  • stuff/houdini_hack.py
  • stuff/magisk.py
  • assets/redroid_extreme_post_fs_data.sh
  • local offline/downloads/
  • local offline/images/

Offline archive

The repo tracks the offline bundle metadata under offline. The large zip/apk/tar payloads are intentionally kept out of Git and should be stored locally under offline/downloads/ and offline/images/.

Use offline/manifest.json for checksums and source metadata, and offline/README.md for the expected local layout.

Expected local files:

  • offline/downloads/mindthegapps.zip
  • offline/downloads/libhoudini.zip
  • offline/downloads/libhoudini_hack.zip
  • offline/downloads/magisk.apk
  • offline/downloads/magisk.version
  • offline/images/redroid-redroid-13.0.0-latest.tar (optional if the base image is already in local Docker storage)

Build resource order (redroid.py)

  • Base image: prefers an existing local redroid/redroid:<ver>-latest, then offline/images/redroid-redroid-13.0.0-latest.tar (docker load), then a registry pull (skipped when offline-only).
  • Zips / APK: prefers files under offline/downloads/ whose MD5 matches the pinned upstream artifacts; downloads only if missing or mismatch (skipped when offline-only).
  • Strict no-network builds: pass --offline or set REDROID_OFFLINE=1 so missing bundles fail fast instead of downloading.

Verify script notes

python verify_offline_bundle.py
  • magisk.version is checked against exact size and sha256 from manifest.json. A short version string without the expected newline/padding will report size mismatch even when magisk.apk is fine for the image build.
  • A missing offline/images/*.tar is expected to FAIL here if you rely on a pre-pulled Docker image instead; that does not block redroid.py when the base image already exists locally.

Dependencies

python -m pip install -r requirements.txt

Compatibility checks

The project probes the host before critical steps (no separate manual checklist required):

Step What it checks Opt-out
redroid.py Container runtime (docker/podman) responds; OS is plausible for redroid --no-compat-check
run_redroid.py Same + Linux /dev/dri for GPU; binder_linux module hint on Linux --no-compat-check

GPU mode (run_redroid.py):

  • --gpu-mode guest (default): software GLES — most stable on headless / server GPUs where host EGL inside the guest often breaks boot or adbd.
  • --gpu-mode auto: stays guest unless REDROID_USE_HOST_GPU=1 (or true/yes/on) and /dev/dri nodes exist; then host and docker run --device … per DRI node.
  • --gpu-mode host: pass-through when DRI exists; otherwise falls back to guest with a warning.

Quick probe only:

python tools/compat.py
python tools/compat.py -c podman --gpu-mode guest

Build the 5570 image

python redroid.py -mtg -i -m

Build flags (short options):

Flag Long form Meaning
-mtg --install-mindthegapps Bake MindTheGapps (Google apps framework) into the image
-i --install-houdini Bake libhoudini + redroid houdini hack (ARM translation on x86)
-m --install-magisk Bake Kitsune Mask / Magisk bootless payload into the image

Together they produce redroid/redroid:13.0.0_mindthegapps_houdini_magisk. None of these control the screen; display is set when you run the container (run_redroid.py).

Air-gapped (requires a complete offline/ tree):

REDROID_OFFLINE=1 python redroid.py -mtg -i -m
# or
python redroid.py -mtg -i -m --offline

Expected image tag:

redroid/redroid:13.0.0_mindthegapps_houdini_magisk

Launch the container

Headless servers have no screen to approve the USB debugging RSA dialog. Always pass --adb-insecure so boot props disable ADB RSA checks and apply before the Pixel user profile (androidboot.adb.secure=0, ro.adb.secure=0, ro.secure=0, ro.debuggable=1). Do not expose the ADB port on a public network.

Persist after reboot (default)

By default run_redroid.py does not pass --rm: the container stays on disk when it stops, and uses --restart unless-stopped so Docker/Podman will start it again after the daemon or host reboots (unless you ran docker stop <name>).

  • Always restart even after explicit stop: --restart always
  • No auto-restart but still keep the container (no --rm): --restart no
  • One-off / dev only (old behavior, removed on stop): pass --rm

On Ubuntu, ensure the engine starts on boot:

sudo systemctl enable docker --now
# or: sudo systemctl enable podman.socket --now   # if you use Podman rootful similarly
python run_redroid.py \
  --image redroid/redroid:13.0.0_mindthegapps_houdini_magisk \
  --bridge libhoudini \
  --device-profile pixel-7-pro \
  --data-dir ~/data-redroid13 \
  --port 5570 \
  --replace \
  --adb-insecure

On the same machine as Docker, one-shot status + logs + logcat after start:

python run_redroid.py ... --adb-insecure --diagnose --diagnose-settle 20

Then:

adb kill-server && adb start-server
adb connect 127.0.0.1:5570
adb devices

If you still see unauthorized after an upgrade, stop the container, remove persisted keys on the host, and retry:

rm -rf ~/data-redroid13/misc/adb

Remote diagnostics over SSH (Paramiko)

When redroid runs on another Linux machine, you can drive checks from your PC with tools/ssh_remote.py (uses Paramiko, declared in requirements.txt).

Do not put passwords in Git. Use a key file or a one-time prompt:

pip install -r requirements.txt
export REDROID_SSH_HOST=192.168.2.179
export REDROID_SSH_USER=eric
python tools/ssh_remote.py --password-prompt diagnose

Key-based:

export REDROID_SSH_HOST=... REDROID_SSH_USER=eric REDROID_SSH_KEY=$HOME/.ssh/id_ed25519
python tools/ssh_remote.py diagnose

Optional env: REDROID_CONTAINER (default redroid_13.0.0_mindthegapps_houdini_magisk), REDROID_ADB_PORT (default 5570). You can also pass --container-name / --adb-port.

Arbitrary remote command (note the -- before the shell snippet):

python tools/ssh_remote.py -H 192.168.2.179 -U eric --password-prompt exec -- bash -lc 'docker ps -a | head -20'

The shell subcommand is a minimal pseudo-shell only; for a full TTY, use normal OpenSSH ssh.

ADB failed to connect / connection refused

This means nothing is listening on the host port (not the same as unauthorized). Typical causes:

  1. Container exited — if you used --rm, a crash removes the instance. By default the container is kept; use docker ps -a and docker logs to inspect. Ensure --restart is not no if you want auto-start after reboot.
  2. androidboot.redroid_gpu_mode=host — Mesa/EGL or DRI inside the guest can fail on some hosts; Android never reaches adbd. Workaround: force software rendering:
    python run_redroid.py ... --adb-insecure --gpu-mode guest
    
  3. Still booting — wait longer, or use --wait-tcp 90 on run_redroid.py to block until TCP opens and print logs if it does not.

Black screen or flickering

With --gpu-mode guest (the default), the display uses software GLES (SwiftShader). On many headless servers, SurfaceFlinger may still show black screen or flicker — try --soft-display and more RAM. Host GPU needs REDROID_USE_HOST_GPU=1 with --gpu-mode auto or --gpu-mode host when DRI works inside the guest.

What to try

  1. GPU on the host: set REDROID_USE_HOST_GPU=1 and --gpu-mode auto, or --gpu-mode host. If ADB never connects, host EGL is likely broken — use default --gpu-mode guest. Manual devices example:

    docker run ... --device /dev/dri ...
    

    The exact device path varies (Intel/AMD/NVIDIA, nvidia-docker, etc.); see redroid-doc GPU notes.

  2. Software GLES (guest) — force low load on the virtual display (often reduces black screen / flicker):

    python run_redroid.py ... --adb-insecure --gpu-mode guest --soft-display --memory 4g
    

    --soft-display sets 720×1280, 15 FPS, dpi 280. You can tune further with --extra-prop if needed.

  3. First boot / SetupWizard can sit on a dark screen for a while. Run bootstrap_redroid.py once adb shows device so provisioning and wizard are skipped as intended.

  4. Debug with logcat (on the host, after adb connect):

    adb -s 127.0.0.1:5570 logcat -d | grep -iE 'SurfaceFlinger|EGL|GLES|redroid'
    

Apply the 5570 hardening

python bootstrap_redroid.py \
  --serial 127.0.0.1:5570 \
  --device-profile pixel-7-pro \
  --proxy-host auto \
  --install-extreme-script

This post-boot step:

  • disables SetupWizard
  • marks the device provisioned
  • enables high accuracy location mode
  • allows com.android.shell to use mock location
  • applies the Pixel 7 Pro / user / release-keys / locked / green identity

With --install-extreme-script, the validated script assets/redroid_extreme_post_fs_data.sh is copied to /data/adb/post-fs-data.d/20-redroid-extreme.sh so that:

  • vendor/bin/su stays visible to app namespaces after reboot
  • Pixel 7 Pro properties are re-applied on every boot

Verified 5570 state

The matching 5570 instance was already validated with:

  • ro.product.model=Pixel 7 Pro
  • ro.build.type=user
  • ro.build.tags=release-keys
  • ro.boot.vbmeta.device_state=locked
  • ro.boot.verifiedbootstate=green
  • app UID su -V = 27001
  • app UID su -mm -c id = uid=0(root)
  • Kitsune home page shows a normal Installed state
  • Kitsune settings page opens normally and SuList / MagiskHide is configurable

Current scope

This repo only reproduces the system environment for the optimized 5570 build.

It does not yet include:

  • virtual camera
  • camera HAL
  • TikTok Live specific patches
Description
No description provided
Readme 276 MiB
Languages
Python 96%
Shell 4%