Android wakelock && suspend


由于博主不是很熟悉Java,只是大致梳理了以下流程,不涉及具体细节。浏览本文,可以大概了解Android wakelock的概念及其在Android发挥的作用、Android suspend流程。


一、Wakelock

wakelocks最初出现在Android为linux kernel打的一个补丁集,该补丁集实现了一个名称为“wakelocks”的系统调用,该系统调用允许调用者阻止系统进入低功耗模式(如idle、suspend等)。同时,该补丁集更改了Linux kernel原生的电源管理执行过程(kernel/power/main.c中的state_show和state_store),转而执行自定义的state_show、state_store。
Android wakelocks提供的功能包括:
a) /sys/power/wake_lock:一个sysfs文件,用户程序向文件写入一个字符串,即可创建一个wakelock,该字符串就是wakelock的名字。该wakelock可以阻止系统进入低功耗模式。
b) /sys/power/wake_unlock,一个sysfs文件,用户程序向文件写入相同的字符串,即可注销一个wakelock。
c) 当系统中所有的wakelock都注销后,系统可以自动进入低功耗状态。
d) 向内核其它driver也提供了wakelock的创建和注销接口,允许driver创建wakelock以阻止睡眠、注销wakelock以允许睡眠

1.1 WakeLock说明

具体请参考PowerManager,以下部分截图和简单文字介绍:
PARTIAL_WAKE_LOCK:保持CPU在运行,屏幕和键盘背光将被允许熄灭;如果用户按下Power键,屏幕会关闭,但CPU将继续运行,直到所有部分唤醒锁都已释放;
PARTIAL_WAKE_LOCK

PROXIMITY_SCREEN_OFF_WAKE_LOCK:和接近传感器配合,当用户接近屏幕时黑屏,离开时亮屏(例如打电话),此API在API21后开放,以前被hide;不能与ACQUIRE_CAUSES_WAKEUP一起使用,可用isWakeLockLevelSupported(int) 用于确定设备是否支持此唤醒锁;
PROXIMITY_SCREEN_OFF_WAKE_LOCK
FULL_WAKE_LOCK:确保屏幕和键盘背光灯全亮;如果用户按下Power键, FULL_WAKE_LOCK将隐式释放,同时关闭屏幕和CPU(此API级别17中已弃用);
FULL_WAKE_LOCK

SCREEN_DIM_WAKE_LOCK:确保屏幕处于打开状态,键盘背光将被熄灭。如果用户按下Power键,SCREEN_DIM_WAKE_LOCK将隐式释放,同时关闭屏幕和CPU(此API级别17中已弃用);
SCREEN_DIM_WAKE_LOCK
SCREEN_BRIGHT_WAKE_LOCK:确保屏幕以全亮度开启,键盘背光将被熄灭;如果用户按下Power键,SCREEN_BRIGHT_WAKE_LOCK将隐式释放,同时关闭屏幕和CPU(此API级别15中已弃用);
SCREEN_BRIGHT_WAKE_LOCK

ACQUIRE_CAUSES_WAKEUP:不会唤醒设备,强制亮屏,键盘灯开启。有一个例外,如果有notification弹出的话,会唤醒设备;不能与PARTIAL_WAKE_LOCK一起使用;
ACQUIRE_CAUSES_WAKEUP

ON_AFTER_RELEASE:当锁被释放时,保持亮屏一段时间(如果释放时屏幕没亮,则不会亮屏)
ON_AFTER_RELEASE

1.2 WakeLock使用

使用public PowerManager.WakeLock newWakeLock (int levelAndFlags, String tag)申请一个wakelock

public PowerManager.WakeLock newWakeLock (int levelAndFlags, String tag)
//levelAndFlags	 int: Combination of wake lock level and flag values defining the requested behavior of the WakeLock.
//tag	String: Your class name (or other tag) for debugging purposes.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3 PMS下WaeLock从上到下流程图

特别说明:
在acquireWakeLockInternal( )函数中,调用了setWakeLockDisabledStateLocked( )函数,
在PMS中,当设备进入doze时,除了白名单中的应用程序,该函数将禁用应用程序持有的所有PARTIAL_WAKE_LOCK
setWakeLockDisabledStateLocked
另外,从代码流程看,当PMS往sysfs写内容时,Android Q(包括Android R)使用HIDL重构了HAL层的接口的实现(当然,最终到底层还是使用write()函数,往节点写内容),Android P是直接调用write( )函数
WakeLock

1.4 wakelock sysfs节点

wakelock sysfs
1.4.1 亮屏前后,wake_lock节点变化:
wake_lock

PowerManager.SuspendLockout:
/frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

SuspendLockout

PowerManagerService.Display :
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
PowerManagerService( )-> synchronized( )

Display
1.4.2 亮屏前后,wake_unlock节点变化:
wake_unlock

1.5 wakeup_sources

wakeup_sources

一个wakeup source代表了一个具有唤醒能力的设备,也称该设备为一个wakeup source

name:该wakeup source的名称,一般为对应的device name; active_count:wakeup source
activate的次数; event_count:wakeup source上报的event个数;
wakeup_count:wakeup source终止suspend过程的次数; expire_count:wakeup source
timeout到达的次数; active_since::wakeup source从上次持锁到cat这个文件时持续处于ative状态的时间
total_time:wakeup source处于activate状态的总时间(可以反映该wakeup
source对应的设备的繁忙、耗电程度); max_time:wakeup
source持续处于activate状态的最大时间(越长越不合理); last_change:wakeup source状态变化的时间点。
prevent_suspend_time:wakeup source阻止内核autosleep触发系统休眠流程的总时间

1.6 wakelock architecture

architecture

  • wakeup events framework
    core,在drivers/base/power/wakeup.c中实现,提供了wakeup events
    framework的核心功能,包括:
    i. 抽象wakeup source和wakeup event的概念;
    ii. 向各个device driver提供wakeup source的注册、使能等接口;
    iii. 向各个device driver提供wakeup event的上报、停止等接口;
    iv. 向PM core(包括wakeup count、auto sleep、suspend、hibernate等模块)提供wakeup event的查询接口,以判断是否可以suspend、是否需要终止正在进行的suspend。

  • wakeup events framework
    sysfs,将设备的wakeup信息,以sysfs的形式提供到用户空间,供用户空间程序查询、配置。在drivers/base/power/sysfs.c中实现。

  • wake lock/unlock,允许用户空间程序报告/停止wakeup
    events。换句话说,允许用户空间的任一程序决定系统是否可以休眠。

  • wakeup count,基于wakeup events framework,解决用户空间同步的问题。

  • auto sleep,允许系统在没有活动时(即一段时间内,没有产生wakeup event),自动休眠。

Note:
在Linux kernel看来,power是系统的核心资源,不应开放给用户程序随意访问(wake lock机制违背了这个原则),而在运行时的电源管理过程中,系统何时进入低功耗状态,也不是用户空间程序能决定的。

二、Suspend

Android suspend流程中,通常使用以下两种方式:1.按power key进入休眠流程,2.settings下面的自动息屏流程。

2.1 Suspend从上到下流程图

Suspend流程基本和Wakelock流程相似,上层调用的接口大部分是相同的,
Suspend
kernel休眠主要分三个主要的步骤:1.冻结用户态进程和内核态任务;2.调用注册的设备的suspend的回调函数,其调用顺序是按照驱动加载时的注册顺序;3.休眠核心设备和使CPU进入休眠态冻结进程是内核把进程列表中所有的进程的状态都设置为停止,并且保存下所有进程的上下文。


总结

当启动一个应用程序的时候,它都可以申请一个wakelock唤醒锁,每当申请成功之后都会在内核中注册一下(通知系统内核,现在已经有锁被申请),当应用程序在某种情况下释放wakelock的时候,会注销之前所申请的wakelock。特别要注意的是:只要是系统中有一个wakelock的时候,系统此时都不能进行睡眠(即kernel无法suspend)。但此时各个模块可以进行early_suspend。当系统中所有的wakelock都被释放之后,系统就会进入真正的kernel的睡眠状态。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cy_yio

谢谢抬爱。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值