Android10.0 MTK 平板橫屏方案修改(強制app橫屏 + 開機logo/動畫+關機充電橫屏 + RecoveryUI 橫屏)

拆解步驟

1、app 強制橫屏顯示,無視 android:screenOrientation=“portrait” 屬性

2、開機動畫橫屏

3、開機logo、關機充電動畫橫屏

4、RecoveryUI 橫屏

上代碼

1、app 強制橫屏顯示

DisPlayContent 顯示 mRotation 默認改爲 3 (270)

frameworks\base\services\core\java\com\android\server\wm\DisplayContent.java

/**
     * Current rotation of the display.
     * Constants as per {@link android.view.Surface.Rotation}.
     *
     * @see #updateRotationUnchecked()
     */
    // private int mRotation = 0;
    private int mRotation = 3;//cczheng add for land scap


 boolean updateRotationUnchecked(boolean forceUpdate) {
        ////cczheng add for app force landscape
        if (true) {
            return true;
        }
        ////20200325 pjz 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;
            }

		......

系統導航欄位置調整,橫屏後 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、開機動畫橫屏

DisplayState::eOrientationDefault 修改爲 3

frameworks\base\cmds\bootanimation\BootAnimation.cpp

status_t BootAnimation::readyToRun() {
    mAssets.addDefaultAssets();

    sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
            ISurfaceComposer::eDisplayIdMain));
    DisplayInfo dinfo;
    status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
    if (status)
        return -1;

    //cczheng add for land scap  [S]
    if (2 > 1) {
        int temp = dinfo.h;
        dinfo.h = dinfo.w;
        dinfo.w = temp;
    }
    Rect destRect(dinfo.w, dinfo.h);
    //270
    t.setDisplayProjection(mDisplayToken, 3, destRect, destRect);
    t.apply();
    //cczheng add for land scap  [E]

    /// M: The tablet rotation maybe 90/270 degrees, so set the lcm config for tablet
    /*t.setDisplayProjection(mDisplayToken, DisplayState::eOrientationDefault,
        Rect(dinfo.w, dinfo.h), Rect(dinfo.w, dinfo.h));
    t.apply();*/

    // create the native surface
    sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
            dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);

    t.setLayer(control, 0x40000000)
        .apply();

	.....

}

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 中已經是橫屏的圖片

ubWkNt.png

則我們將 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 = getValue(MTK_LCM_PHYSICAL_ROTATION_PROP, "0");
    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 ((3 == rotation)|| (1 == 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) {
      charg_anim_ui_dimen.cap_left =387;
      charg_anim_ui_dimen.cap_right= 691;
      charg_anim_ui_dimen.num_left=351+84;
      charg_anim_ui_dimen.num_right=435+84;


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

ok,這樣就大功告成了,完美的橫屏適配

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章