整理:徐建祥(netpirate@gmail.com)
日期:2009/09/16
网址:http://www.anymobile.org
Index
1. Introduction
2. Architecture
3. How to Work
4. Wake Locks
5. Wake Lock Example
6. Music Application
1.Introduction
Android supports its own Power Management (on top of the standard Linux Power Management) designed with the premise that the CPU shouldn't consume power if no applications or services require power. For more information regarding standard Linux power management, please see Linux Power Management Support at http://kernel.org.
Android requires that applications and services request CPU resources with "wake locks" through the Android application framework and native Linux libraries. If there are no active wake locks, Android will shut down the CPU.
2.Architecture
Framework Layer
/frameworks/base/core/java/android/os/PowerManager.java
/frameworks/base/services/java/com/android/server/PowerManagerService.java
/frameworks/base/core/java/android/os/Power.java
/frameworks/base/core/jni/android_os_power.cpp
/hardware/libhardware_legacy/power/power.c
"/sys/power/wake_lock"
"/sys/power/wake_unlock"
"/sys/power/state"
"/sys/android_power/acquire_partial_wake_lock"
"/sys/android_power/release_wake_lock"
"/sys/android_power/request_state"
… …
Kernel Layer
/drivers/android/power.c
/drivers/power/apm_power.c (Advanced Power Management)
3.How to Work
系统正常开机后进入到AWAKE状态,Backlight会从最亮慢慢调节到用户设定的亮度,系统screen off timer(settings->sound & display-> Display settings -> Screen timeout)开始计时,在计时时间到之前,如果有任何的activity事件发生,如Touch click, keyboard pressed等事件,则将Reset screen off timer, 系统保持在AWAKE状态。如果有应用程序在这段时间内申请了Full wake lock,那么系统也将保持在AWAKE状态,除非用户按下power key. 在AWAKE状态下如果电池电量低或者是用AC供电screen off timer时间到并且选中Keep screen on while pluged in选项,backlight会被强制调节到DIM的状态。
如果Screen off timer时间到并且没有Full wake lock或者用户按了power key,那么系统状态将被切换到NOTIFICATION,并且调用所有已经注册的g_early_suspend_handlers函数,通常会把LCD和Backlight驱动注册成early suspend类型,如有需要也可以把别的驱动注册成early suspend,这样就会在第一阶段被关闭. 接下来系统会判断是否有partial wake lock acquired,如果有则等待其释放,在等待的过程中如果有user activity事件发生,系统则马上回到AWAKE状态;如果没有partial wake lock acquired,则系统会马上调用函数pm_suspend关闭其它相关的驱动,让CPU进入休眠状态。
系统在Sleep状态时如果检测到任何一个Wakeup source,则CPU会从Sleep状态被唤醒,并且调用相关的驱动的resume函数,接下来马上调用前期注册的early suspend驱动的resume函数,最后系统状态回到AWAKE状态.
Registering Kernel-level Drivers with the PM Driver
#Be notified immediately before power down
android_register_early_suspend(android_early_suspend_t *handler)
#Be notified immediately after power up
android_register_early_resume(android_early_resume_t *handler)
HARDWARE LIGHTS
#define LIGHT_ID_BACKLIGHT "backlight"
#define LIGHT_ID_KEYBOARD "keyboard"
#define LIGHT_ID_BUTTONS "buttons"
#define LIGHT_ID_BATTERY "battery"
#define LIGHT_ID_NOTIFICATIONS "notifications"
#define LIGHT_ID_ATTENTION "attention"
#define LIGHT_ID_BLUETOOTH "bluetooth"
#define LIGHT_ID_WIFI "wifi"
4.Wake Locks
Wake locks are used by applications and services to request CPU resources.
Types of Wake Locks:
-ACQUIRE_CAUSES_WAKEUP: Normally wake locks don't actually wake the device, they just cause it to remain on once it's already on.
-FULL_WAKE_LOCK: The screen and keyboard are on at full brightness
-ON_AFTER_RELEASE: When this wake lock is released, poke the user activity timer
-PARTIAL_WAKE_LOCK: The CPU is running, The screen might not be on.
-SCREEN_BRIGHT_WAKE_LOCK: The screen is on at full brightness; the keyboard backlight will be allowed to go off.
-SCREEN_DIM_WAKE_LOCK: The screen is on, but the keyboard backlight will be allowed to go off, and the screen backlight will be allowed to go dim.
5.Wake Lock Example
1). Acquire handle to the PowerManager service.
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DEVICE_POWER" />
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2). Create a wake lock and specify the power management flags for screen, timeout, etc.
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);
3). Acquire wake lock.
wl.acquire();
4). Perform operation (play MP3, open HTML page, etc.).
5). Release wake lock.
wl.release();
6.Music Application
/packages/apps/Music/AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK" />
/packages/apps/Music/src/.../MediaPlayerService.java PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
WakeLock mWakeLock =
pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
this.getClass().getName());
#Sets this WakeLock is not ref counted.
mWakeLock.setReferenceCounted(false);
…
#The lock will be released after 30 seconds.
mWakeLock.acquire(30000);
…
mHandler.sendEmptyMessage(RELEASE_WAKELOCK);
#Release the claim to the CPU or screen being on.
mWakeLock.release();
Reference
Android Platform Development Kit:Power Management
http://www.netmite.com/android/mydroid/development/pdk/docs/power_management.html
Android Power Management(Steve Guo)
http://letsgoustc.spaces.live.com/blog/cns!89AD27DFB5E249BA!526.entry
Android 电源管理(hzdysymbol)
http://blog.csdn.net/hzdysymbol/archive/2009/03/19/4004791.aspx
Linux Power Management Support
http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.24.y.git;a=blob;f=Documentation/pm.txt