Incorporating USB battery charging protocols into an Android-based design

Editorial Note: Excerpted from Unboxing Android: A hands on approach with real world examples , by Rajaram Regupathy, the author takes you through the process incorporating effective power management into a design using the Android distribution of the Linux operating system using either its native power management framework or the widely used Universal Serial Bus hardware specification.

USB technology has evolved over the years as the standard for connecting peripherals like keyboards, printers, and so on, to personal computers, and as a result, USB has replaced serial and parallel ports. Modern devices like smart phones and game controllers have also adopted this technology as a primary transport mechanism. As part of their evolution, USB evolved from a data interface to an important source of power to charge portable devices like a smart phones, or even to power up an external audio speaker. In Battery Charging Specification, the Battery Charging Working Group of the USB Implementers Forum (USB-IF) has standardized how a USB power source has to behave, the different types of USB power sources, and how much power a device can consume when connected to a USB source.

This article explores USB-based charging that you, as an Android developer, need to know to develop applications related to charging in various user contexts: wall charger, personal computer, and charging dock. Because both will be important, this article will discuss battery charging in the context of both the formal spec as well as the native one included within the Android framework.

USB Battery Specification overview
In a way, the main focus of the USB Battery Charging 1.2 specification is to define the characteristics of different chargers and describe their mechanisms for how to detect the chargers. This section focuses on the different types of charging options (USB ports and chargers) and their characteristics in brief. The specification also details the mechanism that can differentiate the different types, but that is beyond the scope of this book. Before you study the different types of charging ports, you should first understand some key USB terms relevant to this section.

Downstream Port – A port that data flows away from the host. In laymen terms, a USB port on a host PC or on a hub, with ports that are farthest from the host, are downstream ports.

Upstream Port – A port that sends data toward the host. Generally, a port on a USB device and on a hub, with the port that is closest to the host, are upstream ports.

Here are the different types of charging options (USB ports and chargers) and their characteristics:

Standard Downstream Port (SDP)
refers to a port on a host or hub that’s compliant with USB 2.0 specifications. This means a SDP port can provide different power, depending upon the state of connection with the USB device. An SDP port expects a downstream device to have the following maximum current consumption in different states:

  • 2.5mA when the device is in a suspended state
  • 100mA when connected and not configured
  • 500mA or the amount of current requested by the device’s configuration descriptor, whichever is less, when configured

When a USB device is connected to a SDP, the device can draw 100mA and up to 500mA once the device is enumerated successfully by the host. The charging setup as described for the personal computer example of the previous section represents a Standard Downstream Port.

Charging Downstream Port (CDP)
refers to a port on a host or hub that’s compliant with USB 2.0 specifications. But unlike the SDP, a CDP port allows a USB device to draw more current, thereby facilitating faster charging. When a portable device is connected to a charging port, it is expected to behave in the following way:

  • 2.5mA when the device is in a suspended state
  • 100mA when it is connected and not configured
  • Maximum of 1.5A when configured

When a USB device is connected to a CDP, the device will be enumerated successfully by the host. The charging setup as described for the personal computer example of the previous section can also represent a Charging Downstream Port. A CDP port is generally marked with a symbol to indicate to the user that it can supply more power.

Dedicated Charging Port (DCP)
A downstream port that provides power over a USB connection to a portable device. When a portable device is connected to a DCP, a maximum of 1.5A can be consumed by the device. The key difference between a DCP and the other two charging ports is that the D+ and the D- lines are shorted, which means there is no support for enumeration. The wall charger example in the previous section is an example of a DCP.

Accessory Charger Adapter (ACA)
With portable devices becoming smaller to be more attractive and convenient to users, the number of ports available to the user becomes limited. On any given PD, you will generally find a single USB port in which you can connect a charger to charge the device or connect a USB device like a mouse or keyboard. Herein lies the problem of how to use a USB port for connecting a USB keyboard when the device requires charging.

Accessory Charging Adapter (ACA) is aimed at addressing this problem by expanding a single USB port to be attached to a charger and a USB device at the same time, as shown in Figure 1. Figure A-5.

Figure 1: ACA representation by battery charging specification (REF: USB Battery Charging Specification)

The dock examples discussed earlier in the first section of this appendix belong to this class of device, and it supports the following three ports:

  • OTG port: This port allows users to dock the device with a Micro AB receptacle.
  • Accessory port: This port allows users to connect any device to the PD.
  • Charger port: This port allows users to connect a charger that can power up the PD and the accessory device.

An ACA is classified into two types, based on the features it supports. If an accessory port of an ACA has a Mirco-AB receptacle, allowing connection of A and B devices, it is referred to as Micro ACA. When the accessory port has only a Standard-A receptacle, which allows connection of a B device, the ACA device is referred to as a Standard ACA. Figure 1 shows is a typical standard ACA setup.

The USB battery-charging specification also talks about handling dead batteries, along with mechanisms to differentiate charging ports, and you can refer to the specification for more details. .

Android Battery Charging Overview

Android’s USB battery charging requirement is very straightforward. According to Android CDD 4.2, the Android platform’s USB charging requirement is as follows:

“It SHOULD implement support for USB battery charging specification. Existing and new devices that run Android 4.2 are very strongly encouraged to meet these requirements in Android 4.2 so they will be able to upgrade to the future platform releases.”

A device that claims to be compatible with Android CDD 4.2 supports all modes of USB charging, as explained in the previous section. Inside the Android platform, most of the charging-related activities like detecting the charger type and managing the battery, are done by the hardware and the Android Linux kernel. The Android kernel shares information related to battery charging using system file entries in the user space. The user space Android framework presents the user details of the hardware and kernel changes related to charging by reading the information exported by the kernel. This is managed by the following two blocks of the Android Battery framework:

Battery Manager This framework is implemented through the frameworks/ base/core/java/android/os/ file and acts as an interface between an application and the Battery Service framework. The BatteryManager class defines the constants for applications to extract information from the ACTION_BATTERY_CHANGED intent, which is generated by the Battery Service.

Battery Service
The Battery Service framework is the core part of the Android Battery framework. The Battery Service framework is responsible for generating battery state-related intents and broadcasting them to other Android frameworks. Internally, the battery service is divided into a class and a JNI implementation. The battery service java class is implemented in
frameworks/base/services/java/com/android/server/BatteryService. java

and the JNI part is implemented through

The role of the JNI part is to read appropriate battery driver-related files exported by the Android kernel and pass them to the java class over global variables. The java class in turn interprets the values and generates the appropriate intents related to the battery state. It will shut down the device when the battery is critically low.

Before getting into the details of the Android USB Battery Charging framework, it’s important you understand what kind of information the Android kernel exports that is related to battery charging in the user space. The following snippet lists files and folders under /sys/class/power_supply using the ADB shell of a Samsung Grand mobile:

shell@android:/sys/class/power_supply $ ls
shell@android:/sys/class/power_supply $

shell@android:/sys/class/power_supply/battery $ ls
shell@android:/sys/class/power_supply/battery $

Few of the file entries listed here are specific to the vendor, and this section focuses only on the entries that the Android framework uses. Internally, the Android framework reads these files using a JNI implementation
(frameworks/base/services/jni/com_android_server_BatteryService.cpp ) and stores them internally for sharing with other applications. In the following section, you’ll explore how a Battery Manager and Battery Service, as represented in Figure 2 , generate battery charging-related intents. Android Battery Charger framework uses the following intent.actions intents to pass on the status of battery charging.

Figure 2: Illustrates the Android Battery Manager architecture when plugged in to a USB power source


This intent is generated to indicate that some of the battery-related information has changed and any interested receiver has to recalculate. The intent bundles the following extra data for the receiver, which can be used to develop advanced battery applications:

STATUS – The status field holds one of the following values:
            – BATTERY_STATUS_UNKNOWN = 1;
            – BATTERY_STATUS_FULL = 5;
HEALTH – The health field holds one of the following values:
            – BATTERY_HEALTH_UNKNOWN = 1;
            – BATTERY_HEALTH_GOOD = 2;
            – BATTERY_HEALTH_OVERHEAT = 3;
            – BATTERY_HEALTH_DEAD = 4;
            – BATTERY_HEALTH_COLD = 7;
PRESENT – The present field indicates the presence of the battery. LEVEL – The level field indicates current battery level.
SCALE – The scale field indicates the maximum battery level,indicated as BATTERY_SCALE = 100 in
ICON_SMALL – The icon field hold the resource id of the battery icon
based on the current battery status retreived by getIconLocked in
PLUGGED – The plugged field indicates the type of power source and the value could be one of the following:
          /** Power source is an AC charger. */
          – BATTERY_PLUGGED_AC = 1;
          /** Power source is a USB port. */
          – BATTERY_PLUGGED_USB = 2;
          /** Power source is wireless. */
VOLTAGE – The voltage field indicates current battery voltage in Millivolts.
TEMPERATURE – The temperature field indicates current battery temperature in tenths of a degree Centigrade.
TECHNOLOGY – The technology field specifices the technology that battery is made of.
INVALID_CHARGER – When the charge is unsupported, the charger variable is set to non-zero numeral.

An important point to note about this intent is a protected intent can be sent only by the system. This intent cannot be received through manifest declarations and has to be explicitly registered.

This intent is generated by the Android Battery framework to indicate that the device has reached a low battery level. This intent can be sent only by the system and is a protected intent.

This intent is generated by the Android Battery framework to indicate that the device has recovered from a low battery level and is now OK. This intent can be sent only by the system and is a protected intent.

This intent is generated by the Android Battery framework when an external power source is connected to the system. Any application registered for this intent will be woken up and this protected intent can be sent only by the system.

This intent is generated by the Android Battery framework when an external power source is disconnected from the system. Any application registered for this intent will be woken up, and this protected intent can be sent only by the system.Android Battery Framework Design
Havinglearned about the different intents related to Android Batteryframework, you’re ready to explore how these intents are generated andsent to applications that are registered for these batterynotifications. Figure 3 illustrates the sequence ofoperations for how a battery framework registers to an Android platformuntil the intent generation.

Figure 3: The control flow of the Battery Service framework

Thecore part of the Android Battery framework is the Battery Service,which is extended using Battery Manager with battery-related informationfor an application. The Battery Service starts when the system loads upwith the JNI_OnLoad function. That function registers differentframeworks, including the Battery Service using the register_android_server_BatteryService function, as illustrated in Figure 4 .

TheBattery Service Java implementation starts observing forSUBSYSTEM=power_supply uevents from the battery kernel driver. When thestring is matched by the UEventObserver, the Battery Service frameworkstarts reading the sysfs entries using the JNI function android_server_ BatteryService_update .The read values are compared with the previously read values, whichwere stored internally within the Battery Service framework. If the readvalue is different from the stored value, then the Battery Serviceframework generates appropriate intents to communicate the batterystatus to other Android frameworks.

From the sequence diagram Figure 4 , you can now see that the Battery Managerclass acts as a holder for the ACTION_BATTERY_CHANGED intent's extras.When applications receive the ACTION_BATTERY_CHANGED intent, they canretrieve the additional data using the getIntExtra method, with constants defined in the Battery Manager, as shown here:

int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);

Here are a few interesting change lists extracted from the Battery Service framework’s history:

Fix a deadlock involving Battery Service (Ibf8ab13224f204a9857825265e864f93583bce8e)

ThePowerManager may call into the Battery Service while holding its locks.You need to be careful that the Battery Service doesn't call into otherservices, particularly the Activity Manager, while holding its ownlocks.

Change-Id: Ibf8ab13224f204a9857825265e864f93583bce8e

Thisis a very recent fix, and if you are developing a battery applicationfor older Android versions like Gingerbread, you may be interested inthis defect.

Shut down when capacity is 0% with no charging or when battery is dead.

TheAndroid framework does not shut down when battery capacity is 0% and acharger is attached (USB or AC). This handling is incomplete since acharger might very well be attached, but the charging has stoppedbecause the USB is suspended or the charging algorithm has stoppedbecause of battery safety handling. Also, shutdown may occur when thebattery is reported as “dead.” This might still happen, although thedevice may be currently charging.

Change-Id: If328260ebf4d38f912e4d2fad204431cbb19c993

Thischange list can provide an idea of how to manage the battery statusinformation and control system shutdown. This was reverted and modifiedthrough change list I1e6590611af43812f1bac223dd31570d1d90cfc5.

Nowthat you have an understanding of the internals of the Android Batteryframework, it’s time to explore how to use this information to developadvanced battery applications. The following section provides twoexample applications demonstrating how to:

  • Access the battery driver system information by bypassing the Android Battery framework.
  • Use the Android Battery framework intent to detect when the battery is full.

Sample 1: Battery Status Explorer

Thepurpose of this example is to demonstrate how an application can bypassthe Android Battery framework and collect information about thebattery’s status directly from the files exported by the Android batterydriver.

Design and Flow. The Android kernel battery driver exports battery information through files mounted in the /sys/class/power_supply folder. The Android Battery framework reads those files and broadcaststhe contents as part of the battery intents. However, an applicationdeveloper can bypass this framework and directly read the system filesto gain additional information about the battery status.

Theapplication starts by setting up the default directory to /sys/class/power_supply/battery/, which needs to be listed as shown here:

public class MainActivity extends Activity {

   private File f= new File(“/sys/class/power_supply/battery/”);    
   private String []directory;
   private String start = “/sys/class/power_supply/battery/”;

The application uses BaseExpandableListAdapter to list the file and the contents on a click event, as shown here:

ExpandableListView myview = (ExpandableListView)findViewById(R. id.expandableListView1);
myview.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {

   public boolean onChildClick(ExpandableListView parent, View v, 
                int groupPosition, int childPosition, long id) {
      File myfile = new File(start + directory[groupPosition]);  
      if(myfile.exists()) {
         if (myfile.isDirectory()) { 

–cut–                                                                    }
                         return false.

adp = new myAdapter(getBaseContext(), directory, start); myview.setAdapter(adp);

The snapshot in Figure 4 shows the application list /sys/class/power_ supply/battery folder along with its contents.

Figure 4: Figure A-8. Snapshot of Battery status explorer application

The complete code and project are available at 9781430262084 and at git/batterystatusexplorer.git/ . You can download the code and send patches to add functionalities to the project.

Sample 2: Charging Completion Indicator

The purpose of this example is to demonstrate how an application can parse information from the ACTION_BATTERY_CHANGED intent and generate an alarm when charging is complete. The applicationalso indicates the charging progress using a progress bar.

Design and Flow. If an application is interested in receiving the intentACTION_BATTERY_CHANGED, it has to register rather than project themanifest file.

ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); batteryStatus = registerReceiver(null, ifilter);

After successful registration, you can extract the information passed over on the intent that indicates the charging status.

level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
batteryPct = (level / (float)scale) * 100;
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
int type = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                     status == BatteryManager.BATTERY_STATUS_FULL;

If the status indicates that charging is not complete, you can set the progress bar to indicate the battery level.

if (isCharging) {
   if (type == BatteryManager.BATTERY_PLUGGED_AC)
      final_string =  final_string + “AC Charger Pluggedn”;
   if (type == BatteryManager.BATTERY_PLUGGED_USB)
      final_string = final_string + “USB Charger Pluggedn”;
   textview.setText( final_string + “Battery % = ” + batteryPct);
   if (progressbar.getProgress() <= 99) {

   } else {

Once charging is complete and the battery is full, you can then play a tone for a brief period.

} else {
   textview.setText(final_string + “Battery % = ” + batteryPct);  
   if (temp < 10) {
      if ((temp & 1) == 1);

Thisapplication indicates when to plug in a phone when charging and toswitch off the power source when the battery is fully charged. Thecomplete code and project are available at and at . Figure 5 provides a snapshot of the application.

Figure 5: Snapshot of batteryinfo application

USBas a power source has come a long way and has matured through formalspecifications like the USB-IF’s Battery Charging Specification. Thisappendix explored the different charger types in laymen terms and thenmatched those devices with battery specification requirements. Thisappendix also explored the charging frameworks inside Android andincluded detailed examples.

Let’s not forget also to explore arecent development in the evolution of USB-based charging, known as “USBpower delivery.” The power delivery specification is designed todeliver increased power levels and relax power direction, which meanseither the host or device can supply power and supportive negotiatingpower is required. You can find more detailed information on powerdelivery on the USB organization’s website .

To read more about software development on the Android platform, go to The basics of USB device development using the Android framework.

Rajaram Regupathy
works as Principal Software Engineer with Cypress Semiconductor. He hasmore than 15 years of professional experience in developing firmwareand system software embedded products. He enjoys designing anddeveloping new technology products from scratch. He has patents inembedded domain and is also a senior ACM member and Linux and opensource enthusiast. He has published books on Linux USB stack programmingand other open source articles.

Used with permission fromApress Media LLC, a division of Springer Science+BusinessMedia.Publishing, Copyright 2014, this article was excerpted from Unboxing Android: A hands on approach with real world examples , by Rajaram Regupathy.

5 thoughts on “Incorporating USB battery charging protocols into an Android-based design

  1. “I have not gone through this page completely but looking at Charging Downstream Port (CDP) section, some correction is required.nCDP comes in charging port and does not need to follow current requirement as specified in USB 2.0 specification. A charging

    Log in to Reply
  2. “Interesting article, and very pertinent to work I am about to do.nOne question:n Where does one find the “frameworks/base/services/jni/com_android_server_BatteryService.cpp” file?nSounds silly?nI go into the ../frameworks/base/services/jni

    Log in to Reply
  3. “Androidxref is a good place to browse Android Source. Please find path of ncom_android_server_BatteryService.cpp below:nn if you are

    Log in to Reply
  4. “Thanks. Exactly what I was looking for.nAny idea why a google search for “BatteryService.cpp” would not get a hit near the top of the list at the site?nKind of diminishes my confidence in “googling”. :(n”

    Log in to Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.