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");
相关文章
相关标签/搜索