Mobile devices have a very hard constraint on power consumption due to its limited nature: battery capacity. On a mobile phone, if power consumption is managed correctly the user experience is severely harmed. Can you imagine the consequences of not being able to call home to ask what should you bring from the supermarket? - Serious trouble. Hence, Android Power Management support, which sits on top of Linux Power Management, was designed with the premise that the CPU shouldn't consume power if no applications or services require power.
Android implements, on top of the standard Linux Power Management, a more aggressive Power Management policy, in which applications and services must request CPU resources with "wake locks" through the Android application framework and native Linux libraries in order to keep power on. If there are no active wake locks, Android will shut down the CPU.
Android Power Management Architecture
The figure below illustrates Android Power Management Architecture.
Solid elements represent Android blocks and dashed elements represent partner-specific proprietary blocks.
The Android Power Management Framework is implemented as a driver on top of Linux PM. Then, the Application PM Framework, which is written in Java, interfaces with android_power driver through JNI (Java Native Interface). This Framework is available to the user space applications through the class PowerManager. This class gives you control of the power state of the device. Hence, the application must get an instance of PowerManager in order to enforce its power requirements. Your application can obtain a handle to the PowerManager class by calling Context.getSystemService(), specifying by name which system-level service it requires. For instance:
Activity mContext = this;
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
Then, the application informs the PM Framework its power requirements, which can be viewed as constraints for suspending the system components. These constraints are implemented by means of “wake locks”, which can be created after acquiring a handle to PowerManager. Upon creation of the wake lock, the application must specify the power management flag it needs, as shown below:
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MyTag");
Application Interface
We've seen that Android requires that applications and services request CPU resources with "wake locks" through the Android PM Application Framework, which is available to the application by means of the class PowerManager. The code snippets above illustrate how to accomplish this. Now, let's briefly describe the API, more information can be obtain on Android Power Management Framework.
Classes
android.os.PowerManager
android.os.PowerManager.WakeLock
The nested class PowerManager.WakeLock has three public methods:
void goToSleep(long time) – forces the device to go to sleep.
void newWakeLock(int flags, String tag) - gets a wake lock at the level of the flags parameter.
void userActivity(long when, boolean noChangeLights) - turns the device from whatever state it's in to full on, and resets the auto-off timer.
Wake Locks
Wake locks are used by applications and services to request CPU resources.
Wake Lock | Description |
FULL_WAKE_LOCK | Wake lock that ensures that the screen and |
PARTIAL_WAKE_LOCK | Wake lock that ensures that the CPU is |
SCREEN_BRIGHT_WAKE_LOCK | Wake lock that ensures that the screen is on |
SCREEN_DIM_WAKE_LOCK | Wake lock that |
The above flags are mutually exclusive, hence you can specify only one of them. In addition to the above flags, two more flags, which affect the behaviour of the screen only.
Wake Lock | Description |
ACQUIRE_CAUSES_WAKEUP | Normally wake locks don't actually wake the |
ON_AFTER_RELEASE | If this flag is set, the user activity timer |
Summary
Android implements a very aggressive Power Management Framework on top of Linux PM. In this Framework, the application informs the PM Framework its power requirements, which can be viewed as constraints for suspending the system components. The Android Framework exposes power management to services and applications through the PowerManager class. Applications and services in need of CPU resources must request them from the PM Framework in the following steps:
1.Get a handle to the PowerManager.
2.Create a WakeLock and specify the power management flag.
3.Acquire a wake lock.
4.Perform operation (play MP3, open HTML page, etc.).
5.Release wake lock.
The code snippet below illustrates these steps.
Activity mContext = this; PowerManager pm = (PowerManager)mContext.getSystemService( Context.POWER_SERVICE); PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, “MyTag”); wl.acquire(); // … Perform operations wl.release();