拆解步骤
1、app 强制横屏显示,无视 android:screenOrientation=“portrait” 属性
2、开机动画横屏
3、开机logo、关机充电动画横屏
4、RecoveryUI 横屏
11 和 10 的差别不大,app 强制横屏显示 和 开机动画横屏 不太一样其它都一样处理
上代码
##1、app 强制横屏显示
DisplayRotation 显示 mRotation 默认改为 3 (270)
frameworks\base\services\core\java\com\android\server\wm\DisplayRotation.java
// private int mRotation; private int mRotation = 3;//cczheng add for land scap boolean updateRotationUnchecked(boolean forceUpdate) { //cczheng add for app force landscape if (true) { return true; } //add for app force landscape ScreenRotationAnimation screenRotationAnimation; if (!forceUpdate) { if (mDeferredRotationPauseCount > 0) { // Rotation updates have been paused temporarily. Defer the update until // updates have been resumed. if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused."); return false; } ...... @Surface.Rotation int getRotation() { // return mRotation; return 3; }
按照这样修改后,app 默认能横屏显示的,但出现了新 bug, 目测是 11 新增的属性
当按 home 或者 back 最终回到 Launcher3 时会有一个明显的竖屏转成横屏的效果,这个查了几天也没
找到是哪里的原因,目前先挂着,后面有空了再细细看下!!!
系统导航栏位置调整,横屏后 navigationBarPosition 默认在左边
作为平板项目,需要将位置改为底部,直接修改 navigationBarPosition() 返回 NAV_BAR_BOTTOM
frameworks\base\services\core\java\com\android\server\wm\DisplayPolicy.java
@NavigationBarPosition private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) { //cchzneg annotaion for land scape /*if (mNavigationBarCanMove && displayWidth > displayHeight) { if (displayRotation == Surface.ROTATION_270) { return NAV_BAR_LEFT; } else { return NAV_BAR_RIGHT; } }*/ return NAV_BAR_BOTTOM; }
2、开机动画横屏
设置角度为 ui::ROTATION_270
frameworks\base\cmds\bootanimation\BootAnimation.cpp
status_t BootAnimation::readyToRun() { mAssets.addDefaultAssets(); mDisplayToken = SurfaceComposerClient::getInternalDisplayToken(); if (mDisplayToken == nullptr) return NAME_NOT_FOUND; DisplayConfig displayConfig; const status_t error = SurfaceComposerClient::getActiveDisplayConfig(mDisplayToken, &displayConfig); if (error != NO_ERROR) return error; mMaxWidth = android::base::GetIntProperty("ro.surface_flinger.max_graphics_width", 0); mMaxHeight = android::base::GetIntProperty("ro.surface_flinger.max_graphics_height", 0); ui::Size resolution = displayConfig.resolution; resolution = limitSurfaceSize(resolution.width, resolution.height); // create the native surface sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"), resolution.getHeight(), resolution.getWidth(), PIXEL_FORMAT_RGB_565); //resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565); SurfaceComposerClient::Transaction t; //cczheng add for land scap [S] Rect destRect(resolution.getHeight(), resolution.getWidth()); //270 t.setDisplayProjection(mDisplayToken, ui::ROTATION_270, destRect, destRect); //cczheng add for land scap [E] // this guest property specifies multi-display IDs to show the boot animation // multiple ids can be set with comma (,) as separator, for example: // setprop persist.boot.animation.displays 19260422155234049,19261083906282754 Vector<uint64_t> physicalDisplayIds; ..... }
3、开机logo、关机充电动画横屏
开机logo定义屏幕分辨率以对应资源文件夹的位置为
vendor\mediatek\proprietary\bootable\bootloader\lk\project\xxxx.mk 没有则看下面的
device\mediateksample\xxxx\ProjectConfig.mk
mk 中的 BOOT_LOGO = hdplus
对应的资源文件位置在 vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/hdplus
可以看到 hdplus 中都是竖屏的图片,而 wxganl 中已经是横屏的图片
则我们将 BOOT_LOGO 修改为 wxganl 即可
接下来还需要继续修改显示的角度,依旧改成 270,不然会出现花屏的现象
开机第一张图片 uboot 对应显示 phical_screen.rotation = 270
vendor\mediatek\proprietary\bootable\bootloader\lk\platform\mt6765\mt_logo.c
void init_fb_screen() { ..... // in JB2.MP need to allign width and height to 32 ,but jb5.mp needn't phical_screen.needAllign = 1; phical_screen.allignWidth = ALIGN_TO(CFG_DISPLAY_WIDTH, MTK_FB_ALIGNMENT); /* In GB, no need to adjust 180 showing logo ,for fb driver dealing the change */ /* but in JB, need adjust it for screen 180 roration */ phical_screen.need180Adjust = 0; // need sync with chip driver dprintf(INFO, "[lk logo: %s %d]MTK_LCM_PHYSICAL_ROTATION = %s\n",__FUNCTION__,__LINE__, MTK_LCM_PHYSICAL_ROTATION); if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "270", 3)) { phical_screen.rotation = 270; } else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "90", 2)) { phical_screen.rotation = 90; } else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "180", 3) && (phical_screen.need180Adjust == 1)) { phical_screen.rotation = 180; } else { phical_screen.rotation = 270;//cczheng add for land scap } ....
开机第二张图片 kernel 对应显示 phical_screen.rotation = 270
vendor\mediatek\proprietary\external\libshowlogo\charging_animation.cpp
int anim_fb_init(void) { ..... phical_screen.needAllign = 1; phical_screen.need180Adjust = 1; phical_screen.fb_size = fb_size; if (MTK_LOG_ENABLE == 1) { SLOGD("[libshowlogo: %s %d]MTK_LCM_PHYSICAL_ROTATION = %s\n",__FUNCTION__,__LINE__, MTK_LCM_PHYSICAL_ROTATION); } if(0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "270", 3)) { phical_screen.rotation = 270; } else if(0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "90", 2)){ phical_screen.rotation = 90; } else if(0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "180", 3) && (phical_screen.need180Adjust == 1)){ phical_screen.rotation = 180; } else { phical_screen.rotation = 270;//cczheng add for land scap } if (MTK_LOG_ENABLE == 1) { SLOGD("[libshowlogo]phical_screen: width= %d,height= %d,bits_per_pixel =%d,needAllign = %d,allignWidth=%d rotation =%d ,need180Adjust = %d\n", phical_screen.width, phical_screen.height, phical_screen.bits_per_pixel, phical_screen.needAllign, phical_screen.allignWidth, phical_screen.rotation, phical_screen.need180Adjust); SLOGD("[libshowlogo: %s %d]show old animtion= 1, running show_animationm_ver %d\n",__FUNCTION__,__LINE__, show_animationm_ver); SLOGD("[libshowlogo: %s %d]draw_anim_mode = 1, running mode %d\n",__FUNCTION__,__LINE__, draw_anim_mode); } return 0; }
关机充电动画错位问题
如果出现充电动画图片错位的现象,多数都是因为图形绘制点和屏幕尺寸不匹配导致的。可通过调整 cust_display.h 中位置参数
/vendor/mediatek/proprietary/external/libshowlogo/cust_display.h
之前都是通过修改 cust_display.h 文件夹中预置宏定义,10.0 中代码结构做了调整,宏定义都没了,初始化写在了 show_animation_common.c 中,修改 rotation = 3 对调 lcm_width 和 lcm_height,当 lcm_width1280 && lcm_height800 时动画就不错位了,这里根据你自己的分辨率情况自行微调,不过一般系统默认的配置值都是对了
vendor/mediatek/proprietary/external/libshowlogo/show_animation_common.c
/* * Fill resolution structure based on lcd size * */ void init_charging_animation_ui_dimension() { int lcm_width, lcm_height; struct fb_var_screeninfo vinfo; display_fd = open("/dev/graphics/fb0", O_RDONLY); if (display_fd < 0) { SLOGD("[show_animation_common: %s %d]open mtkfb fail...\n",__FUNCTION__,__LINE__); } if (ioctl(display_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) { close(display_fd); SLOGD("[show_animation_common: %s %d]ioctl FBIOGET_VSCREENINFO failed\n",__FUNCTION__,__LINE__); } close(display_fd); lcm_width = vinfo.xres; lcm_height = vinfo.yres; int rotation = getRotation(); rotation = 3; // cczheng add rotation = 3 for charging landscape if (MTK_LOG_ENABLE == 1) { SLOGD("[libshowlogo: %s %d]rotation = %d\n",__FUNCTION__,__LINE__, rotation); } if ((ORIENTATION_270 == rotation)|| (ORIENTATION_90 == rotation)){ lcm_width = vinfo.yres; lcm_height = vinfo.xres; } SLOGD("[show_animation_common: %s %d] lcm_width and lcm_height= %d , %d \n",__FUNCTION__,__LINE__,lcm_width,lcm_height); if((lcm_width == 1080) && (lcm_height == 1920)) { // Special handling for FHD SLOGD("[show_animation_common: %s %d]Inside 1080*1920 \n",__FUNCTION__,__LINE__);
4、RecoveryUI 横屏
RecoveryUI 在9.0 之前安卓源码并没有为我们适配好旋转配置,之前都是通过自己新增 mt_graphic_rotate.cpp 和 mt_graphic_rotate.h 文件来实现旋转。10.0 中代码也进行了较大重构相比之前,只需修改简单配置 rotation 就能旋转为横屏。
rotation = GRRotation::LEFT; 270
rotation = GRRotation::DOWN; 180
rotation = GRRotation::RIGHT; 90
bootable\recovery\minui\graphics.cpp
int gr_init() { ..... gr_backend = backend.release(); int overscan_percent = android::base::GetIntProperty("ro.minui.overscan_percent", 0); overscan_offset_x = gr_draw->width * overscan_percent / 100; overscan_offset_y = gr_draw->height * overscan_percent / 100; gr_flip(); gr_flip(); if (!gr_draw) { printf("gr_init: gr_draw becomes nullptr after gr_flip\n"); return -1; } std::string rotation_str = android::base::GetProperty("ro.minui.default_rotation", "ROTATION_NONE"); if (rotation_str == "ROTATION_RIGHT") { gr_rotate(GRRotation::RIGHT); } else if (rotation_str == "ROTATION_DOWN") { gr_rotate(GRRotation::DOWN); } else if (rotation_str == "ROTATION_LEFT") { gr_rotate(GRRotation::LEFT); } else { // "ROTATION_NONE" or unknown string gr_rotate(GRRotation::NONE); } rotation = GRRotation::LEFT; //cczheng add rotation = 3 for recoveryUI landscape