一、Android bootanim 啟動(dòng)過(guò)程:
1、bootanim 服務(wù)在 init.rc 文件里面有描述:
service bootanim /system/bin/bootanimation
class main
user graphics
group graphics
disabled // <---- 一開(kāi)始要 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; // 退出刷新動(dòng)畫(huà)的循環(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進(jìn)程在啟動(dòng)SurfaceFlinger服務(wù)的過(guò)程中,首先會(huì)創(chuàng)建一個(gè)SurfaceFlinger實(shí)例,然后再將這個(gè)實(shí)例注冊(cè)到
Service Manager中去。在注冊(cè)的過(guò)程,前面創(chuàng)建的SurfaceFlinger實(shí)例會(huì)被一個(gè)sp指針引用,當(dāng)一個(gè)對(duì)象第一次被
智能指針引用的時(shí)候,這個(gè)對(duì)象的成員函數(shù)onFirstRef就會(huì)被調(diào)用。由于SurfaceFlinger重寫(xiě)了父類RefBase的成員
函數(shù)onFirstRef,因此,在注冊(cè)SurfaceFlinger服務(wù)的過(guò)程中,將會(huì)調(diào)用SurfaceFlinger類的成員函數(shù)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類,當(dāng)它的成員函數(shù)run被調(diào)用的時(shí)候,系統(tǒng)就會(huì)創(chuàng)建一個(gè)新的線程。這個(gè)線程在第
一次運(yùn)行之前,會(huì)調(diào)用SurfaceFlinger類的成員函數(shù)readyToRun來(lái)通知SurfaceFlinger,它準(zhǔn)備就緒了。當(dāng)這個(gè)線程
準(zhǔn)備就緒之后,它就會(huì)循環(huán)執(zhí)行SurfaceFlinger類的成員函數(shù)threadLoop,直到這個(gè)成員函數(shù)的返回值等于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 獲取默認(rèn)的顯示設(shè)備
// 配置硬件方式
// ...
// 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.
// <--- 這里設(shè)置 為 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);
}
}