开机动画的启动
在init.rc 中 会启动core组,Bootanim和surfaceFlinger 划归到了core
on boot
# Start standard binderized HAL daemons
class_start hal
class_start core //启动划分到core组
Bootanim.rc
//frameworks/base/cmds/bootanimation/bootanim.rc
service bootanim /system/bin/bootanimation
class core animation
user graphics
group graphics audio
disabled //禁止自启动 init 不会启动他
oneshot//运行一次
ioprio rt 0
task_profiles MaxPerformance
surfaceFlinger.rc
//frameworks/native/services/surfaceflinger/surfaceflinger.rc
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
capabilities SYS_NICE
onrestart restart zygote
task_profiles HighPerformance
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
init 会将 surfaceFlinger 启动起来 (如果sf不起来就没办法播放动画了)
//frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
//省略。。。
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
flinger->init();
//将sf 加入到ServiceManager里面去
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
//省略。。。
flinger->run();
}
SurfaceFlinger
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() {
//省略
if (mStartPropertySetThread->Start() != NO_ERROR) {
ALOGE("Run StartPropertySetThread failed!");
}
}
StartPropertySetThread
//native/services/surfaceflinger/StartPropertySetThread.cpp
bool StartPropertySetThread::threadLoop() {
property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");
//设置 开机动画属性
property_set("service.bootanim.exit", "0");
property_set("service.bootanim.progress", "0");
// Start BootAnimation if not started
property_set("ctl.start", "bootanim");
// Exit immediately
return false;
}
//这里的属性变化 会导致 init 进程接收到系统属性变化通知 然后启动bootanim //property_service.c
//https://blog.csdn.net/u010223349/article/details/8876232
进入动画相关
//frameworks/base/cmds/bootanimation/bootanimation_main.cpp
int main()
{
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();
// 构建启动BootAnimation
sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks());
waitForSurfaceFlinger();
boot->run("BootAnimation", PRIORITY_DISPLAY);
ALOGV("Boot animation set up. Joining pool.");
IPCThreadState::self()->joinThreadPool();
}
return 0;
}
BootAnimation
初始化构建
//frameworks/base/cmds/bootanimation/BootAnimation.cpp
//继承了 IBinder::DeathRecipient ::RefBase
/**
基本可以分为几步 构建 BootAnimation
1.链接sf onFirstRef
查找路径加载地址, findBootAnimationFile
加载动画路径,loadAnimation
解析出来压缩包中的动画基础属性 parseAnimationDesc
完成构建 BootAnimation
*/
// Sp智能指针 RefBase 则在构建完成后会回调onFirstRef
void BootAnimation::onFirstRef() {
//链接sf
status_t err = mSession->linkToComposerDeath(this);
if (err == NO_ERROR) {
preloadAnimation();//预加载动画
}
}
bool BootAnimation::preloadAnimation() {
//查找动画路径
findBootAnimationFile();
if (!mZipFileName.isEmpty()) {
//查找到对应路径 开始加载动画 会构建一个 BootAnimation对象 然后开始加载
mAnimation = loadAnimation(mZipFileName);
return (mAnimation != nullptr);
}
return false;
}
//查找开机动画路径
void BootAnimation::findBootAnimationFile(){
//构建 动画file 路径组 会挨个遍历该路径下有没有对应文件
static const std::vector<std::string> bootFiles = {
APEX_BOOTANIMATION_FILE, playDarkAnim ? PRODUCT_BOOTANIMATION_DARK_FILE : PRODUCT_BOOTANIMATION_FILE,
OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE
};
//省略
findBootAnimationFileInternal(bootFiles);//主要就是给 mZipFileName 赋值
}
开始动画
bool BootAnimation::threadLoop() {
if (mZipFileName.isEmpty()) {
result = android();//走android 默认的
} else {
result = movie();//设定
}
}
//android 默认 会不断的进行扫光动画
bool BootAnimation::android() {
//base/core/res/assets/images
initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
// 省略
checkExit();
}
bool BootAnimation::movie() {
//二次检查
if (mAnimation == nullptr) {
mAnimation = loadAnimation(mZipFileName);
}
playAnimation(*mAnimation);//该方法中也会调用 checkExit()
}
//检查是否要退出
void BootAnimation::checkExit() {
static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
char value[PROPERTY_VALUE_MAX];
property_get(EXIT_PROP_NAME, value, "0");//标识是否可以结束开机动画
int exitnow = atoi(value);
if (exitnow) {
requestExit();
}
}
动画结束
//native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::bootFinished() {
//省略
property_set("service.bootanim.exit", "1");
}
压缩文件的配置和注意事项
static const char SYSTEM_BOOTANIMATION_FILE[] = "/system/media/bootanimation.zip";
/**
压缩包一般是有desc.txt 文件 和part0到 partN
desc 文件基本如下
1080 360 60
c 1 0 part0 #ffee00 c c
c 0 0 part1 #ffee00 c c
c 1 0 part2 #ffee00 c c
c 1 1 part3 #ffee00 c c
c 1 0 part4 #ffee00 c c
基础格式是
TYPE +COUNT + PAUSE +PATH [#RGBHEX COLOR]
type 2种类型
p 是可以打断
c 是不能打断 一般都是写c
count 0 是无限循环 直到启动完成
pause 这个part 完成后停留几帧 0就直接干下一个 1就停留一帧的时间
path 就是文件夹目录
bacghex 可选项 背景色 一般不写 练习的时候可以测试下 要写成 rgb 模式
clock 坐标参数 c 就中间
图片配置就是从00001到0000号码你的图片结束。
文件包的放置位置
第一种. 最简单方法直接在打出的包的 (目录)
out/target/product/redfin/system/media
扔自己打好的 bootanimation
第二种 追加复制目录
device/google/redfin/aosp_redfin.mk 里面追加(aosp_redfin 是我的手机版本)
PRODUCT_COPY_FILES += \
device/google/redfin/media/bootanimation.zip:system/media/bootanimation.zip
其实这样是过不去的,因为会报错
选择对应的vendor下 ,比如我的是redfin,新建 media (随便什么名字 )将 bootanimation.zip放进去
在mac 上要查看下 zip 包 要所有人都可读可写 不然解析不出来,
不然就下载专门的压缩工具,选择仅压缩
其实就是读的 自己的系统下的system/media 目录里面的压缩文件
和系统代码下的 system/meida 文件夹没啥关系。
在mac 下可能会报错 需要运行一下
source build/envsetup.sh 之后
禁用 export DISABLE_ARTIFACT_PATH_REQUIREMENTS="true"
*/
文件包的放置位置
第一种. 最简单方法直接在打出的包的 (目录)
out/target/product/redfin/system/media 扔自己打好的 bootanimation
第二种 追加复制目录
device/google/redfin/aosp_redfin.mk 里面追加(aosp_redfin 是我的手机版本)
PRODUCT_COPY_FILES += \ device/google/redfin/media/bootanimation.zip:system/media/bootanimation.zip
其实这样是过不去的,因为会报错。
选择对应的vendor下 ,比如我的是redfin,新建 media (随便什么名字 ),将 bootanimation.zip放进去。
在我的主力机是mac, 要查看下 zip 包, 要所有人都可读可写 不然解析不出来。
不然就下载专门的压缩工具,选择仅压缩。
其实就是读的自己的系统下的system/media 目录里面的压缩文件
和系统代码下的 system/meida 文件夹没啥关系。
在mac 下可能会报错 需要运行一下,
source build/envsetup.sh 之后 ,
禁用 export DISABLE_ARTIFACT_PATH_REQUIREMENTS="true"