Android Framework之PowerManagerService的功能.docx
- 文档编号:23749068
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:28
- 大小:90.94KB
Android Framework之PowerManagerService的功能.docx
《Android Framework之PowerManagerService的功能.docx》由会员分享,可在线阅读,更多相关《Android Framework之PowerManagerService的功能.docx(28页珍藏版)》请在冰豆网上搜索。
AndroidFramework之PowerManagerService的功能
AndroidFramework------之PowerManagerService的功能
自从接触Android系统已经一年多了,这段时间内对于Android系统的Framework层的各个模块都有过接触,有时也做过分析,但是一直没能形成一个总结性的东西。
这次下定决心,好好整理整理对于Android系统的学习梳理一下自己的思路。
本文一方面是为了自己梳理下知识,文中涉及的内容,基本是拾人牙慧,很少有自己的东西,最多也就算是自己的总结;除此作用之外,如果能为后来者引玉,也算是一点功德吧。
这次首先是对Android系统中的PowerManagerService进行下整理。
之所以先选择PowerManagerService,是因为这个模块相对于Android系统中其他的模块而言,与系统其他的模块之间的交互较少,而且Framework中的PowerManagerService模块是由Google开发并维护的,虽然以LinuxKernel的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:
将PowerManagerstate的重要变化通过broadcast发送出去。
接下来就说说三个接口文件
SuspendBlocker.java:
相当于一个partialwakelock。
在内部使用,避免了使用上层的唤醒锁机制
DisplayBlanker.java:
主要功能一是BLANKDISPLAY:
Thedisplayisblanked,butdisplaymemoryismaintainedandnewdatacanbeentered;而是UNBLANKDISPLAY:
Thedisplayisrestored/turnedtoactivestate.(不知道这两个英文的解释是否恰当,还有待验证)。
ScreenOnBlanker.java:
描述了一种较为低级的blocker机制,主要用于关屏或者隐藏屏幕内容,直到windowmanager准备好新的内容
DisplayPowerRequest.java:
描述了一些对于display电源状态的请求。
最后看看剩余的这些类:
ShutDownThread.java:
主要功能就是关机和重启,当我想要执行重启或者关机的时候,这个新城就会被启动。
ElectronBeam.java:
负责屏幕由开到关,或者由关到开的一些GL动画。
在DisplayPowerController管理
WirelessChargerDetector.java:
和无线充电相关的东西,没有细看。
每个文件的大致功能就是这样的,也许有些地方不是很恰当,还是需要仔细阅读源码,才能确切地知道到底是怎么回事,有些功能到底是如何实现的。
先从交互的角度去看看PowerManagerService的功能。
在这里的交互是说PowerManagerService与应用程序或者Framework中其他的模块的交互,而不是指和用户之间的直接交互。
和用户之间牵涉到交互的内容,在文章的最后也稍微有点介绍。
下面就分成两个小节,对于PowerManagerService的交互作以总结。
首先:
a).与应用程序之间的交互
在Android中应用程序并不是直接同PowerManagerService交互的,而是通过PowerManager间接地与PowerManagerService打交道。
不过在使用PowerManager和
PowerManager,WakeLock之前,我们要首先在APP中申请使用如下权限:
name="android.permission.WAKE_LOCK"/> name="android.permission.DEVICE_POWER"/> 而APP能够与PowerManager做哪些交互,在Android提供的开发文档中给了我们答案。 我们可以看到PowerManage提供了如下公共的接口: PowerManager PowerManagerService goToSleep(longtime) goToSleep(longeventTime,intreason) isScreenOn() isScreenOn() reboot(Stringreason) reboot(booleanconfirm,Stringreason,booleanwait) userActivity(longwhen,booleannoChangeLights) userActivity(longeventTime,intevent,intflags) wakeUp(longtime) wakeUp(longeventTime) 在这个表格中,仅仅列出了PowerManager的公开方法中的其中五个,同时列出在PowerManagerService中对应的方法。 这里列出的,是与PowerManagerService关系比较紧密的方法,其余的和PowerManager相关的东西会在接下来,慢慢地都谈到的。 如果阅读PowerManager的源码的话,你会很容易发现,其实PowerManager的方法在实现的过程中,都是通过调用PowerManagerService相应的函数来实现的。 PowerManager就像是PowerManagerService的"代理类"。 这里略过PowerManager是如何通过binder与PowerManagerService进行通信的。 下面,我们逐一对PowerManagerService中这几个函数的实现进行下简单的分析,在对这些函数分析之前,我觉得还是先对代码中使用的一些变量作以简要的说明为好。 其实,在PowerManagerService中绝大部分变量通过名字就能大概知道其意义,不过还有几个较为重要的还是仔细说说为好,首先是重要的变量mDirty,根据代码的注释是说,用来表示powerstate的变化,而这样的变化在系统中一共定义了12个,每一个state对应一个固定的数字,都是2的倍数。 这样的话,当有若干个状态一起变化时,他们按位取或,这样得到的结果既是唯一的,又能准去标示出各个状态的变化。 此外还有一个mWakefulness的变量,它用来标示的是device处于的一种状态,是醒着的还是睡眠中,或者处于两者之间的一种状态。 这个状态是和display的电源状态是不同的,display的电源状态是独立管理的。 这个变量用来标示DIRTY_WAKEFULNESS这个powerstate下的一个具体的内容。 比如说,系统从进入Draaming的时候,首先变化的是mDirty,在mDirty中对DIRTY_WAKEFULNESS位置位,这说明系统中的DIRTY_WAKEFULNESS发生了变化;此时,仅仅是知道DIRTY_WAKEFULNESS发生了变化,但是不知道wakefulness到底发生了怎样的变化,如果需要进一步知道系统的wakefulness变成了什么,就需要查看下mWakefulness的内容就知道了。 相当于是对DIRTY_WAKEFULNESS的一个补充说明吧。 像这样的算是补充性质的变量还有mWakeLockSummary和mUserActivitySummary。 好了,接下来我们可以从goToSleep(longeventTime,intreason)开始了,代码如下: 1@Override//Bindercall 2publicvoidgoToSleep(longeventTime,intreason){ 3if(eventTime>SystemClock.uptimeMillis()){ 4thrownewIllegalArgumentException("eventtimemustnotbeinthefuture"); 5} 6 //权限检查 7mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,null); 8 9finallongident=Binder.clearCallingIdentity(); 10try{ 11goToSleepInternal(eventTime,reason);//这里会调用函数的实现,在PowerManagerService中有很多类似的使用方式,之后的代码中我会直接列出对应方法的实现 12}finally{ 13Binder.restoreCallingIdentity(ident); 14} 15} 16 17privatevoidgoToSleepInternal(longeventTime,intreason){ 18synchronized(mLock){ 19if(goToSleepNoUpdateLocked(eventTime,reason)){ 20updatePowerStateLocked(); 21} 22} 23} 对于文中的代码,我会在不影响阅读的情况下,尽量地少。 在这段代码中,涉及到另个重要的函数goToSleepNoUpdateLocked()和updatePowerStateLocked(),而 goToSleepNoUpdateLocked是goToSleep功能的计算者,来决定是否要休眠,而updatePowerStateLocked函数算是功能的执行者,而且这个执行者同时负责执行了很多其他的功能,在总结的时候会着重分析这个函数。 这里先看goToSleepNoUpdateLocked方法的代码: 在总结的时候会着重分析这个函数。 这里先看goToSleepNoUpdateLocked方法的代码: 1privatebooleangoToSleepNoUpdateLocked(longeventTime,intreason){ 2if(DEBUG_SPEW){ 3Slog.d(TAG,"goToSleepNoUpdateLocked: eventTime="+eventTime+",reason="+reason); 4} 5 6if(eventTime 7||! mBootCompleted||! mSystemReady){ 8returnfalse; 9} 10 11switch(reason){ 12casePowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN: 13Slog.i(TAG,"Goingtosleepduetodeviceadministrationpolicy..."); 14break; 15casePowerManager.GO_TO_SLEEP_REASON_TIMEOUT: 16Slog.i(TAG,"Goingtosleepduetoscreentimeout..."); 17break; 18default: 19Slog.i(TAG,"Goingtosleepbyuserrequest..."); 20reason=PowerManager.GO_TO_SLEEP_REASON_USER; 21break; 22} 23 24sendPendingNotificationsLocked(); 25mNotifier.onGoToSleepStarted(reason); 26mSendGoToSleepFinishedNotificationWhenReady=true; 27 28mLastSleepTime=eventTime; 29mDirty|=DIRTY_WAKEFULNESS; 30mWakefulness=WAKEFULNESS_ASLEEP; 31 32//Reportthenumberofwakelocksthatwillbeclearedbygoingtosleep. 33intnumWakeLocksCleared=0; 34finalintnumWakeLocks=mWakeLocks.size(); 35for(inti=0;i 36finalWakeLockwakeLock=mWakeLocks.get(i); 37switch(wakeLock.mFlags&PowerManager.WAKE_LOCK_LEVEL_MASK){ 38casePowerManager.FULL_WAKE_LOCK: 39casePowerManager.SCREEN_BRIGHT_WAKE_LOCK: 40casePowerManager.SCREEN_DIM_WAKE_LOCK: 41numWakeLocksCleared+=1; 42break; 43} 44} 45EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED,numWakeLocksCleared); 46returntrue; 47} 通过这段代码发现,其实这里并没有真正地让device进行sleep,仅仅只是把PowerManagerService中一些必要的属性进行了赋值,等会在分析updatePowerStateLocked的时候,再给出解释。 在PowerManagerService的代码中,有很多的方法的名字中都含有xxxNoUpdateLocked这样的后缀,我觉得这样做大概是因为,都类似于goToSleepNoUpdateLocked方法,并没有真正地执行方法名字所描述的功能,仅仅是更新了一些必要的属性。 所以在Android系统中可以把多个powerstate属性的多个变化放在一起共同执行的,而真正的功能执行者就是updatePowerStateLocked。 b).与系统其它模块之间的交互 PowerManagerService作为Android系统Framework中重要的能源管理模块,除了与应用程序交互之外,还要与系统中其它模块配合,在提供良好的能源管理同时提供友好的用户体验。 Android系统除了提供公共接口与其它模块交互外,还提供BroadCast机制,用来对系统中发生的重要变化做出反应。 下表列出了,在PowerManagerService中注册的Receiver,以及这些Receiver监听的事件,和处理方法: BatteryReceiver ACTION_BATTERY_CHANGED handleBatterStateChangeLocked() BootCompleteReceiver ACTION_BOOT_COMPLETED startWatchingForBootAnimationFinished() userSwitchReceiver ACTION_USER_SWITCHED handleSettingsChangedLocked DockReceiver ACTION_DOCK_EVENT updatePowerStateLocked DreamReceiver ACTION_DREAMING_STARTED ACTION_DREAMING_STOPPED scheduleSandmanLocked PowerManagerService中除了注册了这五个Receiver之外,还定义了一个SettingsObserver,用于监视系统中以下属性的变化: SCREENSAVER_ENABLE,屏保的功能开启 SCREENSAVER_ACTIVE_ON_SLEEP,在睡眠时屏保启动 SCREENSAVER_ACTIVE_ON_DOCK,连接底座并且屏保启动 SCREEN_OFF_TIMEOUT,休眠时间 STAY_ON_PLUGGED_IN,有插入并且屏幕开启 SCREEN_BRIGHTNESS,屏幕的亮度 SCREEN_BRIGHTNESS_MODE,屏幕亮度的模式 当以上这些属性发生变化时,SettingObserver都会监视到,并且调用SettingObserver的onChange方法, 1publicvoidonChange(booleanselfChange,Uriuri){ 2synchronized(mLock){ 3handleSettingsChangedLocked(); 4} 5} 以上内容,说明PowerManagerService不能能够接收用户的请求,被动地去做一些操作,还要主动监视系统中一些重要的属性的变化,和重要的事件的发生。 无论是处理主动还是被动的操作,在上面都一一列出了对应的处理函数。 虽然对这些方法没有逐一说明,但是通过上面的goToSleepNoUpdateLocke的例子, 自己阅读下应该没有问题的。 如果看过这些方法之后,你会发现一个很重要的共同点,就是PowerManagerService在处理各种各样的事件的时候,最终都会经过 这么一个方法updatePowerStateLocked。 在上面这些内容中,我们说各种变化的时候,常用的一个词就是powerstate,而在updatePowerStateLocked方法 的名字中,我们很容易推测出这个方法要做的事情,就是把PowerManagerService中发生的变化,能够影响到PowerManagement的都要放在一起进行更新,让 其真正地起作用。 这么说下去,还是有点空口白话的意味,我们还是从代码中一点一点去阅读效果会好些。 updatePowerStateLocked 1/** 2*UpdatestheglobalpowerstatebasedondirtybitsrecordedinmDirty. 3* 4*Thisisthemainfunctionthatperformspowerstatetransitions. 5*Wecentralizethemheresothatwecanrecomputethepowerstatecompletely 6*eachtimesomethingimportantchanges,andensurethatwedoitthesame 7*wayeachtime.Thepointistogatherallofthetransitionlogichere. 8*/ 9privatevoidupdatePowerStateLocked(){ 10if(! mSystemReady||mDirty==
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android Framework之PowerManagerService的功能 Framework PowerManagerService 功能
![提示](https://static.bdocx.com/images/bang_tan.gif)