1. system进程在启动过程中会调用SurfaceFlinger类的静态成员函数instantiate来启动SurfaceFlinger服务。启动过程中,首先创建一个SurfaceFlinger实例,此实例会被一个SP 指针引用。当一个对象被一个智能指针第一次引用的时候,该类的onFirstRef方法将被调用:
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
2. SurfaceFlinger类继承自Thread类,因此当它的run方法被调用的时候,系统就会创建一个新的线程。这个线程在第一次运行之前,会调用该类的readToRun方法。并且调用mReadyToRunBarrier的wait让主线程(init进程)处于等待状态。readyToRun方法会进行主屏幕以及openGL库的初始化,完成后会调用mReadyToRunBarrier的open来唤醒主线程。紧接着开始启动动画:
void SurfaceFlinger::startBootAnim() {
// start boot animation
property_set("service.bootanim.exit", "0");
property_set("ctl.start", "bootanim");
}
3. 当系统属性发生改变时,init进程就会收到一个系统属性变化的通知,这个通知最终由在init进程中的函数handle_property_set_fd来处理。由于此系统属性是以ctrl.开头的控制类型的属性,因此当属性变更时会启动一个名字为“bootanim”的服务。通过这个名字,可以找到对应的应用程序为/system/bin/bootanimation。于是应用程序的入口函数main函数将被调用:
int main()
{
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.nobootanimation", value, "0");
int noBootAnimation = atoi(value);
ALOGI_IF(noBootAnimation, "boot animation disabled");
if (!noBootAnimation) {
sp proc(ProcessState::self());
ProcessState::self()->startThreadPool();
// create the boot animation object
sp boot = new BootAnimation();
IPCThreadState::self()->joinThreadPool();
}
return 0;
}
4. 由于BootAnimation对象在显示动画时需要与SurfaceFlinger服务通信,因此,应用程序bootanimation就需要启动一个binder线程池。当一个BootAnimation对象第一个被一个只能智能指针引用的时候,BootAnimation的onFirstRef方法将被调用:
void BootAnimation::onFirstRef() {
status_t err = mSession->linkToComposerDeath(this);
ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
if (err == NO_ERROR) {
run("BootAnimation", PRIORITY_DISPLAY);
}
}
在init.rc中声明的服务此时将被启动
service bootanim /system/bin/bootanimation
class core
user graphics
group graphics audio
disabled
oneshot
5. BootAnimation类继承自Thread类,当它的run方法被调用时,将会调用该类的readToRun方法。在/data/local/bootanimation.zip、/system/media/bootanimation.zip、/system/media/bootanimation-encrypted.zip(加密动画)查找是否存在相应的动画压缩包,若存在则使用用户自定义的动画,否则使用android默认的开机动画
status_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets();
.......
.......
.......
if (encryptedAnimation && (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0)) {
mZipFileName = SYSTEM_ENCRYPTED_BOOTANIMATION_FILE;
}
else if (access(OEM_BOOTANIMATION_FILE, R_OK) == 0) {
mZipFileName = OEM_BOOTANIMATION_FILE;
}
else if (access(USER_BOOTANIMATION_FILE, R_OK) == 0) {
mZipFileName = USER_BOOTANIMATION_FILE;
}
else if (access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) {
mZipFileName = SYSTEM_BOOTANIMATION_FILE;
}
return NO_ERROR;
}
6. 当线程准备好运行时,其threadLoop方法会被调用,完整动画zip的解析显示。
7. 停止动画。当系统启动完成时,会调用SurfaceFlinger中的bootFinished方法,通过设定系统参数的方式结束动画的播放
property_set("service.bootanim.exit", "1");