Android10处理Android字样开机动画翻转一次的问题
  R3jekIqJDwNw 2023年11月02日 52 0

一、背景说明

  • 系统版本:Android 10(Q)
  • 厂商:高通
  • 问题描述:系统开机出现Android资源动画时翻转一次,先倒屏再正屏

Android10处理Android字样开机动画翻转一次的问题_Android

二、分析及解决

1、检查persist.panel.orientation

从现象来看是android动画播放时屏幕方向发生了改变,于是检查屏幕方向关联属性persist.panel.orientation

$getprop persist.panel.orientation
90   //我的设备90°为正屏,270°为倒屏

再检查system.prop

$cat system/build.prop
...
persist.panel.orientation=90
...

说明方向属性没毛病

2、代码分析

Android字样图片资源位于: frameworks\base\core\res\assets\images\android-logo-mask.png frameworks\base\core\res\assets\images\android-logo-shine.png frameworks\base\core\res\assets\images\clock_font.png Android字样开机动画显示代码实现位于: frameworks\base\cmds\bootanimation\BootAnimation.cpp

bool BootAnimation::threadLoop()
{
    bool r;
    // We have no bootanimation file, so we use the stock android logo
    // animation.
    if (mZipFileName.isEmpty()) {
        r = android();    //android字样动画
    } else {
        r = movie();    //zip开机帧动画
    }
    ...
}
...
bool BootAnimation::android()
{
    SLOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
            elapsedRealtime());
    initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
    initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");

    mCallbacks->init({});

    // clear screen  清除屏幕
    glShadeModel(GL_FLAT);
    glDisable(GL_DITHER);
    glDisable(GL_SCISSOR_TEST);
    glClearColor(0,0,0,1);
    glClear(GL_COLOR_BUFFER_BIT);
    eglSwapBuffers(mDisplay, mSurface);

    glEnable(GL_TEXTURE_2D);
    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    const GLint xc = (mWidth  - mAndroid[0].w) / 2;
    const GLint yc = (mHeight - mAndroid[0].h) / 2;
    const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h);

    glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(),
            updateRect.height());

    // Blend state
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    const nsecs_t startTime = systemTime();
    do {
        nsecs_t now = systemTime();
        double time = now - startTime;
        float t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w;
        GLint offset = (1 - (t - floorf(t))) * mAndroid[1].w;
        GLint x = xc - offset;

        glDisable(GL_SCISSOR_TEST);
        glClear(GL_COLOR_BUFFER_BIT);

        glEnable(GL_SCISSOR_TEST);
        glDisable(GL_BLEND);
        glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
        glDrawTexiOES(x,                 yc, 0, mAndroid[1].w, mAndroid[1].h);
        glDrawTexiOES(x + mAndroid[1].w, yc, 0, mAndroid[1].w, mAndroid[1].h);

        glEnable(GL_BLEND);
        glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
        glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h);

        EGLBoolean res = eglSwapBuffers(mDisplay, mSurface);
        if (res == EGL_FALSE)
            break;

        // 12fps: don't animate too fast to preserve CPU
        const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
        if (sleepTime > 0)
            usleep(sleepTime);

        checkExit();
    } while (!exitPending());

    glDeleteTextures(1, &mAndroid[0].name);
    glDeleteTextures(1, &mAndroid[1].name);
    return false;
}

分析android播放实现未找到与屏幕方向旋转相关的代码,于是搜索persist.panel.orientation

status_t BootAnimation::readyToRun() {
    //add by xxf
    char value[PROPERTY_VALUE_MAX];
    property_get("persist.panel.orientation", value,"0");  //从属性persist.panel.orientation获取屏幕方向
    int orient= atoi(value) / 90;
    if(orient== 1 || orient == 3) {
        is_land = true;//横屏显示,正屏或倒屏
    }
    //add by xxf
    mAssets.addDefaultAssets();

    mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();
    if (mDisplayToken == nullptr)
        return -1;

    DisplayInfo dinfo;
    status_t status = SurfaceComposerClient::getDisplayInfo(mDisplayToken, &dinfo);
    if (status)
        return -1;

    //add by xxf
    // create the native surface
    sp<SurfaceControl> control;
    if(is_land){
         control= session()->createSurface(String8("BootAnimation"),
            dinfo.h, dinfo.w, PIXEL_FORMAT_RGB_565);
    }else{
         control = session()->createSurface(String8("BootAnimation"),
            dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
    }
    SurfaceComposerClient::Transaction t;
    if(is_land){
        t.setDisplayProjection(mDisplayToken, DisplayState::eOrientation270, Rect(dinfo.h, dinfo.w), Rect(dinfo.h, dinfo.w));  //设置显示参数
        t.apply();
    }
    //add by xxf
 ...
}

从这里可以看出,屏幕方向强行设置为了270°,故倒屏了,再后续流程中拿到了正确的orientation故又正屏了,改动如下:

if(is_land){
        //Modify Start by mart!nhu to correct oriention in bootanimation
        //t.setDisplayProjection(mDisplayToken, DisplayState::eOrientation270, Rect(dinfo.h, dinfo.w), Rect(dinfo.h, dinfo.w));
        t.setDisplayProjection(mDisplayToken, orient == DisplayState::eOrientation90 ? DisplayState::eOrientation90 : DisplayState::eOrientation270, Rect(dinfo.h, dinfo.w), Rect(dinfo.h, dinfo.w));
        //Modify End by mart!nhu to correct oriention in bootanimation
        t.apply();
    }

3、措施验证

编译bootanimation模块

mmm frameworks/base/cmds/bootanimation/

将生成的libbootanimation.so替换至平台中,并重启

adb root;adb remount;adb push \\wsl$\Ubuntu-18.04\home\mart!nhu\AOSP_An10\out\target\product\xxx\obj\SHARED_LIBRARIES\libbootanimation_intermediates\libbootanimation.so system/lib64/libbootanimation.so;adb shell sync;adb reboot

验证OK,设置270° 验证同样显示正常

开机android动画,zip帧动画,视频具体播放实现待有空了再梳理下,敬请期待~

总结

通过问题现象首先排除系统属性是否异常,确认无误后检查代码实现流程,关注屏幕方向的关键参数设置,中间可埋log定位。最终导入措施,替换so文件验证有效。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  R3jekIqJDwNw   2023年11月12日   21   0   0 android关机
R3jekIqJDwNw