Android T about screen rotation(二)
需求:客户因为模具问题,屏幕方向需要动态的变动.(方向: 0 , 90 , 180 ,270)
拆分:设备开机过程中图像显示可分为三个阶段,boot logo(1)->kernel logo(2),这一段的处理需要驱动层,所以暂时忽略.
开机动画 Bootanimation(3)阶段 和 Home Launcher应用显示(4)阶段是需要修改的.
因为是动态的,有涉及到cpp部分,一般用系统属性保存:persist.customer.set.orientation=0
Bootanimation
./frameworks/base/cmds/bootanimation/BootAnimation.cpp/**
* readyToRun()负责构建开机动画,进入readyToRun()中 就来加载显示每一帧动画
*
* createSurface()负责绘制开机动画页面
*/status_t BootAnimation::readyToRun() {mAssets.addDefaultAssets();mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();if (mDisplayToken == nullptr)return NAME_NOT_FOUND;DisplayMode displayMode;const status_t error =SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &displayMode);if (error != NO_ERROR)return error;mMaxWidth = android::base::GetIntProperty("ro.surface_flinger.max_graphics_width", 0);mMaxHeight = android::base::GetIntProperty("ro.surface_flinger.max_graphics_height", 0);ui::Size resolution = displayMode.resolution;resolution = limitSurfaceSize(resolution.width, resolution.height);+ //add text
+ char cOrientation [PROPERTY_VALUE_MAX];
+ property_get("persist.customer.set.orientation",cOrientation,"0");
+ int temp_orientation = atoi(cOrientation);
+
+ SurfaceComposerClient::Transaction t;
+
+ int temp_width = 0;
+ int temp_height = 0;
+
+ if(temp_orientation == 90){
+ temp_width = resolution.getHeight();
+ temp_height = resolution.getWidth();
+ Rect destRect(temp_width, temp_height);
+ t.setDisplayProjection(mDisplayToken, ui::ROTATION_90, destRect, destRect);
+ ALOGD("BootAnimation rotation is 90");
+ }else if(temp_orientation == 180){
+ Rect destRect(temp_width, temp_height);
+ t.setDisplayProjection(mDisplayToken, ui::ROTATION_180, destRect, destRect);
+ ALOGD("BootAnimation rotation is 180");
+ }else if(temp_orientation == 270){
+ temp_width = resolution.getHeight();
+ temp_height = resolution.getWidth();
+ Rect destRect(temp_width, temp_height);
+ t.setDisplayProjection(mDisplayToken, ui::ROTATION_270, destRect, destRect);
+ ALOGD("BootAnimation rotation is 270");
+ }// create the native surfacesp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565);
-
- SurfaceComposerClient::Transaction t;
+ //add text// this guest property specifies multi-display IDs to show the boot animation// multiple ids can be set with comma (,) as separator, for example:...
}//系统自带根据ro.bootanim.set_orientation_<display_id> 旋转屏幕动画方向
// Rotate the boot animation according to the value specified in the sysprop ro.bootanim.set_orientation_<display_id>.
// Four values are supported: ORIENTATION_0,ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270.
// If the value isn't specified or is ORIENTATION_0, nothing will be changed.// This is needed to support having boot animation in orientations different from the natural
// device orientation. For example, on tablets that may want to keep natural orientation
// portrait for applications compatibility and to have the boot animation in landscape.
void BootAnimation::rotateAwayFromNaturalOrientationIfNeeded() {const auto orientation = parseOrientationProperty();if (orientation == ui::ROTATION_0) {// Do nothing if the sysprop isn't set or is set to ROTATION_0.return;}if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) {std::swap(mWidth, mHeight);std::swap(mInitWidth, mInitHeight);mFlingerSurfaceControl->updateDefaultBufferSize(mWidth, mHeight);}Rect displayRect(0, 0, mWidth, mHeight);Rect layerStackRect(0, 0, mWidth, mHeight);SurfaceComposerClient::Transaction t;t.setDisplayProjection(mDisplayToken, orientation, layerStackRect, displayRect);t.apply();
}ui::Rotation BootAnimation::parseOrientationProperty() {const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();if (displayIds.size() == 0) {return ui::ROTATION_0;}const auto displayId = displayIds[0];const auto syspropName = [displayId] {std::stringstream ss;ss << "ro.bootanim.set_orientation_" << displayId.value;return ss.str();}();const auto syspropValue = android::base::GetProperty(syspropName, "ORIENTATION_0");if (syspropValue == "ORIENTATION_90") {return ui::ROTATION_90;} else if (syspropValue == "ORIENTATION_180") {return ui::ROTATION_180;} else if (syspropValue == "ORIENTATION_270") {return ui::ROTATION_270;}return ui::ROTATION_0;
}
applications
动画的屏幕方向,一阶段是由上面的代码决定,二阶段由Framework display决定
frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java+ private int mCustomerRotation = Surface.ROTATION_0;//add text@VisibleForTestingDisplayRotation(WindowManagerService service, DisplayContent displayContent,DisplayAddress displayAddress, DisplayPolicy displayPolicy,DisplayWindowSettings displayWindowSettings, Context context, Object lock,@NonNull DeviceStateController deviceStateController) {mService = service;mDisplayContent = displayContent;...
+ //add text
+ int temp_orientation = SystemProperties.getInt("persist.customer.set.orientation", 0);
+ if (temp_orientation == 0) {
+ mCustomerRotation = Surface.ROTATION_0;
+ } else if (temp_orientation == 90) {
+ mCustomerRotation = Surface.ROTATION_90;
+ } else if (temp_orientation == 180) {
+ mCustomerRotation = Surface.ROTATION_180;
+ } else if (temp_orientation == 270) {
+ mCustomerRotation = Surface.ROTATION_270;
+ }
+ mRotation = mCustomerRotation;//end replace
+ //add text
+ //观察 user_rotationif (isDefaultDisplay) {final Handler uiHandler = UiThread.getHandler();mOrientationListener =new OrientationListener(mContext, uiHandler, defaultRotation);mOrientationListener.setCurrentRotation(mRotation);mSettingsObserver = new SettingsObserver(uiHandler);mSettingsObserver.observe();if (mSupportAutoRotation && mContext.getResources().getBoolean(R.bool.config_windowManagerHalfFoldAutoRotateOverride)) {mFoldController = new FoldController();} else {mFoldController = null;}} else {mFoldController = null;}}boolean updateRotationUnchecked(boolean forceUpdate) {final int displayId = mDisplayContent.getDisplayId();...final int oldRotation = mRotation;final int lastOrientation = mLastOrientation;
- int rotation = rotationForOrientation(lastOrientation, oldRotation);
+ int rotation = mCustomerRotation;//rotationForOrientation(lastOrientation, oldRotation);//add text// Use the saved rotation for tabletop mode, if set.if (mFoldController != null && mFoldController.shouldRevertOverriddenRotation()) {int prevRotation = rotation;...}@Surface.Rotationint rotationForOrientation(@ScreenOrientation int orientation,@Surface.Rotation int lastRotation) {...//关于这里的判断,自己可以根据需求旋转条件
+ //add text
+ if(true){
+ return mCustomerRotation;
+ }
+ //add text
+if (isFixedToUserRotation()) {return mUserRotation;}}/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java @ScreenOrientation@Overrideint getOrientation() {
+ //add text
+ int mCustomerRotation = 0;
+ int temp_orientation = SystemProperties.getInt("persist.customer.set.orientation", 0);
+ if (temp_orientation == 0) {
+ mCustomerRotation = Surface.ROTATION_0;
+ return mCustomerRotation;
+ } else if (temp_orientation == 90) {
+ mCustomerRotation = Surface.ROTATION_90;
+ return mCustomerRotation;
+ } else if (temp_orientation == 190) {
+ mCustomerRotation = Surface.ROTATION_180;
+ return mCustomerRotation;
+ } else if (temp_orientation == 270) {
+ mCustomerRotation = Surface.ROTATION_270;
+ return mCustomerRotation;
+ }
+ //add textif (mWmService.mDisplayFrozen) {if (mWmService.mPolicy.isKeyguardLocked()) {//是否允许设备通过加速器(G-sensor)在所有四个方向自动旋转屏幕
/frameworks/base/core/res/res/values/config.xml<!-- If true, the screen can be rotated via the accelerometer in all 4rotations as the default behavior. -->
- <bool name="config_allowAllRotations">false</bool>
+ <bool name="config_allowAllRotations">true</bool><!-- If true, the direction rotation is applied to get to an application's requestedorientation is reversed. Normally, the model is that landscape is
about SurfaceFlinger
SurfaceFlinger是Android系统中负责屏幕显示内容合成的服务,它接收来自多个应用程序和系统服务的图像缓冲区,
根据它们的位置、大小、透明度、Z轴顺序等属性,将它们合成到一个最终的缓冲区中,然后发送到显示设备上
修改getPhysicalDisplayOrientation 显示方向,也可以实现上面的效果.
如果要动态的,就要用到系统属性,但是可能会遇到针对数据分区加密导致的开机时无法读取系统属性问题.
如何解决,(修改init.mount_all_early.rc和fstab.in)参考:RK平台android12 动态调整屏幕方向
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cppui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(DisplayId displayId,bool isPrimary) const {/*const auto id = PhysicalDisplayId::tryCast(displayId);if (!id) {return ui::ROTATION_0;}if (getHwComposer().getComposer()->isSupported(Hwc2::Composer::OptionalFeature::PhysicalDisplayOrientation)) {switch (getHwComposer().getPhysicalDisplayOrientation(*id)) {case Hwc2::AidlTransform::ROT_90:return ui::ROTATION_90;case Hwc2::AidlTransform::ROT_180:return ui::ROTATION_180;case Hwc2::AidlTransform::ROT_270:return ui::ROTATION_270;default:return ui::ROTATION_0;}}if (isPrimary) {using Values = SurfaceFlingerProperties::primary_display_orientation_values;switch (primary_display_orientation(Values::ORIENTATION_0)) {case Values::ORIENTATION_90:return ui::ROTATION_90;case Values::ORIENTATION_180:return ui::ROTATION_180;case Values::ORIENTATION_270:return ui::ROTATION_270;default:break;}}*/return ui::ROTATION_270;
}void SurfaceFlinger::startBootAnim() {// Start boot animation service by setting a property mailbox// if property setting thread is already running, Start() will be just a NOPmStartPropertySetThread->Start();// Wait until property was setif (mStartPropertySetThread->join() != NO_ERROR) {ALOGE("Join StartPropertySetThread failed!");}
}
SurfaceFlinger的原理
Android显示系统SurfaceFlinger详解 超级干货
正点原子RK3588开发板Android系统屏幕显示方向配置
相关文章:
Android T about screen rotation(二)
需求:客户因为模具问题,屏幕方向需要动态的变动.(方向: 0 , 90 , 180 ,270) 拆分:设备开机过程中图像显示可分为三个阶段,boot logo(1)->kernel logo(2),这一段的处理需要驱动层,所以暂时忽略. 开机动画 Bootanimation(3)阶段 和 Home Launcher应用显示(4)阶段是需要修改的…...
qt反射之类反射、方法反射、字段反射
话不多说,直接上代码: main.cpp: #include < QCoreApplication > #include “fstudent.h” #include “manage.h” int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); //注册类型 qRegisterMetaType(“FStudent”); Manage m…...
服务器数据恢复—raid5阵列离线硬盘强制上线失败如何恢复数据?
服务器数据恢复环境: 某品牌2850服务器上有一组由6块SCSI硬盘组建的raid5磁盘阵列,上层操作系统为Redhat linuxext3文件系统。 服务器故障&初检: 服务器在运行过程中突然瘫痪,管理员对服务器中的raid进行检查后发现有两块硬盘…...
FastAPI+Vue3零基础开发ERP系统项目实战课 20240815上课笔记 列表和字典相关方法的学习和练习
昨日回顾 1、大小写转换2、去除空格3、判断是否为数字4、前缀后缀 昨日练习题进度 练习:判断验证码是否正确 1、生成一个由四个字符组成的验证码字符串,要求有大写有小写,要求左右两边有空格2、打印到控制台3、让用户输入这个验证码&…...
基于微信小程序的诗词智能学习系统的设计与实现(全网独一无二,24年最新定做)
文章目录 前言: 博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为…...
httplib库:用C++11搭建轻量级HTTP服务器
目录 引言 一. httplib库概述 二. httplib核心组件 2.1 数据结构 2.2 类和函数 2.3 服务器搭建 编辑 结语 引言 在现代软件开发中,HTTP服务是网络应用的基础。对于需要快速搭建HTTP服务器或客户端的场景,使用成熟的第三方库可以极大提高开发效…...
基于嵌入式C++、SQLite、MQTT、Modbus和Web技术的工业物联网网关:从边缘计算到云端集成的全栈解决方案设计与实现
一、项目概述 1.1 项目目标与用途 随着工业4.0时代的到来,传统工业设备与现代信息技术的结合越来越紧密。物联网工业网关作为连接工业设备与云端平台的桥梁,在工业自动化、设备监控、远程运维等方面发挥着至关重要的作用。本项目旨在设计并实现一个能够…...
Chapter 38 设计模式
欢迎大家订阅【Python从入门到精通】专栏,一起探索Python的无限可能! 文章目录 前言一、单例模式二、工厂模式 前言 在软件开发中,设计模式提供了一种可重用的解决方案,以应对在特定环境中反复出现的问题。这些模式是基于经验总结…...
Redis5主备安装-Redis
本次Redis有两台服务器及3个独立IP:主服务器的ip地址是192.168.31.190,从服务器的IP地址是192.168.31.191,vipIP地址是192.168.31.216 主备方案承载Redis最大的好处是无需考虑Redis崩后无法访问。 前提是需要优先安装keepalived,…...
C++票据查验、票据ocr、文字识别
现在,80、90后的人们逐渐过渡为职场上的主力人员,在工作中当然也会碰到各种各样的问题。比如,当你的老板给你一个艰难的任务时,肯定是不能直接拒绝的。那么我们该怎么做呢?翔云建议您先认真考虑老板说的任务的难度&…...
pytest.ini介绍
1.pytest.ini是什么 ? pytest.ini文件是pytest的主配置文件;pytest.ini文件的位置一般放在项目的根目录下,不能随便放,也不能更改名字。在pytest.ini文件中都是存放的一些配置选项 ,这些选项都可以通过pytest -h查看到…...
Vue项目打包成桌面应用
Vue项目打包成桌面应用 一、使用 NW.js 打包 NW.js基于Chromium和Node.js。它允许您直接从浏览器调用Node.js代码和模块,并在应用程序中使用Web技术。此外,您可以轻松地将web应用程序打包为本机应用程序。 NW官网...
DEFAULT_JOURNAL_IOPRIO
/* * 这些是 CFQ(完全公平排队)实现的 I/O 优先级组。 RT 是实时类,它总是能获得优质服务。 BE 是尽力而为的调度类,是任何进程的默认类别。 IDLE 是空闲调度类,只有在没有其他人使用磁盘时才会被服务。 */ /* *…...
【阿卡迈防护分析】Vueling航空Akamai破盾实战
文章目录 1. 写在前面2. 风控分析3. 破盾实战 【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…...
使用AWS Lambda轻松开启Amazon Rekognition之旅
这是本系列文章的第一篇,旨在通过动手实践,帮助大家学习亚马逊云科技的生成式AI相关技能。通过这些文章,大家将掌握如何利用亚马逊云科技的各类服务来应用AI技术。 那么让我们开始今天的内容吧! 介绍 什么是Amazon Rekognition&…...
如何获取VS Code扩展的版本更新信息
获取VS Code 扩展的版本更新的需求 因为企业内部有架设私有扩展管理器的要求,但是对于一些官方市场的插件,希望可以自动获取这些扩展的更新并上传至私有扩展管理器。于是就有了本篇介绍的需求: 通过API的方式获取VS Code 扩展的更新。 关于…...
Python开源项目周排行 2024年第13周
#2024年第13周2024年8月5日1roop一款基于深度学习框架TensorFlow和Keras开发的单图换脸工具包,提供了丰富的功能和简洁易用的界面,使得用户可以轻松实现单图换脸操作。支持多张人脸替换成同一个人脸,勾选多人脸模式即可 人脸替换 高清修复自…...
day04--js的综合案例
1.1 商品全选 需求:商品全选 1. 全选 :点击全选按钮,所有复选框都被选中 2. 全不选 :点击全不选按钮,所有复选框都被取消选中 3. 反选 : 点击反选按钮,所有复选框状态取反 <!DOCTYPE html> <html lang"en">…...
【产品经理】定价策略
年初的时候,尝试自己独立运营了一个美团店铺,最终没有继续做下去了,原因是利润率太低,平台和骑手把利润拿走太多了,根本没有钱赚,烧钱搞流量更是深不见底。 不过也学到了很多东西,比如选品策略…...
webrtc学习笔记3
Nodejs实战 对于我们WebRTC项目而言,nodejs主要是实现信令服务器的功能,客户端和服务器端的交互我们选择websocket作为通信协议,所以以websocket的使用为主。 web客户端 websocket WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
