Linux 3.10Android 4.4

http://blog.csdn.net/u013686019/article/details/53691897

一、autosleep诞生记

由于《【Android休眠】之Android休眠机制》提到的“Android的特别需求”,Android提出了“Opportunistic Suspend”:Rather than trying to put the various system components into a low-power state, opportunistic suspend works by simply suspending the entire devicewhenever it is determined that nothing interesting is going on。如此简单粗暴,所以 “Opportunistic Suspend”从提出后就有着争议。

然后,接下来的问题就是:休眠时机。“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:向该文件写入字串ABCABC唤醒源置状态为“deactive”。 当所有唤醒源状态都为“deactive”,系统自动进入休眠状态,实现该功能的即是“autosleep”。

“autosleep”在2012年并入kernel的mainline,kernel版本3.5。

二、autosleep在framework

我们说Android现在“Opportunistic Suspend”的实现是autosleep,怎么证明? Android向上层提供了操作休眠相关的接口(即读写/sys/power/目录下文件),即libsuspend.so,位于:
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.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空间的应用完成

更多相关文章

  1. Android(安卓)Edittext获取焦点后,弹出的软键盘显示搜索、发送、
  2. Android(安卓)利用百度地图SDK实现定位功能
  3. android 写入收件箱
  4. android 写入收件箱
  5. Android热更新一:JAVA的类加载机制
  6. Android高级--自定义控件一,优酷…
  7. Android多渠道打包(四):360多渠道打包
  8. Android启动流程——1序言、bootloader引导与Linux启动
  9. 如何使用Spark快速将数据写入Elasticsearch

随机推荐

  1. Android(安卓)PromptDialog example
  2. android 隐藏输入法
  3. Android根据URL下载文件保存到SD卡
  4. Android传感器使用
  5. Linaro android media create BUG
  6. Android(安卓)Popupwindow 点击外部消失
  7. Android(安卓)listview怎么实现滚动分页
  8. native programming on android
  9. xpose框架使用android studio
  10. android获取屏幕的宽高