diff --git a/README.zh-cn.md b/README.zh-cn.md deleted file mode 100644 index 0a1ec04..0000000 --- a/README.zh-cn.md +++ /dev/null @@ -1,9 +0,0 @@ -[English](README.md) | 简体中文 - -# redroid - -- https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/ -- `export REPO_URL=https://github.com/aosp-mirror/tools_repo.git` - -TODO :) - diff --git a/android-builder-docker/README.detailed.md b/android-builder-docker/README.detailed.md index c99f43a..fde2bdb 100644 --- a/android-builder-docker/README.detailed.md +++ b/android-builder-docker/README.detailed.md @@ -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 @@ -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 {} + @@ -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 . diff --git a/android-builder-docker/README.md b/android-builder-docker/README.md index a2cc42d..4c332e5 100644 --- a/android-builder-docker/README.md +++ b/android-builder-docker/README.md @@ -1,51 +1,52 @@ # 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 +``` +
+Alternative solution -##################### -# 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 +``` +
-##################### -# 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+) @@ -53,7 +54,9 @@ lunch redroid_x86_64-userdebug # start to build m - +``` +### 5. Create redroid image +```bash ##################### # create redroid image in *HOST* ##################### @@ -61,6 +64,9 @@ 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 diff --git a/assets/redroid11.png b/assets/redroid11.png deleted file mode 100644 index a26e55c..0000000 Binary files a/assets/redroid11.png and /dev/null differ diff --git a/assets/redroid17.png b/assets/redroid17.png new file mode 100644 index 0000000..452bc60 Binary files /dev/null and b/assets/redroid17.png differ diff --git a/debug.py b/debug.py new file mode 100644 index 0000000..c83a27c --- /dev/null +++ b/debug.py @@ -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) diff --git a/deploy/arch-linux.md b/deploy/arch-linux.md index 9fd8b15..200327d 100644 --- a/deploy/arch-linux.md +++ b/deploy/arch-linux.md @@ -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 ``` diff --git a/README.md b/profile/README.md similarity index 51% rename from README.md rename to profile/README.md index 8a60463..f0017cb 100644 --- a/README.md +++ b/profile/README.md @@ -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`) @@ -39,7 +41,7 @@ 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 @@ -47,15 +49,12 @@ Quick start on *Ubuntu 20.04* here; Check [deploy section](deploy/README.md) for ## 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 @@ -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)
15 (GPU not enabled)| -| `androidboot.redroid_dpi` | display DPI | 320 | -| `androidboot.use_memfd` | use `memfd` to replace deprecated `ashmem`
plan to enable by default | false | -| `androidboot.use_redroid_overlayfs` | use `overlayfs` to share `data` partition
`/data-base`: shared `data` partition
`/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`;
`guest`: use software rendering;
`host`: use GPU accelerated rendering;
`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)
15 (GPU not enabled) | +| `androidboot.redroid_dpi` | display DPI | 320 | +| `androidboot.use_memfd` | use `memfd` to replace deprecated `ashmem`
plan to enable by default | false | +| `androidboot.use_redroid_overlayfs` | use `overlayfs` to share `data` partition
`/data-base`: shared `data` partition
`/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`;
`guest`: use software rendering;
`host`: use GPU accelerated rendering;
`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 @@ -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 @@ -166,13 +165,13 @@ 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 @@ -180,10 +179,11 @@ Check [android-builder-docker](./android-builder-docker) for details. - Container running, but adb cannot connect (device offline etc.) > run `docker exec -it 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 diff --git a/profile/README.zh-cn.md b/profile/README.zh-cn.md new file mode 100644 index 0000000..ba72ceb --- /dev/null +++ b/profile/README.zh-cn.md @@ -0,0 +1,196 @@ +[English](README.md) | 简体中文 + +# 目录 +- [概览](#概览) +- [开始](#开始) +- [配置](#配置) +- [原生桥接支持](#原生桥接支持) +- [GMS 支持](#gms-支持) +- [WebRTC 流](#webrtc-流) +- [如何构建](#如何构建) +- [解决故障](#解决故障) +- [联系我](#联系我) +- [许可](#许可) + +## 概览 +*redroid* (*远*程 安*卓*) 是一个GPU加速的 AIC (Android In Cloud) 解决方案. 你可以在Linux主机上启动许多 +实例 (`Docker`, `podman`, `k8s` etc.). *redroid* 支持 `arm64` 和 `amd64` 架构. +*redroid* 适用于云游戏, 虚拟手机, 自动测试以及更多场景. + +![Screenshot of redroid 17](../assets/redroid17.png) + +目前支持: +- 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`) +- Android 15 64bit only (`redroid/redroid:15.0.0_64only-latest`) +- Android 14 (`redroid/redroid:14.0.0-latest`) +- Android 14 64bit only (`redroid/redroid:14.0.0_64only-latest`) +- Android 13 (`redroid/redroid:13.0.0-latest`) +- Android 13 64bit only (`redroid/redroid:13.0.0_64only-latest`) +- Android 12 (`redroid/redroid:12.0.0-latest`) +- Android 12 64bit only (`redroid/redroid:12.0.0_64only-latest`) +- Android 11 (`redroid/redroid:11.0.0-latest`) +- Android 10 (`redroid/redroid:10.0.0-latest`) +- Android 9 (`redroid/redroid:9.0.0-latest`) +- Android 8.1 (`redroid/redroid:8.1.0-latest`) + + +## 开始 +*redroid* 应该可以运行在任何Linux发行版上 (启用一些特点的内核功能). + +在 *Ubuntu 20.04* 快速开始; 查看 [deploy section](../deploy/README.md) 以获得其他发行版的有关内容. + +```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" +# ashmem's deprecated since 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 + +### Explanation: +### --pull always -- use latest image +### -v ~/data:/data -- mount data partition +### -p 5555:5555 -- expose adb port + +### DISCLAIMER +### Should NOT expose adb port on public network +### otherwise, redroid container (even host OS) may get compromised + +## install adb https://developer.android.com/studio#downloads +adb connect localhost:5555 +### NOTE: change localhost to IP if running redroid remotely + +## view redroid screen +## install scrcpy https://github.com/Genymobile/scrcpy/blob/master/README.md#get-the-app +scrcpy -s localhost:5555 +### NOTE: change localhost to IP if running redroid remotely +### typically running scrcpy on your local PC +``` + +## 配置 + +``` +## running redroid with custom settings (custom display for example) +docker run -itd --rm --privileged \ + --pull always \ + -v ~/data:/data \ + -p 5555:5555 \ + redroid/redroid:12.0.0_64only-latest \ + androidboot.redroid_width=1080 \ + androidboot.redroid_height=1920 \ + androidboot.redroid_dpi=480 \ +``` + +| 条目 | 描述 | 默认 | +|----------------------------------------------|--------------------------------------------------------------------------------------------|------------------------------------------| +| `androidboot.redroid_width` | 显示宽度 | 720 | +| `androidboot.redroid_height` | 显示高度 | 1280 | +| `androidboot.redroid_fps` | 显示刷新率 | 30(GPU enabled)
15 (GPU not enabled) | +| `androidboot.redroid_dpi` | 显示密度 | 320 | +| `androidboot.use_memfd` | 用 `memfd` 替换弃用的 `ashmem`
我们计划将其设为默认true | false | +| `androidboot.use_redroid_overlayfs` | 使用 `overlayfs` 分享`data` 分区
`/data-base`: 共享 `data` 分区
`/data-diff`: 私有数据 | 0 | +| `androidboot.redroid_net_ndns` | DNS服务数量, 如果DNS未指定。默认使用`8.8.8.8` | 0 | +| `androidboot.redroid_net_dns<1..N>` | DNS | | +| `androidboot.redroid_net_proxy_type` | 代理类型; 可用值: `static`, `pac`, `none`, `unassigned` | | +| `androidboot.redroid_net_proxy_host` | | | +| `androidboot.redroid_net_proxy_port` | | 3128 | +| `androidboot.redroid_net_proxy_exclude_list` | 逗号分隔列表 | | +| `androidboot.redroid_net_proxy_pac` | | | +| `androidboot.redroid_gpu_mode` | 可用值: `auto`, `host`, `guest`;
`guest`: 使用软件渲染;
`host`: 使用GPU加速渲染;
`auto`: 自动检测 | `guest` | +| `androidboot.redroid_gpu_node` | | 自动检测 | +| `ro.xxx` | **调试** 目的, 允许覆盖 `ro.xxx` 属性; 比如, 设置 `ro.secure=0`, 然后 root adb shell 就会默认开启 | | + + +## 原生桥接支持 +在 `x86` *redroid* 实例运行`arm`Apps是可能的,通过 `libhoudini`, `libndk_translation` 或 `QEMU translator`. + +检查 [@zhouziyang/libndk_translation](https://github.com/zhouziyang/libndk_translation) 获得预构建的 `libndk_translation`. +已发布的 `redroid` 镜像已经包含 `libndk_translation`. + +``` bash +# example structure, be careful the file owner and mode + +system/ +├── bin +│   ├── arm +│   └── arm64 +├── etc +│   ├── binfmt_misc +│   └── init +├── lib +│   ├── arm +│   └── libnb.so +└── lib64 + ├── arm64 + └── libnb.so +``` + +```dockerfile +# Dockerfile +FROM redroid/redroid:11.0.0-latest + +ADD native-bridge.tar / +``` + +```bash +# build docker image +docker build . -t redroid:11.0.0-nb + +# running +docker run -itd --rm --privileged \ + -v ~/data11-nb:/data \ + -p 5555:5555 \ + redroid:11.0.0-nb \ +``` + +## GMS 支持 + +添加GMS(Google Mobile Service)是可能的,*redroid* 通过 [Open GApps](https://opengapps.org/), [MicroG](https://microg.org/) 或 [MindTheGapps](https://gitlab.com/MindTheGapps/vendor_gapps)支持该功能. + +检查 [android-builder-docker](./android-builder-docker)以获取详情. + + +## WebRTC 流 +计划从`cuttlefish`移植 `WebRTC` 解决方案, 包括前端 (HTML5), 后端和许多虚拟HALs. + +## 如何构建 +与 AOSP 构建流程相同, 但是我建议使用 `docker` 构建它. + +检查 [android-builder-docker](../android-builder-docker)了解详情. + +## 解决故障 +- 如何收集调试数据 +> `curl -fsSL https://raw.githubusercontent.com/remote-android/redroid-doc/master/debug.sh | sudo bash -s -- [CONTAINER]` +> +> 如果容器已不存在,可省略*CONTAINER* + +- 容器立即消失 +> 确保已经安装了需要的内核模块; 运行 `dmesg -T` 获得详细日志 + +- 容器运行, 但是adb无法链接(设备离线之类.) +> 运行 `docker exec -it sh`, 然后检查 `ps -A` 和 `logcat` +> +> 尝试 `dmesg -T` 如果不能获得一个容器 shell + +## 联系我 +- ziyang.zhou@outlook.com +- 3590361911@qq.com + +## 许可 +*redroid* 自身基于 [Apache License](https://www.apache.org/licenses/LICENSE-2.0), 自从 *redroid* 包含了 +许多第三方模块后, 你也许需要去仔细检查许可. + +*redroid* 内核模块都基于 [GPL v2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)