海思android随笔之bootvideo与bootanimation流程分析

一. 启动入口

1. bootvideo

rc文件配置位于Android/device/hisilicon/bigfish/etc/initrc/init.bigfish.rc

......
service bootvideo /system/bin/bootvideo
    priority -20
    class core
    user system
    group system graphics input root
    oneshot

on init
    start bootvideo
    # Set log level
    loglevel 3

    # Create cgroup mount point for memory
    mount tmpfs none /sys/fs/cgroup mode=0750,uid=0,gid=1000
    mkdir /sys/fs/cgroup/memory 0750 root system
    mount cgroup none /sys/fs/cgroup/memory memory
......

2. bootanimation

rc配置位于Android/frameworks/base/cmds/bootanimation/bootanim.rc

service bootanim /system/bin/bootanimation
    class core animation
    user graphics
    group graphics audio
    disabled
    oneshot
    writepid /dev/stune/top-app/tasks

这里rc文件是通过Android/frameworks/base/cmds/bootanimation/Android.mk里的

......
LOCAL_INIT_RC := bootanim.rc
......

编译到/system/etc/init目录中的,然后是由Android/system/core/init/init.cpp里的LoadBootScripts解析

static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);

    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/init.rc");
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
        if (!parser.ParseConfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.ParseConfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
    } else {
        parser.ParseConfig(bootscript);
    }
}

所以,从这里可以看出bootvideo服务启动是比bootanimation早的

二. bootvideo

code位于Android/device/hisilicon/bigfish/frameworks/hibootvideo,结构如下:

主函数入口在src/bootvideo_main.cpp里,这里会先判断prop.service.bootop.type属性是否等于bootvideo,如果不等于,则会直接退出bootvideo;否则进入HI_StartPlayBootvideo

int main(int argc, char **argv)
{
    int count = 0;
    const int waitPropCount = 100; // try to wait prop service 1 sec
    const int waitPropDelay = 10000; // 10ms
    char bootop[PROPERTY_VALUE_MAX] = {0};
    while (!property_get("prop.service.bootop.type", bootop, nullptr)) {
        // bootvideo starts at on init process, property may not load ready,
        // try to wait a while...
        count++;
        if (count >= waitPropCount) {
            break;
        }
        usleep(waitPropDelay);
    }
    if (strncmp(bootop, "bootvideo", strlen("bootvideo"))) {
        return 0;
    }

    ALOGD("bootvideo START!");
    HI_StartPlayBootvideo();

    return 0;
}

海思的code结构很清晰,这里就不做详细解读了,有code的同学自己看下就很清晰明了了

bootvideo大概流程如下:

HI_BootvideoInit --> HI_InitBootVideoPlayer --> HI_BootPlayVideo --> HiBootvideoUI --> HI_CheckIfExitPlay

三. bootanimation

code位于Android/frameworks/base/cmds/bootanimation,结构如下:

 主函数入口在bootanimation_main.cpp里,这里海思也会先判断prop.service.bootop.type属性是否等于bootanim,如果不等于,则会直接退出bootanimation。否则创建BootAnimation线程

int main()
{
    //HISILICON add begin
    //support bootvide||quickplay||bootanimation
    char bootop[PROPERTY_VALUE_MAX];
    property_get("prop.service.bootop.type", bootop, "bootanim");
    if(strncmp(bootop, "bootanim", 8) != 0) {
        ALOGV("bootop %s enabled", bootop);
        return 0;
    }
    //HISILICON add end

    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);

    bool noBootAnimation = bootAnimationDisabled();
    ALOGI_IF(noBootAnimation,  "boot animation disabled");
    if (!noBootAnimation) {

        sp<ProcessState> proc(ProcessState::self());
        ProcessState::self()->startThreadPool();

        waitForSurfaceFlinger();

        // create the boot animation object
        sp<BootAnimation> boot = new BootAnimation(new AudioAnimationCallbacks());
        ALOGV("Boot animation set up. Joining pool.");

        IPCThreadState::self()->joinThreadPool();
    }
    ALOGV("Boot animation exit");
    return 0;
}

framework的Thread,它是一个while循环。

创建线程时,会sp和wp一次线程本身。

如果是第一次执行会运行线程的readyToRun()方法,再执行threadLoop(),否则,直接运行threadLoop()。

threadLoop()方法有返回值,如果threadLoop()返回false的时候,线程会做清理工作,然后退出while循环,结束运行。

原生的bootanimation会先判断对应路径下的开机动画zip文件是否存在,如果不存在则跑android()图片显示流程

bool BootAnimation::android()
{
    ALOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
            elapsedRealtime());
    initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
    initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");

    mCallbacks->init({});

    // clear screen
......

如果存在zip文件,则走movie()压缩zip显示流程

bool BootAnimation::movie()
{
    Animation* animation = loadAnimation(mZipFileName);
    if (animation == NULL)
        return false;
......

四. debug

1. 根据上面分析可知,如果我们想直接调试机器的bootanitiom或bootvideo,可以修改prop.service.bootop.type属性。这个属性在机器里的/vendor/build.prop里,修改完重启即可生效

2. 对应bootanitiom或bootvideo的文件路径下需要存放资源

bootanimation默认路径读取的是ro.prop.bootanim.path=/atv/bootvideo/bootanimation.zip的值

......
    char customBootanimationFile[PROPERTY_VALUE_MAX];
    property_get("ro.prop.bootanim.path", customBootanimationFile, "");

    bool encryptedAnimation = atoi(decrypt) != 0 ||
        !strcmp("trigger_restart_min_framework", decrypt);

    if (!mShuttingDown && encryptedAnimation) {
        static const char* encryptedBootFiles[] =
            {PRODUCT_ENCRYPTED_BOOTANIMATION_FILE, SYSTEM_ENCRYPTED_BOOTANIMATION_FILE};
        for (const char* f : encryptedBootFiles) {
            if (access(f, R_OK) == 0) {
                mZipFileName = f;
                return NO_ERROR;
            }
        }
    }
    static const char* bootFiles[] =
        {customBootanimationFile, PRODUCT_BOOTANIMATION_FILE, OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE};
    static const char* shutdownFiles[] =
        {"/atv/bootvideo/shutdownanimation.zip", PRODUCT_SHUTDOWNANIMATION_FILE, OEM_SHUTDOWNANIMATION_FILE, SYSTEM_SHUTDOWNANIMATION_FILE};

    for (const char* f : (!mShuttingDown ? bootFiles : shutdownFiles)) {
        if (access(f, R_OK) == 0) {
            mZipFileName = f;
            return NO_ERROR;
        }
    }
......

bootvideo路径是通过system/etc/config.xml配置的

HI_BootvideoGetPath --> HiBootvideoConfiger::GetFeature --> HiBootvideoConfiger::GetPropertyValue --> 解析xml文件的path1和path2路径

<?xml version='1.0'?>
<config>
  <bootvideo>
    <property key="path1" value="/vendor/media/bootvideo.mp4"/>
    <property key="path2" value="/data/local/data/bootvideosnd.mp4"/>
    <property key="strPath1" value="/data/local/data/strbootvideo.mp4"/>
    <property key="strPath2" value="/data/local/data/strbootvideosnd.mp4"/>
    <property key="isEnableInput" enable="true"/>
    <property key="isEnableUI" enable="true">
      <property key="isEnableCountDown" enable="false" language="en"/>
      <property key="isEnableVolumeBar" enable="true"/>
      <property key="isEnableVolumeMute" enable="true"/>
    </property>
  </bootvideo>
</config>

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值