解决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 小时前
如何判断手机是否是纯血鸿蒙系统
android
火柴就是我2 小时前
flutter 之真手势冲突处理
android·flutter
法的空间3 小时前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
循环不息优化不止3 小时前
深入解析安卓 Handle 机制
android
恋猫de小郭3 小时前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter
jctech3 小时前
这才是2025年的插件化!ComboLite 2.0:为Compose开发者带来极致“爽”感
android·开源
用户2018792831673 小时前
为何Handler的postDelayed不适合精准定时任务?
android
叽哥3 小时前
Kotlin学习第 8 课:Kotlin 进阶特性:简化代码与提升效率
android·java·kotlin
Cui晨3 小时前
Android RecyclerView展示List<View> Adapter的数据源使用View
android
氦客3 小时前
Android Doze低电耗休眠模式 与 WorkManager
android·suspend·休眠模式·workmanager·doze·低功耗模式·state_doze