Android Framework------之PowerManagerService的功能
自从接触Android系统已经一年多了,这段时间内对于Android系统的Framework层的各个模块都有过接触,有时也做过分析,但是一直没能形成一个总结性的东西。这次下定决心,好好整理整理对于Android系统的学习梳理一下自己的思路。本文一方面是为了自己梳理下知识,文中涉及的内容,基本是拾人牙慧,很少有自己的东西,最多也就算是自己的总结;除此作用之外,如果能为后来者引玉,也算是一点功德吧。这次首先是对Android系统中的PowerManagerService进行下整理。之所以先选择PowerManagerService,是因为这个模块相对于Android系统中其他的模块而言,与系统其他的模块之间的交互较少,而且Framework中的PowerManagerService模块是由Google开发并维护的,虽然以Linux Kernel的Power为基础,但是它们之间的耦合度低,完全可以把两者分开,单独进行分析也不会造成困惑。接下来,我会从不同的角度,分别介绍下PowerManagerService的功能。还是先来看看PowerManagerService在Framework中的目录结构吧。 PowerManagerService在Android4.2源码中的位置是:/frameworks/base/services/java/com/android/server/power/,在这个目录下有以下文件:
DisplayBlanker.java
DisplayPowerController.java
DisplayPowerRequest.java
DisplayPowerState.java
ElectronBeam.java
Notifier.java
PowerManagerService.java
RampAnimator.java
ScreenOnBlocker.java
ShutdownThread.java
SuspendBlocker.java
WirelessChargerDetector.java
这些文件中,个人认为对于PoweManagerService而言除了本身的代码,较为重要的有DisplayPowerController.java,DisPlayPowerState.java, Notifier.java.而DisplayPowerRequest相当于一个辅助类,用来存储一些统一的属性和变量,让PowerManagerService和DisplayPoerController, DisplayPowerState交互时能够使用统一的变量。 另外,还有及个接口文件SuspendBlocker.java,DisplayBlanker.java, ScreenOnBlanker.java。其次就是ShutdownThread.java,WirelessChargerDetector.java,RampAnimator.java, ElectronBeam.java. 下面,就先逐一介绍下PowerManagerService在Framework中的这些文件:PowerManagerService.java: 主要是计算系统中和Power相关的计算,然后决策系统应该如何反应。同时协调Power如何与系统其它模块的交互,比如没有用户活动时,屏幕变暗等等。
DisplayPowerController.java:管理Display设备的电源状态。仅在PowerManagerService中实例化了一个对象,它算是PowerManagerService的一部分,只不过是独立出来了而已。主要处理和距离传感器,灯光传感器,以及包括关屏在内的一些动画,通过异步回调的方式来通知PowerManagerService某些事情发生了变化。
DisPlayPowerState.java:在本质上类似于View,只不过用来描述一个display的属性,当这些属性发生变化时,可以通过一个序列化的命令,让这些和display电源状态的属性一起产生变化。这个类的对象只能被DispalyPowerController的Looper持有。而这个Looper应该就是PowerManagerService中新建的一个HandlerThread中的Looper。和PowerManager相关的,包括DisplayPowerState和DisplayPowerController相关的消息处理应该都可以通过这个HandlerThread进行运转的。
Notifier.java: 将Power Manager state的重要变化通过broadcast发送出去。
接下来就说说三个接口文件
SuspendBlocker.java: 相当于一个partial wake lock。在内部使用,避免了使用上层的唤醒锁机制
DisplayBlanker.java:主要功能一是BLANK DISPLAY: The display is blanked, but display memory is maintained and new data can be entered;而是UNBLANK DISPLAY:The display is restored/turned to active state.(不知道这两个英文的解释是否恰当,还有待验证)。
ScreenOnBlanker.java:描述了一种较为低级的blocker机制,主要用于关屏或者隐藏屏幕内容,直到window manager准备好新的内容
DisplayPowerRequest.java:描述了一些对于display电源状态的请求。
最后看看剩余的这些类:
ShutDownThread.java: 主要功能就是关机和重启,当我想要执行重启或者关机的时候,这个新城就会被启动。
ElectronBeam.java: 负责屏幕由开到关,或者由关到开的一些GL动画。在DisplayPowerController管理
WirelessChargerDetector.java:和无线充电相关的东西,没有细看。
每个文件的大致功能就是这样的,也许有些地方不是很恰当,还是需要仔细阅读源码,才能确切地知道到底是怎么回事,有些功能到底是如何实现的。
先从交互的角度去看看PowerManagerService的功能。在这里的交互是说PowerManagerService与应用程序或者Framework中其他的模块的交互,而不是指和用户之间的直接交互。和用户之间牵涉到交互的内容,在文章的最后也稍微有点介绍。下面就分成两个小节,对于PowerManagerService的交互作以总结。首先:
a). 与应用程序之间的交互
在Android中应用程序并不是直接同PowerManagerService交互的,而是通过PowerManager间接地与PowerManagerService打交道。不过在使用PowerManager和
PowerManager,WakeLock之前,我们要首先在APP中申请使用如下权限:
<uses-permission android:name = "android.permission.WAKE_LOCK" /> <uses-permission android:name = "android.permission.DEVICE_POWER"/>
而APP能够与PowerManager做哪些交互,在Android提供的开发文档中给了我们答案。我们可以看到PowerManage提供了如下公共的接口:
PowerManager |
PowerManagerService |
goToSleep(long time) |
goToSleep(long eventTime, int reason) |
isScreenOn() |
isScreenOn() |
reboot(String reason) |
reboot(boolean confirm, String reason, boolean wait) |
userActivity(long when, boolean noChangeLights) |
userActivity(long eventTime, int event, int flags) |
wakeUp(long time) |
wakeUp(long eventTime) |
在这个表格中,仅仅列出了PowerManager的公开方法中的其中五个,同时列出在PowerManagerService中对应的方法。这里列出的,是与PowerManagerService关系比较紧密的方法,其余的和PowerManager相关的东西会在接下来,慢慢地都谈到的。如果阅读PowerManager的源码的话,你会很容易发现,其实PowerManager的方法在实现的过程中,都是通过调用PowerManagerService相应的函数来实现的。PowerManager就像是PowerManagerService的"代理类"。这里略过PowerManager是如何通过binder与PowerManagerService进行通信的。下面,我们逐一对PowerManagerService中这几个函数的实现进行下简单的分析,在对这些函数分析之前,我觉得还是先对代码中使用的一些变量作以简要的说明为好。其实,在PowerManagerService中绝大部分变量通过名字就能大概知道其意义,不过还有几个较为重要的还是仔细说说为好,首先是重要的变量mDirty,根据代码的注释是说,用来表示power state的变化,而这样的变化在系统中一共定义了12个,每一个state对应一个固定的数字,都是2的倍数。这样的话,当有若干个状态一起变化时,他们按位取或,这样得到的结果既是唯一的,又能准去标示出各个状态的变化。此外还有一个mWakefulness的变量,它用来标示的是device处于的一种状态,是醒着的还是睡眠中,或者处于两者之间的一种状态。这个状态是和 display的电源状态是不同的,display的电源状态是独立管理的。这个变量用来标示DIRTY_WAKEFULNESS这个power state下的一个具体的内容。比如说,系统从进入Draaming的时候,首先变化的是mDirty,在mDirty中对DIRTY_WAKEFULNESS位置位,这说明系统中的DIRTY_WAKEFULNESS发生了变化;此时,仅仅是知道DIRTY_WAKEFULNESS发生了变化,但是不知道wakefulness到底发生了怎样的变化,如果需要进一步知道系统的wakefulness变成了什么,就需要查看下mWakefulness的内容就知道了。相当于是对DIRTY_WAKEFULNESS的一个补充说明吧。 像这样的算是补充性质的变量还有mWakeLockSummary和mUserActivitySummary。好了,接下来我们可以从goToSleep(long eventTime, int reason)开始了,代码如下:
@Override // Binder call
public void goToSleep(long eventTime, int reason) {
if (eventTime > SystemClock.uptimeMillis()) {
throw new IllegalArgumentException("event time must not be in the future");
}
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
final long ident = Binder.clearCallingIdentity();
try {
goToSleepInternal(eventTime, reason);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private void goToSleepInternal(long eventTime, int reason) {
synchronized (mLock) {
if (goToSleepNoUpdateLocked(eventTime, reason)) {
updatePowerStateLocked();
}
}
}