解决recovery页面反转的问题

1.前言

在android 10.0的系统rom定制化开发工作中,在系统中recoverv的页面也是相关重要的一部分,在系统recovery ta升级等功能,都是需要recoverv功能的,在某些产品定制化中

在recovery的时候,发现居然旋转了180度,接下来分析下recovery关于屏幕显示方向的相关源码,来修改这个功能

2.recovery页面旋转180度问题的解决方案的核心类

cpp 复制代码
     bootable/recovery/minui/include/minui/minui.h
     boottable/recovery/minui/graphics.cpp

3.recovery页面旋转180度问题的解决方案的核心功能分析和实现

recovery页面旋转180度问题的解决方案的核心功能实现中,Android10.0的Recovery中的相关系统源码中,recoverv是以bootablerecovery下的minui库作为基础,采用的是直接存取framebuffer的万式,来完成recovery中所需的各种UI的绘制。

在recoverv的源码中,跟ui显示相关的代码的大致结构为:

boottable/recovery/minui下resources.cpp,graphics.cpp

其中resources.cpp提供的api主要用于图片资源的读取和加载

graphics.cpp负责具体完成各类ui的绘制既然graphics.cpp是负责各类UI的绘制那么旋转方向的修改 就要从这里入手了。

cpp 复制代码
   #include "graphics.h"
     
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #include <memory>
     
    #include <android-base/properties.h>
     
    #include "graphics_adf.h"
    #include "graphics_drm.h"
    #include "graphics_fbdev.h"
    #include "minui/minui.h"
    ...
     
    int gr_measure(const GRFont* font, const char* s) {
      if (font == nullptr) {
        return -1;
      }
     
      return font->char_width * strlen(s);
    }
     
    int gr_font_size(const GRFont* font, int* x, int* y) {
      if (font == nullptr) {
        return -1;
      }
     
      *x = font->char_width;
      *y = font->char_height;
      return 0;
    }
     
     
    // Increments pixel pointer right, with current rotation.
    static void incr_x(uint32_t** p, int row_pixels) {
      if (rotation == GRRotation::LEFT) {
        *p = *p - row_pixels;
      } else if (rotation == GRRotation::RIGHT) {
        *p = *p + row_pixels;
      } else if (rotation == GRRotation::DOWN) {
        *p = *p - 1;
      } else {  // GRRotation::NONE
        *p = *p + 1;
      }
    }
     
    // Increments pixel pointer down, with current rotation.
    static void incr_y(uint32_t** p, int row_pixels) {
      if (rotation == GRRotation::LEFT) {
        *p = *p + 1;
      } else if (rotation == GRRotation::RIGHT) {
        *p = *p - 1;
      } else if (rotation == GRRotation::DOWN) {
        *p = *p - row_pixels;
      } else {  // GRRotation::NONE
        *p = *p + row_pixels;
      }
    }
     
     
    void gr_fill(int x1, int y1, int x2, int y2) {
      x1 += overscan_offset_x;
      y1 += overscan_offset_y;
     
      x2 += overscan_offset_x;
      y2 += overscan_offset_y;
     
      if (outside(x1, y1) || outside(x2 - 1, y2 - 1)) return;
     
      int row_pixels = gr_draw->row_bytes / gr_draw->pixel_bytes;
      uint32_t* p = PixelAt(gr_draw, x1, y1, row_pixels);
      uint8_t alpha = static_cast<uint8_t>(((gr_current & alpha_mask) >> 24));
      if (alpha > 0) {
        for (int y = y1; y < y2; ++y) {
          uint32_t* px = p;
          for (int x = x1; x < x2; ++x) {
            *px = pixel_blend(alpha, *px);
            incr_x(&px, row_pixels);
          }
          incr_y(&p, row_pixels);
        }
      }
    }
     
     
    int gr_init_font(const char* name, GRFont** dest) {
      GRFont* font = static_cast<GRFont*>(calloc(1, sizeof(*gr_font)));
      if (font == nullptr) {
        return -1;
      }
     
      int res = res_create_alpha_surface(name, &(font->texture));
      if (res < 0) {
        free(font);
        return res;
      }
     
      // The font image should be a 96x2 array of character images.  The
      // columns are the printable ASCII characters 0x20 - 0x7f.  The
      // top row is regular text; the bottom row is bold.
      font->char_width = font->texture->width / 96;
      font->char_height = font->texture->height / 2;
     
      *dest = font;
     
      return 0;
    }
    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 == "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<MinuiBackend>{ std::make_unique<MinuiBackendAdf>() };
      gr_draw = backend->Init();
     
      if (!gr_draw) {
        backend = std::make_unique<MinuiBackendDrm>();
        gr_draw = backend->Init();
      }
     
      if (!gr_draw) {
        backend = std::make_unique<MinuiBackendFbdev>();
        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");
      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::RIGHT;//add code
      if (gr_draw->pixel_bytes != 4) {
        printf("gr_init: Only 4-byte pixel formats supported\n");
      }
     
      return 0;
    }
     
    void gr_rotate(GRRotation rot) {
      rotation = rot;
    }

recoverv页面旋转180度问题的解决方案的核心功能实现中,从graphics.cpp中的上述源码中,可以看出 r get width (const GRSurtace?surface)是获取屏幕的宽度

gr get height(const GRSurface* surface) 获取屏幕的高度

gr init font(const char* name.GRFont** dest) 获取字体大小

gr init() 主要是设置RGB 和 屏幕旋转方向,gr cear()清除一些绘制屏幕参数,重新绘制屏幕显示相关的参数接下来看下相关的设置recoverv的方向的相关代码的分析

gr rotate(DEFAULT ROTATION):

在gr init()的方法中中的gr rotate(DEFAULT ROTATION):设置屏幕的方向为默认方向而在minui.h中定义了recoverv方向的相关参数,如下

cpp 复制代码
enum GRRotation {
 
ROTATION_NONE = 0,
 
ROTATION_RIGHT = 1,//90
 
ROTATION_DOWN = 2,//180
 
ROTATION_LEFT = 3,//270
 
};

recovev页面旋转180度问题的解决方案的核心功能实现中,根据GRRotation 的相关参数可以得知,ROTATION RIGHT就是屏幕旋转90度,而ROTATION DOWN就是屏幕旋转180度,而ROTATION LEFT就是屏幕旋转270度,

所以设置横屏上下翻转就需要把屏幕方向修改为ROTATION LEFT就可以了具体修改为:

cpp 复制代码
int gr_init() {
 
....
 
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;//add code
 
....
 
}

recover页面旋转180度问题的解决方案的核心功能实现中,在上述的graphics.cpp中的上述源码中分析得知,在gr init) 主要是设置RGB和 屏幕旋转方向,所以就是根据返回的

rotation的值来判断当前屏幕的旋转方向的,所以通过上述的修改方法,在gr init()

增加rotation = GRRotation:LEFT://add code来作为当前屏幕的旋转方法,就确保旋转180度,就是实现了功能要求

相关推荐
圆号本昊2 小时前
Flutter Android Live2D 2026 实战:模型加载 + 集成渲染 + 显示全流程 + 10 个核心坑( OpenGL )
android·flutter·live2d
冬奇Lab3 小时前
ANR实战分析:一次audioserver死锁引发的系统级故障排查
android·性能优化·debug
冬奇Lab3 小时前
Android车机卡顿案例剖析:从Binder耗尽到单例缺失的深度排查
android·性能优化·debug
ZHANG13HAO4 小时前
调用脚本实现 App 自动升级(无需无感、允许进程中断)
android
圆号本昊5 小时前
【2025最新】Flutter 加载显示 Live2D 角色,实战与踩坑全链路分享
android·flutter
小曹要微笑5 小时前
MySQL的TRIM函数
android·数据库·mysql
mrsyf6 小时前
Android Studio Otter 2(2025.2.2版本)安装和Gradle配置
android·ide·android studio
DB虚空行者6 小时前
MySQL恢复之Binlog格式详解
android·数据库·mysql
liang_jy8 小时前
Android 事件分发机制(一)—— 全流程源码解析
android·面试·源码