技術(shù)實(shí)現(xiàn)
input注入
目前常用的input注入有兩種,一種是以uinput為代表的創(chuàng)建/dev/input/xx節(jié)點(diǎn),往節(jié)點(diǎn)里注入原始input數(shù)據(jù);一種是以scrcpy為代表的利用adbd的高權(quán)限調(diào)用framework inputManager注入事件的接口。
投屏
以scrcpy為例,簡述投屏的原理。scrcpy會通過adb在android內(nèi)創(chuàng)建一個VirtualDisplay,并有一塊surface與之關(guān)聯(lián),surface由mediacodec創(chuàng)建,surfaceFlinger在合成渲染完畢后會將結(jié)果傳遞給這個surface,mediacodec再編碼后的結(jié)果通過socket傳遞給adb reverse傳遞的pc端映射端口,pc端解碼后就拿到了該圖像。
商業(yè)云手機(jī)在android端的圖像采集技術(shù)與scrcpy類似,但是在各端的推拉流顯示原理則各有差異,如webrtc/xdp等。
binder 驅(qū)動
redroid本質(zhì)上是通過docker啟動的android容器,與宿主共用一個內(nèi)核,而各個容器都需要單獨(dú)的binder驅(qū)動,因此一般會通過binderfs創(chuàng)建容器專屬的binder節(jié)點(diǎn),再在docker啟動容器時映射進(jìn)去。

渲染
redroid被設(shè)計用來跑在不同架構(gòu)和GPU的平臺,因此redroid預(yù)置了相當(dāng)多的渲染相關(guān)的so,以便在運(yùn)行時根據(jù)配置來決定是使用軟渲染還是硬件渲染,使用哪個平臺的渲染驅(qū)動等。
namespace和cgroup資源隔離
這是android容器能跑起來的最關(guān)鍵的機(jī)制,一般通過docker/podman/lxc實(shí)現(xiàn)。、
如何閱讀 redroid
#####################
# 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
# add local manifests
git clone https://github.com/remote-android/local_manifests.git ~/redroid/.repo/local_manifests -b 11.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
redroid代碼主要分為patch倉庫和redroid倉庫兩部分。
先看patch倉庫部分

主要是屏蔽了selinux、vintf、seccomp等導(dǎo)致系統(tǒng)起不來的部分邏輯。
redroid倉庫相對aosp的主要改動如下


可以看到都是為了應(yīng)對不同平臺和環(huán)境的一些渲染和編解碼的庫。