Android recoveryUI方向修改(7.1+11)
迪丽瓦拉
2025-05-31 14:23:48
0

有时候修改了屏幕的方向,recoveryUI的方向却没有跟着改变。

7.1系统修改recoveryUI方向

①新增文件graphics_rotate.cpp
  • bootable/recovery/minui/graphics_rotate.cpp
/*
* Copyright (C) 2014 MediaTek Inc.
* Modification based on code covered by the mentioned copyright
* and/or permission notice(s).
*/#include 
#include 
#include 
#include #include 
#include #include 
#include 
#include 
#include #include 
#include #include "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 LCM_PHYSICAL_ROTATION
#ifndef LCM_PHYSICAL_ROTATION
#define LCM_PHYSICAL_ROTATION "undefined"
#endif
static int rotate_config(GRSurface *gr_draw)
{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 LCM_PHYSICAL_ROTATION
#ifndef LCM_PHYSICAL_ROTATION
#define 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 onlyelse if (0 == strncmp(LCM_PHYSICAL_ROTATION, "90", 2)) rotate_index=1;else if (0 == strncmp(LCM_PHYSICAL_ROTATION, "180", 3)) rotate_index=2;else if (0 == strncmp(LCM_PHYSICAL_ROTATION, "270", 3)) rotate_index=3;else rotate_index=0;printf("[graphics] rotate_config %d %s\n", rotate_index, LCM_PHYSICAL_ROTATION);}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; hheight; h++, v--) {for (w=0; wwidth; 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; hheight && 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; wwidth && 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; hheight; h++) {for (w=0, k=src->height-1; wwidth; 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);
}
②新增文件graphics_rotate.h
  • bootable/recovery/minui/graphics_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.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
③graphics_rotate.cpp加入编译
  • bootable/recovery/minui/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_SRC_FILES := \events.cpp \graphics.cpp \graphics_adf.cpp \graphics_drm.cpp \graphics_fbdev.cpp \resources.cpp \graphics_rotate.cpp \
④修改graphics_fbdev.cpp
  • bootable/recovery/minui/graphics_fbdev.cpp
include 
#include 
#include 
#include #include 
#include #include 
#include 
#include 
#include #include 
#include #include "minui.h"
#include "graphics.h"
// add for recovery ui
#include "graphics_rotate.h"static GRSurface* fbdev_init(minui_backend*);
static GRSurface* fbdev_flip(minui_backend*);
static void fbdev_blank(minui_backend*, bool);
static void fbdev_exit(minui_backend*);static GRSurface gr_framebuffer[2];
static bool double_buffered;
static GRSurface* gr_draw = NULL;
static int displayed_buffer;static fb_var_screeninfo vi;
static int fb_fd = -1;static minui_backend my_backend = {.init = fbdev_init,.flip = fbdev_flip,.blank = fbdev_blank,.exit = fbdev_exit,
};minui_backend* open_fbdev() {return &my_backend;
}static void fbdev_blank(minui_backend* backend __unused, bool blank)
{int ret;ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);if (ret < 0)perror("ioctl(): blank");
}static void set_displayed_framebuffer(unsigned n)
{if (n > 1 || !double_buffered) return;vi.yres_virtual = gr_framebuffer[0].height * 2;vi.yoffset = n * gr_framebuffer[0].height;vi.bits_per_pixel = gr_framebuffer[0].pixel_bytes * 8;if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {perror("active fb swap failed");}displayed_buffer = n;
}static GRSurface* fbdev_init(minui_backend* backend) {int fd = open("/dev/graphics/fb0", O_RDWR);if (fd == -1) {perror("cannot open fb0");return NULL;}fb_fix_screeninfo fi;if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {perror("failed to get fb0 info");close(fd);return NULL;}if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {perror("failed to get fb0 info");close(fd);return NULL;}// We print this out for informational purposes only, but// throughout we assume that the framebuffer device uses an RGBX// pixel format.  This is the case for every development device I// have access to.  For some of those devices (eg, hammerhead aka// Nexus 5), FBIOGET_VSCREENINFO *reports* that it wants a// different format (XBGR) but actually produces the correct// results on the display when you write RGBX.//// If you have a device that actually *needs* another pixel format// (ie, BGRX, or 565), patches welcome...printf("fb0 reports (possibly inaccurate):\n""  vi.bits_per_pixel = %d\n""  vi.red.offset   = %3d   .length = %3d\n""  vi.green.offset = %3d   .length = %3d\n""  vi.blue.offset  = %3d   .length = %3d\n",vi.bits_per_pixel,vi.red.offset, vi.red.length,vi.green.offset, vi.green.length,vi.blue.offset, vi.blue.length);void* bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (bits == MAP_FAILED) {perror("failed to mmap framebuffer");close(fd);return NULL;}memset(bits, 0, fi.smem_len);gr_framebuffer[0].width = vi.xres;gr_framebuffer[0].height = vi.yres;gr_framebuffer[0].row_bytes = fi.line_length;gr_framebuffer[0].pixel_bytes = vi.bits_per_pixel / 8;gr_framebuffer[0].data = reinterpret_cast(bits);memset(gr_framebuffer[0].data, 0, gr_framebuffer[0].height * gr_framebuffer[0].row_bytes);/* check if we can use double buffering */if (vi.yres * fi.line_length * 2 <= fi.smem_len) {double_buffered = true;memcpy(gr_framebuffer+1, gr_framebuffer, sizeof(GRSurface));gr_framebuffer[1].data = gr_framebuffer[0].data +gr_framebuffer[0].height * gr_framebuffer[0].row_bytes;gr_draw = gr_framebuffer+1;} else {double_buffered = false;// Without double-buffering, we allocate RAM for a buffer to// draw in, and then "flipping" the buffer consists of a// memcpy from the buffer we allocated to the framebuffer.gr_draw = (GRSurface*) malloc(sizeof(GRSurface));memcpy(gr_draw, gr_framebuffer, sizeof(GRSurface));gr_draw->data = (unsigned char*) malloc(gr_draw->height * gr_draw->row_bytes);if (!gr_draw->data) {perror("failed to allocate in-memory surface");return NULL;}}memset(gr_draw->data, 0, gr_draw->height * gr_draw->row_bytes);fb_fd = fd;set_displayed_framebuffer(0);printf("framebuffer: %d (%d x %d)\n", fb_fd, gr_draw->width, gr_draw->height);fbdev_blank(backend, true);fbdev_blank(backend, false);// add for recovery ui// return gr_draw;return rotate_canvas_get(gr_draw);// end
}static GRSurface* fbdev_flip(minui_backend* backend __unused) {// add for recovery uirotate_surface(gr_draw, rotate_canvas_get(gr_draw));// endif (double_buffered) {// Change gr_draw to point to the buffer currently displayed,// then flip the driver so we're displaying the other buffer// instead.gr_draw = gr_framebuffer + displayed_buffer;set_displayed_framebuffer(1-displayed_buffer);} else {// Copy from the in-memory surface to the framebuffer.memcpy(gr_framebuffer[0].data, gr_draw->data,gr_draw->height * gr_draw->row_bytes);}// add for recovery ui//return gr_draw;return rotate_canvas_get(gr_draw);//end
}static void fbdev_exit(minui_backend* backend __unused) {close(fb_fd);fb_fd = -1;// add for recovery uirotate_canvas_exit();// endif (!double_buffered && gr_draw) {free(gr_draw->data);free(gr_draw);}gr_draw = NULL;
}

11.0系统修改recovUI方向

第一种方式

  • bootable/recovery/minui/graphics.cpp

int gr_init() {// pixel_format needs to be set before loading any resources or initializing backends.std::string format = android::base::GetProperty("ro.minui.pixel_format", "");if (format == "ABGR_8888") {pixel_format = PixelFormat::ABGR;} else if (format == "RGBX_8888") {pixel_format = PixelFormat::RGBX;} else if (format == "ARGB_8888") {pixel_format = PixelFormat::ARGB;} else if (format == "BGRA_8888") {pixel_format = PixelFormat::BGRA;} else {pixel_format = PixelFormat::UNKNOWN;}int ret = gr_init_font("font", &gr_font);if (ret != 0) {printf("Failed to init font: %d, continuing graphic backend initialization without font file\n",ret);}auto backend = std::unique_ptr{ std::make_unique() };gr_draw = backend->Init();if (!gr_draw) {backend = std::make_unique();gr_draw = backend->Init();}if (!gr_draw) {backend = std::make_unique();gr_draw = backend->Init();}if (!gr_draw) {return -1;}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");// add for recovery uirotation_str = ROTATION_RIGHT;   // endif (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 stringgr_rotate(GRRotation::NONE);}if (gr_draw->pixel_bytes != 4) {printf("gr_init: Only 4-byte pixel formats supported\n");}return 0;
}

第二种方式

  • device/mediateksample/{project}/BoardConfig.mk
# add for recovery ui
TARGET_RECOVERY_DEFAULT_ROTATION := ROTATION_RIGHT
# end

相关内容