鸿蒙OS 开机动画流程
开机动画的启动与竣事foundation\graphic\graphic_2d\graphic.cfg
"services" : [{
"name" : "render_service",
"path" : ["/system/bin/render_service"],
"critical" : ,
"importance" : -20,
"uid" : "graphics",
"gid" : ["system", "tp_host"],
"caps" : ["SYS_NICE"],
"permission" : [
"ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT"
],
"secon" : "u:r:render_service:s0",
"jobs" : {
"on-restart" : "services:restartrender_service"
},
"once" : 0
}, {
"name" : "bootanimation",
"path" : ["/system/bin/bootanimation"],
"bootevents": [
"bootevent.bootanimation.started",
"bootevent.bootanimation.finished"
],
"importance" : -20,
"once" : 1,
"uid" : "graphics",
"gid" : ["graphics"],
"secon" : "u:r:bootanimation:s0"
}
]
foundation\graphic\graphic_2d\frameworks\bootanimation\src\main.cpp
int main(int argc, const char *argv[])
{
LOGI("main enter");
//等待renderService的初始化
WaitRenderServiceInit();
Rosen::RSInterfaces& interface = Rosen::RSInterfaces::GetInstance();
Rosen::ScreenId defaultId = interface.GetDefaultScreenId();
if (defaultId == Rosen::INVALID_SCREEN_ID) {
LOGE("invalid default screen id, return");
return 0;
}
//获取屏的宽高
Rosen::RSScreenModeInfo modeinfo = interface.GetScreenActiveMode(defaultId);
int screenWidth = modeinfo.GetScreenWidth();
int screenHeight = modeinfo.GetScreenHeight();
//运行动画
BootAnimation bootAnimation;
bootAnimation.Run(defaultId, screenWidth, screenHeight);
LOGI("main exit");
return 0;
}
foundation\graphic\graphic_2d\frameworks\bootanimation\src\boot_animation.cpp
void BootAnimation::Run(Rosen::ScreenId id, int screenWidth, int screenHeight)
{
LOGI("Run enter");
//解析配置的json文件
animationConfig_.ParserCustomCfgFile();
Rosen::RSInterfaces& interface = Rosen::RSInterfaces::GetInstance();
//根据配置的json文件中是否配置了其他的屏,获取对应宽高
if (animationConfig_.GetRotateScreenId() >= 0) {
id = interface.GetActiveScreenId();
LOGI("GetActiveScreenId: " BPUBU64 "", id);
Rosen::RSScreenModeInfo modeinfo = interface.GetScreenActiveMode(id);
screenWidth = modeinfo.GetScreenWidth();
screenHeight = modeinfo.GetScreenHeight();
LOGI("screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
if (id > 0) {
LOGI("SetScreenPowerStatus POWER_STATUS_OFF_FAKE: 0");
interface.SetScreenPowerStatus(0, Rosen::ScreenPowerStatus::POWER_STATUS_OFF_FAKE);
LOGI("SetScreenPowerStatus POWER_STATUS_ON: " BPUBU64 "", id);
interface.SetScreenPowerStatus(id, Rosen::ScreenPowerStatus::POWER_STATUS_ON);
}
} else if (interface.GetScreenPowerStatus(id) != Rosen::ScreenPowerStatus::POWER_STATUS_ON) {
//设置屏幕状态为点亮状态
interface.SetScreenPowerStatus(id, Rosen::ScreenPowerStatus::POWER_STATUS_ON);
}
//异步处理init,playvideo,playsound
runner_ = AppExecFwk::EventRunner::Create(false);
mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
mainHandler_->PostTask(std::bind(&BootAnimation::Init, this, id, screenWidth, screenHeight));
LOGI("PostTask Init");
#ifdef PLAYER_FRAMEWORK_ENABLE
//根据配置设置是否支持开机视频
if (animationConfig_.IsBootVideoEnabled()) {
mainHandler_->PostTask(std::bind(&BootAnimation::PlayVideo, this));
LOGI("PostTask PlayVideo");
} else {
mainHandler_->PostTask(std::bind(&BootAnimation::PlaySound, this));
LOGI("PostTask PlaySound");
}
#else
LOGI("player_framework part is not enabled.");
#endif
runner_->Run();
}
......
void BootAnimation::Init(Rosen::ScreenId defaultId, int32_t width, int32_t height)
{
defaultId_ = defaultId;
windowWidth_ = width;
windowHeight_ = height;
LOGI("Init enter, width: %{public}d, height: %{public}d", width, height);
//计算中心点坐标
InitPicCoordinates();
//配置RSDisplayNodeConfig的displayOffset,frame,bounds等参数
InitRsDisplayNode();
//配置RSSurfaceNodeConfig的PositionZ,FrameGravity,BackgroundColor,bounds等参数
InitRsSurfaceNode();
#ifdef PLAYER_FRAMEWORK_ENABLE
//根据配置设置是否支持开机视频
if (animationConfig_.IsBootVideoEnabled()) {
LOGI("Init end");
return;
}
#endif
//使用序列帧动画播放
LOGI("Playing boot animation using sequence frames.");
//投票bootevent.bootanimation.started 为true
system::SetParameter("bootevent.bootanimation.started", "true");
auto& rsClient = OHOS::Rosen::RSInterfaces::GetInstance();
while (receiver_ == nullptr) {
//获取VSyncReceiver的代理端,用于显示
receiver_ = rsClient.CreateVSyncReceiver("BootAnimation", mainHandler_);
}
VsyncError ret = receiver_->Init();
if (ret) {
LOGE("vsync receiver init failed: %{public}d", ret);
PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner_));
return;
}
//初始化renderSurface
InitRsSurface();
ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::preload");
//通过读取配置的图片动画,获取对应的大小
if (animationConfig_.ReadPicZipFile(imageVector_, freq_)) {
imgVecSize_ = imageVector_.size();
} else {
LOGE("Read PicZipFile failed");
PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner_));
return;
}
ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
OHOS::Rosen::VSyncReceiver::FrameCallback fcb = {
.userData_ = this,
//显示回调
.callback_ = std::bind(&BootAnimation::OnVsync, this),
};
//开机动画的送显帧率
int32_t changefreq = static_cast<int32_t>((1000.0 / freq_) / 16);
ret = receiver_->SetVSyncRate(fcb, changefreq);
if (ret) {
PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner_));
LOGE("SetVSyncRate failed: %{public}d %{public}d %{public}d", ret, freq_, changefreq);
return;
} else {
LOGI("SetVSyncRate success: %{public}d %{public}d", freq_, changefreq);
}
}
......
void BootAnimation::OnVsync()
{
//绘制
PostTask(std::bind(&BootAnimation::Draw, this));
}
......
void BootAnimation::Draw()
{
if (picCurNo_ < (imgVecSize_ - 1)) {
picCurNo_ = picCurNo_ + 1;
} else {
//开机动画播放完成退出
CheckExitAnimation();
return;
}
ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::Draw RequestFrame");
auto frame = rsSurface_->RequestFrame(windowWidth_, windowHeight_);
if (frame == nullptr) {
LOGE("Draw frame is nullptr");
return;
}
ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
#ifdef NEW_RENDER_CONTEXT
if (rsSurface_ == nullptr) {
LOGE("rsSurface is nullptr");
return;
}
auto canvas = rsSurface_->GetCanvas();
//开始绘制
OnDraw(canvas, picCurNo_);
ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::Draw FlushFrame");
rsSurface_->FlushFrame();
ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
#else
framePtr_ = std::move(frame);
auto canvas = framePtr_->GetCanvas();
OnDraw(canvas, picCurNo_);
ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::Draw FlushFrame");
rsSurface_->FlushFrame(framePtr_);
ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
#endif
}
.....
void BootAnimation::OnDraw(SkCanvas* canvas, int32_t curNo)
{
if (canvas == nullptr) {
LOGE("OnDraw canvas is nullptr");
return;
}
if (curNo > (imgVecSize_ - 1) || curNo < 0) {
return;
}
std::shared_ptr<ImageStruct> imgstruct = imageVector_;
sk_sp<SkImage> image = imgstruct->imageData;
ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::OnDraw in drawRect");
SkPaint backPaint;
backPaint.setColor(SK_ColorBLACK);
canvas->drawRect(SkRect::MakeXYWH(0.0, 0.0, windowWidth_, windowHeight_), backPaint);
ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::OnDraw in drawImageRect");
SkPaint paint;
SkRect rect;
rect.setXYWH(pointX_, pointY_, realWidth_, realHeight_);
canvas->drawImageRect(image.get(), rect, SkSamplingOptions(), &paint);
ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
}
......
bool BootAnimation::CheckExitAnimation()
{
if (!isAnimationEnd_) {
LOGI("Boot animation is end");
//投票
system::SetParameter("bootevent.bootanimation.finished", "true");
isAnimationEnd_ = true;
}
//检查所有的投票事件是否都已经完成
std::string bootEventCompleted = system::GetParameter("bootevent.boot.completed", "false");
if (bootEventCompleted == "true") {
mainHandler_->PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner_));
LOGI("Read bootevent.boot.completed is true");
return true;
}
return false;
}
#ifdef PLAYER_FRAMEWORK_ENABLE
void BootAnimation::PlaySound()
{
LOGI("PlaySound start");
bool bootSoundEnabled = BootAnimationUtils::GetBootAnimationSoundEnabled();
if (bootSoundEnabled == true) {
LOGI("PlaySound read bootSoundEnabled is true");
if (soundPlayer_ == nullptr) {
soundPlayer_ = Media::PlayerFactory::CreatePlayer();
}
std::string uri = animationConfig_.GetSoundUrl();
soundPlayer_->SetSource(uri);
soundPlayer_->SetLooping(false);
soundPlayer_->PrepareAsync();
soundPlayer_->Play();
}
LOGI("PlaySound end");
}
#endif
#ifdef PLAYER_FRAMEWORK_ENABLE
void BootAnimation::PlayVideo()
{
LOGI("PlayVideo start w:%{public}d h:%{public}d", windowWidth_, windowHeight_);
if (!animationConfig_.IsBootVideoEnabled()) {
return;
}
fcb_ = {
.userData_ = this,
.callback_ = std::bind(&BootAnimation::CloseVideoPlayer, this),
};
LOGI("PlayVideo setVideo screenId:%{public}d", (int32_t)defaultId_);
bootVideoPlayer_ = std::make_shared<BootVideoPlayer>();
bootVideoPlayer_->SetVideoPath(
defaultId_ == 0 ? animationConfig_.GetBootVideoPath() : animationConfig_.GetBootExtraVideoPath());
bootVideoPlayer_->SetPlayerSurface(rsSurfaceNode_ ? rsSurfaceNode_->GetSurface() : nullptr);
bootVideoPlayer_->SetCallback(&fcb_);
if (!bootVideoPlayer_->PlayVideo()) {
LOGE("Play video failed.");
CloseVideoPlayer();
}
}
#endif
foundation\graphic\graphic_2d\frameworks\bootanimation\src\boot_animationconfig.cpp
void BootAnimationConfig::ParserCustomCfgFile()
{
//读取对应的开机播放的图片动画,视频,音频
std::string file = GetCustomCfgFile();
if (!file.empty()) {
//解析出对应的文件地址
ReadCustomBootConfig(file, custConfig_);
//根据配置设置是否支持开机视频
CheckBootVideoEnabled();
}
}
......
std::string BootAnimationConfig::GetCustomCfgFile()
{
std::string ret = "";
char buf = {0};
//获取文件etc/bootanimation/bootanimation_custom_config.json
char *pfile = GetOneCfgFile(BOOT_CUSTOM_PATHSUFFIX.c_str(), buf, MAX_PATH_LEN);
if (pfile != nullptr) {
LOGI("get one filePath:%{public}s", pfile);
return pfile;
} else {
LOGI("not find %{public}s", BOOT_CUSTOM_PATHSUFFIX.c_str());
}
return ret;
}
bootanimation_custom_config.json文件如下
设置了对应的开机播放的图片动画,视频,音频
{
"cust.bootanimation.pics": "/sys_prod/etc/bootanimation/cust_bootpic.zip",
"cust.bootanimation.sounds": "/sys_prod/etc/bootanimation/cust_bootsound.wav",
"cust.bootanimation.video": "/sys_prod/etc/bootanimation/cust_bootvideo.mp4"
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]