1 问题背景
问题背景为APK组同事为了优化显示界面,期望增加模糊显示,Android系统下模糊效果是由一个只读系统属性控制,名为:ro.surface_flinger.supports_background_blur,当在系统mk文件中打开该属性后,虽然模糊效果满足了APK组需求,但在进行长按power键进行关机操作时,发现原本关机效果的相关组件如ProgressBar等均无法显示。
异常效果图如下图1:
图1 异常效果图
对比之下修改后的正常效果图如下图2:
图2 正常效果图
可以看到正常效果图在关机时是有文本组件与进度组件正常显示的,而异常图却完全消失,因此产生一个关机动画缺失体验Bug,为方便后续说明,补充一下上面两个效果图是在长按power键弹出相应对话框后由用户点击关机组件后产生的,所以在上述两个效果图之前还有个dialog图,如下图3所示:
图3 长按power dialog图
图1和图2其实都是在点击图3关机组件后的流程,为便于读者理解后续流程特此说明下
2 代码框架流程与问题分析解决
根据问题现象,将问题分为以下三个步骤进行逐步拆解:
(1). 追踪Android12.0系统,长按power键场景下,Dialog图显示代码流程。
(2). 追踪点击关机组件行为产生后,关机动画显示代码流程。
(3). Android系统层模糊属性相关位置代码和上述流程产生关联的位置
2.1 长按power键, Dialog图显示流程
Android 系统下,power按键隶属于输入系统中的一部分,主体输入事件处理流程为driver->InputReader线程->InputDispatcher线程->Activity or ViewGroup or View进行事件消费,由于本章重点不在IMS部分,所以直接从key事件分发部分开始说起。代码起点为:Inputdispatcher::notifyKey方法
2.1.1 Inputdispatcher::notifyKey按键分发
文件路径:
framework/native/services/inputflinger/dispatcher/InputDispatcher.cpp;
核心代码片段如下图4所示:
图4 notifyKey核心逻辑
注意虽然notifyKey这个方法实现是在InputDispatcher类中,但此时执行的线程还是在InputReader线程中,InputDispatcher还未被wake唤醒起来,notifyKey执行完后由在结束时由是否正常进入InBoundQueue队列的返回值needwake来决定是否唤醒InputDispatcher线程,这部分逻辑不在截图片段里,读者可自行去aosp开源网站阅读。
notifyKey 逻辑中, 进一步调用mPolicy->interceptKeyBeforeQueueing进行输入事件分发
2.1.2 InputDispatcher转Java按键链路
需要追踪mPolicy是何对象,以及interceptKeyBeforeQueueing最终调用位置在何处,这里直接结论是最终调用到PhoneWindowManager.java中, 那现在就追踪下是如何一步步调用到这个Java文件中来的,所以这里先抛出问题1:interceptKeyBeforeQueueing调用走向
追踪这个问题的来源需要先从SystemServer.java开始看, 核心位置在于IMS和WMS服务创建时
2.1.2.1 JNI->Java流程
文件路径:
frameworks/base/services/java/com/android/server/SystemServer.java
核心代码片段如下图5所示:
图5 IMS示例化
实例化时在IMS中直接调用nativeInit 使用JNI进入native层C++运行环境
文件路径:
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
核心代码片段如下图6所示:
图6 IMS JNI调用
此时进入C++运行环境,
对应IMS JNI的文件路径:
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
核心代码片段如下图7所示:
图7 nativeInit具体实现
核心逻辑在于初始化NativeInputManager,查看NativeInputManager构造
代码片段如下图8所示:
图8 NativeInputManager实例化
在NativeInputManager构造方法中进一步构造了InputManager, 注意这里传入的this,this表示本类对象,即NativeInputManager对象(因为后面会用到),继续转入InputManager构造
文件路径:
frameworks/native/services/inputflinger/InputManager.cpp
代码片段如下图9所示:
还没有评论,来说两句吧...