android PowerManager分析

来源:互联网 发布:java自带线程池 编辑:程序博客网 时间:2024/05/22 18:37

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();            }        }    }




0 0
原创粉丝点击