函数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来显示第三个开机画面。