开机动画进程流程
开机动画进程流程 bootanimation进程主函数所在路径:foundation/graphic/graphic_2d/frameworks/bootanimation/src/main.cpp int main(int argc, const char *argv[]) { LOGI("main enter"); WaitRenderServiceInit(); Rose
·
开机动画进程流程
bootanimation进程主函数所在路径:foundation/graphic/graphic_2d/frameworks/bootanimation/src/main.cpp
int main(int argc, const char *argv[])
{
LOGI("main enter");
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); // 只会在默认屏显示bootanimation
LOGI("main exit");
return 0;
}
BootAnimation事务运行
void BootAnimation::Run(Rosen::ScreenId id, int screenWidth, int screenHeight)
{
LOGI("Run enter");
animationConfig_.ParserCustomCfgFile(); // 解析配置文件,获取bootanimation图片、音频、视频所在的位置
Rosen::RSInterfaces& interface = Rosen::RSInterfaces::GetInstance();
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);
}
runner_ = AppExecFwk::EventRunner::Create(false); // 创建事件线程队列
mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
mainHandler_->PostTask(std::bind(&BootAnimation::Init, this, id, screenWidth, screenHeight)); // 将Init加入事件队列中
LOGI("PostTask Init");
#ifdef PLAYER_FRAMEWORK_ENABLE
if (animationConfig_.IsBootVideoEnabled()) { // 播放视频
mainHandler_->PostTask(std::bind(&BootAnimation::PlayVideo, this)); // 将PlayVideo加入事件队列中
LOGI("PostTask PlayVideo");
} else { // 播放图片时播放声音
mainHandler_->PostTask(std::bind(&BootAnimation::PlaySound, this)); // 将PlaySound加入事件队列中
LOGI("PostTask PlaySound");
}
#else
LOGI("player_framework part is not enabled.");
#endif
runner_->Run();
}
BootAnimation初始化
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(); // 设置bootanimation在屏幕中显示的位置(以显示器较短的边为边的中间正方形区域)
InitRsDisplayNode();
InitRsSurfaceNode();
#ifdef PLAYER_FRAMEWORK_ENABLE
if (animationConfig_.IsBootVideoEnabled()) { // 如果是播放视频,初始化完成
LOGI("Init end");
return;
}
#endif
LOGI("Playing boot animation using sequence frames."); // 播放图片流程
system::SetParameter("bootevent.bootanimation.started", "true");
auto& rsClient = OHOS::Rosen::RSInterfaces::GetInstance();
while (receiver_ == nullptr) {
receiver_ = rsClient.CreateVSyncReceiver("BootAnimation", mainHandler_);
}
VsyncError ret = receiver_->Init(); // 初始化vsync receiver
if (ret) {
LOGE("vsync receiver init failed: %{public}d", ret);
PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner_));
return;
}
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 = { // 设置vsync回调函数(当接收到vsync信号时draw)
.userData_ = this,
.callback_ = std::bind(&BootAnimation::OnVsync, this),
};
int32_t changefreq = static_cast<int32_t>((1000.0 / freq_) / 16); // 屏幕刷新率:int(1000ms / 30 / 16次) = 2ms/次
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);
}
}
若播放video,则调用BootAnimation::PlayVideo()
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();
}
}
bool BootVideoPlayer::PlayVideo()
{
#ifdef PLAYER_FRAMEWORK_ENABLE
LOGI("PlayVideo begin");
if (mediaPlayer_ == nullptr) {
mediaPlayer_ = Media::PlayerFactory::CreatePlayer(); // 此处创建media播放器,依赖BMS和MemMgr两个SA,如果这两个服务没起来,会阻塞1.2s
}
while (mediaPlayer_ == nullptr) {
LOGE("CreatePlayer fail, mediaPlayer_ is nullptr");
mediaPlayer_ = Media::PlayerFactory::CreatePlayer();
usleep(SLEEP_TIME_US);
}
std::shared_ptr<VideoPlayerCallback> cb = std::make_shared<VideoPlayerCallback>(shared_from_this());
int32_t ret = mediaPlayer_->SetPlayerCallback(cb);
if (ret != 0) {
LOGE("PlayVideo SetPlayerCallback fail, errorCode:%{public}d", ret);
return false;
}
std::string uri = "file:/" + videopath_;
ret = mediaPlayer_->SetSource(uri); // 这里也依赖BMS和MemMgr两个SA,如果这两个服务没起来,会阻塞0.8s
if (ret != 0) {
LOGE("PlayVideo SetSource fail, uri:%{public}s, errorCode:%{public}d", uri.c_str(), ret);
return false;
}
if (surface_ == nullptr) {
LOGE("PlayVideo surface is null");
return false;
}
ret = mediaPlayer_->SetVideoSurface(surface_);
if (ret != 0) {
LOGE("PlayVideo SetVideoSurface fail, errorCode:%{public}d", ret);
return false;
}
SetVideoSound();
ret = mediaPlayer_->Prepare();
if (ret != 0) {
LOGE("PlayVideo Prepare fail, errorCode:%{public}d", ret);
return false;
}
mediaPlayer_->Play(); // 发送播放信号
LOGI("PlayVideo end");
return true;
#else
LOGI("player_framework part is not enabled.");
return false;
#endif
}
若播放图片,则调用BootAnimation::PlaySound()
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(); // 此处创建media播放器,依赖BMS和MemMgr两个SA,如果这两个服务没起来,会阻塞1.2s
}
const int maxFailCount = 3;
for (int i = 0; i < maxFailCount; i++) {
if (soundPlayer_ != nullptr) {
break;
}
soundPlayer_ = Media::PlayerFactory::CreatePlayer();
usleep(SLEEP_TIME_US);
}
if (soundPlayer_ == nullptr) {
LOGE("CreatePlayer fail, soundPlayer_ is nullptr");
return;
}
std::string uri = animationConfig_.GetSoundUrl();
soundPlayer_->SetSource(uri);
soundPlayer_->SetLooping(false);
soundPlayer_->PrepareAsync();
soundPlayer_->Play(); // 发送播放命令,图片动画与声音分别播放,没有同步机制
}
LOGI("PlaySound end");
}
更多推荐
已为社区贡献6条内容
所有评论(0)