1 综述
Android的GUI系统由C语言框架和JAVA语言框架组成。对下层,Android的GUI系统通过调用显示输出设备和输入设备的驱动,从而将Android的软件系统和底层的硬件联系起来。对上层,Android的GUI系统提供了Java层次的绘图结构,Android的Java框架层调用这些绘图接口来构建各种UI元素,这些绘图接口也可以供Java应用程序层来调用。
Android的GUI系统架构图如图1所示:
图1 GUI系统框架图
其中驱动包括FrameBuffer驱动,Event输入驱动等。
由上图可知,libui是提供接口的框架库,其他的库大部分通过继承并实现libui中定义的类来实现相应的功能。因此,理解libui的构造对于了解GUI的整体框架存在必然性。以下就来介绍一下该库。
2 libui库
libui是Android在本地层次一个框架性质的集成库,它不仅是现实的中枢,也是整个AndroidGUI系统的中枢。
这个库提供了一些接口,由其他的库通过类继承方式来实现,而调用者只需要调用libui库的接口即可。libui库包含了颜色格式,Egl窗口(用户显示),按键及事件处理,Surface(显示界面),Overlay(显示叠加层接口),Camera(照相机接口)等多个方面的定义。
libui库中包含的内容如下:
1) Format(颜色格式))部分
这个部分本身定义颜色空间的枚举类型和数据结构,它需要重用pixelflinger中的一些数据格式的定义。
2) Native Windows(本地窗口)部分
本部分用于实现一个本地显示的接口,也就是实现一个egl_native_window_t类,程序通过调用从而实现基本的显示功能。
3) Key/Event(按键和时间处理)部分
本部分是系统输入的基础,其中定义按键的映射,通过操作Event时间设备来实现获取系统的输入。
4) Surface(显示界面)部分
本部分定义了显示界面较高层次的接口,包含部分显示界面的管理功能。
5) Overlay(显示部分的叠加层)部分
定义了一个叠加的显示输出层接口,覆盖在主显示层之上,常用于视频输出。
6) Camera(照相机)部分
定义摄像头的框架和接口。
3 显示输出与硬件的接口
显示输出接口最终需要与硬件交互,对于Linux操作系统,就是要和驱动程序打交道。这两部分原本也是属于“硬件抽象层”的内容,由于Android中使用的是FrameBuffer的标准显示驱动,因此本部分内容在libui库中使用标准方式来实现。
对于Android的显示部分,需要实现的接口是egl_native_window_t,它是一个OpenGL结构,也是给libEGL使用的。
Android使用标准的FrameBuffer作为驱动程序,同时也在本地框架中提供了系统和FrameBuffer驱动程序之间的适配层,即硬件抽象层。这个部分主要在Gralloc模块中实现调用标准的FrameBuffer驱动,它是系统和FrameBuffer设备之间的接口,以硬件模块的形式存在。Gralloc被libui库调用。
Gralloc模式是显示模块的实现,其中,framebuffer.cpp用于基于FrameBuffer的显示实现。其中定义了帧缓冲区为双缓冲:
// numbers ofbuffers for page flipping
#defineNUM_BUFFERS 2
……
//使用FBIOGET_FSCREENINFO和FBIOGET_VSCREENINFO的ioctl()接口来获取驱动程序的基本信息,并调用mmap()将驱动程序的内存映射到用户空间
structfb_fix_screeninfo finfo;
if (ioctl(fd, FBIOGET_FSCREENINFO,&finfo) == -1)
return -errno;
structfb_var_screeninfo info;
if (ioctl(fd, FBIOGET_VSCREENINFO,&info) == -1)
return -errno;
//RequestNUM_BUFFERS screens (at lest 2 for page flipping)
info.yres_virtual= info.yres * NUM_BUFFERS;
libui对gralloc模块实现了调用,在FrameBufferNativeWindow.cpp中打开了gralloc设备。
FramebufferNativeWindow::FramebufferNativeWindow()
:BASE(),fbDev(0),grDev(0),mUpdateOnDemand(false)
{
hw_module_tconst* module;
if(hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
int stride;
int err;
err = framebuffer_open(module,&fbDev);
LOGE_IF(err,"couldn't open framebuffer HAL (%s)", strerror(-err));
err =gralloc_open(module, &grDev);
LOGE_IF(err,"couldn't open gralloc HAL (%s)", strerror(-err));
// ......
}