OpenHarmony系统解决方案 - 配置屏幕方向导致开机动画和Launcher显示异常 原创 精华
TiZizzz
发布于 2023-7-16 16:38
浏览
3收藏
问题描述
问题环境
系统版本:OpenHarmony-3.2-Release
问题现象
- 配置设备默认方向,例如修改为横屏显示,修改文件display_manager_config.xml的buildInDefaultOrientation参数值为2(Orientation::HORIZONTAL)。
源码中文件位于foundation/window/window_manager/resources/config/rk3568/display_manager_config.xml。
系统中文件位于/etc/window/resources/display_manager_config.xml。
- 系统启动后开机动画横竖屏切换,Launcher显示异常(偶现,去掉锁屏应用和锁屏服务后大概率出现)。
异常效果:
正常效果:
问题原因
- ScreenRotationController初始化会设置rotationLockedRotation_属性初始值,而ScreenRotationController初始化的触发点在开机动画窗口销毁时,此时间点在Launcher的Window加载之后。
- Launcher加载Window时会设置SetScreenRotation(屏幕旋转角度),因为Launcher的方向加载配置为AUTO_ROTATION_RESTRICTED(方向随传感器旋转),所以SetScreenRotation会根据rotationLockedRotation_属性值设置旋转角度,而此时rotationLockedRotation_属性并未被设置初始值,所以SetScreenRotation设置的值取得是默认值0(如果配置为Orientation::HORIZONTAL,则应旋转90度,取值为1),导致问题的产生。
解决方案
调整ScreenRotationController初始化时序,使ScreenRotationController在Launcher加载Window时触发。修改源码文件:foundation/window/window_manager/wmserver/src/window_node_container.cpp
- WindowNodeContainer::RemoveWindowNode函数中,移除以下代码:
修改后WindowNodeContainer::RemoveWindowNode函数代码:
- WindowNodeContainer::AddWindowNode函数中,在WLOGFD("AddWindowNode windowId: %{public}u end", node->GetWindowId());行代码前添加以下代码:
修改后WindowNodeContainer::AddWindowNode函数代码:
定位过程
- 落盘异常开机日志,查找SetRotation相关日志,发现系统启动过程中横竖屏被设置两次。
- 查找对应源码发现rotation代表含义。在系统启动时已成功设置旋转90度(水平),但又被设置为旋转0度(垂直),导致异常。
- 追踪设置旋转0度(垂直)操作日志。发现set orientation时,orientation被设置为8,对应源码含义为AUTO_ROTATION_RESTRICTED。
- Launcher在创建window时会把PreferredOrientation设置为Window.Orientation.AUTO_ROTATION_RESTRICTED。
- 当Launcher显示窗口时执行SetOrientation,isFromWindow参数为true。
- 因orientation为AUTO_ROTATION_RESTRICTED,会执行ProcessSwitchToSensorRelatedOrientation函数。
- 当rotationLockedRotation_与GetCurrentDisplayRotation()不一致时会切换旋转角度。在此处增加日志打印rotationLockedRotation_和GetCurrentDisplayRotation()的值,发现在开机触发Launcher设置屏幕旋转角度时GetCurrentDisplayRotation()函数获取的当前屏幕旋转角度为1(水平)是正确的。而rotationLockedRotation_为0(垂直)。
- 查看rotationLockedRotation_被设置的场景。分别增加日志,发现开机启动时SetScreenRotationLocked函数不会被触发,而Init函数则是在Launcher启动后被触发,此时Launcher已经把屏幕旋转角度设置为0(垂直),rotationLockedRotation_的初始化值则会变成Launcher设置后的参数0(垂直)。而在Launcher触发SetScreenRotation时,rotationLockedRotation_还未被设置,此时取默认值0(垂直),导致异常的产生。
- ScreenRotationController::Init()的触发时机是在系统检测到启动完成后,关闭开机动画窗口时触发。如果此操作在Launcher加载Window之后,则会导致问题。改变ScreenRotationController::Init()的初始化时序,在Launcher的window加载时初始化可以修复此问题。
知识分享
如果应用的方向需要随系统切换,可以在module.json5的ability中配置orientation为auto_rotation_restricted。
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2023-7-16 16:41:06修改
赞
6
收藏 3
回复
6
4
3
相关推荐
一般遇到这种情况不影响使用就忽视了,还是楼主细致
这种属于设计失误吗
程序设计出来总会有一些场景没有被考虑到,而出现Bug,尤其是当多个模块协同调用的时候,最容易出现。是否属于设计失误咱们没必要去纠结它,问题可以得到解决,我们能从中学习到一些知识,看出当初设计人的一些设计想法,充实自己,会更有意义。
博主您好,我也在开发OpenHarmonyOS开发板,不知是否能添加以下您的联系方式