编译适用于RK3588的Redroid镜像

编译适用于RK3588的Redroid镜像

不想编译的话可以用笔者的镜像:
GitHub链接

引言

Redroid是什么,不想多说,一个词总结: 云手机

准备工作

AOSP代码一堆,编译起来要命,所以租个高配服务器,笔者用的是Vultr的云服务器,6c 16G 320G配置,五个小时才编译出来

装docker,装repo,装git-lfs:

sudo apt install docker.io repo git-lfs

创用户,自己拿adduser创个,教程一堆,创完给root权限,然后切到这个用户下。

同步代码:

# 这里使用了ice-black-tea大佬的仓库,在此对他表示感谢。
mkdir ~/redroid && cd ~/redroid
sudo repo init -u https://github.com/redroid-rockchip/platform_manifests.git -b redroid-12.0.0 --depth=1 --git-lfs
sudo repo sync -c

同步webview:

sudo apt install git-lfs
sudo repo forall -g lfs -c git lfs pull

修改build/soong/cc/config/global.go,向commonGlobalCflags数组添加全局cflags "-DANDROID_12"

代码同步完成后将源码的所有者改为当前用户:

sudo chown -R `whoami`:`whoami` ~/redroid

编译

构建编译镜像:

cd ~/ && git clone https://github.com/remote-android/redroid-doc.git
cd redroid-doc/android-builder-docker/
docker build --build-arg userid=$(id -u) --build-arg groupid=$(id -g) --build-arg username=$(id -un) -t redroid-builder .

启动镜像:

# 建议丢到screen里面
docker run -it --rm --hostname redroid-builder --name redroid-builder -v ~/redroid:/src redroid-builder

在镜像命令行中输入:

cd /src
. build/envsetup.sh
lunch redroid_arm64-userdebug
export TARGET_BOARD_PLATFORM_GPU=mali-G52 TARGET_RK_GRALLOC_VERSION=4

开始编译:

m

打包

回到主机命令行:

cd ~/redroid/out/target/product/redroid_arm64
sudo mount system.img system -o ro
sudo mount vendor.img vendor -o ro
sudo tar --xattrs -avcf redroid.tar.xz vendor -C system --exclude="./vendor" . 
sudo umount system vendor

导入

打完包把镜像推开发板上,然后导入:

xz -dcT0 redroid.tar.xz | docker import -c 'ENTRYPOINT ["/init", "androidboot.hardware=redroid"]' - redroid

运行

docker run -d -p 5555:5555 -v ~/redroid-data:/data --name redroid --privileged redroid androidboot.redroid_height=1920 androidboot.redroid_width=1080

自定义

Android 12有个secure flag机制,有些app在输入用户名密码界面会用到这个flag,导致scrcpy串流的时候会黑屏。这里通过修改surfaceflinger的方式来去掉这个限制:
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:

sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, bool secure,
                                          float requestedRefreshRate) {
    // onTransact already checks for some permissions, but adding an additional check here.
    // This is to ensure that only system and graphics can request to create a secure
    // display. Secure displays can show secure content so we add an additional restriction on it.
    const int uid = IPCThreadState::self()->getCallingUid();
    if (secure && uid != AID_GRAPHICS && uid != AID_SYSTEM) {
        ALOGE("Only privileged processes can create a secure display");
        return nullptr;
    }

    class DisplayToken : public BBinder {
        sp<SurfaceFlinger> flinger;
        virtual ~DisplayToken() {
             // no more references, this display must be terminated
             Mutex::Autolock _l(flinger->mStateLock);
             flinger->mCurrentState.displays.removeItem(wp<IBinder>::fromExisting(this));
             flinger->setTransactionFlags(eDisplayTransactionNeeded);
         }
     public:
        explicit DisplayToken(const sp<SurfaceFlinger>& flinger)
            : flinger(flinger) {
        }
    };

    sp<BBinder> token = sp<DisplayToken>::make(sp<SurfaceFlinger>::fromExisting(this));

    Mutex::Autolock _l(mStateLock);
    // Display ID is assigned when virtual display is allocated by HWC.
    DisplayDeviceState state;
    // 默认创建安全显示器 
    secure = true;
    state.isSecure = secure;
    state.displayName = displayName;
    state.requestedRefreshRate = Fps::fromValue(requestedRefreshRate);
    mCurrentState.displays.add(token, state);
    return token;
}

搞出来之后可以编译成镜像,或者cdframeworks/native/services/surfaceflingermmsurfaceflinger可执行文件之后丢到已有的容器里面。

个人blog: cnflysky.com,欢迎访问。

你可能感兴趣的:(debian,linux,android,arm)