基于单Linux内核的多Android系统共享输入显示设备的方法
【专利摘要】本发明公开了一种基于单Linux内核的多Android系统共享输入显示设备的方法,包括:修改虚拟机中的各Android系统中的图形管理服务,使得宿主机中Android系统和虚拟机中的各Android系统的图形管理服务各自独占一个tty设备;用户通过输入设备使内核中产生输入事件,内核将该输入事件转发至各个Android系统中的输入管理服务,各Android系统接收到内核传来的输入事件后,判断当前运行的tty设备是否是自己占据的;如果是,则接收并处理该输入事件;否则,则屏蔽该输入事件。本发明充分利用Linux内核的隔离性,解决了多个Android系统对输入设备和显示设备的分配问题。
【专利说明】基于单Linux内核的多Android系统共享输入显示设备的方法
【技术领域】
[0001]本发明涉及计算机虚拟化【技术领域】,尤其涉及基于单Linux内核的多Android系统共享输入显示设备的方法。
【背景技术】
[0002]在Android操作系统的用户量迅速增长的背景下,其安全性也受到越来越广泛的关注。由于Android缺乏像iOS那样封闭的生态系统,恶意软件已经成为其安全性的最大威胁。为了限制恶意软件的活动范围,最大限度地保护用户的个人信息,有人提出了 Android虚拟化这一解决方案。Android虚拟化是指在一台设备上运行多个Android操作系统,这些操作系统相互隔离,安装在某一个系统中的应用软件无法对其它系统构成影响。这样就可以将用户的个人信息封锁在某一个系统中,即使其它系统中安装了恶意软件也不会对个人信息构成威胁。在这些虚拟化解决方案中,基于Container技术的虚拟化相对其它方案具有很大的性能优势。
[0003]Container (容器)技术是近年来操作系统虚拟化领域迅猛发展起来的一种技术。相较于其他的虚拟化技术,Container技术是一种轻量级的虚拟化解决方案。该技术能够利用Linux内核提供的命名空间(NameSpace)特性和控制分组(Cgroups)特性来隔离出一套完整的虚拟平台。因为Container技术隔离出的虚拟机平台仅仅是主机系统中的一组进程,而不需要完全模拟出一整套的硬件环境,所以Container技术一个最明显的优势就是快速、轻量级。目前云计算领域在实现私有云的部署时,主要就是采用Container技术。
[0004]因为具有上述特点,所以Container技术非常适合运用到Android操作系统的虚拟化中。众所周知,Android是为智能手机和其他手持式设备设计的一款操作系统。手持设备处理器的性能完全不足以让传统的虚拟化技术运用在其上,而占用资源极少的Container技术则恰恰弥补了这个不足。
[0005]Android操作系统的架构也使得其运用Container技术成为可能。Android系统的底层是Linux内核,上层则基于Linux内核搭建起了 Android的运行环境层。通过在Linux内核层和Android层之间采用Container技术,就可以达到多个Android运行环境层共同运行在一个内核之上的效果。不同的Android运行环境可以有不同的用户数据、应用、文件系统和设备。而进程调度、内存管理、与硬件交互等具体问题则交于Linux内核统一管理。
[0006]不同的Android运行环境层共用一个Linux内核,也就得共用一套物理设备资源。这就带来如何管理这些设备,让每个Android运行环境层都能以看似独占的方式使用这些设备的问题。传统的技术和观念是所谓的“设备虚拟化”,即通过添加Linux内核驱动,增加虚拟设备以模仿物理设备的功能,然后再在物理设备中添加处理和仲裁的相关功能。这种思路对于Linux虚拟设备非常适合,但是对于物理设备,修改驱动的方法必然会带来非常大的不可移植性。因而对于物理设备,更好的思路应该是充分利用内核提供的隔离特性,从Android运行环境层入手,对资源进行隔离。[0007]在所有的这些设备中,最重要的就是用户输入和图形显示两部分设备,因此如何进行让多Android系统共享输入显示设备是需要解决的问题。
【发明内容】
[0008]为了增加Android系统运行的安全性,利用Container技术进行Android系统的虚拟化,为了解决在单Linux内核中多Android系统共享输入显示设备的问题,本发明提供了一种多Android系统共享输入和显不设备的方法。
[0009]—种基于单Linux内核的多Android系统共享输入显示设备的方法,所述多Android系统运行于单Linux内核环境中,所述多Android系统的其中一个运行于宿主机中,其余运行在虚拟机中,包括:
[0010]初始化虚拟机中的各Android系统中的图形管理服务,使得宿主机中Android系统和虚拟机中的各Android系统的图形管理服务各自独占一个tty设备;
[0011]用户通过输入设备使内核中产生输入事件,内核将该输入事件转发至各个Android系统中的输入管理服务,各Android系统接收到内核传来的输入事件后,判断当前在前台运行的tty设备是否是自己占据的;
[0012]如果是,则接收并处理该输入事件;
[0013]否则,则屏蔽该输入事件。
[0014]利用单Linux内核的隔离性,使得宿主机与虚拟机各自占用一个tty设备,并且在不同的tty设备中打开设备文件并写入文件互不影响。通过让Android输入管理服务自主判断当前内核传来的输入事件是否为传给自己,有选择的屏蔽或接收该输入事件,从而实现了输入设备的共享。
[0015]图形管理服务通过以下新增的代码来各自独占一个tty设备,其中新增的代码是预先设定的,代码增加方式如下:
[0016]SI,在图形管理服务的DisplayDevice类中增加一个新类TerminalManager,TerminalManager 继承 Android 系统的基类 Thread ;
[0017]S2,将TerminalManager的对象mTermManager作为成员变量添加到DisplayDevice 类中。
[0018]SurfaceFlinger是Android系统的图形管理服务,其源代码位于Android系统的 frameworks/native/services/surfaceflinger 目录下。通过在 DisplayDevice.cpp增加一个新类TerminalManager,让各个Android系统的SurfaceFlinger占据一个不同的tty设备进行显示。mTermManager使得图形管理服务另外启动一个线程。新线程专门负责接收并处理内核发来的获得屏幕和释放屏幕的信号。因为图形管理服务SurfaceFlinger中操纵显示设备的代码实现在类DisplayDevice中,所以在DisplayDevice中添加对象mTermManager能够更自然而方便的实现上述作用。
[0019]所述新类TerminalManager 用于:
[0020]向操作系统查询空闲的tty设备,并将图形管理服务切换到该tty设备,切换完成后将新tty设备设置为图形模式;
[0021]设置新tty设备的切换操作方式为由进程管理,并通过用户自定义的方式增加获取屏幕和释放屏幕两个响应信号;[0022]以及向内核中注册所述两个响应信号的处理函数。
[0023]其中,用户自定义是指Linux的一个信号类型SI⑶SR。通过调用SurfaceFlinger的screenAcquired函数和screenReleased函数即可实现两个响应信号的响应函数。
[0024]其中宿主机和虚拟机运行在各自的命名空间内,并且由Cgroups组件限制虚拟机能够访问的资源。在Android系统中建立命名空间,使得宿主机和虚拟机的图形管理器运行在不同的命名空间中,宿主机和虚拟机相互感知不到对方的存在,从而为宿主机和虚拟机之间提供隔离保证。再使用Cgroups组件限制虚拟机能够访问的资源,并限制其权限,这样就保证了宿主机的安全。
[0025]宿主机和虚拟机中对应目录下的tty设备文件都分配相同的主设备号和次设备号。
[0026]宿主机中tty设备文件的主设备号与虚拟机中tty设备文件的主设备号相同,宿主机中tty设备文件的次设备号与虚拟机中tty设备文件的次设备号相同,这样内核中所有的虚拟tty设备对宿主机和虚拟机都是可见的。虚拟机图形界面在启动的时候向内核中查询空闲的tty设备并占据该设备作为自己的输出终端。这样当宿主机和虚拟机各自独占一个tty设备后,就可以独立隔离地读写帧缓存设备文件,从而实现宿主系统和虚拟系统能够同时地在不同的tty设备下显示自己的图形界面而互不干扰。
[0027]各Android系统通过输入管理服务中的代码逻辑来判断当前在前台运行的tty设备是否是自己占据的,其中代码逻辑是预先增加的。
[0028]通过修改各Android系统中的输入管理服务,使各Android系统屏蔽不属于自己tty设备的事件,转交属于自己tty设备的输入事件,避免了输入冲突。
[0029]预先增加的代码逻辑在各Android系统中输入管理服务中的EventHub类下的成员函数getEvents中,代码逻辑分为两部分:
[0030]输入管理服务每次从输入设备文件中读取输入事件时,取得当前在前台运行的tty设备的编号;
[0031]并通过所取得的编号判断在前台运行的tty设备是不是对应SurfaceFlinger所占据的tty设备,如果不是则表明该输入事件不是发送给自己的,则对消息不作处理;否则接受消息并进行处理。
[0032]当前运行的tty设备为Linux系统的一种状态:如果一个tty设备的内容输出到显示器上,那么这个tty设备就是当前在前台运行的tty设备。例如,在Linux中,图形界面输出到tty7,在按下ctrl+alt+fl键时,系统切换到了 ttyl, ttyl的内容显示在显示器上,那么当前在前台运行的tty设备就是ttyl ;而通过按下ctrl+alt+f7键切换回图形界面时,则tty7的内容输出到显示器上,这时当前在前台运行的tty设备就是tty7。
[0033]Android输入管理服务是WindowManagerService。该服务代码的实现分java和c++两层,在修改输入管理服务时,只需修改c++层,将不必要的事件屏蔽即可。
[0034]WindowManagerService 的 c++层代码实现在 frame/base/service/input 中,该目录下的EventHub.cpp负责读取/dev/input下的设备文件来获取用户输入,因此修改该文件即可。具体地,类EventHub下的成员函数getEvents负责读取用户输入,因此通过在该成员函数getEvents中增加代码逻辑来实现对输入管理服务的修改。
[0035]通过本发明基于单Linux内核的多Android系统共享输入显示设备的方法,充分利用Linux内核的隔离性,解决了多个Android系统同时运行时对输入设备和显示设备的分配问题。
【专利附图】
【附图说明】
[0036]图1是本发明一个实施例的架构图;
[0037]图2是本发明实施例从系统启动到运行SurfaceFlinger的流程图;
[0038]图3是Android系统输入部分的架构图。
【具体实施方式】
[0039]基于单Linux内核的多Android系统共享输入显示设备的方法主要对Android系统进行修改。本发明实施例进行操作的Android系统版本为Android4.3。
[0040]图1为本发明一个实施例整体的架构图,当前实施例中包括I个虚拟机。如图1所示,Linux内核为宿主机和虚拟机分别提供命名空间,宿主机和虚拟机运行在各自的命名空间内,且由Cgroups组件限制虚拟机能够访问的空间。在初始化图形管理服务以后,宿主机和虚拟机中Android系统的SurfaceFlinger各自占用一个tty设备,宿主机中表示为ttyX,虚拟机中表示为tty Y。宿主机和虚拟机中的tty设备均配置为图形模式,且各个各自占据对应的tty设备,且宿主机tty设备文件的主设备号和次设备号与虚拟机中tty设备文件的主设备号和次设备号相同。
[0041]现具体说明本发明当前实施例基于单Linux内核的多Android系统共享显示设备的方法:图2给出了本发明当前实施例从系统启动到宿主机运行SurfaceFlinger (即图形管理服务)的简要流程图(步骤(I)至步骤(3)),具体步骤如下:
[0042](I) Linux内核启动并初始化,在内核初始化完成时启动init进程。
[0043](2) init进程打开/dev/ttyl (即宿主机tty设备),并将其置为图形模式。
[0044](3) init 进程启动 SystemServer 服务,SystemServer 服务又启动SurfaceFlinger。SurfaceFlinger占据系统当前在前台运行的tty设备来输出内容。因而,SurfaceFlinger在当前在前台运行的tty设备中打开/dev/graphics/fbO,并创建双缓存,并将显示内容交替刷入/dev/graphics/fbO中。
[0045](4) SystemServer继续启动Android系统的其他相关服务,直至Android系统初始化完成。
[0046]至此,宿主机Android系统的启动完成。
[0047](5)在宿主机Android系统启动结束后,虚拟机的init进程开始在新的NameSpace中启动。
[0048](6)虚拟机init进程不打开新的tty设备,直接启动SystemServer服务,SystemServer服务启动SurfaceFlinger。SurfaceFlinger向操作系统查询空闲的tty设备,并切换到该tty设备,记该tty设备为ttyX。
[0049](7)切换完成后,SurfaceFlinger将ttyX置为图形模式,后续过程和宿主机相同,最终宿主机和虚拟机的图形管理服务各自占据一个tty设备。
[0050]其中关键步骤为步骤(2)和(3)。/dev/graphics/fbO是 Linux 中 Framebuffer 设备的图形设备文件,它有一个特性是在不同的tty设备之下打开该图形设备文件所写入的内容不会相互影响。但在Android的代码中SurfaceFlinger默认都是从/dev/ttyl启动图形模式的。因此本发明对宿主机和虚拟机的SurfaceFlinger的源代码都进行了修改,使得宿主机和虚拟机在启动时不从当前在前台运行的tty设备中启动图形模式,而是查找ー个空闲的tty设备并启动图形模式,因而避免对相同的tty设备进行访问而造成冲突。
[0051]通过预先修改宿主机和虚拟机内Android系统中SurfaceFlinger中的源代码,使得宿主机中Android系统和虚拟机中的各Android系统的图形管理服务各自独占ー个tty设备。
[0052]SurfaceFlinger 的源代码位于 Android 系统的 frameworks/native/ services/surfacef linger 目录下。通过对 SurfaceFlinger 源代码中 DisplayDevice.cpp 的修改,让各个SurfaceFlinger占据ー个不同的tty设备进行显示。
[0053]具体的改动有: [0054](I)设i十一个新的类TerminalManager,该类要继承Android系统的基类Thread,该新类用于:
[0055]向Android系统查询空闲的tty设备并切换到该tty设备;切换完成后将新tty设备设置成图形模式;将新tty设备的切換操作方式设置为“由进程管理”,并增加获取屏幕信号和释放屏幕信号。
[0056]实现操作系统获取屏幕响应信号和释放屏幕响应信号的处理函数。通过调用SurfaceFlinger的screenAcquired函数和screenReleased即可实现这两个信号的响应函数。
[0057](2)将TerminalManager类的对象mTermManager作为成员变量添加到DisplayDevice 类中,在 DisplayDevice 的构造开始时将 mTermManager 构造好。
[0058]在向显示器输出时,由进程管理各个tty设备,在不同Android系统的图形管理服务所占据的tty设备之间切换,通过用户输入信号,将对应的tty设备切换为当前在前台运行的tty设备。
[0059]图3展示了 Android系统输入部分的架构。现根据图3具体说明共享输入设备的方法:
[0060]Linux输入事件是通过读取输入设备文件来获得的,一般情况下,这些设备文件都位于/dev/input目录下。用户通过触摸屏、键盘、鼠标等输入设备向输入设备文件中写入输入事件,由EventHub.cpp从输入设备文件读取用户的输入事件;输入事件以队列形式输入到WindowManagerService中,由WindowManagerService对输入事件进行管理,并最终发送至JAVA应用程序。在本发明当前实施例中,容器中运行的Android虚拟机和宿主机中拥有相同的设备文件,也就是说,相同的外部输入事件能够同时转发给宿主机和虚拟机。通过修改Android系统中输入事件处理部分的源代码,让其将不属于自己终端的输入事件丢弃,这样在不同的終端中,输入事件就能转发给不同的Android系统运行实体。
[0061]Android系统的输入服务是WindowManagerService。该服务代码的实现分java和c++两层,只需修改c++层的代码,将不必要的事件屏蔽即可。
[0062]WindowManagerService 的 c++ 层代码实现在 frame/base/service/input 这一目录中,该目录下的EventHub.cpp负责读取/dev/input下的设备文件来获取用户输入,只需修改该文件即可。[0063]具体地,类EventHub (即EventHub.cpp)下的成员函数getEvents负责读取用户输入。在该成员函数中增加两部分代码逻辑:
[0064]每次获取事件时获取当前SurfaceFlinger所在的tty设备。
[0065]判断当前所在的tty设备是不是对应SurfaceFlinger被激活的tty设备:如果不是,则表明该输入事件不是发送给自己的,对消息不作处理;否则表明自己当前正是处于前台占据显示屏幕的tty设备,接受消息并进行处理。
【权利要求】
1.ー种基于单Linux内核的多Android系统共享输入显示设备的方法,所述多Android系统运行于单Linux内核环境中,所述多Android系统的其中ー个运行于宿主机中,其余运行在虚拟机中,其特征在于,包括: 初始化虚拟机中的各Android系统中的图形管理服务,使得宿主机中Android系统和虚拟机中的各Android系统的图形管理服务各自独占ー个tty设备; 用户通过输入设备使内核中产生输入事件,内核将该输入事件转发至各个Android系统中的输入管理服务,各Android系统接收到内核传来的输入事件后,判断当前在前台运行的tty设备是否是自己占据的; 如果是,则接收并处理该输入事件; 否则,则屏蔽该输入事件。
2.如权利要求1所述基于单Linux内核的多Android系统共享输入显示设备的方法,其特征在于,图形管理服务通过以下新增的代码来各自独占ー个tty设备,其中新增的代码是预先设定的,代码增加方式如下: 51,在图形管理服务的DisplayDevice类中增加一个新类TerminalManager,TerminalManager 继承 Android 系统的基类 Thread ; 52,将TerminalManager 的对象 mTermManager 作为成员变量添加到 DisplayDevice 类中。
3.如权利要求2所述基于单Linux内核的多Android系统共享输入显示设备的方法,其特征在于,所述新类TerminalManager用于: 向操作系统查询空闲的tty设备,并将图形管理服务切换到该tty设备,切換完成后将新tty设备设置为图形模式; 设置新tty设备的切換操作方式为由进程管理,并通过用户自定义的方式増加获取屏幕和释放屏幕两个响应信号; 以及向内核中注册所述两个响应信号的处理函数。
4.如权利要求1所述基于单Linux内核的多Android系统共享输入显示设备的方法,其特征在于,其中宿主机和虚拟机运行在各自的命名空间内,并且由Cgroups组件限制虚拟机能够访问的资源。
5.如权利要求4所述基于单Linux内核的多Android系统共享输入显示设备的方法,其特征在于,宿主机和虚拟机中对应目录下的tty设备文件都分配相同的主设备号和次设备号。
6.如权利要求1所述基于单Linux内核的多Android系统共享输入显示设备的方法,其特征在于,各Android系统通过输入管理服务中的代码逻辑来判断当前在前台运行的tty设备是否是自己占据的,其中代码逻辑是预先増加的。
7.如权利要求6所述基于单Linux内核的多Android系统共享输入显示设备的方法,其特征在干,预先增加的代码逻辑在各Android系统中输入管理服务中的EventHub类下的成员函数getEvents中,代码逻辑分为两部分: 输入管理服务每次从输入设备文件中读取输入事件时,取得当前在前台运行的tty设备的编号; 并通过所取得的编号判断在前台运行的tty设备是不是对应SurfaceFlinger所占据的tty 设备,如果不是则表明该输入事件不是发送给自己的,则对消息不作处理;否则接受消息并进行处理。
【文档编号】G06F21/53GK103593185SQ201310537870
【公开日】2014年2月19日 申请日期:2013年11月4日 优先权日:2013年11月4日
【发明者】王总辉, 孙伟杰, 徐磊, 李川, 李国玺 申请人:浙江大学