WindowManagerService类的成员函数performEnableScreen的实现如下所示:
  1. public class WindowManagerService extends IWindowManager.Stub   
  2.         implements Watchdog.Monitor {   
  3.     ......   
  4.    
  5.     public void performEnableScreen() {   
  6.         synchronized(mWindowMap) {   
  7.             if (mDisplayEnabled) {   
  8.                 return;   
  9.             }   
  10.             if (!mSystemBooted) {   
  11.                 return;   
  12.             }   
  13.    
  14.             ......   
  15.    
  16.             mDisplayEnabled = true;   
  17.             ......   
  18.    
  19.             try {   
  20.                 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");   
  21.                 if (surfaceFlinger != null) {   
  22.                     //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");   
  23.                     Parcel data = Parcel.obtain();   
  24.                     data.writeInterfaceToken("android.ui.ISurfaceComposer");   
  25.                     surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,   
  26.                                             data, null, 0);   
  27.                     data.recycle();   
  28.                 }   
  29.             } catch (RemoteException ex) {   
  30.                 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");   
  31.             }   
  32.         }   
  33.    
  34.         ......   
  35.     }   
  36.    
  37.     ......   
  38. }   

        WindowManagerService类的另外一个成员变量mDisplayEnabled用来描述WindowManagerService是否已经初始化过系统的屏幕了,只有当它的值等于false,并且系统已经完成启动,即WindowManagerService类的成员变量mSystemBooted等于true的情况下,WindowManagerService类的成员函数performEnableScreen才通知SurfaceFlinger服务停止显示开机动画。
        注意,WindowManagerService类的成员函数performEnableScreen是通过一个类型为IBinder.FIRST_CALL_TRANSACTION的进程间通信请求来通知SurfaceFlinger服务停止显示开机动画的。
        在SurfaceFlinger服务,类型为IBinder.FIRST_CALL_TRANSACTION的进程间通信请求被定义为停止显示开机动画的请求,如下所示:
  1. class BnSurfaceComposer : public BnInterface<ISurfaceComposer>  
  2. {  
  3. public:  
  4.     enum {  
  5.         // Note: BOOT_FINISHED must remain this value, it is called from  
  6.         // Java by ActivityManagerService.  
  7.         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,  
  8.         ......  
  9.     };  
  10.   
  11.     virtual status_t    onTransact( uint32_t code,  
  12.                                     const Parcel& data,  
  13.                                     Parcel* reply,  
  14.                                     uint32_t flags = 0);  
  15. };  
        BnSurfaceComposer类定义在文件frameworks/base/include/surfaceflinger/ISurfaceComposer.h中,它是SurfaceFlinger服务所要继承的Binder本地对象类,其中。当SurfaceFlinger服务接收到类型为IBinder::FIRST_CALL_TRANSACTION,即类型为BOOT_FINISHED的进程间通信请求时,它就会将该请求交给它的成员函数bootFinished来处理。
        SurfaceFlinger服务的成员函数bootFinished实现在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中,如下所示:
  1. void SurfaceFlinger::bootFinished()  
  2. {  
  3.     const nsecs_t now = systemTime();  
  4.     const nsecs_t duration = now - mBootTime;  
  5.     LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );  
  6.     mBootFinished = true;  
  7.     property_set("ctl.stop", "bootanim");  
  8. }  
       这个函数主要就是将系统属性“ctl.stop”的值设置为“bootanim”。前面提到,每当有一个系统属性发生变化时,init进程就会被唤醒,并且调用运行在它里面的函数handle_property_set_fd来处理这个系统属性变化事件。在我们这个场景中,由于被改变的系统属性的名称是以"ctl."开头的,即被改变的系统属性是一个控制类型的属性,因此,接下来函数handle_property_set_fd又会调用另外一个函数handle_control_message来处理该系统属性变化事件。
       函数handle_control_message实现在文件system/core/init/init.c中,如下所示:
  1. void handle_control_message(const char *msg, const char *arg)  
  2. {  
  3.     if (!strcmp(msg,"start")) {  
  4.         msg_start(arg);  
  5.     } else if (!strcmp(msg,"stop")) {  
  6.         msg_stop(arg);  
  7.     } else {  
  8.         ERROR("unknown control msg '%s'\n", msg);  
  9.     }  
  10. }  
       从前面的调用过程可以知道,参数msg和arg的值分别等于"stop"和“bootanim”,这表示要停止执行名称为“bootanim”的服务,这是通过调用函数msg_stop来实现的。   
       函数msg_stop也是实现在文件system/core/init/init.c中,如下所示:
  1. static void msg_stop(const char *name)  
  2. {  
  3.     struct service *svc = service_find_by_name(name);  
  4.   
  5.     if (svc) {  
  6.         service_stop(svc);  
  7.     } else {  
  8.         ERROR("no such service '%s'\n", name);  
  9.     }  
  10. }  
       这个函数首先调用函数service_find_by_name来找到名称等于name,即“bootanim”的服务,然后再调用函数service_stop来停止这个服务。
       前面提到,名称为“bootanim”的服务对应的应用程序即为/system/bin/bootanimation。因此,停止名称为“bootanim”的服务即为停止执行应用程序/system/bin/bootanimation,而当应用程序/system/bin/bootanimation停止执行的时候,开机动画就会停止显示了。
       至此,Android系统的三个开机画面的显示过程就分析完成了。通过这个三个开机画面的显示过程分析,我们学习到:
       1. 在内核层,系统屏幕是使用一个称为帧缓冲区的硬件设备来描述的,而用户空间的应用程序可以通过设备文件/dev/fb0或者/dev/graphics/fb0来操作这个硬件设备。实际上,帧缓冲区本身并不是一个真正的硬件,它只不过是对显卡的一个抽象表示,不过,我们通过访帧缓冲区就可以间接地操作显卡内存以及显卡中的其它寄存器。
       2. OpenGL是通过EGL接口来渲染屏幕,而EGL接口是通过ANativeWindow类来间接地渲染屏幕的。我们可以将ANativeWindow类理解成一个Android系统的本地窗口类,即相当于是Windows系统中的窗口句柄概念,它最终是通过文件/dev/fb0或者/dev/graphics/fb0来渲染屏幕的。
       3. init进程在启动的过程中,会将另外一个ueventd进程也启动起来。ueventd进程对应的可执行文件与init进程对应的可执行文件均为/init,不过ueventd进程主要负责处理内核发出的uevent事件,即负责管理系统中的设备文件。
       4. 每当我们设置一个系统属性的时候,init进程都会接收到一个系统属性变化事件。当发生变化的系统属性的名称等于“ctl.start”或者“ctl.stop”,那么实际上是向init进程发出一个启动或者停止服务的命令。
       前面第1点和第2点的知识是与Android系统的UI实现相关的,而后面第3点和第4点是两个额外获得的知识点。
       本文的目的并不是单纯为了介绍Android系统的开机画面,而是希望能够以Android系统的开机画面来作为切入点来分析Android系统的UI实现。在后面的文章中,我们就会根据本文所涉及到的知识点,来展开分析Android系统的UI实现,敬请关注。

Android系统的开机画面显示过程分析(13)相关推荐

  1. Android系统的开机画面显示过程分析

    提到Android系统的UI,我们最先接触到的便是系统在启动过程中所出现的画面了.Android系统在启动的过程中,最多可以出现三个画面,每一个画面都用来描述一个不同的启动阶段.本文将详细分析这三个开 ...

  2. Android系统的开机画面显示过程分析(8)

         3. 第三个开机画面的显示过程         第三个开机画面是由应用程序bootanimation来负责显示的.应用程序bootanimation在启动脚本init.rc中被配置成了一个服 ...

  3. 安卓linux开机画面,Android系统的开机画面显示过程分析(1)

    好几个月都没有更新过博客了,从今天开始,老罗将尝试对Android系统的UI实现作一个系统的分析,也算是落实之前所作出的承诺.提到Android系统的UI,我们最先接触到的便是系统在启动过程中所出现的 ...

  4. Android系统的开机画面显示过程分析(5)

    2. 第二个开机画面的显示过程       由于第二个开机画面是在init进程启动的过程中显示的,因此,我们就从init进程的入口函数main开始分析第二个开机画面的显示过程.       init进 ...

  5. Android系统手机开机画面各个阶段代码执行流程分析(Part2)

    3. 第三个开机画面的显示过程 第三个开机画面是由应用程序bootanimation来负责显示的.应用程序bootanimation在启动脚本init.rc中被配置成了一个服务,如下所示: servi ...

  6. Android系统定制开机logo和开机动画

    定制开机logo和开机动画 开机logo 开机动画 bootanimation.zip 生成zip文件 添加新的开机动画 开机logo MTK ASOP中lk阶段的logo是开机后的第一个界面,也被称 ...

  7. Android系统手机开机画面各个阶段代码执行流程分析(Part1)

    提到Android系统的UI,我们最先接触到的便是系统在启动过程中所出现的画面了.Android系统在启动的过程中,最多可以出现三个画面,每一个画面都用来描述一个不同的启动阶段.本文将详细分析这三个开 ...

  8. android系统修改开机动画

    前提须知 开机动画是bootanimation.zip文件,包含part0和desc.txt两部分. part0文件夹:存放与屏幕分辨率相同的图片,图片命名数字递增. desc.txt文本:配置图片如 ...

  9. Android系统Surface机制的SurfaceFlinger服务的启动过程分析

    在前面一篇文章中,我们简要介绍了Android系统Surface机制中的SurfaceFlinger服务.SurfaceFlinger服务是在System进程中启动的,并且负责统一管理设备的帧缓冲区. ...

最新文章

  1. [转]Hyper-V功能大跃进 或引发市场洗牌
  2. java 根据客户端重定向_JavaWeb【1.4HttpServletResponse类、重定向】
  3. vue怎么让接口带上cookie_在Vue中怎么使用cookie 之 vue-cookies
  4. android中虚拟程序停止,为什么我的在虚拟机运行后出现应用程序停止运行
  5. 最新emlog媒体范美化版v6.3.1
  6. ServiceComb java-chassis和CSE java-chassis的区别
  7. [转]OAuth 认证步骤
  8. Microsoft SQL Server 2000 索引碎片整理最佳实践(上)
  9. NSCT(Nonsubsampled Contourlet变换)
  10. 给CentOS 6.7 配置IP地址
  11. 【工具封装】不用 for 循环, 教你如何向MySQL数据库批量插入数据
  12. [读书][笔记]WINDOWS PE权威指南《零》PE基础
  13. try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后
  14. Titan学习笔记-初识
  15. Java中的委托和继承(Delegation and Inheritance)
  16. 华为智慧搜索 v9.1.2.300
  17. 11B Cosmos 平台手写笔画显示比较滞后问题
  18. 给90后发了面试邀请,可他却因为“薪酬面议”拒绝了
  19. 加强顶层设计 推动数字出版高质量发展
  20. 延时函数delay与sleep有什么区别呢?

热门文章

  1. 经典算法面试题目-置矩阵行列元素为0(1.7)
  2. 处理JSON格式的数据
  3. erlang的lists笔记
  4. 插入ts以及判断列是否存在(支持多数据库)
  5. 使用代码生成建立可扩展序列化器(上)
  6. YCbCr与YUV的区别
  7. SSE命令示例代码(算术、逻辑、比较)
  8. 使用OpenGL Shader实现放大镜效果
  9. Android 卡片翻转动画效果
  10. 美国的机器人军团要来了吗?