【Android休眠】之AutoSleep
来源:互联网 发布:阿里云服务器登录密码 编辑:程序博客网 时间:2024/05/22 10:23
Linux 3.10Android 4.4
http://blog.csdn.net/u013686019/article/details/53691897
一、autosleep诞生记
然后,接下来的问题就是:休眠时机。“nothing interesting is going on”的判断标准是什么?
Android给出的解决方案是“wakelocks”,也叫“suspend blockers”,只要有休眠锁存在(被kernel或user空间持有),就说明“something interesting is going on”,系统就不能休眠。
接下来的另一个问题:怎么阻止系统进入休眠?
Android给出的解决方案是“Early Suspend”,在进入休眠的过程中会先进入Android的“Early Suspend”路径,然后根据“wakelocks”的存在与否决定是否让系统休眠。由与这种做法改变了Linux kernel原生的PM流程,所以kernel开发者拒绝把“wakelocks”机制合并到kernel的mainline。
随着Android市场份额越来越大,在2011年的一次kernel讨论会中,Linus明确表态:kernel应该考虑把“suspend blockers”合并到mainline中了。
于是,kernel开发者着手实现了kernel的“wakelocks”:
/sys/power/wake_lock:向该文件写入字串ABC,即创建了一个名字ABC的唤醒源并置状态为“active”。
/sys/power/wake_unlock:向该文件写入字串ABC,即ABC唤醒源置状态为“deactive”。
当所有唤醒源状态都为“deactive”,系统自动进入休眠状态,实现该功能的即是“autosleep”。
“autosleep”在2012年并入kernel的mainline,kernel版本3.5。
二、autosleep在framework
我们说Android现在“Opportunistic Suspend”的实现是autosleep,怎么证明?
Android向上层提供了操作休眠相关的接口(即读写/sys/power/目录下文件),即libsuspend.so,位于:
在初始化函数里面:
autosuspend_init()用于初始化autosuspend_ops结构体定义的enable和disable成员函数,autosuspend_ops的初始化有3个:
按照顺序依次执行,一旦某个执行成功,直接退出;autosuspend_ops即使初始化成功的值。
autosuspend_earlysuspend_init()初始化失败,接着轮到autosuspend_autosleep_init():
system/core/libsuspend
在初始化函数里面:
autosuspend_ops.h (system\core\libsuspend)struct autosuspend_ops { int (*enable)(void); int (*disable)(void);};autosuspend.c (system\core\libsuspend)static int autosuspend_init(void){ if (autosuspend_inited) { return 0; } autosuspend_ops = autosuspend_earlysuspend_init(); if (autosuspend_ops) { goto out; } autosuspend_ops = autosuspend_autosleep_init(); if (autosuspend_ops) { goto out; } autosuspend_ops = autosuspend_wakeup_count_init(); if (autosuspend_ops) { goto out; } if (!autosuspend_ops) { ALOGE("failed to initialize autosuspend\n"); return -1; }out: autosuspend_inited = true; ALOGV("autosuspend initialized\n"); return 0;}
autosuspend_init()用于初始化autosuspend_ops结构体定义的enable和disable成员函数,autosuspend_ops的初始化有3个:
autosuspend_ops = autosuspend_earlysuspend_init();autosuspend_ops = autosuspend_autosleep_init();autosuspend_ops = autosuspend_wakeup_count_init();
按照顺序依次执行,一旦某个执行成功,直接退出;autosuspend_ops即使初始化成功的值。
autosuspend_earlysuspend.c (system\core\libsuspend)struct autosuspend_ops *autosuspend_earlysuspend_init(void){// #define EARLYSUSPEND_SYS_POWER_STATE "/sys/power/state" sPowerStatefd = open(EARLYSUSPEND_SYS_POWER_STATE, O_RDWR);// 向/sys/power/state文件写入"on" ret = write(sPowerStatefd, "on", 2);// 写入"on"的时候失败,所以跳转到err_write并退出被函数 if (ret < 0) { ALOGW("Error writing 'on' to %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf); goto err_write; } ALOGI("Selected early suspend\n"); start_earlysuspend_thread(); return &autosuspend_earlysuspend_ops;err_write: close(sPowerStatefd); return NULL;}
autosuspend_earlysuspend_init()初始化失败,接着轮到autosuspend_autosleep_init():
autosuspend_autosleep.c (system\core\libsuspend)struct autosuspend_ops *autosuspend_autosleep_init(void){ int ret; char buf[80];// #define SYS_POWER_AUTOSLEEP "/sys/power/autosleep" autosleep_fd = open(SYS_POWER_AUTOSLEEP, O_WRONLY); if (autosleep_fd < 0) { return NULL; } ALOGI("Selected autosleep\n"); autosuspend_autosleep_disable(); return &autosuspend_autosleep_ops;}
这里成功了!
autosuspend_autosleep.c (system\core\libsuspend)struct autosuspend_ops autosuspend_autosleep_ops = { .enable = autosuspend_autosleep_enable, .disable = autosuspend_autosleep_disable,};static int autosuspend_autosleep_enable(void){// static const char *sleep_state = "mem"; ret = write(autosleep_fd, sleep_state, strlen(sleep_state)); return 0;}static int autosuspend_autosleep_disable(void){// static const char *on_state = "off"; ret = write(autosleep_fd, on_state, strlen(on_state)); return 0;}
所谓启用autosleep,就是向"/sys/power/autosleep"文件写入系统支持的休眠模式(从/sys/power/state文件读取),比如这里的"mem"。一旦系统检测到再没有active的休眠锁,就进入"mem"的休眠。
向"/sys/power/autosleep"文件写入"off",禁止autosleep功能。
libsuspend.so向framework层提供enable、disable接口:
autosuspend_enable()、autosuspend_disable()的使用方:
继续跟踪代码我们知道,在屏幕点亮的时候,disable autosleep,屏幕暗下来后enable autosleep。
至此,autosleep在user空间的应用完成
libsuspend.so向framework层提供enable、disable接口:
autosuspend.c (system\core\libsuspend)int autosuspend_enable(void){ ret = autosuspend_init();if (autosuspend_enabled) { return 0; } ret = autosuspend_ops->enable(); autosuspend_enabled = true; return 0;}int autosuspend_disable(void){ ret = autosuspend_init(); if (!autosuspend_enabled) { return 0; } ret = autosuspend_ops->disable(); autosuspend_enabled = false; return 0;}
autosuspend_enable()、autosuspend_disable()的使用方:
com_android_server_power_PowerManagerService.cpp (frameworks\base\services\jni)static void nativeSetAutoSuspend(JNIEnv *env, jclass clazz, jboolean enable) { if (enable) { ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off"); autosuspend_enable(); } else { ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on"); autosuspend_disable(); }}
继续跟踪代码我们知道,在屏幕点亮的时候,disable autosleep,屏幕暗下来后enable autosleep。
至此,autosleep在user空间的应用完成
0 0
- 【Android休眠】之AutoSleep
- 【Android休眠】之AutoSleep
- Android AutoSleep休眠机制
- Android AutoSleep休眠机制
- 【Android休眠】之Android休眠机制
- 【Android休眠】之Android休眠机制
- 【Android休眠】之Android休眠机制
- 【Android休眠】之休眠锁的获取和释放
- earlysuspend、autosleep以及wakeup_count三种休眠机制的分析和比较
- earlysuspend、autosleep以及wakeup_count三种休眠机制的分析和比较
- Android基础学习之防止手机休眠
- Android 6.0变化之休眠模式
- 【Android休眠】之PowerKey唤醒源实现
- Android 6.0变化之休眠模式
- 【Android休眠】之kernel电源管理
- android休眠
- linux autosleep
- Android中休眠与唤醒之wake_lock, early_suspend, late_resume
- 桶排序 原理(简单版)
- 关于apache2报443端口被占用的问题
- EditText单行、多行和自动换行显示内容以及只输入数字和小数点
- 【Android休眠】之休眠锁的获取和释放
- 《自己动手写网络爬虫》笔记4-带偏好的网络爬虫
- 【Android休眠】之AutoSleep
- maven项目常用技巧: profile与资源过滤
- JVM之——生产环境jvm参数设置建议
- 红帽RHEL7版本RHCE认证学习及考试经历
- seo软文标题写作技巧:好的标题是靠这样想出来的
- jquery each报 Uncaught TypeError: Cannot use 'in' operator to search for错误
- hibernate三套查询
- 文章标题
- 什么是耦合?