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

相关推荐
rocpp4 小时前
Android 相册选择与拍照接入实践:MediaStore 分页、权限适配与 FileProvider
android
Flynt5 小时前
升级Flutter 3.44,我踩了HCPP和AGP 9的坑
android·flutter·dart
白色牙膏6 小时前
Cocos Creator 2.4.x 接入 AdMob 插件的迁移实践
android
我命由我123457 小时前
C++ - 面向对象 - 常成员函数
android·java·linux·c语言·开发语言·c++·算法
tryqaaa_8 小时前
学习日志(四)【php反序列化魔术方法以及pop构造配实战】
android
Java小学生丶10 小时前
记录一下我的 Gradle 开发环境配置过程
android·java·gradle·maven·安卓
问心无愧051310 小时前
ctf show web 入门256
android·前端·笔记
霸道流氓气质10 小时前
MySQL 索引设计实战指南
android·数据库·mysql
R语言爱好者11 小时前
叠氮酸介绍
android
方白羽11 小时前
Android WebView 中实现第三方 QQ 登录的架构与流程详解
android·app