开机动画相关

开机动画社区代码默认为视频播放,想要测试图片播放可以修改源码或者增加配置文件使其播放图片,一般建议是增加配置文件
代码修改如下

路径: foundation/graphic/graphic_2d/frameworks/bootanimation/include/boot_animation_operation.h
将 if (IsBootVideoEnabled(config)) 里面的条件写为 false 即可

    void BootAnimationOperation::StartEventHandler(const BootAnimationConfig& config)
    {
        LOGI("StartEventHandler");
        runner_ = AppExecFwk::EventRunner::Create(false);
        mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
        // mainHandler_->PostTask([this] { this->InitRsDisplayNode(); });
        mainHandler_->PostTask([this, &config] { this->InitRsSurfaceNode(config.rotateDegree); });
        mainHandler_->PostTask([this] { this->StopBootAnimation(); }, duration_);
        advertisement = config.advertisement_status;
        rotateDegree = config.rotateDegree;
    #ifdef PLAYER_FRAMEWORK_ENABLE
        if (IsBootVideoEnabled(config)) {
            mainHandler_->PostTask([this, &config] { this->PlayVideo(config.videoDefaultPath); });
            if (ADVERTISEMENTPRESENT == advertisement)
            {
                mainHandler_->PostTask([this] { this->RegisterInput(); });
            }
            runner_->Run();
            LOGI("runner run has ended.");
            return;
        } else {
            mainHandler_->PostTask([this, &config] { this->PlaySound(config.soundPath); });
        }
    #else
        LOGI("player framework is disabled");
    #endif
        mainHandler_->PostTask([this, &config] { this->PlayPicture(config.picZipPath); });
        if (ADVERTISEMENTPRESENT == advertisement)
        {
            mainHandler_->PostTask([this] { this->RegisterInput(); });
        }
        runner_->Run();
        LOGI("runner run has ended.");
    }

一、增加配置文件使其图片视频播放

  1. hisi默认将视频播放关闭了,需要修改宏

    vendor/hisilicon/hispark_hi3751v352/config.jsongraphic_2d_feature_bootanimation_video_enable = false改为true

  2. 本地新建bootanimation_custom_config.json文件,内容如下:

测试图片播放:

{
    "cust.bootanimation.pics": "/system/etc/graphic/bootpic.zip",
    "cust.bootanimation.sounds": "/system/etc/graphic/bootsound.wav"
}

测试视频播放:

{
    "cust.bootanimation.video": "/system/etc/graphic/bootvideo.mp4"
}
  1. 创建文件夹/system/etc/bootanimation,将bootanimation_custom_config.json推入此目录下。
  2. 执行hdc shell bootanimation播放开机动画

二、开机动画旋转

bootanimation_custom_config.json文件中添加以下内容控制旋转,degree为旋转角度。

    "cust.bootanimation.rotate.screenid": "0",
    "cust.bootanimation.rotate.degree": "90"

由于图层是在原始角度下绘制好了之后再进行旋转的,超出屏幕的部分并没有被绘制,旋转之后如果有超出屏幕的部分也不会显示,所以旋转后会出现只显示中间部分的现象。使用旋转功能需要确保旋转前后的动画均在屏幕范围内,即动画资源分辨率要不大于屏幕内所能显示的最大正方形的大小。

目标效果:开机动画按degree的角度旋转。

三、开机动画资源替换

在 /system/etc/graphic/ 下 有 bootvideo.mp4 和 bootpic.zip文件,分别对应默认开机动画的视频和图片资源,可以替换成自己想要的资源重命名为 bootvideo.mp4 和 bootpic.zip 即可

四、开机动画相关问题案例以及解决方法

无法播放开机动画(显示黑屏),内核logo后黑屏一会直接进入 launcher

  1. 开机动画资源问题
    查看日志没有明显报错,或者播放视频资源的时候显示创建 mediaplayer 失败后退出。
    这种情况可以替换下开机动画资源,可以下载社区上的开机动画资源替换
  1. 视频播放 视频音轨问题导致无法播放
    日志会有 创建 mediaplaer失败的打印,明显可以看到 获取 SA:3002服务失败,这种情况是视频音轨有问题导致
    音频服务获取异常,可以替换资源或者在获取sa服务的地方增加重试次数(次操作会拉长开机总体耗时),代码如下
    foundation/systemabilitymgr/samgr/frameworks/native/source/system_ability_manager_proxy.cpp

     sptr<IRemoteObject> SystemAbilityManagerProxy::GetSystemAbilityWrapper(int32_t systemAbilityId, const string& deviceId)
     {
         if (!CheckInputSysAbilityId(systemAbilityId)) {
             HILOGW("GetSaWrap SA invalid:%{public}d!", systemAbilityId);
             return nullptr;
         }
    
         bool isExist = false;
         int32_t timeout = RETRY_TIME_OUT_NUMBER;
         HILOGD("GetSaWrap:Waiting for SA:%{public}d, ", systemAbilityId);
         do {
             sptr<IRemoteObject> svc;
             int32_t errCode = ERR_NONE;
             if (deviceId.empty()) {
                 svc = CheckSystemAbility(systemAbilityId, isExist, errCode);
                 if (errCode == ERR_PERMISSION_DENIED) {
                     HILOGE("GetSaWrap SA:%{public}d selinux denied", systemAbilityId);
                     return nullptr;
                 }
                 if (!isExist) {
                     HILOGD("%{public}s:SA:%{public}d is not exist", __func__, systemAbilityId);
                 }
             } else {
                 svc = CheckSystemAbility(systemAbilityId, deviceId, errCode);
                 if (errCode == ERR_PERMISSION_DENIED) {
                     HILOGE("GetSaWrap SA:%{public}d deviceId selinux denied", systemAbilityId);
                     return nullptr;
                 }
             }
    
             if (svc != nullptr) {
                 return svc;
             }
             if (timeout > 0) {
                 usleep(SLEEP_ONE_MILLI_SECOND_TIME * SLEEP_INTERVAL_TIME);
             }
         } while (timeout--);
         HILOGE("GetSaWrap SA:%{public}d not start", systemAbilityId);
         return nullptr;
     }
    

    在这里加一个逻辑,如果是 3002 服务,将它的timeout从默认的6次增加到 20(尝试后得出的次数)后可以正常获取到服务

视频播放开机动画闪屏,图片播放正常,且进桌面后手动执行开机动画,视频播放不响应

 这种情况下,所有的日志正常,开机动画流程正常,画面闪烁,而且内核log一直不消失

 这种情况查看 layer 信息发现也是正常的,就比较难定位了。后来尝试关闭 g0图层的显示发现可以正常显示开机动画了,才得知此项目上
 视频播放走的不是系统的图形层,而是特殊的 vo层,闪屏是因为 内核logo的背景是白色的,会透出 vo视频层的画面。
 解决方法有两种,一种是内核logo修改下,让它最后刷一帧黑色背景。但是这种修改无法解决在桌面手动执行开机动画无法显示的问题(但是考虑到正常场景不会有进入系统后再播放开机动画,所以可以采用这个办法)
 二是在开机动画里面加一下执行逻辑,在开始播放视频的时候手动去隐藏掉 图形层g0,在结束播放的时候在解除隐藏即可。代码如下
 foundation/graphic/graphic_2d/frameworks/bootanimation/src/boot_video_player.cpp
    void VideoPlayerCallback::OnInfo(Media::PlayerOnInfoType type, int32_t extra, const Media::Format &infoBody)
    {
        switch (type) {
            case Media::INFO_TYPE_SEEKDONE:
                LOGI("PlayerCallback: OnSeekDone currentPositon is: %{public}d", extra);
                break;
            case Media::INFO_TYPE_SPEEDDONE:
                LOGI("PlayerCallback: SpeedDone");
                break;
            case Media::INFO_TYPE_BITRATEDONE:
                LOGI("PlayerCallback: BitRateDone");
                break;
            case Media::INFO_TYPE_EOS: {
                LOGI("PlayerCallback: OnEndOfStream isLooping is: %{public}d", extra);
                boot_->StopVideo();
                break;
            }
            case Media::INFO_TYPE_BUFFERING_UPDATE:
                LOGI("PlayerCallback: Buffering Update");
                break;
            case Media::INFO_TYPE_BITRATE_COLLECT:
                LOGI("PlayerCallback: Bitrate Collect");
                break;
            case Media::INFO_TYPE_STATE_CHANGE:
                LOGI("PlayerCallback: State Change, current state is: %{public}d", extra);
                if (Media::PlayerStates::PLAYER_PREPARED == extra) {
                    int32_t width = boot_->GetMediaPlayer()->GetVideoWidth();
                    int32_t height = boot_->GetMediaPlayer()->GetVideoHeight();
                    LOGI("UpdateBound[%{public}d %{public}d]", width, height);
                    boot_->UpdateBound(width, height);
                    LOGI("Begin to play");
                    std::system("echo hide > /proc/msp/gfbg0");
                
                    boot_->GetMediaPlayer()->Play();
                }
                break;
            case Media::INFO_TYPE_POSITION_UPDATE: {
                LOGD("PlayerCallback: Position Update");
                break;
            }
            case Media::INFO_TYPE_MESSAGE:
                LOGI("PlayerCallback: OnMessage is: %{public}d", extra);
                if (!system::GetBoolParameter(BOOT_ANIMATION_STARTED, false)) {
                    system::SetParameter(BOOT_ANIMATION_STARTED, "true");
                }
                break;
            case Media::INFO_TYPE_RESOLUTION_CHANGE:
                LOGI("PlayerCallback: Resolution Change");
                break;
            case Media::INFO_TYPE_VOLUME_CHANGE:
                LOGI("PlayerCallback: Volume Changed");
                break;
            default:
                LOGI("PlayerCallback: Default");
                break;
        }
    }
使用 std::system("echo hide > /proc/msp/gfbg0"); 手动隐藏

foundation/graphic/graphic_2d/frameworks/bootanimation/src/boot_animation_strategy.cpp
    bool BootAnimationStrategy::CheckExitAnimation()
{
    if (!isAnimationEnd_) {
        LOGI("boot animation is end");
        system::SetParameter(BOOT_ANIMATION_FINISHED, "true");
        isAnimationEnd_ = true;
    }
    bool bootEventCompleted = system::GetBoolParameter(BOOT_COMPLETED, false);
    if (bootEventCompleted) {
        LOGI("read boot completed is true");
        std::system("echo show > /proc/msp/gfbg0");
        return true;
    }
    return false;
}
std::system("echo show > /proc/msp/gfbg0");退出的时候释放

开机动画卡在最后一帧没进系统,查看进程发现开机动画没退出

这种情况下参考上面我们将图层解除隐藏的那块代码,开机动画退出的条件是 bootcomplete,找一下投票事件是谁没有准备好,和开机动画流程没有关系
一般是launcher有问题导致的
在hilog里面搜索 bootevent 查看投票事件

黑屏

  1. 排查是不是有双屏异显代码,可以接另一个屏幕看看有没有画面。
  2. 屏幕是否上电/背光下发是否成功,搜索关键日志 "lcd_kit_o|lcd_kit_set_backlight|lcd_kit_check_reg_report_dsm|dpu_gfxdev_blank", 其中primary是内屏black mode: 0上电, 4下电, 1假下电
  3. dump下rs tree 看下displayNode surfaceNode 是否都在树上

播放过程中卡顿、花屏、马赛克等

先排查资源问题
进系统后用视频播放器播放同样的资源播放,是否有同样的现象,找media相关的报错排查。不是开机动画这块的问题
Logo

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

更多推荐