OpenFDE技术解析(一) : 我们是如何让安卓应用在linux上顺畅运行的?

背景

众所周知,android系统是基于linux内核运行的,而安卓丰富且成熟的软件生态和linux的生态形成了鲜明的对比,所以,都是基于一个内核,为什么不能让安卓应用直接在linux上跑呢?

目前市面上能在linux上跑android的技术方案主要就是两个,一个是虚拟机,二是用容器化的方案,前者会吃掉太多电脑硬件性能,且两个系统在完全隔离之后是无法交互,而容器化则没有这些缺点,所以成为了我们的首选,具体来说就是相当于在linux的地盘上隔出一个安卓运行的空间,但是两个系统之间还保有交互的通道。

OpenFDE软件架构

现在,我们来看看OpenFDE的软件架构。自底向上可以分为分为标准Linux内核、LXC隔离和融合层、API框架层、应用层和Linux桌面图形栈几个部分。

image-20240425-085148.png
OpenFDE架构图

应用层

OpenFDE应用层主要包含安卓应用和Linux的X11类应用。其中Android应用可以原生运行。但Linux的X11类应用还是运行在linux系统中,我们是通过运行在FDE中的vnc client将Linux X11类应用的显示融合到Android系统中,同时进行(键鼠信号和输入法)事件转发,目前我们正在开发基于安卓系统的XServer,以替换Linux上的vnc server X11,这样可以获得更高的显示性能和更强的兼容性。

API框架层

API框架层提供了一组标准的API接口,使应用程序能够与底层系统进行通信和交互,这些API包括访问设备驱动、管理文件系统、处理网络通信等功能。OpenFDE是直接继承Android API设计框架,使两者遵循一套统一的外设、功耗管理API,能极大的缓解API版本代次共存、图形界面使用与开发过程中修改较为随意和混乱的问题。

LXC隔离层

LXC隔离层负责将Linux和Android的文件系统及API层进行隔离,但同时又共享Linux内核。融合层则充分利用标准桌面协议(Wayland)和Linux桌面图形栈,提供图形显示、输入设备管理、窗口管理等关键功能。另外我们正在做将Linux桌面图形栈的OpenGL/ES融合成动态库的形式,提供到Android端直接进行调用,以兼容更多的硬件。

Linux融合方案详解

Linux上的DRI显示框架的逻辑(也是目前最高效的显示框架)是,客户端直接调用gpu渲染,渲染完毕后,提交给合成器,合成器合成后提交显示。

image-20240425-092821.png
Linux上的DRI显示框架逻辑

安卓的显示逻辑是应用向surfaceflinger申请缓存,surfaceflinger调用gralloc完成申请,再同步给应用程序使用。渲染过程由应用调取gpu直接完成,最后交给surfaceflinger调用hwcomposer完成合成。

在Linux上跑安卓,就可以将这两个流程进行合并,前面部分保持安卓原流程不变,将hwcomposer改造成wayland client(因此就失去了硬件合成功能),在surfaceflinger请求hwcomposer合成的时候,hwcomposer返回全部让gpu合成的数据,此时surfaceflinger会调用gpu完成合成,再将合成后的结果发给hwcomposer进行提交。此时hwcomposer就通过wayland协议将缓存发送到linux合成器——mutter,最终由mutter发到linux的dpu上进行显示。

当然这种方法会有一定的性能损耗,但是可以很好的达到我们的目的。