函数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. "unknown control msg '%s'\n", msg);  
9.     }  
10. }


       控制类型的系统属性的名称是以"ctl."开头,并且是以“start”或者“stop”结尾的,其中,“start”表示要启动某一个服务,而“stop”表示要停止某一个服务,它们是分别通过函数msg_start和msg_stop来实现的。由于当前发生变化的系统属性是以“start”来结尾的,因此,接下来就会调用函数msg_start来启动一个名称为“bootanim”的服务。 



 



       函数msg_start实现在文件system/core/init/init.c中,如下所示:


1. static void msg_start(const char *name)  
2. {  
3. struct service *svc;  
4. char *tmp = NULL;  
5. char *args = NULL;  
6.   
7. if (!strchr(name, ':'))  
8.         svc = service_find_by_name(name);  
9. else {  
10.         tmp = strdup(name);  
11. ':');  
12. '\0';  
13.         args++;  
14.   
15.         svc = service_find_by_name(tmp);  
16.     }  
17.   
18. if (svc) {  
19.         service_start(svc, args);  
20. else {  
21. "no such service '%s'\n", name);  
22.     }  
23. if (tmp)  
24.         free(tmp);  
25. }


       参数name的值等于“bootanim”,它用来描述一个服务名称。这个函数首先调用函数service_find_by_name来找到名称等于“bootanim”的服务的信息,这些信息保存在一个service结构体svc中,接着再调用另外一个函数service_start来将对应的应用程序启动起来。



 



      从前面的内容可以知道,名称等于“bootanim”的服务所对应的应用程序为/system/bin/bootanimation,这个应用程序实现在frameworks/base/cmds/bootanimation目录中,其中,应用程序入口函数main是实现在frameworks/base/cmds/bootanimation/bootanimation_main.cpp中的,如下所示:

1. int main(int argc, char** argv)  
2. {  
3. #if defined(HAVE_PTHREADS)  
4.     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);  
5. #endif  
6.   
7. char value[PROPERTY_VALUE_MAX];  
8. "debug.sf.nobootanimation", value, "0");  
9. int noBootAnimation = atoi(value);  
10. "boot animation disabled");  
11. if (!noBootAnimation) {  
12.   
13.         sp<ProcessState> proc(ProcessState::self());  
14.         ProcessState::self()->startThreadPool();  
15.   
16. // create the boot animation object  
17. new BootAnimation();  
18.   
19.         IPCThreadState::self()->joinThreadPool();  
20.   
21.     }  
22. return 0;  
23. }


       这个函数首先检查系统属性“debug.sf.nobootnimaition”的值是否不等于0。如果不等于的话,那么接下来就会启动一个Binder线程池,并且创建一个BootAnimation对象。这个BootAnimation对象就是用来显示第三个开机画面的。由于BootAnimation对象在显示第三个开机画面的过程中,需要与SurfaceFlinger服务通信,因此,应用程序bootanimation就需要启动一个Binder线程池。



 



       BootAnimation类间接地继承了RefBase类,并且重写了RefBase类的成员函数onFirstRef,因此,当一个BootAnimation对象第一次被智能指针引用的时,这个BootAnimation对象的成员函数onFirstRef就会被调用。



       BootAnimation类的成员函数onFirstRef实现在文件frameworks/base/cmds/bootanimation/BootAnimation.cpp中,如下所示:


1. void BootAnimation::onFirstRef() {  
2. this);  
3. "linkToComposerDeath failed (%s) ", strerror(-err));  
4. if (err == NO_ERROR) {  
5. "BootAnimation", PRIORITY_DISPLAY);  
6.     }  
7. }


       mSession是BootAnimation类的一个成员变量,它的类型为SurfaceComposerClient,是用来和SurfaceFlinger执行Binder进程间通信的,它是在BootAnimation类的构造函数中创建的,如下所示:


1. BootAnimation::BootAnimation() : Thread(false)  
2. {  
3. new SurfaceComposerClient();  
4. }


         SurfaceComposerClient类内部有一个实现了ISurfaceComposerClient接口的Binder代理对象mClient,这个Binder代理对象引用了SurfaceFlinger服务,SurfaceComposerClient类就是通过它来和SurfaceFlinger服务通信的。



         回到BootAnimation类的成员函数onFirstRef中,由于BootAnimation类引用了SurfaceFlinger服务,因此,当SurfaceFlinger服务意外死亡时,BootAnimation类就需要得到通知,这是通过调用成员变量mSession的成员函数linkToComposerDeath来注册SurfaceFlinger服务的死亡接收通知来实现的。



 



        BootAnimation类继承了Thread类,因此,当BootAnimation类的成员函数onFirstRef调用了父类Thread的成员函数run之后,系统就会创建一个线程,这个线程在第一次运行之前,会调用BootAnimation类的成员函数readyToRun来执行一些初始化工作,后面再调用BootAnimation类的成员函数htreadLoop来显示第三个开机画面。