Android P 修改Recovery UI方向

本文介绍如何将Android系统的RecoveryUI从默认的竖屏显示修改为横屏显示。通过在bootable/recovery/minui/目录下进行文件的修改与添加,实现了屏幕旋转功能,并详细展示了具体的代码改动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:恢复出厂设置时,recovery UI是竖屏的显示,客户需求需要修改为横屏显示。
实现:
1.bootable/recovery/minui/Android.mk

@@ -18,6 +18,8 @@ LOCAL_PATH := $(call my-dir)
 # ===============================
 include $(CLEAR_VARS)
 
+MEDIATEK_RECOVERY_PATH := vendor/mediatek/proprietary/bootable/recovery
+
 LOCAL_SRC_FILES := \
     events.cpp \
     graphics.cpp \
@@ -25,6 +27,7 @@ LOCAL_SRC_FILES := \
     graphics_drm.cpp \
     graphics_fbdev.cpp \
     resources.cpp \
+    ../../../$(MEDIATEK_RECOVERY_PATH)/minui/mt_graphic_rotate.cpp
 
 LOCAL_WHOLE_STATIC_LIBRARIES := \
     libadf \
@@ -36,7 +39,8 @@ LOCAL_STATIC_LIBRARIES := \
     libbase
 
 LOCAL_CFLAGS := -Wall -Werror
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include\
+                    $(MEDIATEK_RECOVERY_PATH)/minui/include
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 
 LOCAL_MODULE := libminui

2.bootable/recovery/minui/graphics_fbdev.cpp

@@ -27,6 +27,7 @@
 #include <unistd.h>
 
 #include "minui/minui.h"
+#include "mt_graphic_rotate.h"
 
 MinuiBackendFbdev::MinuiBackendFbdev() : gr_draw(nullptr), fb_fd(-1) {}
 
@@ -139,10 +140,12 @@ GRSurface* MinuiBackendFbdev::Init() {
   Blank(false);
 #endif
 
-  return gr_draw;
+  //return gr_draw;
+  return rotate_canvas_get(gr_draw);
 }
 
 GRSurface* MinuiBackendFbdev::Flip() {
+  rotate_surface(gr_draw, rotate_canvas_get(gr_draw));
   if (double_buffered) {
     // Change gr_draw to point to the buffer currently displayed,
     // then flip the driver so we're displaying the other buffer
@@ -153,12 +156,14 @@ GRSurface* MinuiBackendFbdev::Flip() {
     // Copy from the in-memory surface to the framebuffer.
     memcpy(gr_framebuffer[0].data, gr_draw->data, gr_draw->height * gr_draw->row_bytes);
   }
-  return gr_draw;
+  //return gr_draw;
+  return rotate_canvas_get(gr_draw);
 }
 
 MinuiBackendFbdev::~MinuiBackendFbdev() {
   close(fb_fd);
   fb_fd = -1;
+  rotate_canvas_exit();
 
   if (!double_buffered && gr_draw) {
     free(gr_draw->data);

3.添加vendor/mediatek/proprietary/bootable/recovery/minui/Android.mk

#
# recovery rotation
#
ifneq ($(TARGET_SIMULATOR),true)
ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm arm64))

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
MEDIATEK_MINUI_PATH := /bootable/recovery/minui

LOCAL_SRC_FILES := \
     ../../../../../$(MEDIATEK_MINUI_PATH)/graphics.cpp \
     mt_graphic_rotate.cpp 

LOCAL_C_INCLUDES += $(LOCAL_PATH)/include \
              ../../../../../$(MEDIATEK_MINUI_PATH)/include
    

LOCAL_MODULE := libmt_minui
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_OWNER := mtk

LOCAL_MODULE_TAGS := optional


include $(MTK_STATIC_LIBRARY)

endif # TARGET_ARCH == arm64
endif # !TARGET_SIMULATOR

4.添加vendor/mediatek/proprietary/bootable/recovery/minui/include/mt_graphic_rotate.h

/*
* Copyright (C) 2014 MediaTek Inc.
* Modification based on code covered by the mentioned copyright
* and/or permission notice(s).
*/

#ifndef MT_GRAPHICS_ROTATE_H_
#define MT_GRAPHICS_ROTATE_H_

#include "minui/minui.h"

void rotate_canvas_exit(void);
void rotate_canvas_init(GRSurface *gr_draw);
void rotate_surface(GRSurface *dst, GRSurface *src);
GRSurface *rotate_canvas_get(GRSurface *gr_draw);

#endif

5.添加vendor/mediatek/proprietary/bootable/recovery/minui/mt_graphic_rotate.cpp

/*
* Copyright (C) 2014 MediaTek Inc.
* Modification based on code covered by the mentioned copyright
* and/or permission notice(s).
*/


#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>

#include <fcntl.h>
#include <stdio.h>

#include <sys/cdefs.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>

#include <linux/fb.h>
#include <linux/kd.h>

#include "minui/minui.h"
#include "graphics.h"

GRSurface __gr_canvas;

GRSurface* gr_canvas = NULL;
int rotate_index=-1;

static void print_surface_info(GRSurface *s, const char *name)
{
    printf("[graphics] %s > Height:%d, Width:%d, PixelBytes:%d, RowBytes:%d, Size:%d, Data: 0x%08" PRIxPTR "\n",
        name, s->height, s->width, s->pixel_bytes, s->row_bytes, s->height* s->row_bytes, (uintptr_t) s->data);
}

// Read configuration from MTK_LCM_PHYSICAL_ROTATION
#ifndef MTK_LCM_PHYSICAL_ROTATION
#define MTK_LCM_PHYSICAL_ROTATION "undefined"
#endif
static int rotate_config(GRSurface *gr_draw)
{
    if (rotate_index<0)
    {
        if (gr_draw->pixel_bytes != 4) rotate_index=0; // support 4 bytes pixel only
        else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "90", 2)) rotate_index=1;
        else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "180", 3)) rotate_index=2;
        else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "270", 3)) rotate_index=3;
        else rotate_index=2;
        printf("[graphics] rotate_config %d %s\n", rotate_index, MTK_LCM_PHYSICAL_ROTATION);
    }
    //return rotate_index;
    return 3;//需要修改的方向
}

#define swap(x, y, type) {type z; z=x; x=y; y=z;}

// Allocate and setup the canvas object
void rotate_canvas_init(GRSurface *gr_draw)
{
    gr_canvas = &__gr_canvas;
    memcpy(gr_canvas, gr_draw, sizeof(GRSurface));

    // Swap canvas' height and width, if the rotate angle is 90" or 270"
    if (rotate_config(gr_draw)%2) {
        swap(gr_canvas->width, gr_canvas->height, int);
        gr_canvas->row_bytes = gr_canvas->width * gr_canvas->pixel_bytes;
    }

    gr_canvas->data = (unsigned char*) malloc(gr_canvas->height * gr_canvas->row_bytes);
    if (gr_canvas->data == NULL) {
        printf("[graphics] rotate_canvas_init() malloc gr_canvas->data failed\n");
        gr_canvas = NULL;
        return;
    }

    memset(gr_canvas->data,  0, gr_canvas->height * gr_canvas->row_bytes);

    print_surface_info(gr_draw, "gr_draw");
    print_surface_info(gr_canvas, "gr_canvas");
}

// Cleanup the canvas
void rotate_canvas_exit(void)
{
    if (gr_canvas) {
        if (gr_canvas->data)
            free(gr_canvas->data);
        free(gr_canvas);
    }
    gr_canvas=NULL;
}

// Return the canvas object
GRSurface *rotate_canvas_get(GRSurface *gr_draw)
{
    // Initialize the canvas, if it was not exist.
    if (gr_canvas==NULL)
        rotate_canvas_init(gr_draw);
    return gr_canvas;
}

// Surface Rotate Routines
static void rotate_surface_0(GRSurface *dst, GRSurface *src)
{
    memcpy(dst->data, src->data, src->height*src->row_bytes);
}

static void rotate_surface_270(GRSurface *dst, GRSurface *src)
{
    int v, w, h;
    unsigned int *src_pixel;
    unsigned int *dst_pixel;

    for (h=0, v=src->width-1; h<dst->height; h++, v--) {
        for (w=0; w<dst->width; w++) {
            dst_pixel = (unsigned int *)(dst->data + dst->row_bytes*h);
            src_pixel = (unsigned int *)(src->data + src->row_bytes*w);
            *(dst_pixel+w)=*(src_pixel+v);
        }
    }
}

static void rotate_surface_180(GRSurface *dst, GRSurface *src)
{
    int v, w, k, h;
    unsigned int *src_pixel;
    unsigned int *dst_pixel;

    for (h=0, k=src->height-1; h<dst->height && k>=0 ; h++, k--) {
        dst_pixel = (unsigned int *)(dst->data + dst->row_bytes*h);
        src_pixel = (unsigned int *)(src->data + src->row_bytes*k);
        for (w=0, v=src->width-1; w<dst->width && v>=0; w++, v--) {
            *(dst_pixel+w)=*(src_pixel+v);
        }
    }
}

static void rotate_surface_90(GRSurface *dst, GRSurface *src)
{
    int w, k, h;
    unsigned int *src_pixel;
    unsigned int *dst_pixel;

    for (h=0; h<dst->height; h++) {
        for (w=0, k=src->height-1; w<dst->width; w++, k--) {
            dst_pixel = (unsigned int *)(dst->data + dst->row_bytes*h);
            src_pixel = (unsigned int *)(src->data + src->row_bytes*k);
            *(dst_pixel+w)=*(src_pixel+h);
        }
    }
}

typedef void (*rotate_surface_t) (GRSurface *, GRSurface *);

rotate_surface_t rotate_func[4]=
{
    rotate_surface_0,
    rotate_surface_90,
    rotate_surface_180,
    rotate_surface_270
};

// rotate and copy src* surface to dst surface
void rotate_surface(GRSurface *dst, GRSurface *src)
{
    rotate_surface_t rotate;
    rotate=rotate_func[rotate_config(dst)];
    rotate(dst, src);
}



<think>好的,用户的问题是关于在Android 12源码中调整Recovery模式的方向。首先,我需要回想一下Android Recovery系统的基本结构。Recovery模式通常运行在独立的引导加载程序环境中,其界面显示可能依赖于特定的图形库,比如minui或者更现代的Gralloc。 根据用户提供的引用,特别是引用[1]和引用[3],用户提到通过修改源码中的某个函数,例如旋转画布或者调整surface的方向。引用[3]中的代码片段`rotate_surface(gr_draw, rotate_canvas_get(gr_draw));`可能涉及到图形绘制的旋转处理。因此,我需要确认在Android 12源码中,Recovery模式的图形渲染部分是否有类似的函数调用。 接下来,我需要确定Recovery模式的图形库位置。通常,这部分代码可能在`bootable/recovery`目录下,特别是与minui相关的部分。比如,`minui/graphics.cpp`或类似的文件中可能存在处理屏幕旋转的函数。此外,Gralloc(图形内存分配器)相关的代码可能在`hardware/libhardware/modules/gralloc`中,但Recovery可能使用更简化的版本。 用户的问题还涉及到旋转界面,可能需要调整显示的方向参数。比如,在`recovery.cpp`或`screen_ui.cpp`中,可能存在初始化显示方向的代码。例如,检查是否有设置旋转角度的函数调用,如`gr_rotate`或者`setDisplayRotation`之类的函数。 另外,引用[1]中提到修改源码中的某个地方即可,这提示可能需要在某个关键点插入旋转函数。比如,在初始化图形界面之后立即调用旋转函数,或者在绘制界面元素之前调整画布的方向。 同时,需要考虑不同设备的硬件差异。有些设备可能通过内核参数或设备树(device tree)配置显示方向,但用户的问题更倾向于修改源码层面的解决方案。因此,可能需要修改Recovery的图形初始化代码,强制设置旋转角度。 总结步骤可能是:1. 定位Recovery的图形库源码中的旋转函数;2. 在初始化过程中调用旋转函数,设置所需方向;3. 编译并刷入修改后的Recovery镜像进行测试。 需要注意的是,不同Android版本可能代码结构有所变化,Android 12的Recovery代码路径可能与旧版本不同,需要确认具体文件位置。此外,如果设备使用了不同的图形驱动,可能需要适配特定的旋转方式,比如通过修改显示缓冲区(framebuffer)的旋转参数。 最后,生成的相关问题应该围绕Recovery模式的其他定制方法、图形库的工作原理以及调试技巧,帮助用户进一步理解和解决问题。</think>在Android 12源码中调整Recovery界面方向,需修改图形渲染相关的源码。以下是具体步骤: ### 1. 定位图形渲染关键函数 Recovery界面绘制通常通过`minui`或`Gralloc`库实现,核心代码位于: - `bootable/recovery/minui/graphics.cpp` - `bootable/recovery/screen_ui.cpp` 在`gr_init()`初始化函数后添加旋转逻辑: ```cpp // 修改后的gr_init() bool gr_init() { // ...原有初始化代码... gr_rotate(ROTATION_90); // 设置旋转角度 return true; } ``` ### 2. 实现旋转函数 在`graphics.cpp`中添加旋转支持: ```cpp void gr_rotate(int rotation) { gr_draw->rotation = rotation; rotate_surface(gr_draw, rotation); // 关键渲染接口调用[^3] } ``` ### 3. 调整绘制坐标系 修改`gr_blit()`等绘制函数,加入坐标变换逻辑: ```cpp void gr_blit(...) { if (gr_draw->rotation != ROTATION_0) { // 实现坐标旋转变换 transform_coordinates(&x, &y, gr_draw->rotation); } // ...后续绘制代码... } ``` ### 4. 编译验证 执行完整编译流程: ```bash source build/envsetup.sh lunch <target> make recoveryimage -j8 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最乱纷飞的code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值