android suspend/resume

阅读: 评论:0

android suspend/resume

android suspend/resume

一、应用层当系统未处于 Suspend 状态下用户按下Power键时会在产生一个信号,上层的 WindowManager? 会收到这个上节点的变化而得知当前应该进入休眠状态, 通知PowerManagerService, 它会做如下调用,

路径:./frameworks/base/services/java/com/android/server/PowerManagerService.java" line 1452

 private int setScreenStateLocked(boolean on) {int err = Power.setScreenState(on); ------------------------------------------>在这里调用setScreenState()if (err == 0) {mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);if (mUseSoftwareAutoBrightness) {enableLightSensor(on);if (!on) {// make sure button and key backlights are off toomButtonLight.turnOff();mKeyboardLight.turnOff();// clear current value so we will update based on the new conditions// when the sensor is reenabled.mLightSensorValue = -1;// reset our highest light sensor value when the screen turns offmHighestLightSensorValue = -1;}}}return err;}

setScreenState最终会调到hardware/libhardware_legacy/power/power.c 中的set_screen_state

const char * const NEW_PATHS[] = {"/sys/power/wake_lock","/sys/power/wake_unlock","/sys/power/state"
};static const char *off_state = "mem";
static const char *on_state = "on";下边这个函数打开NEW_PATHS[]中的三个描述符
static int
open_file_descriptors(const char * const paths[])
{int i;for (i=0; i<OUR_FD_COUNT; i++) {int fd = open(paths[i], O_RDWR);if (fd < 0) {fprintf(stderr, "fatal error opening "%s"n", paths[i]);g_error = errno;return -1;}g_fds[i] = fd;}g_error = 0;return 0;
}int
set_screen_state(int on)
{QEMU_FALLBACK(set_screen_state(on));LOGI("*** set_screen_state %d", on);initialize_fds();//LOGI("go_to_sleep eventTime=%lld now=%lld g_error=%sn", eventTime,//      systemTime(), strerror(g_error));if (g_error) return g_error;char buf[32];int len;if(on){len = sprintf(buf, on_state);len = write(g_fds[REQUEST_STATE], buf, len);sys_file = fopen(FILENAME_SYS_3G_RESTART, "w");if(sys_file){fputc(2, sys_file);fclose(sys_file);}}else{len = sprintf(buf, off_state);len = write(g_fds[REQUEST_STATE], buf, len);  ===> echo mem > /sys/power/statesys_file = fopen(FILENAME_SYS_3G_RESTART, "w");if(sys_file){fputc(0, sys_file);fclose(sys_file);}write_resume_state(1);}if(len < 0) {LOGE("Failed setting last user activity: g_error=%dn", g_error);}return 0;
}

到些完成了从按下power键到 echo mem > /sys/power/state 的过程,接下来就是进入内核中

二、内核中的休眠过程分析1、创建 /sys/power/state节点在内核中 kernel/power/main.cpower_attr(state);这是一个宏(定义在kernel/power/power.h),它实现在/sys/power/ 下创建对应节点state,对这个结点进行读写对应的函数为

//写结点时调用的函数
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t n)
//读结点时调用的函数
static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,char *buf)

接上边echo mem > /sys/power/state后state_store被调用

static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t n)
{
#ifdef CONFIG_SUSPEND
#ifdef CONFIG_EARLYSUSPENDsuspend_state_t state = PM_SUSPEND_ON;
#elsesuspend_state_t state = PM_SUSPEND_STANDBY;
#endifconst char * const *s;
#endifchar *p;int len;int error = -EINVAL;p = memchr(buf, 'n', n);len = p ? p - buf : n;/* First, check if we are requested to hibernate */if (len == 4 && !strncmp(buf, "disk", len)) {error = hibernate();goto Exit;}#ifdef CONFIG_SUSPENDfor (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) {if (*s && len == strlen(*s) && !strncmp(buf, *s, len))break;}if (state < PM_SUSPEND_MAX && *s)
#ifdef CONFIG_EARLYSUSPEND    ---------------------------------------------------------------if (state == PM_SUSPEND_ON || valid_state(state)) {                         |error = 0;                                                          |->android 添加的部分,如果定义了request_suspend_state(state);                                       |->earlysuspend则调用request_suspend_state(state); (定义在kernel/power/earlysuspend.c)}                                                                           |
#else ---------------------------------------------------------------------------------------error = enter_state(state);   ===========================>标准linux进入休眠的路径                  
#endif
#endifExit:return error ? error : n;
}

request_suspend_state 位于: kernel/power/earlysuspend.c

void request_suspend_state(suspend_state_t new_state)
{       unsigned long irqflags;int old_sleep;spin_lock_irqsave(&state_lock, irqflags);old_sleep = state & SUSPEND_REQUESTED;if (debug_mask & DEBUG_USER_STATE) {struct timespec ts;struct rtc_time tm;getnstimeofday(&ts);rtc_time_to_tm(ts.tv_sec, &tm);pr_info("request_suspend_state: %s (%d->%d) at %lld ""(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)n",new_state != PM_SUSPEND_ON ? "sleep" : "wakeup",requested_suspend_state, new_state,ktime_to_ns(ktime_get()),tm.tm_year + 1900, tm.tm_mon + 1, tm.tm__hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);}if (!old_sleep && new_state != PM_SUSPEND_ON) {state |= SUSPEND_REQUESTED;queue_work(suspend_work_queue, &early_suspend_work);------------- >这个是把工作early_suspend_work添加到工作队列suspend_work_queue中requested_suspend_state = new_state;spin_unlock_irqrestore(&state_lock, irqflags);} else if (old_sleep && new_state == PM_SUSPEND_ON) {state &= ~SUSPEND_REQUESTED;wake_lock(&main_wake_lock);queue_work(suspend_work_queue, &late_resume_work);requested_suspend_state = new_state;spin_unlock_irqrestore(&state_lock, irqflags);mdelay(300);}else {requested_suspend_state = new_state;spin_unlock_irqrestore(&state_lock, irqflags);}
}

工作队列suspend_work_queue定义在kernel/power/wakelock.c中在wakelocks_init()函数中对这个工作队列初始化

static int __init wakelocks_init(void)
{。。。。suspend_work_queue = create_singlethread_workqueue("suspend");  创建一个单线程休眠工作队列if (suspend_work_queue == NULL) {ret = -ENOMEM;goto err_suspend_work_queue;}。。。。。return ret;
}

本文发布于:2024-01-28 02:17:35,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063794634072.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:android   suspend   resume
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23