User:Lgarciameza/sandbox

Android APIs and Tools for Developing Power Efficient Apps

Overview

edit

The Android OS has lacked direct methods for developers to access the power management capabilities of the OS at the app level. Until the recent release of Android 5.0 Lollipop (more information below), the Application Programming Interfaces (APIs) that have been available to developers have had few capabilities, limiting app developers in the ways that they could optimized their apps for power efficiency.

APIs - Pre-Android 5.0

edit

PowerManager and WakeLocks

edit

The PowerManager and WakeLocks are some of the oldest APIs available for app developers that allow them to have some control over the power consumption of a device. WakeLocks have the benefit of allowing the developer to keep the screen on or the processor active for specific tasks. For example, a developer might want to keep the screen on while running a background task in order to show the user some kind of visual feedback. Another example would be for keeping the processor active so background tasks are run even if the screen is off [11]. The PowerManager acts as the interface with the systems’ POWER_SERVICE, allowing users to instantiate these WakeLocks and acquire the lock on the specified system resource. Developers must make sure to release the WakeLock after each use to prevent excessive battery drain as well as allowing the processor to return to idle or sleep states. WakeLocks have proven to be difficult to manage and sometimes even buggy depending on the Android device’s OEM customizations to the OS. They must be handled properly and used only when necessary to prevent unwanted power consumption and hurting the user’s experience. However, they remain one of the most used APIs for developer for controlling the state of the device. These issues lead Google to the creation of the new JobScheduler API explained below.

Code snippet for instantiating a WakeLock to keep the processor in the active state from the SDK [11]:

PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); 
Wakelock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 
"MyWakelockTag"); 
wakeLock.acquire();

Developers must also make use of this permission to enable the use of WakeLocks [11]:

 <uses-permission android:name="android.permission.WAKE_LOCK" />

AlarmManager

edit

AlarmManager was one of the few public Android APIs that allowed developers to schedule tasks at specific times before the release of the new APIs. Developers could run their background tasks whenever they wanted through the use of a built in system service even if their app was not running. This means that this API has the big disadvantage of not being aware of the state of the device or network that it’s using, it will run as along as the device is on [5]. This can cause excessive battery drain if the device is routinely brought out of the idle state to run tasks, especially if they require waking the radio to run network transactions [8]. Another disadvantage is that the scheduled alarm will be cleared once the device is restarted, unless the developer adds special handling to have the alarm re-register on boot [8]. Alarms hold a wake lock to keep the device awake, and it will not let the device go to idle or sleep state until the task is done running, further causing power consumption on the device [9].

Code snippet for instantiating an AlarmManager from the SDK [10]:

// Set the alarm to start at approximately 2:00 p.m. 
Calendar calendar = Calendar.getInstance(); 
calendar.setTimeInMillis(System.currentTimeMillis()); 
calendar.set(Calendar.HOUR_OF_DAY, 14); 

// With setInexactRepeating(), you have to use one of the AlarmManager interval constants--in this case, AlarmManager.INTERVAL_DAY. 
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 
AlarmManager.INTERVAL_DAY, alarmIntent);

New APIs and Tools on Android 5.0 - Project Volta

edit

The public release of Android 5.0 (Lollipop) introduced many new APIs for developers to manage their apps power usage more efficiently [1]. Google decided to improve on the old APIs that were less intuitive to work with and usually required methods not outlined by the SDK guidelines to achieve the desired effects.

JobScheduler

edit

The JobScheduler class provides a new API that overrides the older and less efficient AlarmManager, which was not made as a general solution for running all sorts of different tasks that application wanted to run at specific times[1]. The new scheduler class allows developers to decide under what parameters they want their apps to run these specific tasks. For example, the developers can take advantage of running the task when the phone is charging or when they have WiFi connection if they are doing network intensive work such as when backup up photos or loading up emails in the background. Furthermore, this API has the advantage of natively batching together different tasks requested by an application while taking advantage of the power state the phone is in [1]. By combining the API’s capability to run tasks under specific parameters and batching these tasks, it allows for app developers to trigger these tasks under advantageous conditions of the state of the device. For example, by executing the network tasks while the phone’s radio is already awake, the developer can reduce the energy used for waking and ramping up the radio as well as reducing the latency associated with this process. Again this API can take advantage of when the phone is idling or charging to run demanding tasks without hurting the user’s experience or overall performance. Developers can instantiate a task by building a JobInfo object using the JobBuilder API with the specific parameters that the task should run under. The object is passed into the JobService class that the developer must implement to start or stop the job.

Google has included an example project called JobScheduler in their latest SDK. Below is a code snippet showing how to instantiate a job through the JobScheduler API [7]:

public void scheduleJob(View v) { 
if (!ensureTestService()) { 
return; 
} 

JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent); 

String delay = mDelayEditText.getText().toString(); 
if (delay != null && !TextUtils.isEmpty(delay)) { 
builder.setMinimumLatency(Long.valueOf(delay) * 1000); 
} 
String deadline = mDeadlineEditText.getText().toString(); 
if (deadline != null && !TextUtils.isEmpty(deadline)) { 
builder.setOverrideDeadline(Long.valueOf(deadline) * 1000); 
} 
boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked(); 
boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isChecked(); 
if (requiresUnmetered) { 
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); 
} else if (requiresAnyConnectivity) { 
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); 
} 
builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked()); 
builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked()); 

mTestService.scheduleJob(builder.build()); 
}

Battery Statistics

edit

The new APIs have a tool that collects battery statistics for developers to benchmark their applications. Developers can see the power and network usage of the app, which can help them optimize the app to target these areas. This tool is accessible through the following command [1]:

$ adb shell dumpsys batterystats --charged <package-name>

Example console output shown in Figure 1.

Further useful statistics [1]:

  • History of battery related events
  • Global statistics for the device
  • Approximate power use per UID and system component
  • Per-app mobile ms per packet
  • System UID aggregated statistics
  • App UID aggregated statistics
 
Figure 1: Sample output of batterystats from a Nexus 7 running the JobScheduler sample app.

Battery Historian

edit

The historian tool further processes the results of batterystats into an easier to read HTML page that makes it easier for developers to identify the different events power consumption. It is a python script freely available in github[4]. Figure 2 shows an example of report taken from an app.

 
Figure 2: Sample HTML generated from the batterystats output.

App usage statistics

edit

This new API allows developers to collect system data of the app over different periods of timing, having data persistence for certain rages of time. Data can be collected from daily up to yearly ranges [1]. This can help developers understand their user’s app usage and how they can optimize this behavior for improving power efficiency over the long term use of their apps. They could run certain tasks such as updating data when users are the least likely to use the app through the use of the JobScheduler described above. Developers wanting to make use of this API must add this permission to their manifest [1]:

"android.permission.PACKAGE_USAGE_STATS"

The Ahead-of-Time compilation runtime (ART) is the latest runtime for the Android OS. It serves as a replacement to the aging Dalvik Runtime which used Just-in-Time compilation [6]. Beginning from Android 5.0, ART will be the only supported runtime. The greatest advantage for power efficiency that this new runtime brings is the fact that it compiles the app upon installation for the specific platform, in contrast, to Dalvik’s JIT compilation which compiles and optimizes the app every time that it’s launched. This change allows for increased battery life since the processor will not have to do extra work to compile the app every time; however, ART comes at the expense of increased app size since compiled code will take more storage space. Another advantage is that ART has an improved garbage collector (GC) which allows the device’s processor to spend less time in the active state cleaning up allocated objects and spend more time idling or running higher priority tasks for greater responsiveness and performance [6].

Research examples of APIs and Tools for improving power efficiency

edit

WattsOn

edit

WattsOn is an experimental tool that attempts to model the power consumption of a mobile device by estimating the energy consumption of the various components of the device, such as displays, radios, and processors, which can help app developers, determine how the app uses energy and how the efficiency can be improved for greater battery life [12]. One of the advantages of WattsOn is that it attempts to model the energy consumption from the development environment, instead of using the device with the app and execute the model there. WattsOn makes use of resource scaling in order to account for the differences of resource usage between the device and the development environment where resource scaling attempts to bridge this gap. One of the effects of resource scaling is emulating the latency, bandwidth, and packet loss that the actual device would experience in a wireless network in order for it to be properly accounted in the power model [12]. WattsOn further makes use of separate power models for each component, it can account for the energy consumption of the GPU, CPU, display, and wireless radios (WiFi and Cellular). Additionally, WattsOn has an average error for the energy consumption estimation from 4% to 9% when compared with real devices, Figure 3 shows a sample reading comparing the accuracy of the model [12]. This relatively low margin of error can allow developers make design decisions about their app that will help reduce their power consumption with greater confidence by using this tool.

File:Measured vs Emulated Energy Consumption.png
Figure 3: Comparison between measured and emulated energy [12]

Latency, Accuracy, and Battery (LAB) Abstraction

edit

The LAB abstraction implements a system service API called Senergy in order to make it easier for developers to optimize their apps for contextual sensing while maintaining power efficiency [13]. The mobile context is defined as the sensing of “location, movement, social, situation, mood, and stress levels” either through processing in the foreground or background of the OS [13]. The Senergy API implementation allows a level of abstraction that reduces the amount of work the developer has to put into developing their own optimized contextual algorithm, instead Senergy abstracts all those issues into an expressive API. Figure 4 how the Senergy API is built on top of the OS as an interface between the apps and the OS. Developers are able to specify the priority order for optimizing contextual sensing, in this case, accuracy, latency, and battery; additionally, each parameter can be optimized for reduced latency or battery gains (partial quantitative specification) [13]. The API also allows for the developer specify the level of optimization for different types of activities such as driving, walking, etc.; an example of this can be seen in the code snippet below. Using Senergy optimizations throughout the OS and targeting multiple apps, Senergy can achieve up to 50% power savings compared to optimizing individual apps, Figure 5 shows an example of the gains achieved by Senergy. By providing this abstraction layer for optimizing for battery, contextual sensing, and performance, LAB and Senergy can help developers improve the energy consumption of their apps without having to deal with the complexities associated when performing such optimizations.

Sample code snippet for optimizing app context for walking [13]:

ChangeAlert(Activity.WALKING,Priority.BATTERY,5,Priority.LATENCY,10,Priority.ACCURACY);
File:Senery Architecture.png
Figure 4: Senergy Architecture [13].
File:Senergy Battery Savings.png
Figure 5: Senergy battery savings on multiple app optimizations[13].


ScreenLock Service

edit

The ScreenLock service is another experimental API solution for improving power consumption of the display on devices running the Android OS. By understanding the user’s screen usage behavior through a data collection service, it attempts to lower the level of “annoyance” caused by “turning off the screen in inopportune moments” [14]. Due to this annoyance the user would try to turn the screen back on, leading to further battery drain. Annoyance is defined more clearly as when the “user restarts the screen within a time interval of less than or equal to 5 seconds” [14]. Using this as a threshold, the service logged how many times the user is annoyed into an app that collects the data, it also logs all other apps that were being used during that time. The data collected is used to build a history of usage for the user which is then used by the ScreenLock service to readjust the screen timeout every time an app goes to the foreground or background [14]. The algorithm used to reduce annoyance showed that an increase in mean screen timeout lead to less annoyance; however, increasing the timeout too much would lead to unnecessary battery drain since the screen would not be used [14]. Ultimately the goal of ScreenLock was to make a more dynamic screen timeout capability for the smartphone that better adjust to the user’s usage habits which leads to greater power savings by having less display restart cycles.

References

edit
edit