其实与android开机动画启动流程基本一模一样。除了文件换了位置,就是添加了一些函数。
内核起来后会启动第一个进程,即init进程。
init进程会根据init.rc配置启动surfaceflinger进程。
service surfaceflinger /system/bin/surfaceflinger
class main
user system
group graphics drmrpc
onrestart restart zygote
surfaceflinger进程便启动了,跟着就会跑进程的main()函数。
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int argc, char** argv) {
....
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();//创建surfaceflinger服务实例
....
flinger->init();
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//注册到service manager里
// run in this thread
flinger->run();//开跑
return 0;
}
首先new一个SurfaceFlinger实例,然后init,然后run
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
.....
// start boot animation
startBootAnim();//开始播放动画
}
初始化graphics之后,就调用startBootAnim()播放开机动画。
void SurfaceFlinger::startBootAnim() {
// start boot animation
mBootFinished = false;
property_set("service.bootanim.exit", "0");//这个会有bootanimation进程周期检测,=1退出动画
property_set("ctl.start", "bootanim");//通过ctl.start命令启动bootanim
}
把service.bootanim.exit属性设为0,这个属性bootanimation进程里会周期检查,=1时就退出动画,这里=0表示要播放动画。
后面通过ctl.start的命令启动bootanim进程,动画就开始播放了。
下面来到bootanimation的实现
frameworks/base/cmds/bootanimation/bootanimation_main.cpp
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
// create the boot animation object
sp<BootAnimation> boot = new BootAnimation();//创建BootAnimation实例
IPCThreadState::self()->joinThreadPool();//binder线程池,与surfaceflinger通信用的。
}
return 0;
}
new一个BootAnimation实例,然后建个binder线程池,因为BootAnimation在显示动画时要与SurfaceFlinger服务进程通信,所以要启个binder线程池。
frameworks/base/cmds/bootanimation/BootAnimation.cpp
BootAnimation::BootAnimation() : Thread(false)
{
mSession = new SurfaceComposerClient();//创建一个对象
}
创建实例时,构造函数就会被调用,new一个SurfaceComposerClient实例,他是用来与surfaceflinger通信的
void BootAnimation::onFirstRef() {
status_t err = mSession->linkToComposerDeath(this);//注册surfaceflinger死亡消息的通知书
ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
if (err == NO_ERROR) {
run("BootAnimation", PRIORITY_DISPLAY);//开跑
}
}
如下,收到通知后就退出动画了,因为surfaceflinger都挂掉了,播放不了了。
void BootAnimation::binderDied(const wp<IBinder>& who)
{
// woah, surfaceflinger died!
ALOGD("SurfaceFlinger died, exiting...");
// calling requestExit() is not enough here because the Surface code
// might be blocked on a condition variable that will never be updated.
kill( getpid(), SIGKILL );//收到surfaceflinger死亡的消息,好吧自己也跟着去了。
requestExit();
}
另一个函数run()在BootAnimation的父类Thead里,用来创建一个线程并跑起来。
父类
system/core/libutils/Threads.cpp
status_t