屏幕参数方向引入
由于客户的选型,需要更改自身屏幕方向;在P之前的android SDK中,谷歌并不支持相关的功能;所以需要原厂自行定制;在P上 MTK为统一刷GSI和不刷GSI方向的统一,向谷歌mainline提供了对应的补丁;之后在Q上谷歌又进行了相关的修改;使得安卓支持改变默认显示方向的功能也日趋稳定;当然也是会存在bug,如在android Q上就出现了开机动画和应用启动动画异常问题(已解决);但为了统一后续android平台下的横屏竖用使用配置;全志平台androidQ横屏竖用也是依托这个补丁进行横屏竖用的实现;
有兴趣的可以访问这个网站查看更多的信息:GSI 支持横屏模式
本文目的
一:梳理安卓TP,gsensor,surfaceflinger中rotation的系数之间的关系,客户配置地方;
二:系统旋转监听以及应用旋转方向申请;
三:现有显示框架支持横屏竖用原理;
参数配置
dtbo中设置TP方向
为了分离linux环境(dragonboard)和android环境的中TP的方向,使其不相互影响,为了使用android的新朝向,我们将TP方向更改的配置放到dtbo中;在android source并lunch对应的版型后,cbd即可到对应的路径;本文将以全志A50 A7版型为例讲解配置;
1 | &soc { |
参数解释:
1 | ctp_screen_max_x 触摸板的x轴最大坐标 |
修改好需要重新编译和打包内核,在配置该参数的需注意检查驱动是否支持该方法;
非安全固件可以通过命令行修改参数进行验证,将default/env.cfg中将bootdelay改成3s,配合串口在uboot启动过程中按住enter键进入uboot命令行,用fdt 命令的修改验证;
步骤如下:
1 | 如当下需要修改ctp_screen_max_x,可按如下步骤进行修改 |
方案目录下配置显示和sensor方向
1 | + # change SurfaceFlinger Orientation(0, 90, 180, 270) |
camera方向配置
在有摄像头的方案下面还需调整自己的摄像头方向,提供的配置地方有:
configs/camera.cfg
1 | camera_orientation //可设置0,90,180,270 |
hawkview/sensor_list_cfg.ini
1 | sensor_hflip0 //水平反转 |
客户可以adb remount,选择busybox vi到对应的文件下;先调整camera的朝向,在调整镜像;
1 | vendor/etc/camera.cfg |
Gsensor方向调整方法二
对于Gsensor还有一种改法与camera一样,在方案目录下面有相应的文件可以提供配置;方案商的话其实根据想要的屏幕朝向和sensor的摆放,配置这个文件会是一件更为简单和兼容性更好的操作;
目录为config/gsensor.cfg,
1 | gsensor_name = sc7660 |
gsensor坐标系:
匹配规则:
安卓是用的右手坐标系,Z轴相对屏幕朝外,gsensor的数据是一个三维数组,values[0]对应的x轴的值,value[1]对应的y轴,value[2]对应的Z轴,将相对轴竖直朝上放置时候,以该轴为对应的值为正(约9.8左右),其他两轴对应为0为准;
总结
对于Q平台上需要更改默认屏幕方向,为兼容多个设备,且统一后续平台谷歌方案配置需要配置的选项如上述所述配置Android显示方向,recovery显示方向,TP方向,gsensor,camera,以及bootlogo图片方向;
至此,若是只需要知道怎么配置的可以不看以下的章节;
Input系统
linux input简介
软件框图
Tp驱动流程
借着梳理这个事件上报流程,我们也可以将主要的架构和流程涵盖;
以TP gslx680为例:
1 | static int gsl_ts_probe(struct i2c_client *client, |
简而言之:input_dev在中断处理函数里面上报事件 -> input_core找到对应的handler -> input_handler:如edev通过___pass_event将事件上报给用户层;
android Input流程
流程简单介绍:
一:APP setView建立inputChannel和window的连接
当一个应用程序有Activity能接受用户输入,他就要将自己的Window(ViewRoot)通过setView()注册到Window Manager Service中;
frameworks/base/core/java/android/view/ViewRootImpl.java
1 | public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { |
建立Window和InputDispatch的联系;
二:framework层的收集和分发
1 | framework/native/services/inputflinger/EventHub.cpp |
流程总结:内核将原始事件写入设备节点中,InputReader不断地通过Eventhub将原始事件取出来并翻译加工成android输入事件,然后交给InputDispacther.InputDispactcher根据WMS提供的窗口信息,将事件交给格式的窗口,窗口的ViewRootimpl对象再沿着控件树将事件派发给感兴趣的控件,控件对其接收到的事件做出响应,更新自己的画面,执行特定的动作;当事件处理完成后,会执行finishInputEvent()方法,在进一步调用InputConsumer:sendFinshedSignal告知InputDispatcher线程事件已经处理完成,InputDispatch完成后,最终会调用doDispatchCycleFinishedLockedInterrupttible方法将dispacthEntry从等待队列里面移除;
如Gityuan总结的图片所示
显示方向旋转
Sensor的框架分为三个层次,客户层,服务层,HAL层,服务端负责从HAL层读取数据,并将数据写到管道中,客户端通过管道读取服务端数据;具体细节可以看这两份文档
流程图:
自动旋转监听
系统从SystemUI或者setting中获取到是否开启自动旋转;最终设置到mUserRotationMode和mUserRotation
1 | systemUI: |
1 | services/core/java/com/android/server/policy/WindowOrientationListener.java |
rotation和orientation区别
rotation:旋转方向是指界面(不是手机)相对于默认情况情况顺时针旋转的角度,平板一般默认横屏,而小屏幕设备默认竖屏;
1 | frameworks/base/core/java/android/view/Surface.java |
orientation:分为两种情况,一个是ActivityInfo.java,另一个在Configuration.java.前者具体来说是ActivityInfo.screenOrientation,这个值用于记录App强制设定的方向或者旋转模式。具体代码如下:
rotation旋转的是物体坐标系,而orientation旋转的是世界坐标系,即观察视角;
应用申请旋转
对于应用开发者而言可以通过调用如下api去申请屏幕朝向
1 | core/java/android/app/Activity.java |
获取命令如下:
1 | dumpsys window | grep mCurrentAppOrientation |
1 | frameworks/base/core/java/android/content/pm/ActivityInfo.java |
流程图如下所示:
横屏竖用原理
参数设置流程介绍
1 | hardware/interface |
应用欺骗
在SurfaceFlinger中初始化primaryDisplayOrientation,当应用获取显示配置的时候getDisplayConfigs,此时的应用就能够获取到对应的竖屏配置了;
1 | status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, |
显示欺骗
在DisplayDevice中就会初始化mDisplayInstallOrientation,在设置矩阵的时候oritentationToTransform就会被篡改;
1 | void DisplayDevice::setProjection(int orientation, |
这样给到GPU的Transform就会被欺骗带有一个角度;
1 | system/core/libsystem/include/system/graphics-base-v1.0.h |
这样就实现了从应用到显示横屏竖用的欺骗流程
其他
常见命令
模拟输入事件
1 | 1. 模拟文本 input text "hello,word" |
旋转事件
1 | settings put system accelerometer_rotation 0 //关闭自动旋转 |
安卓触点显示
1 | settings put system show_touches 1 |
传感器
1 | 可以利用查看目前sensor上报的事件值 |
参考资料
图解Android-AndroidGUI 系统(5)-Android的Event Input System