Android12.0 背景模糊blur属性开启后关机动画消失问题解决与流程总结

马肤
这是懒羊羊

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所示:


文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复:表情:
评论列表 (暂无评论,0人围观)

还没有评论,来说两句吧...

目录[+]

取消
微信二维码
微信二维码
支付宝二维码