Android bootanim開機動畫啓動流程

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");
相關文章
相關標籤/搜索