解决recovery页面反转的问题
1.前言
在android 10.0的系统rom定制化开发工作中,在系统中recoverv的页面也是相关重要的一部分,在系统recovery ta升级等功能,都是需要recoverv功能的,在某些产品定制化中
在recovery的时候,发现居然旋转了180度,接下来分析下recovery关于屏幕显示方向的相关源码,来修改这个功能
2.recovery页面旋转180度问题的解决方案的核心类
bootable/recovery/minui/include/minui/minui.hboottable/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的绘制那么旋转方向的修改 就要从这里入手了。
#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 stringgr_rotate(GRRotation::NONE);}rotation = GRRotation::RIGHT;//add codeif (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方向的相关参数,如下
enum GRRotation {ROTATION_NONE = 0,ROTATION_RIGHT = 1,//90ROTATION_DOWN = 2,//180ROTATION_LEFT = 3,//270};
recovev页面旋转180度问题的解决方案的核心功能实现中,根据GRRotation 的相关参数可以得知,ROTATION RIGHT就是屏幕旋转90度,而ROTATION DOWN就是屏幕旋转180度,而ROTATION LEFT就是屏幕旋转270度,
所以设置横屏上下翻转就需要把屏幕方向修改为ROTATION LEFT就可以了具体修改为:
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 stringgr_rotate(GRRotation::NONE);}+ rotation = GRRotation::LEFT;//add code....}
recover页面旋转180度问题的解决方案的核心功能实现中,在上述的graphics.cpp中的上述源码中分析得知,在gr init) 主要是设置RGB和 屏幕旋转方向,所以就是根据返回的
rotation的值来判断当前屏幕的旋转方向的,所以通过上述的修改方法,在gr init()
增加rotation = GRRotation:LEFT://add code来作为当前屏幕的旋转方法,就确保旋转180度,就是实现了功能要求
相关文章:
解决recovery页面反转的问题
1.前言 在android 10.0的系统rom定制化开发工作中,在系统中recoverv的页面也是相关重要的一部分,在系统recovery ta升级等功能,都是需要recoverv功能的,在某些产品定制化中 在recovery的时候,发现居然旋转了180度&…...
如何使用nuScenes数据集格式的单帧数据推理(以DETR3D为例)
【请尊重原创!转载和引用文章内容务必注明出处!未经许可上传到某文库或其他收费阅读/下载网站赚钱的必追究责任!】 无论是mmdetection3D还是OpenPCDet都只有使用数据集(使用哪个数据集由配置文件里指定)训练和测试的代码,没有使用…...
大语言模型之十三 LLama2中文推理
在《大语言模型之十二 SentencePiece扩充LLama2中文词汇》一文中已经扩充好了中文词汇表,接下来就是使用整理的中文语料对模型进行预训练了。这里先跳过预训练环节。先试用已经训练好的模型,看看如何推理。 合并模型 这一步骤会合并LoRA权重࿰…...
iOS AVAudioSession 详解
iOS AVAudioSession 详解 - 简书 默认没有options,category 7种即可满足条件 - (BOOL)setCategory:(AVAudioSessionCategory)category error:(NSError **)outError API_AVAILABLE(ios(3.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); 有optionsÿ…...
26-网络通信
网络通信 什么是网络编程? 可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)。 java.net.包下提供了网络编程的解决方案! 基本的通信架构有2种形式:CS架构( Client客户端/Server服…...
嵌入式Linux应用开发-基础知识-第十九章驱动程序基石③
嵌入式Linux应用开发-基础知识-第十九章驱动程序基石③ 第十九章 驱动程序基石③19.5 定时器19.5.1 内核函数19.5.2 定时器时间单位19.5.3 使用定时器处理按键抖动19.5.4 现场编程、上机19.5.5 深入研究:定时器的内部机制19.5.6 深入研究:找到系统滴答 1…...
一文拿捏SpringMVC的调用流程
SpringMVC的调用流程 1.核心元素: DispatcherServlet(前端控制器)HandlerMapping(处理器映射器)HandlerAdapter(处理器适配器) ---> Handler(处理器)ViewResolver(视图解析器 )---> view(视图) 2.调用流程 用户发送请求到前端控制器前端控制器接收用户请求…...
一文详解 JDK1.8 的 Lambda、Stream、LocalDateTime
Lambda Lambda介绍 Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。 Lambda表达式的结构 一个 Lamb…...
WebSocket实战之二协议分析
一、前言 上一篇 WebSocket实战之一 讲了WebSocket一个极简例子和基础的API的介绍,这一篇来分析一下WebSocket的协议,学习网络协议最好的方式就是抓包分析一下什么就都明白了。 二、WebSocket协议 本想盗一张网络图,后来想想不太好&#x…...
LeetCode //C - 208. Implement Trie (Prefix Tree)
208. Implement Trie (Prefix Tree) A trie (pronounced as “try”) or prefix tree is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and s…...
【Python】time模块和datetime模块的部分函数说明
时间戳与日期 在说到这俩模块之前,首先先明确几个概念: 时间戳是个很单纯的东西,没有“时区”一说,因为时间戳本质上是经过的时间。日常生活中接触到的“日期”、“某点某时某分”准确的说是时间点,都是有时区概念的…...
Python 无废话-基础知识元组Tuple详讲
“元组 Tuple”是一个有序、不可变的序列集合,元组的元素可以包含任意类型的数据,如整数、浮点数、字符串等,用()表示,如下示例: 元组特征 1) 元组中的各个元素,可以具有不相同的数据类型,如 T…...
【Win】Microsoft Spy++学习笔记
参考资料 《用VisualStudio\Spy查窗口句柄,监控窗口消息》 1. 安装 Spy是VS中的工具,所以直接安装VS就可以了; 2. 检查应用程序架构 ChatGPT-Bing: 对于窗口应用程序分析,确定应用程序是32位还是64位是很重要的,因…...
如何解决版本不兼容Jar包冲突问题
如何解决版本不兼容Jar包冲突问题 引言 “老婆”和“妈妈”同时掉进水里,先救谁? 常言道:编码五分钟,解冲突两小时。作为Java开发来说,第一眼见到ClassNotFoundException、 NoSuchMethodException这些异常来说&…...
数据结构—归并排序-C语言实现
引言:归并排序跟快速排序一样,都运用到了分治的算法,但是归并排序是一种稳定的算法,同时也具备高效,其时间复杂度为O(N*logN) 算法图解: 然后开始归并: 就是这个思想,拆成最小子问题…...
Multiple CORS header ‘Access-Control-Allow-Origin‘ not allowed
今天在修改天天生鲜超市项目的时候,因为使用了前后端分离模式,前端通过网关统一转发请求到后端服务,但是第一次使用就遇到了问题,比如跨域问题: 但是,其实网关里是有配置跨域的,只是忘了把前端项…...
msvcp100.dll丢失怎样修复,msvcp100.dll丢失问题全面解析
msvcp100.dll是一个动态链接库文件,属于 Microsoft Visual C Redistributable 的一个组件。它包含了 C 运行时库,这些库在运行程序时会被加载到内存中。msvcp100.dll文件的主要作用是为基于 Visual C 编写的程序提供必要的运行时支持。 当您运行一个基于…...
最新AI智能问答系统源码/AI绘画系统源码/支持GPT联网提问/Prompt应用+支持国内AI提问模型
一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图…...
全连接网络实现回归【房价预测的数据】
也是分为data,model,train,test import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optimclass FCNet(nn.Module):def __init__(self):super(FCNet,self).__init__()self.fc1 nn.Linear(331,200)s…...
mysql八股
1、请你说说mysql索引,以及它们的好处和坏处 检索效率、存储资源、索引 索引就像指向表行的指针,是一个允许查询操作快速确定哪些行符合WHERE子句中的条件,并检索到这些行的其他列值的数据结构索引主要有普通索引、唯一索引、主键索引、外键…...
MATLAB算法实战应用案例精讲-【优化算法】狐猴优化器(LO)(附MATLAB代码实现)
代码实现 MATLAB LO.m %======================================================================= % Lemurs Optimizer: A New Metaheuristic Algorithm % for Global Optimization (LO)% This work is published in Journal of "Applied …...
C#WPF动态资源和静态资源应用实例
本文实例演示C#WPF动态资源和静态资源应用 一、资源概述 静态资源(StaticResource)指的是在程序载入内存时对资源的一次性使用,之后就不再访问这个资源了。 动态资源(DynamicResource)指的是在程序运行过程中然会去访问资源。 WPF中,每个界面元素都含有一个名为Resources…...
游戏逆向中的 NoClip 手段和安全应对方式
文章目录 墙壁边界寻找碰撞 NoClip 是一种典型的黑客行为,允许你穿过墙壁,所以 NoClip 又可以认为是避免碰撞体积的行为 墙壁边界 游戏中设置了碰撞体作为墙壁边界,是 玩家对象 和墙壁发生了碰撞,而不是 相机 玩家对象有他的 X…...
nodejs+vue流浪猫狗救助领养elementui
第三章 系统分析 10 3.1需求分析 10 3.2可行性分析 10 3.2.1技术可行性:技术背景 10 3.2.2经济可行性 11 3.2.3操作可行性: 11 3.3性能分析 11 3.4系统操作流程 12 3.4.1管理员登录流程 12 3.4.2信息添加流程 12 3.4.3信息删除流程 13 第四章 系统设计与…...
Css Flex 弹性布局中的换行与溢出处理方法
Css Flex 弹性布局中的换行与溢出处理方法 CSS弹性布局(Flex)是CSS3中的一种新的布局方式,它能够帮助我们更加灵活地布局元素。在Flex弹性布局中,元素的布局仅依赖于父容器的设置,而不再需要复杂的相对或绝对定位。本…...
linux系统与应用
Windows中的硬盘和盘符的关系; 硬盘通常为一块到两块;数量与盘符没有直接关系;一块硬盘可以分为多个盘符,如c,d,e,f,g等;当然理论上也可以一块硬盘只有一个盘符;学习linux时,最好使用固态硬盘&a…...
MySQL的结构化语言 DDL DML DQL DCL
一、SQL结构化语言介绍 数据查询语言DQL:其语句称为“数据检索语言”,用以从库中获取数据,确定数据怎样在应用程序给出,保留select是dql(也是所有sql)用的最多的动词 数据操作语言DML:其语句包括动词insert…...
P5488 差分与前缀和
传送门:洛谷 前题提要:包含了简单的生成函数思想以及多项式乘法,是一道不可多得的多项式好题.故记录一下. 题意:给定一个长为 n 的序列 a,求出其 k 阶差分或前缀和。结果的每一项都需要对 1004535809取模。 对于差分和前缀和我们分开来讨论. 先讨论前缀和部分: …...
uboot启动流程-uboot内存分配
一. uboot启动流程 _main 函数中会调用 board_init_f 函数,本文继续简单分析一下 board_init_f 函数。 具体分析 board_init_f函数的第二部分:内存分配代码。 本文继上一篇文章的学习,地址如下: uboot启动流程-涉及board_init…...
LeetCode 面试题 08.02. 迷路的机器人
文章目录 一、题目二、C# 题解 一、题目 设想有个机器人坐在一个网格的左上角,网格 r 行 c 列。机器人只能向下或向右移动,但不能走到一些被禁止的网格(有障碍物)。设计一种算法,寻找机器人从左上角移动到右下角的路径…...
郑州做网站公司 汉狮网络专业/uc浏览器网页版入口
var testString:String "wo shi string"var utf8String (testString as NSString).UTF8String 转载于:https://www.cnblogs.com/MartinLi841538513/p/3825574.html...
网站开发工程师培训班/网络营销总结
升压IC芯片在诸多电子电路中均有所应用,在现代生活中,升压芯片是不可或缺的器件之一。对于升压芯片,想必大家均具备一定了解。在本文中,将主要为大家讲解FSB628升压IC芯片,不知大家对这款升压芯片以及其应用是否熟悉。…...
网站 模板 安装/广西壮族自治区免费百度推广
Windows Phone笔记(10)使用独立存储(中) 在我们前面的笔记中了解如何通过使用IsolatedStorageSettings类来保存应用程序设置,也知道独立存储还可以通过使用使用 IsolatedStorageFile类存储文件和文件夹。在这篇笔记中,让我们一起来了解并学会使用Isolate…...
深圳本地做网站/网上推广培训
硬盘分区表扫盲:MBR和GPT表MBR全称为Master Boot Record主引导记录,是传统的分区机制,应用于绝大多数使用BIOS的PC设备MBRBIOSMBR支持32位和64位系统。MBR支持分区数量有限。MBR只支持不超过2T的硬盘,超过2T的硬盘将只能用2T空间(…...
邢台网站建设优化/百度官方app下载
我试图在OmegaT这是一个Java翻译记忆库应用程序混合PHP/HTML源文件准备翻译。它有一个HTML过滤器,可以很好地处理干净的HTML文件,但当PHP代码混入时会变得混乱。如何选择性地在HTML文件中注释PHP代码?为了避免这个问题,我试图想出…...
wordpress目录分页/正规网站建设服务
压缩文件的解压码是一种打开密码,想要解压文件就必须输入解压码才能成功解压文件,如果不知道解压码,可以通过破解软件找回正确的密码。比如奥凯丰 压缩包解密大师 添加压缩包(支持zip、rar、7z压缩包)到软件中&#x…...