This commit is contained in:
eric
2026-04-04 16:02:19 -05:00
parent 78bbbc1303
commit e56629bcc2
3 changed files with 65 additions and 1 deletions

View File

@@ -135,13 +135,24 @@ If you still see `unauthorized` after an upgrade, stop the container, remove per
rm -rf ~/data-redroid13/misc/adb 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 ## 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. 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** **What to try**
1. **GPU on the host:** ensure **`--gpu-mode auto`** (default) so DRI is detected, or set **`--gpu-mode host`** explicitly. If you must pass devices manually (unusual when `auto` works), for example: 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 ```bash
docker run ... --device /dev/dri ... docker run ... --device /dev/dri ...
``` ```

View File

@@ -4,8 +4,10 @@ import argparse
import os import os
import re import re
import shlex import shlex
import socket
import subprocess import subprocess
import sys import sys
import time
import tools.compat as compat import tools.compat as compat
from tools.helper import bcolors, print_color from tools.helper import bcolors, print_color
@@ -181,6 +183,18 @@ def quote_cmd(args):
return " ".join(shlex.quote(part) for part in args) return " ".join(shlex.quote(part) for part in args)
def wait_tcp_port(host, port, timeout_sec, interval=1.0):
"""Return True once TCP connect succeeds, False on timeout."""
deadline = time.monotonic() + timeout_sec
while time.monotonic() < deadline:
try:
with socket.create_connection((host, port), timeout=2.0):
return True
except OSError:
time.sleep(interval)
return False
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Launch a redroid container with a tested native bridge configuration." description="Launch a redroid container with a tested native bridge configuration."
@@ -276,6 +290,16 @@ def main():
action="store_true", action="store_true",
help="Skip compatibility messages and docker/podman probe (still resolves --gpu-mode auto from DRI)", help="Skip compatibility messages and docker/podman probe (still resolves --gpu-mode auto from DRI)",
) )
parser.add_argument(
"--wait-tcp",
type=int,
default=0,
metavar="SEC",
help=(
"After start, wait up to SEC seconds for 127.0.0.1:PORT to accept TCP (Android adbd). "
"If it never opens, print container logs. Use 90 when debugging failed adb connect."
),
)
args = parser.parse_args() args = parser.parse_args()
image = args.image image = args.image
@@ -365,7 +389,31 @@ def main():
subprocess.run(cmd, check=True) subprocess.run(cmd, check=True)
print_color("Container started as {}".format(name), bcolors.GREEN) print_color("Container started as {}".format(name), bcolors.GREEN)
if args.wait_tcp > 0:
print_color(
"Waiting up to {}s for 127.0.0.1:{} (adbd TCP) ...".format(args.wait_tcp, args.port),
bcolors.GREEN,
)
if not wait_tcp_port("127.0.0.1", args.port, args.wait_tcp):
print_color(
"Port {} never opened. Common with androidboot.redroid_gpu_mode=host when EGL/GPU fails inside "
"the guest — try: python run_redroid.py ... --gpu-mode guest (and drop DRI if needed).".format(
args.port
),
bcolors.RED,
)
print_color("Last logs from container {!r}:".format(name), bcolors.YELLOW)
subprocess.run([args.container, "logs", "--tail", "100", name], check=False)
print(
"\nIf the container already exited with --rm, logs are gone; re-run with "
"--keep-container (no --rm) to capture docker logs after a crash."
)
print("ADB: adb connect 127.0.0.1:{}".format(args.port)) print("ADB: adb connect 127.0.0.1:{}".format(args.port))
if effective_gpu_mode == "host":
print(
"Note: host GPU mode can prevent full boot; if connect fails, use --gpu-mode guest or "
"--wait-tcp 90 to diagnose."
)
if not args.adb_insecure: if not args.adb_insecure:
print( print(
"If the device shows as unauthorized, stop the container and re-run with --adb-insecure " "If the device shows as unauthorized, stop the container and re-run with --adb-insecure "

View File

@@ -141,6 +141,11 @@ def analyze_for_run(
) )
if req == "auto" and not skip_check: if req == "auto" and not skip_check:
report.notes.append("Resolved --gpu-mode auto -> {}".format(effective)) report.notes.append("Resolved --gpu-mode auto -> {}".format(effective))
if effective == "host" and not skip_check:
report.notes.append(
"GPU host mode: if ADB cannot connect (connection refused), Android may not have finished boot "
"or init crashed (EGL/driver mismatch); try --gpu-mode guest or docker logs on the container."
)
return report, effective, device_args return report, effective, device_args