Files
gitlab-instance-0a899031_re…/README.md
2026-04-04 16:08:32 -05:00

230 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
- `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](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](offline/manifest.json) for checksums and source metadata, and [offline/README.md](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
```bash
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
```bash
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 auto` (default):** uses **`host`** when DRI devices exist and automatically adds `docker run --device …` for each `/dev/dri/card*` / `renderD*` node; otherwise **`guest`** (software GLES).
- **`--gpu-mode host`:** pass-through when DRI exists; otherwise **falls back to `guest`** with a warning.
- **`--gpu-mode guest`:** force software rendering (common black-screen case on headless servers).
Quick probe only:
```bash
python tools/compat.py
python tools/compat.py -c podman --gpu-mode auto
```
## Build the 5570 image
```bash
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):
```bash
REDROID_OFFLINE=1 python redroid.py -mtg -i -m
# or
python redroid.py -mtg -i -m --offline
```
Expected image tag:
```bash
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.**
```bash
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
```
Then:
```bash
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:
```bash
rm -rf ~/data-redroid13/misc/adb
```
## 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** — especially with `--rm`, a crash removes the instance. Run `docker ps -a` and `docker logs` on a **non-`--rm`** run (`--keep-container`) to see init/EGL errors.
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:
```bash
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`** (or **`auto`** when no `/dev/dri` exists), the display uses **software GLES** (SwiftShader). On many **headless servers**, SurfaceFlinger may show a **black screen**, **flicker**, or very low FPS. That is a **display stack** issue, not ADB. The default **`auto`** mode uses **host** GPU when DRI nodes are visible and injects **`--device`** flags automatically.
**What to try**
1. **GPU on the host:** **`--gpu-mode auto`** (default) enables **host** when `/dev/dri` exists. If the instance **crashes** or **ADB never connects**, host EGL may be incompatible — fall back to **`--gpu-mode guest`**. If you must pass devices manually, for example:
```bash
docker run ... --device /dev/dri ...
```
The exact device path varies (Intel/AMD/NVIDIA, `nvidia-docker`, etc.); see [redroid-doc](https://github.com/remote-android/redroid-doc) GPU notes.
2. **Software GLES (`guest`)** — force low load on the virtual display (often reduces black screen / flicker):
```bash
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`):
```bash
adb -s 127.0.0.1:5570 logcat -d | grep -iE 'SurfaceFlinger|EGL|GLES|redroid'
```
## Apply the 5570 hardening
```bash
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](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