1. system进程在启动过程当中会调用SurfaceFlinger类的静态成员函数instantiate来启动SurfaceFlinger服务。启动过程当中,首先建立一个SurfaceFlinger实例,此实例会被一个SP 指针引用。当一个对象被一个智能指针第一次引用的时候,该类的onFirstRef方法将被调用:android
void SurfaceFlinger::onFirstRef() { mEventQueue.init(this); }
2. SurfaceFlinger类继承自Thread类,所以当它的run方法被调用的时候,系统就会建立一个新的线程。这个线程在第一次运行以前,会调用该类的readToRun方法。而且调用mReadyToRunBarrier的wait让主线程(init进程)处于等待状态。readyToRun方法会进行主屏幕以及openGL库的初始化,完成后会调用mReadyToRunBarrier的open来唤醒主线程。紧接着开始启动动画:bash
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<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); // create the boot animation object sp<BootAnimation> boot = new BootAnimation(); IPCThreadState::self()->joinThreadPool(); } return 0; }
4. 因为BootAnimation对象在显示动画时须要与SurfaceFlinger服务通讯,所以,应用程序bootanimation就须要启动一个binder线程池。当一个BootAnimation对象第一个被一个只能智能指针引用的时候,BootAnimation的onFirstRef方法将被调用:oop
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默认的开机动画this
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");