OpenFDE技术解析(四):突破vnc局限,在Android上解锁linux多窗口自由体验

效果对比:

看过我们上一期技术文章的小伙伴应该都有所了解,我们之前在桌面上跑linux应用,用的就是vnc的技术方案,但是这个方案会有一个缺陷,由于他是直接拿linux画面投影过来,在使用的时候始终只有一个窗口,不管你打开多少页面,都会被限制在这个框内,十分不方便。

所以在经过研究探索之后,我们采用了一种新的技术方案—xserver,它能直接传递程序显示内容而不经过屏幕图像转发,实操下来最大的变化就是,你可以开多个窗口,且整体交互也和linux无异(比如直接通过拖动实现窗口的合并分开、关闭文档提示你是否保存等等)。

原理解说:

以防有人不知道,讲原理之前提一句,我们其实是基于aosp的linux桌面,底层是基于waydroid的,所以有会点像是能在linux上跑的安卓桌面

这是两者的技术结构对比图,能看到vnc是通过vncserver进行操作以及图像的转发,而xserver流程简化了许多,其在性能、兼容性、使用体验等方面都有更好的效果,接下来我们就针对xserver的方案进行详细解说:

这是xserver的详细结构图,先简单介绍一下背景,Xserver是X Window系统的核心组件,而X Window其实是linux发行版的图形环境的基础之一,像我们熟知的GNOME和KDE Plasma等流行的Linux桌面环境都是基于X Window System构建的。所以大家能看到的是,我们将原用于linux系统的xserver移植到了我们FDE桌面上来,负责管理显示设备和处理来自X客户端的请求,通过这种形式来让linux应用直接跑在我们桌面上。

接下来我们详细讲一下这个结构,左边橙色部分是linux中负责显示的两个模块,它会把所有显示信息,包括窗口信息,传递给移植过来的xserver,而我们的Xserver运行在一个独立进程的Android service(XWindowService)里,在这个service中通过native函数启动一个TCP服务端或者unix socket服务端,支持X11协议的Linux程序可以与这个服务端连接,向其发送绘图指令和接收输入事件。

Xserver上的许多扩展和补充协议使得它目前还是Linux上兼容性和效率最好的显示方案,支持本地和远程连接,很小的内存占用。在Android NDK中的编译调试也比较方便,没有多余的依赖,还有不少成熟的方案可以借鉴。

在XWindowService下面还有另一个模块就是WindowManager(窗口管理器),用于管理和控制 X Window System (X11) 窗口的程序。它处理窗口的打开、关闭、移动、调整大小等操作,并决定窗口的外观和行为。OpenFDE上Xserver连接的是自定义开发的一个基础版窗口管理器,运行在FDE-X11中,没有窗口修饰功能,额外了实现合成器、窗口属性同步、剪贴板同步等功能。

窗口管理器这块有一个我们比较创新的点叫做Compositor(合成器)图像重定向,在窗口管理器中启用了Compositor扩展,Composite允许在所有窗口创建和显示的过程中重定向窗口输出内容,将一个窗口树中的所有窗口渲染重定向到内部存储,再通过窗口指针最终拿到这个窗口的图像buffer。合成器实现窗口特效的原理也基于此。

这样就可以将每个窗口的图像buffer分离出来,转到Android处理绘制,也就是直接将图像数据从linux的窗口拿到android的窗口中。

而最右边绿色部分则是SurfaceManager和Activity,负责显示内容和接收事件

其中SurfaceManager是FDE-X11抽象出来的一个模块,用来管理绘制buffer的所有Surface。将不同的Surface传到Xserver的EGL环境中,使不同的Surface正确绘制不同的buffer。对于一些OverrideRedirect的窗口,将不会新建Surface,而绘制在它所依赖的窗口上。

Activity部分,主要还是使用它做为与Linux一一对应的窗口。在Android的窗口系统中,APP窗口所处理的层次被限定在一个层级范围,只有在这个层级范围的窗口才会与其他APP的窗口交互行为相同,目前可选的Android组件就只有Activity和Dialog了。作用是创建SurfaceView显示输出图像,接收Android输入事件发送给Xserver。在FDE使用的Android freeform模式下,表现大致等同于Linux桌面,在理论上甚至可以做到完全一致。

在Linux窗口创建的时,在Android中创建一个Activity,将Linux窗口的图像显示在这个Activity的SurfaceView上,如果Activity有按键或者鼠标输入就发送到Xserver对应的坐标。这个过程需要处理的问题非常多,比如生命周期同步,窗口类型,事件重定向,窗口图标和标题栏操作等等。

除了上述所说的内容之外,我们还做了Android和Linux窗口属性同步、Android和Linux剪贴板同步等相关的工作,这里就不赘述了。

总结来说,与现在的各个平台的Xserver实现不同,因为FDE-X11本身是一个桌面环境,借助AOSP的强大,和一些开源方案的思路(比如Termux:X11),从而实现了这个创新的方案。本方案研究开发历时不短,但是还有不少不成熟之处,比如X窗口的复杂特性只实现了其中一部分,还有Android的窗口受限于framework的原始设计,改动起来也工作量巨大,尤其生命周期耗时与X窗口高出一两个数量级,还有效率更高wayland协议,这些都给用户体验留下很大优化空间。

希望能给大家一些参考和启发~本方案的代码也放在了我们代码仓中,有需要可以自取,如果有其他的疑问可以留言,都会一一解答滴。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值