一、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; // 退出刷新動畫的循環(huán)
/*
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服務的過程中,首先會創(chuàng)建一個SurfaceFlinger實例,然后再將這個實例注冊到
Service Manager中去。在注冊的過程,前面創(chuàng)建的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被調用的時候,系統(tǒng)就會創(chuàng)建一個新的線程。這個線程在第
一次運行之前,會調用SurfaceFlinger類的成員函數readyToRun來通知SurfaceFlinger,它準備就緒了。當這個線程
準備就緒之后,它就會循環(huán)執(zhí)行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);
}
}