一、背景说明
- 系统版本:android 10(q)
- 厂商:高通
- 问题描述:系统开机出现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文件验证有效。
发表评论