FireFox OS是移动操作系统的新成员,它以Linux内核和Gecko为基础,延续了Web版的开源理念。这款新的操作系统在设计上究竟有哪些独到之处?是否能满足移动市场中多元化的用户需求?本文将从FireFox OS的底层架构为入口,从技术角度带领读者开启一段FireFox OS的探秘之旅。
Firefox OS是由Mozilla主导开发的新一代开源移动操作系统。自2011年6月项目正式启动以来,受到越来越多的关注。在过去的几个月中,我常在不同的场合被问到一些关于Firefox OS的问题,其中最常见的主要有下面几个。
下面我们就对Firefox OS这个系统做一个全面的介绍,请大家跟随我,一起完成这段Firefox OS的探秘之旅吧。
第一站:Firefox OS概念馆
Firefox OS作为一款开放网络技术的移动操作系统,基于Linux内核及Gecko引擎技术,从一开始就完全采取开源的方式进行开发,其核心理念是用户可接触到的 应用都是基于Web的应用,这些应用使用HTML5技术和硬件设备接口,可以通过JavaScript直接访问手机的硬件设备。Firefox OS架构主要由三层组成(如图1所示),分别为Gonk、Gecko和Gaia。
与现有的平台相比,Firefox OS在技术上具有以下特点。
第二站:Gonk机器工厂
Gonk 一词来源于《Star Wars》中的一个叫做Gonk Droid的机器人。Gonk层是Firefox OS的最底层,由Linux内核和用户态硬件抽象层组成,来自通用的开源项目,其中部分与Android硬件抽象层共享,也包括部分硬件厂商提供的需要授 权的代码或库,如RIL、OpenGLES、FM等。
当打开安装Firefox OS设备的电源时,主引导程序(Bootloader)开始执行,引导主系统内核的过程以通常的方式进行,最后,执行由Bootloader转交到 Linux内核。接下来进入Linux内核启动阶段,这一阶段与主流Linux系统的内核启动一致,Gonk中的Linux内核在一定程度上接近 AOSP(Android Open Source Project)的内核部分。在内核启动的最后,用户空间中的Init进程被触发,此时,只有内存虚拟盘被挂载。Ramdisk在Firefox OS系统构建的过程中被构建,包含了关键工具、其他启动脚本和可装载内存模块。许多设备通过sysfs暴露给Gecko。下面给出了Gecko中获取电池 状态的代码:
在Linux内核完成启动后,会进入Init初始化过程,这部分将挂载必要的文件系统,加载系统服务和核心进程,并在服务启动后充当服务管理器。孵化系统服 务与其他类Unix系统的Init进程非常相似,由Init阶段加载的主要进程有b2g、rild、rildproxy、dbus-daemon等。其中 b2g为主要运行环境进程,图2展示了Firefox OS用户空间中的主要进程(虚线表示被Init孵化的进程,实线表示其他通信管道)。
总的来说,我们可以认为Gonk层是一个简化过的Linux分发版本,是支撑Gecko在硬件设备上运行的基础。我们知道,Gecko同样是Firefox 浏览器在各平台上运行的核心,但与浏览器不同的是Firefox OS对Gonk有完全的控制能力,它把在其他平台上无法获得的硬件接口暴露给Gecko层,例如全部的电话堆栈(telephony stack)和显示帧缓冲(display framebuffer)。
第三站:Gecko两栖动物乐园
Gecko层是Firefox OS的技术核心,也是整个系统的应用运行环境,这一层提供对公开标准的支持。为了确保这一支持,这一层还包括其他内容,包括网络处理、图形图像处理、排版引擎、JavaScript虚拟机和对GonkHAL的支持等。
在处理输入方面,Gecko中的大部分动作都是由输入事件触发的,这些事件包括:按下按钮和触摸屏幕等。这些输入事件起源于标准的Linux输入事件系统,由输入设备驱动对这些事件进行转发。我们在提供了一些良好特性的事件(如事件过滤器)之上,使用了一个简单抽象。
对于图像处理,在非常底层的地方,Gecko使用OpenGL ES 2.0进行绘制,绘制到一个包含硬件帧缓冲的叫做“图形上下文”的地方。它使用了图形驱动的gralloc硬件接口,映射帧缓冲到缓冲区,Gecko使用 它的图层系统将内容进行组合,绘制显示到屏幕上。Gecko绘制不同的页面区域到内存缓冲中,有时这些缓冲就是系统内存,另外一些时候,它们是映射到 Gecko地址空间的纹理,即Gecko直接绘制到VRAM(Video Random Access Memory),Gecko使用GL指令组合这些纹理到屏幕上。值得注意的是Gecko里也存在一个硬件抽象层,为了避免Gecko的硬件抽象层与 Gonk的硬件抽象层混淆,Gecko硬件层将被称为hal,而Gonk的硬件抽象层被称为HAL。hal位于Gecko的移植层,它为Gecko中的更 高层次提供了一个跨平台的C++ API,这些API是在hal内部实现的,并且只能被Gecko中的C++代码所访问。
目前,Web的通用语言是JavaScript,而主流的浏览器引擎大多是用C++开发的,Gecko也不例外,DOM Bindings就是使JavaScript可以通过DOM API调用一些由C++实现的功能(如图4所示)。
Gecko内部使用最多的还是基于XPConnect上的DOM Bindings,使用ScriptableHelper来帮助把XPCOM组件暴露在JavaScript上,但这种方式有一些内存管理和速度上的缺 点,并且XPIDL(XPCOM界面定义语言)与WebIDL(Web界面定义语言)在语义上有一定的不同,会使各种加速方法和处理语义问题的 Wrapper需要手工地针对不同API进行修改。
因为XPIDL的一些问题,Firefox OS里还提供一种DOM bindings的方法。由于这个问题是在法国巴黎首次讨论的,所以最早被称为“Paris Bindings”。因为这些DOM API实际上不使用XPCOM的许多功能,所以它的速度比原有的XPConnect会快许多。通过WebIDL DOM bindings可以省略掉一些虚函数的开销,还可以节省掉XPCOM处理线程安全的花费,透过新的JIT技术,从JavaScript可以调用DOM API,甚至直接调用C++的实现。未来描述DOM API的语言可能统一为WebIDL。
第四站:Gaia视觉体验中心
Gaia 层是指Firefox OS的用户界面层,当Firefox OS启动后任何可以显示在屏幕上的内容都可看成该层的一个应用。Gaia层实现了HomeScreen、ScreenLock乃至一个现代智能手机所具备 的标准应用。它由Gecko层提供实现支持,通过开放的Web接口访问潜在的操作系统功能。在介绍Gaia之前,我认为有必要描述一下Firefox OS的显示流程。Firefox OS在Gonk层和Android系统类似,但又有很多不同。首先我们来看看简易的类别图和几个简单的概念(如图5所示)。
在目前的Gecko引擎当中,所有的绘图动作都会作用在一个称为Layer的对象上。每一个Layer基本上就是一张点阵图,并且包含了应该怎样被显示在屏 幕上的基本信息。值得注意的是,每一个Web应用只负责把它自己的Layer内容准备好,并不会把它们合并在一起,每个Web应用最终可能是由多个 Layer的树形结构所组成(如图6所示)。
最终由CompositorParent把收集起来的所有Layer叠加在一起,形成整个画面。基于此,我们大致可以把Firefox OS的显示流程分为下面几个步骤。
在Gaia的结构设计上,使用XULRunner作为最外层的框架(如图7所示),System App作为权限最高的应用在设备启动后被系统默认加载。System App本身包含锁屏管理、Home桌面、声音管理、窗口管理、状态栏管理、输入事件管理、电源管理,以及系统设置等,是系统的核心应用。
在Gaia层,除了System App外,其他应用都是由System App负责创建的,例如拨号盘、浏览器、游戏等,基本上遵循以下过程。
在Web应用中,最容易让人产生误解的就是应用和网络之间的关系,那么在没有网络时,我们该如何是好呢?
HTML5提供了离线缓存机制,开发者可以通过使用这些App缓存接口指定浏览器应该将哪些资源存储下来供脱机时使用,这样即便在脱机状态下,只要用户点击了刷新键,App也能读取缓存并正确地运行下去。使用缓存能为App带来以下几点好处。
当浏览器访问一个设置了manifest属性的页面,它会检测是否已创建该页面的缓存文件,如果还未创建,那么浏览器就会载入页面并抓取所有在这份缓存声明 文件中定义的资源,并在客户端创建App缓存的第一个版本。再次访问该页,浏览器在载入页面时,会优先从客户端的App缓存中获取相关资源。此外,在遵循 HTTP缓存协议的前提下,浏览器还会送出一个触发事件给window.applicationCache这个对象, 并会去抓取服务器的缓存声明文件。
如果当前的缓存声明文件是最新的,浏览器会发送一个noupdate事件给applicationCache对象,告知其更新已结束。需要注意:如果你修改了服务器上的资源,必须及时更新缓存声明文件,这样浏览器才会知道需要抓取新的资源。
如果缓存声明文件被修改了,所有在其中罗列的文件(包括那些之前已经通过调用 applicationCache.add()方法存入缓存的文件)会根据HTTP缓存协议被再次抓取到一个临时的存储空间中。所有被抓到这个临时存储空 间的文件,浏览器都会发送一个process事件给appliCation对象(如果有错误发生,浏览器也会发送一个error事件,并停止更新)。等到所有文件被成功地下载下来,它们会自动调入真正的离线缓存,并且发送一个cached事件给appliCation对象。因为文档已被浏览器通过缓存读 取,所以新的文档暂时不会取而代之,直到页面刷新。
起航吧,新起点
HTML5是近十年来Web开发标准最巨大的飞跃。HTML5并不是仅仅用来表示Web内容,它的新使命是将Web带入一个成熟的应用平台——视频、音频、图像、动画,同电脑的交互全部标准化。在这个群雄并起的移动平台上,Firefox OS是否会为移动互联网开启一个新的局面,还需要靠未来的市场做最终评价。虽然本次Firefox OS的探秘之旅已然接近终点,但对Open Web及Firefox OS的开发者和爱好者来说,却是旅程中的一个新起点,还有更多的秘密等待大家去探索,向着新的目标,起航吧。
作者薛东升,火狐软件经理,主要负责国内火狐移动产品的研发和管理工作,包括Fennec、Firefox for Android和Firefox OS。
本文选自《程序员》杂志2013年4期,未经允许不得转载。如需转载请联系 [email protected]
《程序员》2013年杂志订阅送好礼活动火热进行中