1. 电源管理架构

PowerManagerService是android系统电源管理的核心服务。
PowerManagerService在Framework层本质为策略控制方案,其作用为:

  1. 向上提供给应用程序接口,例如音频场景中保持系统唤醒、消息通知中唤醒手机屏幕场景;
  2. 向下决策HAL层以及Kernel层来控制设备待机状态,控制显示屏、背光灯、距离传感器、光线传感器等硬件设备的状态;

2. 电源管理的4个层次

  • 应用接口层(PowerManager.java)
    PowerManager 中开发给应用一系列接口,应用可以调用PM的接口申请wakelock,让系统唤醒或休眠;
  • Framework层(PowerManagerService.java)
    应用调用PowerManager开发的接口的实现方为 PowerManagerService;
    PowerManagerService是整个电源管理的决策系统,例如亮灭屏、系统唤醒休眠;
  • Hal层(Power.c)
    该层只有一个power.c文件。通过接受上层参数,向/sys/power/wake_lock或/sys/power/wake_unlock文件节点写数据来与Kernel进行通信。主要功能为申请/释放锁,维持屏幕亮灭;
  • 内核层(Kernel/Power)
  1. 实现系统电源管理框架机制:Kernel/power/
  2. 实现对特定板的处理器电源管理:Arch/arm/match-xxx/pm.c
  3. 电源驱动为设备电源管理提供基础框架: Drivers/power

3. 电源管理服务 - PowerManagerService

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
负责管理、协调设备电源管理的系统服务之一,设备中常见功能如亮灭屏、亮度调节、低电量模式、保持CPU唤醒都是通过PMS进行协调和处理。

3.1 SystemServer startService PowerManagerService

PowerManagerService 继承SystemSerive即具备生命周期, SystemService系的服务都是在SystemServer中启动、注册到系统服务中,通过Binder和其他组件进行交互

故我们先看下SystemServer的启动流程。
SystemServer.main
->SystemServer.run
->->SystemServer.startBootstrapServices() 启动引导服务
->->->mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); // 通过Java的newInstance()反射启动电源管理服务,好处是代码很解耦

#mermaid-svg-otf0DIFkL066fe5e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-otf0DIFkL066fe5e .error-icon{fill:#552222;}#mermaid-svg-otf0DIFkL066fe5e .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-otf0DIFkL066fe5e .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-otf0DIFkL066fe5e .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-otf0DIFkL066fe5e .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-otf0DIFkL066fe5e .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-otf0DIFkL066fe5e .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-otf0DIFkL066fe5e .marker{fill:#333333;stroke:#333333;}#mermaid-svg-otf0DIFkL066fe5e .marker.cross{stroke:#333333;}#mermaid-svg-otf0DIFkL066fe5e svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-otf0DIFkL066fe5e .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-otf0DIFkL066fe5e text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-otf0DIFkL066fe5e .actor-line{stroke:grey;}#mermaid-svg-otf0DIFkL066fe5e .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-otf0DIFkL066fe5e .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-otf0DIFkL066fe5e #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-otf0DIFkL066fe5e .sequenceNumber{fill:white;}#mermaid-svg-otf0DIFkL066fe5e #sequencenumber{fill:#333;}#mermaid-svg-otf0DIFkL066fe5e #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-otf0DIFkL066fe5e .messageText{fill:#333;stroke:#333;}#mermaid-svg-otf0DIFkL066fe5e .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-otf0DIFkL066fe5e .labelText,#mermaid-svg-otf0DIFkL066fe5e .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-otf0DIFkL066fe5e .loopText,#mermaid-svg-otf0DIFkL066fe5e .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-otf0DIFkL066fe5e .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-otf0DIFkL066fe5e .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-otf0DIFkL066fe5e .noteText,#mermaid-svg-otf0DIFkL066fe5e .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-otf0DIFkL066fe5e .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-otf0DIFkL066fe5e .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-otf0DIFkL066fe5e .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-otf0DIFkL066fe5e .actorPopupMenu{position:absolute;}#mermaid-svg-otf0DIFkL066fe5e .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-otf0DIFkL066fe5e .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-otf0DIFkL066fe5e .actor-man circle,#mermaid-svg-otf0DIFkL066fe5e line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-otf0DIFkL066fe5e :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}PowerManagerServiceDreamManagerServiceDisplayManagerServiceDisplayPowerControlleronStart():publishBinderService/publishLocalServiceonBootPhase():mDirty |= DIRTY_BOOT_COMPLETEDsystemReady():mDreamManagersystemReady():mDisplayManagerInternalinitPowerManagementPowerManagerServiceDreamManagerServiceDisplayManagerServiceDisplayPowerController

3.2 PowerManagerService 的构造函数

  1. 建立Handle: 消息发送与处理
  2. 2种WakeLock锁,分别为 mWakeLockSuspendBlocker 和 mDisplaySuspendBlocker
    a. mDisplaySuspendBlocker: 上层调用,控制屏幕的点亮和息屏
    b. mWakeLockSuspendBlocker: 系统内部调用,控制CPU的唤醒
PowerManagerService(Context context, Injector injector) {...mHandlerThread = new ServiceThread(TAG,Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);mHandlerThread.start();mHandler = injector.createHandler(mHandlerThread.getLooper(),new PowerManagerHandlerCallback());...// 控制CPU的唤醒mWakeLockSuspendBlocker =mInjector.createSuspendBlocker(this, "PowerManagerService.WakeLocks");// 控制屏幕的点亮和息屏mDisplaySuspendBlocker =mInjector.createSuspendBlocker(this, "PowerManagerService.Display");...
}看到上述的2个锁,让我联系到经常使用的如下FlagFlag Value                 CPU        Screen      KeyboardPARTIAL_WAKE_LOCK            On           Off         Off 0x00000001 1SCREEN_DIM_WAKE_LOCK         On           Dim         Off 0x00000006 6SCREEN_BRIGHT_WAKE_LOCK      On           Bright      Off 0x0000000a 10FULL_WAKE_LOCK               On           Bright      Bright 0x0000001a 26

3.3 PowerManagerService.onStart()

Onstart的作用:

  1. 将 POWER_SERVICE 注册到 Binder 服务端,这样其他模块就可以通过Binder获取实例。同理当进行本地注册后,只有在Sysem进程才能获得到其实例。
  2. 设置 Watchdog 监视 PowerManagerService 和 Handler
      @Overridepublic void onStart() {// 其他模块就可以通过Binder获取实例publishBinderService(Context.POWER_SERVICE, mBinderService, /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_DEFAULT | DUMP_FLAG_PRIORITY_CRITICAL);// 当进行本地注册后,只有在Sysem进程才能获得到其实例publishLocalService(PowerManagerInternal.class, mLocalService);Watchdog.getInstance().addMonitor(this);Watchdog.getInstance().addThread(mHandler);}

3.4 PowerManagerService.systemReady()

systemReady()函数作用:初始化工作,即我们可以看到电源管理策略的需要用的功能初始化。

  1. 初始化互动屏保
  2. 初始化屏幕显示管理服务
  3. 初始化电池管理服务
  4. 获取屏幕亮度信息
  5. 获取传感器管理服务
  6. 初始化电量统计服务
  7. SettingsProvier监听
  8. LED指示灯管理服务
  9. 初始化屏幕显示服务
  10. 广播相关:电池广播、用户切换广播
  11. 更新电源相关信息

例如我们在做冻结策略、场景识别策略的ROM定制也大体都是在 systemReady 进行init

public void systemReady(IAppOpsService appOps) {...mDreamManager = getLocalService(DreamManagerInternal.class); // 1. 初始化互动屏保mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);// 2. 初始化屏幕显示管理服务mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);// 3. 初始化电池管理服务SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());//5. 获取传感器管理服务mBatteryStats = BatteryStatsService.getService();//6. 初始化电量统计服务mLightsManager = getLocalService(LightsManager.class);//8. LED指示灯管理服务mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);//8. LED指示灯管理服务mDisplayManagerInternal.initPowerManagement(mDisplayPowerCallbacks, mHandler, sensorManager);// 9. 初始化屏幕显示服务// 整个 PMS 中最重要的方法updatePowerStateLocked();// 11. 更新电源相关信息...
}

总结一下:SystemReady完成的工作主要如下:

  1. 获取与PowerManangerService相关的系统服务以及本地服务;
  2. 获取屏幕最大、最小以及默认亮度值
  3. 创建SensorManager对象用于与SensorService交互
  4. 创建Notifier对象,用户通知系统电源状态的改变
  5. 调用DisplayManangerService的initPowerMannagerMent()方法来初始化Power显示模块
  6. 注册SettingsObserver监听系统设置的变化

3.5 PowerManager 的相关接口

PowerMananger 是PowerManangerService的代理类,PowerMananger向上层应用提供交互的接口。上层调用对应的接口后,具体的工作内容交予PowerManangerService完成。可以重点关注如下接口:

  1. wakeUp()
    hide接口,不开放给应用。作用:强制系统从睡眠状态唤醒。
  2. gotoSleep()
    hide接口,不开放给应用。作用:强制系统进入睡眠状态
  3. userActivity()
    向PowerManagerService报告影响系统休眠的用户活动,重新计算灭屏时间,背光亮度,例如触屏、滑屏、power键等用户行为。
  4. Wakelock(特别常用)
    wakelock是PowerManager的一个内部类,提供了相关的接口来操作wakelock锁。应用层可以使用newWakeLock方法创建wakelock锁,使用acquire()和release()来申请和释放锁。例如如下demo的使用
package com.sufadi.commlib.utilsimport android.annotation.SuppressLint
import android.content.Context
import android.os.PowerManager/*Flag Value                 CPU        Screen      KeyboardPARTIAL_WAKE_LOCK            On           Off         Off 0x00000001 1SCREEN_DIM_WAKE_LOCK         On           Dim         Off 0x00000006 6SCREEN_BRIGHT_WAKE_LOCK      On           Bright      Off 0x0000000a 10FULL_WAKE_LOCK               On           Bright      Bright 0x0000001a 26*/
object AlertWakeLock {private val TAG = "AlertWakeLock"private var sCpuWakeLock: PowerManager.WakeLock? = null@SuppressLint("InvalidWakeLockTag")internal fun createPartialWakeLock(context: Context): PowerManager.WakeLock? {// 第一步:获取PowerManager的实例val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager ?: return null// 第二步:调用PowerManager中的newWakeLock方法创建一个WakeLock对象return pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG)//return pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, TAG);}fun acquireCpuWakeLock(context: Context) {if (sCpuWakeLock != null) {return}sCpuWakeLock = createPartialWakeLock(context)// 第三步:acquire()获取相应的锁sCpuWakeLock!!.acquire()}fun releaseCpuLock() {if (sCpuWakeLock != null) {// 最后:release释放sCpuWakeLock!!.release()sCpuWakeLock = null}}
}
  1. isDeviceIdleMode
    查看是否进入了Doze低功耗模式

PowerManagerService 电源管理架构初识相关推荐

  1. 翻译:Linux的电源管理架构

    设备电源管理 Copyright (c) 2010 Rafael J. Wysocki<rjw@sisk.pl>, Novell Inc. Copyright (c) 2010 Alan ...

  2. android电源管理

    Android 的电源管理也是很重要的一部分.比如在待机的时候关掉不用的设备,timeout之后的屏幕和键盘背光的关闭,用户操作的时候该打开多少设备等等,这些都直接关系到产品的待机时间,以及用户体验. ...

  3. Android电源管理介绍

    一.电源管理基础知识 1.1电源管理的几种状态 Android kernel源码中,定义了三种电源状态,在kernel/power/suspend.c中: 对应的宏定义/include/linux/s ...

  4. 关闭linux服务器电源,linux关闭ACPI电源管理模块

    一.运行环境 # cat /etc/redhat-release CentOS release 6.2 (Final) # uname -a Linux web-server- 2.6.-.el6.x ...

  5. Windows CE设备驱动开发之电源管理

    4.7电源管理 电源管理模块管理设备电源,从而全面改进操作系统的电源使用效率:它所有设备的电源使用,同时能与不支持电源管理的应用程序及驱动程序共存. 使用电源管理可以有效的减少目标设备的电源消耗,同时 ...

  6. Andriod 电源管理

    Andriod PM suspend&resume Android的电源管理还是比较简单的, 主要就是通过锁和定时器来切换系统的状态,使系统的功耗降至最低,整个系统的电源管理架构图如下: (注 ...

  7. Linux电源管理(一)电源管理系统架构

    概述 Linux 电源管理非常复杂,牵扯到系统级的待机.频率电压变换.系统空闲时的处理以及每个设备驱动对于系统待机的支持和每个设备的运行时电源管理,可以说和系统中的每个设备驱动都息息相关. 对于消费电 ...

  8. 【STM32】初识STM32(型号+封装+内核+储存器+时钟、复位和电源管理+工作模式+ADC)

    折腾着折腾着终于开始了 目录 ■STM32型号的说明: ■几种封装样式: ■ 内核:ARM 32位的Cortex™-M3 CPU ■ 存储器 ■ 时钟.复位和电源管理 ■内嵌RC振荡器和外接晶振: ■ ...

  9. Linux电源管理(1)_整体架构 -- wowo

    1. 前言 在这个世界中,任何系统的运转都需要能量.如树木依靠光能生长,如马儿依靠食物奔跑,如计算机系统依靠电能运行.而能量的获取是有成本的,因此如果能在保证系统运转的基础上,尽量节省对能量的消耗,就 ...

  10. Android5.1--PowerManagerService电源管理

    系统电源管理简介 Android电源管理概述 电源管理(PowerManager)在任何设备中都是最重要的组成部分之一,良好的电源管理方案可以达到节能.延长电池寿命.降低辐射.降温等目的. 移动设备的 ...

最新文章

  1. Spring.Net Aop
  2. 坑!只要年轻博士,薪资按考核结果发放, 高校的博后制度,究竟有多少门道?...
  3. asp多重查询的解决方案
  4. 搞定系统设计 02:估算的一些方法
  5. java中策略设计模式_Java中的设计模式(五):策略模式
  6. linux lua socket编程,CentOs 安装lua,luasocket
  7. Spring入门(一)之简介
  8. dubbo学习之源码创建属于自己的dubbo-demo
  9. 华为HG255D救砖小总结1----概述及相关硬件准备
  10. 主板检测卡c5_计算机主板检测卡检测显示C5是哪的問題?
  11. 公司官网如何快速让百度收录?以及如何做网站流量?
  12. Linux基本操作之虚拟机和主机的域名映射
  13. 我熬夜开发了一款简约实用、支持多平台的Markdown在线编辑器(开源)
  14. 通天塔导游:各种编程语言优缺点
  15. Python模糊匹配 | 刷英语六级段落匹配只需要3秒?
  16. 磁力链接方式下载完全攻略
  17. C语言基础--编写风格1
  18. 电路与模拟电子技术----正弦交流电路(下)
  19. 408自装或4S店加装的凯立德导航升级地图技术贴
  20. geoip java api_利用GeoIP数据库及API进行地理定位查询 Java

热门文章

  1. 计算机专业入学教育报告,信息工程学院20级计算机专业入学教育大会和专业介绍会顺利召开...
  2. python 华氏度转换摄氏度
  3. [技术讨论]关于前几天公布的京东bug上的问题分析
  4. 探索性与验证性因子分析
  5. 蒙版操作—剪切蒙版制作艺术字
  6. 如何利用视频做动图?视频转gif动图
  7. matlab用imcrop进行图片裁剪,并用imwrite存图
  8. 利用base64展示图片
  9. 推荐一些2021年整理的跨平台uniapp的作品案例
  10. Redis是否存在线程安全问题