Currently I'm locking at the Android Kernel and I'm wondering about the Wake lock mechanism. How and where is the interval time specified which defines at what point the phone will suspend. Is there a sysfs interface which passes a value (in milliseconds or something) to the kernel. For example the sleep option in the Android OS settings how does a change there reflects in the kernel?
2 Answers
It is a big topic about suspend/resume code flow (on android phone).The code flow in kernel have been inlustrated by:
After Android receice event.POWER and affirm no wake_lock exist, Android trigger the suspend flow in kernel by echo mem > /sys/power/state:
state_store >> pm_suspend >> enter_state >> suspend_prepare >> suspend_devices_and_enter >> dpm_suspend_start >> dpm_suspend >> device_suspend >> __device_suspend ---> suspend_enter (called by suspend_device_and_enter after __device_suspend is completed)
What's more, kernel private interface(mechanism) to suspend system to Android. But most of the control logic(policy) is in PowerManagerService of Android system. I hope this much help you to understand what system really do after press the Power Key.
1. Report the PowerKey
report the power key event by input system in kernel, maybe like this:(up to what SoC platform you are)
input_report_key(powerkeydev,KEY_POWER, 1); input_sync(powerkeydev); msleep(1); input_report_key(powerkeydev,KEY_POWER, 1); input_sync(powerkeydev);
KEY_POWER = 116 define in include/uapi/linux/input.h
key code mapping in android android/frameworks/base/data/keyboards/Generic.kl android/frameworks/native/include/input/KeycodeLables.h
intercept the Key event android/frameworks/base/services/core/java/com/anroid/server/policy/PhoneWindowManager.java interceptKeyBeforeQueueing() >> interceptPowerKeyUp() >> powerPress() >> powerPress >> case SHORT_PRESS_POWER_GO_TO_SLEEP >> mPowerManager.goToSleep
manage the wake locks in PowerManagerService: PowerManager.java: goToSleep() -> mService.goToSleep() PowerManagerService.java: goToSleep() -> goToSleepInternal -> goToSleepNoUpdateLocked() -> updatePowerStateLocked() -> updateSuspendBlockerLocked() (clear the wake locks)
2. libsuspend trigger the suspend
suspend_thread_func check should suspend per 100ms. After all the wake lock clear:
android/system/core/libsuspend/autosuspend.c: suspend_thread_func() -> write(state_fd, sleep_state, strlen(sleep_state))
This menes: echo "mem" > /sys/power/state, which trigger the suspend flow in kernel.
3. how to setup autosuspend thread?
Thread suspend_thread_func() was create by:
init autosuspend
android/system/core/libsuspend/autosuspend.c: int autosuspend_enable(void)
call autosuspend in jni
android/frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp: autosuspend_enable() -> nativeSetAutoSuspend()
init by PowerManagerService
android/services/core/java/com/android/server/power/PowerManagerService.java: nativeSetAutoSuspend(boolean enable);

- 331
- 2
- 12
After some research and digging within the Android sources I saw that the PowerManagerService is taking care of measuring the time since the last activity in order to send the device to sleep.

- 491
- 4
- 14