Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions README.zh-cn.md

This file was deleted.

12 changes: 6 additions & 6 deletions android-builder-docker/README.detailed.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Build Redroid with Docker
```
WARNING: YOU NEED ~200GB OF FREE SPACE ON HDD TO COMPLETE THE WHOLE PROCESS (~250GB IF BUILDING WITH GAPPS)
```
> [!WARNING]
> YOU NEED ~200GB OF FREE SPACE ON HDD TO COMPLETE THE WHOLE PROCESS (~250GB IF BUILDING WITH GAPPS)

#### 1) Setup
```
# update and install packages
Expand Down Expand Up @@ -44,7 +44,7 @@ git clone https://github.com/remote-android/local_manifests.git ~/redroid/.repo/
repo sync -c -j$(nproc)

# get latest Dockerfile from Redroid repository
wget https://raw.githubusercontent.com/remote-android/redroid-doc/master/android-builder-docker/Dockerfile
wget https://raw.githubusercontent.com/Nredroid/redroid-doc/master/android-builder-docker/Dockerfile

# check if 'Webview.apk' files were properly synced by 'git-lfs'. Each .apk should be at least ~80MB in size.
find ~/redroid/external/chromium-webview -type f -name "*.apk" -exec du -h {} +
Expand Down Expand Up @@ -102,8 +102,8 @@ find ~/redroid/external/chromium-webview -type f -name "*.apk" -exec du -h {} +
#### 4) Apply Redroid patches, create builder and start it
```
# apply redroid patches
git clone https://github.com/remote-android/redroid-patches.git ~/redroid-patches
~/redroid-patches/apply-patch.sh ~/redroid
git clone https://github.com/Nredroid/redroid-patches.git ~/redroid-patches
~/redroid-patches/apply-patch.py ~/redroid

docker buildx create --use
docker buildx build --build-arg userid=$(id -u) --build-arg groupid=$(id -g) --build-arg username=$(id -un) -t redroid-builder --load .
Expand Down
52 changes: 29 additions & 23 deletions android-builder-docker/README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,72 @@
# Build redroid with docker

### 1. Fetch Code
```bash
#####################
# fetch code
#####################
mkdir ~/redroid && cd ~/redroid

# check supported branch in https://github.com/remote-android/redroid-patches.git
repo init -u https://android.googlesource.com/platform/manifest --git-lfs --depth=1 -b android-11.0.0_r48
repo init -u https://android.googlesource.com/platform/manifest --git-lfs --depth=1 -b android17-release

# add local manifests
git clone https://github.com/remote-android/local_manifests.git ~/redroid/.repo/local_manifests -b 11.0.0
git clone https://github.com/Nredroid/local_manifests.git ~/redroid/.repo/local_manifests -b 17.0.0

# sync code
repo sync -c

# apply redroid patches
git clone https://github.com/remote-android/redroid-patches.git ~/redroid-patches
~/redroid-patches/apply-patch.sh ~/redroid
git clone https://github.com/Nredroid/redroid-patches.git ~/redroid-patches
~/redroid-patches/apply-patch.py ~/redroid
```
<details>
<summary title="Another way to fetch with legacy code.">Alternative solution</summary>

#####################
# fetch code (LEGACY)
#####################
### 1. Fetch code (LEGACY)
```bash
mkdir ~/redroid && cd ~/redroid

repo init -u https://github.com/remote-android/platform_manifests.git -b redroid-11.0.0 --depth=1 --git-lfs
# check @remote-android/platform_manifests for supported branch / manifest

repo sync -c
```
</details>

#####################
# create builder
#####################
### 2. Create builder
```bash
docker build --build-arg userid=$(id -u) --build-arg groupid=$(id -g) --build-arg username=$(id -un) -t redroid-builder .
```

#####################
# start builder
#####################
### 3.Start builder
```bash
docker run -it --rm --hostname redroid-builder --name redroid-builder -v ~/redroid:/src redroid-builder

#####################
# build redroid
#####################
```
### 4. Build Redroid
```bash
cd /src

. build/envsetup.sh

# For Android 17 +
lunch redroid_x86_64-aosp_current-eng
# For Older Android version
lunch redroid_x86_64-userdebug
# redroid_arm64-userdebug
# redroid_x86_64_only-userdebug (64 bit only, redroid 12+)
# redroid_arm64_only-userdebug (64 bit only, redroid 12+)

# start to build
m

```
### 5. Create redroid image
```bash
#####################
# create redroid image in *HOST*
#####################
cd ~/redroid/out/target/product/redroid_x86_64

sudo mount system.img system -o ro
sudo mount vendor.img vendor -o ro
#For Android 17+
sudo tar --xattrs -c vendor ramdisk -C system --exclude="./vendor" . | docker import -c 'ENTRYPOINT ["/ramdisk/init", "androidboot.hardware=redroid"]' - redroid
#For Older Android
sudo tar --xattrs -c vendor -C system --exclude="./vendor" . | docker import -c 'ENTRYPOINT ["/init", "androidboot.hardware=redroid"]' - redroid
sudo umount system vendor

Expand Down
Binary file removed assets/redroid11.png
Binary file not shown.
Binary file added assets/redroid17.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
120 changes: 120 additions & 0 deletions debug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env python3
import shutil
import subprocess
import sys
import os
import time
import zipfile
from platform import uname
import gzip

usage = f"""
USAGE: {os.path.basename(sys.argv[0])} [container] [-h]

where:
container: container id or container name
"""


def p_usage():
print(usage)
sys.exit(1)

def main(container:str|None = None):
if os.geteuid() != 0:
print("\033[31mYou must be root to run this script.\033[0m")
sys.exit(1)
if not container:
container = input("Container name (leave empty if stopped):")
print("Collecting, please wait...")
tmp_dir = f"redroid_report_{time.time()}"
os.makedirs(tmp_dir)
if os.path.exists(f"/boot/config-{uname().release}") and False:
shutil.copyfile(f"/boot/config-{uname().release}", f"{tmp_dir}/config-{uname().release}")
else:
if os.path.exists("/proc/config.gz"):
with gzip.GzipFile("/proc/config.gz") as f, open(f"{tmp_dir}/config-{uname().release}", 'wb', newline='\n') as g:
g.write(f.read())
with open(f"{tmp_dir}/drivers.txt","w", encoding='utf-8',newline='\n') as f, open("/proc/filesystems") as fs:
for line in fs.readlines():
if "binder" in line:
f.write(line)
break
with open(f"{tmp_dir}/drivers.txt", "a", encoding='utf-8',newline='\n') as f, open("/proc/misc") as fs:
for line in fs.readlines():
if "ashmem" in line:
f.write(line)
break
with open(f"{tmp_dir}/uname.txt", "w", encoding='utf-8', newline='\n') as f:
f.write(" ".join(uname()))

for c in ['lscpu', 'getenforce']:
with open(f"{tmp_dir}/{c}.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output([c], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))

with open(f"{tmp_dir}/dri.txt", "w", encoding='utf-8', newline='\n') as f:
for c in [["lshw", "-C", "display"],["ls", "-al", "/dev/dri/"]]:
print("running:", c)
ret = subprocess.check_output(c, stderr=subprocess.STDOUT, shell=True)
f.write(ret.decode("utf-8"))
for i in os.listdir("/sys/kernel/debug/dri"):
if os.path.exists(f"/sys/kernel/debug/dri/{i}/name"):
with open(f"/sys/kernel/debug/dri/{i}/name") as nf:
f.write(nf.read())

with open(f"{tmp_dir}/dmesg.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output(["dmesg", "-T"], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))

with open(f"{tmp_dir}/docker-info.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output(["docker", "info"], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
if container:
with open(f"{tmp_dir}/ps.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output(["docker", "exec", container, "ps", '-A'], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
with open(f"{tmp_dir}/logcat.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output(["docker", "exec", container, "logcat", '-d'], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
with open(f"{tmp_dir}/crash.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output(["docker", "exec", container, "logcat", '-d', '-b', 'crash'], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
with open(f"{tmp_dir}/vainfo.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output(["docker", "exec", container, "/vendor/bin/vainfo", '-a'], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
with open(f"{tmp_dir}/getprop.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output(["docker", "exec", container, "getprop"], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
with open(f"{tmp_dir}/dumpsys.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output(["docker", "exec", container, "dumpsys"], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
with open(f"{tmp_dir}/network.txt", "w", encoding='utf-8', newline='\n') as f:
f.write("-----ip a")
ret = subprocess.check_output(["docker", "exec", container, "ip", 'a'], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
f.write("-----ip rule")
ret = subprocess.check_output(["docker", "exec", container, "ip", 'rule'], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
f.write("-----ip r show table eth0")
ret = subprocess.check_output(["docker", "exec", container, "ip", 'r', 'show', 'table', 'eth0'], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
with open(f"{tmp_dir}/container-inspect.txt", "w", encoding='utf-8', newline='\n') as f:
ret = subprocess.check_output(["docker", "container","inspect", container], stderr=subprocess.STDOUT)
f.write(ret.decode("utf-8"))
zipfile_ = os.path.basename(tmp_dir)+".zip"
with zipfile.ZipFile(zipfile_, 'w') as zipObj:
for file in os.listdir(tmp_dir):
zipObj.write(os.path.join(tmp_dir, file))
shutil.rmtree(tmp_dir)
os.chown(zipfile_, 0o755, 1000)
print("===================================")
print("Please provide the collected logs")
print(os.path.realpath(zipfile_))
print("请提供此处收集的日志")
print("===================================")

if __name__ == "__main__":
if "-h" in sys.argv or "--help" in sys.argv:
p_usage()
main(sys.argv[1] if len(sys.argv)>=2 else None)
10 changes: 3 additions & 7 deletions deploy/arch-linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
```
## install zen kernel
pacman -S linux-zen

mkdir -p /dev/binderfs
mount -t binder binder /dev/binderfs
## run redroid
docker run -itd --rm --privileged \
--pull always \
-v ~/data11:/data \
-p 5555:5555 \
--name redroid11 \
redroid/redroid:12.0.0_64only-latest
docker run -it --rm --privileged --pull always -v ~/data11:/data -p 5555:5555 --name redroid11 redroid/redroid:12.0.0_64only-latest
```
60 changes: 30 additions & 30 deletions README.md → profile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ English | [简体中文](README.zh-cn.md)
## Overview
*redroid* (*Re*mote an*Droid*) is a GPU accelerated AIC (Android In Cloud) solution. You can boot many
instances in Linux host (`Docker`, `podman`, `k8s` etc.). *redroid* supports both `arm64` and `amd64` architectures.
*redroid* is suitable for Cloud Gaming, Virtualise Phones, Automation Test and more.
*redroid* is suitable for Cloud Gaming, Virtualize Phones, Automation Test and more.

![Screenshot of redroid 11](./assets/redroid11.png)
![Screenshot of redroid 17](../assets/redroid17.png)

Currently supported:
- Android 17
- Android 17 64bit only
- Android 16 (`redroid/redroid:16.0.0-latest`)
- Android 16 64bit only (`redroid/redroid:16.0.0_64only-latest`)
- Android 15 (`redroid/redroid:15.0.0-latest`)
Expand All @@ -39,23 +41,20 @@ Currently supported:
## Getting Started
*redroid* should be able to run on any linux distribution (with some kernel features enabled).

Quick start on *Ubuntu 20.04* here; Check [deploy section](deploy/README.md) for other distros.
Quick start on *Ubuntu 20.04* here; Check [deploy section](../deploy/README.md) for other distros.

```bash
## install docker https://docs.docker.com/engine/install/#server

## install required kernel modules
apt install linux-modules-extra-`uname -r`
modprobe binder_linux devices="binder,hwbinder,vndbinder"
# No need for android 17+
modprobe ashmem_linux


## running redroid
docker run -itd --rm --privileged \
--pull always \
-v ~/data:/data \
-p 5555:5555 \
redroid/redroid:12.0.0_64only-latest
docker run -itd --rm --privileged --pull always -v ~/data:/data -p 5555:5555 redroid/redroid:12.0.0_64only-latest

### Explanation:
### --pull always -- use latest image
Expand Down Expand Up @@ -91,24 +90,24 @@ docker run -itd --rm --privileged \
androidboot.redroid_dpi=480 \
```

| Param | Description | Default |
| --- | --- | --- |
| `androidboot.redroid_width` | display width | 720 |
| `androidboot.redroid_height` | display height | 1280 |
| `androidboot.redroid_fps` | display FPS | 30(GPU enabled)<br> 15 (GPU not enabled)|
| `androidboot.redroid_dpi` | display DPI | 320 |
| `androidboot.use_memfd` | use `memfd` to replace deprecated `ashmem`<br>plan to enable by default | false |
| `androidboot.use_redroid_overlayfs` | use `overlayfs` to share `data` partition<br>`/data-base`: shared `data` partition<br>`/data-diff`: private data | 0 |
| `androidboot.redroid_net_ndns` | number of DNS server, `8.8.8.8` will be used if no DNS server specified | 0 |
| `androidboot.redroid_net_dns<1..N>` | DNS | |
| `androidboot.redroid_net_proxy_type` | Proxy type; choose from: `static`, `pac`, `none`, `unassigned` | |
| `androidboot.redroid_net_proxy_host` | | |
| `androidboot.redroid_net_proxy_port` | | 3128 |
| `androidboot.redroid_net_proxy_exclude_list` | comma seperated list | |
| `androidboot.redroid_net_proxy_pac` | | |
| `androidboot.redroid_gpu_mode` | choose from: `auto`, `host`, `guest`;<br>`guest`: use software rendering;<br>`host`: use GPU accelerated rendering;<br>`auto`: auto detect | `guest` |
| `androidboot.redroid_gpu_node` | | auto-detect |
| `ro.xxx`| **DEBUG** purpose, allow override `ro.xxx` prop; For example, set `ro.secure=0`, then root adb shell provided by default | |
| Param | Description | Default |
|----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|
| `androidboot.redroid_width` | display width | 720 |
| `androidboot.redroid_height` | display height | 1280 |
| `androidboot.redroid_fps` | display FPS | 30(GPU enabled)<br> 15 (GPU not enabled) |
| `androidboot.redroid_dpi` | display DPI | 320 |
| `androidboot.use_memfd` | use `memfd` to replace deprecated `ashmem`<br>plan to enable by default | false |
| `androidboot.use_redroid_overlayfs` | use `overlayfs` to share `data` partition<br>`/data-base`: shared `data` partition<br>`/data-diff`: private data | 0 |
| `androidboot.redroid_net_ndns` | number of DNS server, `8.8.8.8` will be used if no DNS server specified | 0 |
| `androidboot.redroid_net_dns<1..N>` | DNS | |
| `androidboot.redroid_net_proxy_type` | Proxy type; choose from: `static`, `pac`, `none`, `unassigned` | |
| `androidboot.redroid_net_proxy_host` | | |
| `androidboot.redroid_net_proxy_port` | | 3128 |
| `androidboot.redroid_net_proxy_exclude_list` | comma seperated list | |
| `androidboot.redroid_net_proxy_pac` | | |
| `androidboot.redroid_gpu_mode` | choose from: `auto`, `host`, `guest`;<br>`guest`: use software rendering;<br>`host`: use GPU accelerated rendering;<br>`auto`: auto detect | `guest` |
| `androidboot.redroid_gpu_node` | | auto-detect |
| `ro.xxx` | **DEBUG** purpose, allow override `ro.xxx` prop; For example, set `ro.secure=0`, then root adb shell provided by default | |


## Native Bridge Support
Expand Down Expand Up @@ -157,7 +156,7 @@ docker run -itd --rm --privileged \

It's possible to add GMS (Google Mobile Service) support in *redroid* via [Open GApps](https://opengapps.org/), [MicroG](https://microg.org/) or [MindTheGapps](https://gitlab.com/MindTheGapps/vendor_gapps).

Check [android-builder-docker](./android-builder-docker) for details.
Check [android-builder-docker](../android-builder-docker) for details.


## WebRTC Streaming
Expand All @@ -166,24 +165,25 @@ Plan to port `WebRTC` solutions from `cuttlefish`, including frontend (HTML5), b
## How To Build
It's the same way as AOSP building process, but I suggest to use `docker` to build it.

Check [android-builder-docker](./android-builder-docker) for details.
Check [android-builder-docker](../android-builder-docker) for details.

## Troubleshooting
- How to collect debug blobs
> `curl -fsSL https://raw.githubusercontent.com/remote-android/redroid-doc/master/debug.sh | sudo bash -s -- [CONTAINER]`
>
> omit *CONTAINER* if not exist any more
> omit *CONTAINER* if not exist anymore

- Container disappeared immediately
> make sure the required kernel modules are installed; run `dmesg -T` for detailed logs

- Container running, but adb cannot connect (device offline etc.)
> run `docker exec -it <container> sh`, then check `ps -A` and `logcat`
>
> try `dmesg -T` if cannot get a container shell
> try `dmesg -T` if you cannot get a container shell

## Contact Me
- ziyang.zhou@outlook.com
- 3590361911@qq.com

## License
*redroid* itself is under [Apache License](https://www.apache.org/licenses/LICENSE-2.0), since *redroid* includes
Expand Down
Loading