一. 启动入口
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>