一、Android bootanim 启动过程:
1、bootanim 服务在 init.rc 文件里面有描述:
service bootanim /system/bin/bootanimation
class main
user graphics
group graphics
disabled // <---- 一开始要 disable ,原因如下
oneshot
if(mBootVideo)
{
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->checkService(String16("media.player"));
if (binder != 0)
break;
ALOGD("media player not published, waiting...");
usleep(500000); // 0.5 s
} while (true);
mPlayer = new MediaPlayer();
if(mPlayer == NULL)
{
ALOGE("MediaPlayer is null!");
return BAD_VALUE;
}
//mMediaPlayerControl = mp;
mPlayer->setDataSource(USER_BOOTVIDEO_FILE, NULL);
Parcel* _parcel = new Parcel;
mPlayer->setParameter(100, *_parcel);
mPlayer->setVideoSurfaceTexture(s->getSurfaceTexture());
mPlayer->prepare();
mPlayer->start();
// If the device has encryption turned on or is in process
// of being encrypted we show the encrypted boot animation.
char decrypt[PROPERTY_VALUE_MAX];
property_get("vold.decrypt", decrypt, "");
// For infinite parts, we've now played them at least once, so perhaps exit
if(exitPending() && !part.count)
break; // 退出刷新动画的循环
/*
bool Thread::exitPending() const
{
Mutex::Autolock _l(mLock);
return mExitPending;
}
*/
}
// free the textures for this part
if (part.count != 1) {
for (int j=0 ; j<fcount ; j++) {
const Animation::Frame& frame(part.frames[j]);
glDeleteTextures(1, &frame.tid);
}
}
}
Sytem进程在启动SurfaceFlinger服务的过程中,首先会创建一个SurfaceFlinger实例,然后再将这个实例注册到
Service Manager中去。在注册的过程,前面创建的SurfaceFlinger实例会被一个sp指针引用,当一个对象第一次被
智能指针引用的时候,这个对象的成员函数onFirstRef就会被调用。由于SurfaceFlinger重写了父类RefBase的成员
函数onFirstRef,因此,在注册SurfaceFlinger服务的过程中,将会调用SurfaceFlinger类的成员函数onFirstRef().
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
// Wait for the main thread to be done with its initialization
mReadyToRunBarrier.wait(); // 用于同步线程
}
SurfaceFlinger类继承了Thread类,当它的成员函数run被调用的时候,系统就会创建一个新的线程。这个线程在第
一次运行之前,会调用SurfaceFlinger类的成员函数readyToRun来通知SurfaceFlinger,它准备就绪了。当这个线程
准备就绪之后,它就会循环执行SurfaceFlinger类的成员函数threadLoop,直到这个成员函数的返回值等于false为止。
status_t SurfaceFlinger::readyToRun() -> void SurfaceFlinger::startBootAnim()
status_t SurfaceFlinger::readyToRun()
{
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
// initialize EGL for the default display
// 初始化 EGL 获取默认的显示设备
// 配置硬件方式
// ...
// We're now ready to accept clients...
mReadyToRunBarrier.open();
// set initial conditions (e.g. unblank default device)
initializeDisplays();
// wait patiently for the window manager death
const String16 name("window");
sp<IBinder> window(defaultServiceManager()->getService(name));
if (window != 0) {
window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
}
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
// <--- 这里设置 为 1,刚刚好符合第四步所描述的,void BootAnimation::checkExit()
property_set("service.bootanim.exit", "1");
char value[PROPERTY_VALUE_MAX];
if((srcFp = fopen(srcPath, "r")) == NULL){
ALOGE("#####cannot open file %s to read#####",srcPath);
}
else
{
char type[4] = "";
char format[4] = "";
int len1 = 4;
int len2 = 4;
fgets(type,len1,srcFp);
fgets(format,len2,srcFp);
int outtype = atoi(type);
int outformat = atoi(format);
ALOGD("####read file %s, outtype is %d, outformat is %d",srcPath,outtype,outformat);
if(outtype >= 0 && outformat >= 0){
setDisplayProp(DISPLAY_CMD_SETDISPPARA,0,outtype,outformat);
setDisplayProp(DISPLAY_CMD_SETDISPMODE,DISPLAY_MODE_SINGLE_VAR_FE,0,0);
}
fclose(srcFp);
}
}