解决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度,就是实现了功能要求

相关推荐
FL4m3Y4n1 分钟前
MySQL索引原理与SQL优化
android·sql·mysql
我命由我123451 小时前
Android Gradle - Gradle 自定义插件(Build Script 自定义插件、buildSrc 自定义插件、独立项目自定义插件)
android·java·java-ee·kotlin·android studio·android-studio·android runtime
冬奇Lab1 小时前
AudioFlinger混音机制深度解析
android·音视频开发·源码阅读
滑雪的企鹅.3 小时前
Kotlin云头条技术点剖析(项目复习02)——用户协议页面
android·开发语言·kotlin
JMchen1233 小时前
Android NDK开发从入门到实战:解锁应用性能的终极武器
android·开发语言·c++·python·c#·android studio·ndk开发
脚大江山稳4 小时前
单独为mysql数据库的某个库创建用户
android·数据库·mysql
吉哥机顶盒刷机5 小时前
XDBL安卓玩机刷机工具V2.8_解压缩版
android·智能手机·电脑
XiaoLeisj7 小时前
Android 广播机制实战:从系统广播监听、自定义登录通知到有序广播分发
android
urkay-7 小时前
Android 图片轮廓提取与重叠轮廓合并处理
android·算法·iphone
2501_916008897 小时前
2026 iOS 证书管理,告别钥匙串依赖,构建可复制的签名环境
android·ios·小程序·https·uni-app·iphone·webview