开机动画进程流程

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");
}
Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐