问题描述
锁屏界面进入电话界面,解锁后不能直接进入
复现方式
设置中将锁屏设置成PIN码,灭屏后点亮屏幕,从左下角电话处滑动,出现PIN码解锁界面,输入正确PIN码后,没有直接进入拨号界面,点击屏幕会有圈圈的水纹,多次尝试后发现需要按返回键,然后再次滑屏,才能解锁
分析过程
在输入正确的PIN码后,上层的PIN界面因为匹配成功而被Dismiss掉,但是点击其他Home键等无效,通过对home键的监听,了解到home键只在Keyguard界面时,无效,因此可以判断,Keyguard界面未消失,而log中找不到handlehide的打印,可以判断应该是由于Keyguard界面未消失导致,接下来主要从用户滑动Phone应用开始,查找与Keyguard界面的关联。
用户通过滑动电话图标启动了phone应用,通过SecurityMode securityMode = mSecurityModel.getSecurityMode(KeyguardUpdateMonitor.getCurrentUser())获取到当前模式为PIN码模式,之后showSecurityScreen显是PIN码解锁界面,通过判断输入的数字是否正确,来判断是否解锁成功,若解锁成功,调用handleStartKeyguardExitAnimation动画退出keyguard界面。
添加log发现,在启动phone的时候,所带参数dismissShade为true导致在executeRunnableDismissingKeyguard的时候,无法执行readykeyguardDone致使keyguard无法消失。
以下是executeRunnableDismissingKeyguard方法:
由于dismissshade为true,而当前未解锁,因此ExpandedVisibile依然为true,无法执行runPostCollapseRunnables而进入到animatecollapsepanels方法,以下为animatecollapsepanels:
在进入到animatecollapsepanels方法时,由于所带参数Force为true,导致无法进入到runPostCollapseRunnables而致使无法执行readKeyguardDone,因此Keyguard界面无法消失。
解决方案
因为在启动Phone时,多带dismissShade的默认值即为true,所以从上述过程去解决问题的话,风险较大,转而从加密模式完成解锁开始思考。
PIN界面由于密码匹配而被dismiss掉,在PIN码完成匹配时,会调用Keyguard的dismiss从而取消Keyguard的显示,但是输入正确的PIN码后,PIN界面消失但是Keyguard界面未消失,接下来我们来看一下在PIN码完成解锁的过程中时,Keyguard的状态,以下为完成解锁后,通过加密模式去取消Keyguard显示:
在finish时,由于mDismissAction不为空,导致执行onDismiss()即executeRunnableDismissingKeyguard中的方法,而由于deferKeyguardDone通过mDismissAction.onDismiss获取到的返回值为true导致进入到keyguardDonePendin,因此,可以通过对executeRunnableDismissingKeyguard执行animatecollapsepanels告诉用户一个返回值false,此时Keyguard并未消失。