AOD始终显示时间和信息(Dream)简析
DreamManagerService启动
在SystemServer的startOtherServices方法中会启动DreamManagerService服务
这里是调用SystemServiceManager的startService方法
显然,在SystemServiceManager的startService方法中首先将要启动的系统服务添加到其mServices列表中,这样后面方便添加系统服务的生命周期回调,然后调用了要启动的系统服务的onStart方法,查看下DreamManagerService的onStart方法
这里publishBinderService和publishLocalService方法都是将系统服务添加到一个集合中,以便在其他代码中获取对应的系统服务
例如publishLocalService如下
在publishLocalService后,就可以调用LocalServices的getService方法获取添加的对象
onBootPhase
前面在SystemServer调用了SystemServiceManager的startService方法后,在启动过程不同阶段还会调用mSystemServiceManager.startBootPhase方法,
显然这里会调用系统服务的onBootPhase方法,来知会各系统服务启动阶段并做相应的逻辑
查看DreamManagerService的onBootPhase方法
这里主要是注册了一个广播接收器(监听切换用户的广播,一般只涉及多用户场景),注册了一个Settings数据监听器,还有调用了下writePulseGestureEnabled方法
查看下writePulseGestureEnabled方法逻辑
这里几个逻辑可能涉及后面具体具体的功能流程,所以这里简单分析下
getDozeComponent
在判断功能启用时这里会返回对应实现功能的组件,这里mDozeConfig是AmbientDisplayConfiguration的对象,其ambientDisplayComponent只是返回一个字串,然后通过ComponentName的unflattenFromString方法返回一个字串对应的ComponentName对象,其表示功能对应的组件
查看下config_dozeComponent字串值,发现默认资源中其字串是空(frameworks/base/core/res/res/values/config.xml)
按理说如果配置是空应该不支持AOD的,但手中的一个手机却支持,dumpsys overlay命令看了下,发现其中有对应配置
将/vendor/overlay/framework-res__auto_generated_rro_vendor.apk导出来反编译查看发现有如下配置
那么该机器上getDozeComponent获取的则是systemui的DozeService组件
validateDream
这里是校验对应ComponentName的有效性,首先要确实是个服务,然后需要对应服务的的应用的目标SDK要大于等于L版本(21),还需要服务声明了android.permission.BIND_DREAM_SERVICE权限
InputManagerService.setPulseGestureEnabled
从上面的代码可以看出setPulseGestureEnabled方法主要是记录一个开关,按代码作用,其在config中对config_doubleTouchGestureEnableFile写入一个文件的路径,然后在调用setPulseGestureEnabled的时候,对文件写入1/0,不过从源码上看config_doubleTouchGestureEnableFile是空,所以这里代码并未实现
设置始终显示时间和信息
查看设置中对应字串
查看Settings中res/xml/security_lockscreen_settings.xml有如下代码:
查看AmbientDisplayAlwaysOnPreferenceController中相关逻辑
从这里可以看到,在开关始终显示时间和信息开关时会设置Settings.Secure表中设置doze_always_on的字段的值
AmbientDisplayConfiguration的alwaysOnEnabled
在框架和SystemUI等地方大部分不是直接获取Settings.Secure表中的doze_always_on的字段的值,而是通过AmbientDisplayConfiguration的alwaysOnEnabled方法来获取是否打开了AOD
其中boolSetting的代码就是获取Settings.Secure表中的doze_always_on的字段的值(缺省值为mAlwaysOnByDefault,是从系统资源中获取,系统资源源码中是true,overlay的apk中是false)
其中alwaysOnAvailable是获取是否支持AOD(如下面代码,通过系统资源或debug配置获取是否支持AOD,并判断系统资源配置的AOD组件是否不为空)
config_dozeComponent前面通过反编译的系统资源的overlay的apk获取到是com.android.systemui/com.android.systemui.doze.DozeService
config_dozeAlwaysOnDisplayAvailable同样源码中是false,查看反编译的overlay的apk获取是true
startDream
在灭屏的时候会调用DreamManagerService的startDream方法
这里分别查看下chooseDreamForUser和startDreamLocked方法
chooseDreamForUser
在doze为true时,走if中的逻辑,主要是getDozeComponent和validateDream方法,这两个方法前面已经介绍过了,手中机器返回的是systemui的DozeService的组件,而这里也是一般走的逻辑
在doze为flase时虽然自测并未走该分支,但也简单看下其逻辑,这里其实也是返回一个组件,不过是调用getDreamComponentsForUser方法
显然getDreamComponentsForUser方法是根据Settings.Secure.SCREENSAVER_COMPONENTS和Settings.Secure.SCREENSAVER_DEFAULT_COMPONENTS对应的字串值来获取组件的
startDreamLocked
这里主要是调用了DreamController的startDream方法
上面DreamController的startDream方法中主要做了两个事,
一是绑定了前面传过来的AOD组件(这里即systemui的DozeService),绑定后连接为DreamRecord(继承了ServiceConnection)
二是发送了个延时消息,如果5秒后仍没有绑定服务成功,则调用stopDream方法停止AOD
其主要逻辑还是在绑定DozeService服务上,而查看DozeService其实并没有什么具体的逻辑,也没有绑定服务的逻辑,其绑定相关逻辑其实在其父类DreamService中,而应用实现自己的AOD和屏保相关服务一般也都是继承DreamService
查看DreamController和DreamService的绑定服务相关逻辑:
在DreamController中绑定服务后主要调用了下attach方法,而其主要是调用DreamService的attach方法
在DreamService中查看绑定服务相关和attach方法
所以这里主要调用到了DreamService的attach方法,其中主要逻辑如下:
这里有个分支mWindowless,是调用DreamService的setWindowless方法可设置的
而在DozeService中的onCreate方法中其有调用setWindowless为true,所以上面显然走的是else的分支,即调用onDreamingStarted方法
onDreamingStarted和onDreamStopped是DozeService实现AOD功能的主要的一个生命周期,分别对应在进入和退出AOD模式
再看下DozeService的onDreamingStarted后的具体逻辑
这里有两个主要方法调用,
一是DozeMachine的requestState方法切换状态,设置屏幕状态、知会到应用内相关做一些变更等
一是调用startDozing方法
startDozing方法具体实现在其父类DreamService中
显然startDozing最后会调用到DreamManagerService的startDozing方法
显然这里会调用PowerManagerService的startDozeOverrideFromDreamManager方法,设置power的一些状态,然后申请一个power锁mDozeWakeLock
小节
AOD从代码分析和现象查看,其是一种介于亮屏和灭屏的状态,主要是power状态的变更,既希望能省电,又希望能时刻看到时间等信息,主要是希望以较小的耗电的代价来让用户能随时看到时间等信息,而不用去特别的亮屏后才能看到,一般灭屏进入AOD,亮屏退出AOD,前面主要讲了一些进入AOD的逻辑,退出的逻辑基本相似,上面分析的主要是一些框架和应用层的逻辑,其后面还有很多其他方面,比如doze状态应用的管理、屏幕显示和亮度的变更等,这些都是为了省电,这里不继续分析
标签:逻辑,AOD,服务,查看,Dream,简析,调用,方法 From: https://www.cnblogs.com/luoliang13/p/18277084