The basics of USB device development using the Android framework

(Editor's Note: Excerpted from Unboxing Android: A hands on approach with real world examples , by Rajaram Regupathy, the author takes you through features of importance to a device developer.in Android’s USB framework. He explains the various USB APIs that it exports to assist in implementation of an application on an embedded/mobile/consumer IoT design. )

Android has become one of the most successful open platforms, powering up millions of mobile devices and similar embedded devices worldwide. According to Google, more than a million new Android devices are added to this statistic every day. This large market presence and continuous market penetration makes it the ideal platform for developers, SMEs, and bigger enterprises to portray their presence and reach out to end users. For Android devices, Google provides the necessary infrastructure to develop new applications. These devices can reach millions of end users through Google’s open market platform named “Google Play.”

Such a large development and deployment process necessitates standardization in order to ensure compatibility of these applications across the multitudes of Android devices that exist. To facilitate this, Google created a compatibility program that enables application developers, end users, and platform manufacturers to maintain program consistency and a similar user experience across devices. A detailed overview of the compatibility program is available on Google’s Android web site.
.
The compatibility program consists of three key components: a Compatibility Definition Document (CDD), theAndroid Platform Source Code, and  a Compatibility Test Suite (CTS). Any device that claims to be an “Android” device has to comply with the Android CDD and successfully pass all CTS test suites.

In order to study the framework within Android, it is important to understand the aforementioned three key components. Thus, in order to best study the Android USB framework, it is important to focus and explore what Android CDD defines as a USB requirement, and how that requirement is implemented. This article explores the USB section of the Android CDD in the Android USB framework. It will also introduce you to the various USB APIs that the Android framework exports in order to assist an application developer in managing the USB functionality of an Android device.

Android CDD – USB
At the time of this writing, Android 4.4 Kit Kat is the latest version of Android and Android 4.4 CDD defines the compatibility requirement of the Android Kit Kat version. You can find the complete list of Android CDDs on Google’s Android website.

So, what is an Android CDD? In simple terms, the Android CDD defines the requirements that must be met in order for a device to claim that it is an Android-compatible device. To an extent, Android CDD is brief in that it is a 30-40 page document. This document can point to specifications like the USB Audio, for example, to indicate the user’s expectation. The CDD also identifies features as “must,” “must not,” “required,” “shall,” “shall not,” “should,” “should not,” “recommended,” “may,” and “optional,” as per the IETF standard that is defined in RFC2119 . It is important for developers to pay attention to these terms and take care while developing Android applications when using an optional feature or any feature listed as “may.”

When it comes to USB, an Android device can operate in two modes—USB device mode or USB host mode.

USB Device Mode
When an Android device is connected to a host PC using USB, as illustrated in Figure 1 , the Android device is said to be in USB device mode and power is sourced from the host PC USB port. (A device that needs more power than the host can provide should have its own power source.)

Figure 1: Illustration of an Android device in USB device mode

USB Host Mode
When a USB device is connected to an Android device, as illustrated in Figure 2 , the Android device is said to be in USB host mode, and the Android device has to supply power to the connected device. An Android device functioning as a USB embedded host or as an On-The-Go (OTG) host must supply 5V/500mA of power when the connected device is USB bus powered.

Figure 2: Illustration of an Android device in USB host mode

There is also a unique Android USB setup, which was introduced during the Honeycomb version of Android, named the USB accessory mode.

USB Accessory Mode
In USB accessory mode, an Android device that is in the USB device mode can manage external devices. This ability is achieved by connecting the Android device to an external embedded accessory device, which acts as a USB host. The Android device goes to USB accessory mode in order to manage devices that connect to the accessory device. Figure 3 depicts Android accessory mode with a simple illustrative example of managing a camera from an Android device using an accessory device. Accessory mode is explained in detail in Chapter 5 of the book, which will provide you with a better understanding of the process.

Figure 3: Illustration of an Android device in USB accessory mode

The USB section of Android CDD defines which USB functionalities have to be supported in the host and device modes. Table 1 and Table 2 capture the requirements when an Android device acts as a USB device or as a USB host.


USB Device Requirement
  • The port must be connectable to a USB host with a standard USB-A port.
  • The port should use the micro-USB form factor on the device side
  • The port should be centered in the middle of an edge. Device implementations should either locate the port on the bottom of the device (according to natural orientation) or enable software screen rotation for all apps (including the home screen), so that the display draws correctly when the device is oriented with the port at the bottom. Existing and new devices that run Android 4.4 are very strongly encouraged to meet these requirements in Android 4.4 so that they will be able to upgrade to future platform releases.
  • If the device has other ports (such as a non-USB charging port) it should be on the same edge as the micro-USB port.
  • It must allow a host connected to the device to access the contents of the shared storage volume using either USB Mass Storage Protocol or the Media Transfer Protocol.
  • It must implement the Android Open Accessory API and specification as documented in the Android SDK documentation, and also must declare support for the hardware feature android.hardware.usb. accessory .
  • It must implement the USB audio class (version not mentioned in CDD) as documented in Android SDK documentation (http://developer. android.com/reference/android/hardware/usb/UsbConstants. html#USB_CLASS_AUDIO).
  • It should implement support for USB battery charging specification (version 1.2) [Resources, 64]. Existing and new devices that run Android 4.4 are very strongly encouraged to meet these requirements in Android 4.4, so that they will be able to upgrade to future platform releases.
  • Device implementations must implement the Android Debug Bridge.
  • If a device implementation omits a USB client port, it must then implement the Android Debug Bridge via a local area network (such as Ethernet or 802.11).

Table1: Android CDD 4.4 requirements as defined in USB Device Requirements

Existing and new devices that run Android 4.4 are very strongly encouraged to meet these requirements in Android 4.4 so that they will be able to upgrade to future platform releases.


USB Host Requirement
  • It may use a non-standard port form factor, but if so, the device must be shipped with a cable or cables that will adapt the port to a standard USB-A.
  • It must implement the Android USB host API as documented in the Android SDK and declare support for the hardware feature android.hardware.usb.host .

Table 2: Android CDD 4.4 as Defined in USB Host Requirements

These requirements are defined in section 7.7 USB of the Android CDD 4.4, and you should also note that the requirements are brief and point to the actual specifications. It is important to note that there are few requirements that define actual physical characteristics of an Android device. These physical characteristics will be handy when maintaining compatibility with external accessories, such as audio docks.

Over and above these two tables, USB requirements can also be found across other sections such as “Memory and Storage.” The following snippet captures one such requirement from the storage section of CDD:

“Regardless of the form of shared storage used, device implementations MUST provide some mechanism to access the contents of shared storage from a host computer, such as USB mass storage (UMS) or Media Transfer Protocol (MTP). Device implementations MAY use USB mass storage, but SHOULD use Media Transfer Protocol. If the device implementation supports Media Transfer Protocol:

  • The device implementation should be compatible with the reference Android MTP host and Android File Transfer.
  • The device implementation should report a USB device class of 0x00.
  • The device implementation should report a USB interface name of MTP.

If the device implementation lacks USB ports, it must then provide a host computer with access to the contents of the shared storage by some other means, such as a network file system.”

The storage section defines how the storage space of an Android device should be shared by a host PC over USB and. The storage section explains in detail mandating MTP as the preferred USB protocol for sharing the storage space.

These requirements are defined in section 7.7 USB of the Android CDD 4.4, and you should also note that the requirements are brief and point to the actual specifications. It is important to note that there are few requirements that define actual physical characteristics of an Android device. These physical characteristics will be handy when maintaining compatibility with external accessories, such as audio docks.

Now that you are able to understand Google Android’s USB requirements, you can now explore how these requirements are built within the Android framework.Android USB Architecture
This section explains Android USBarchitecture based on the various USB modes in which an Android devicecan perform as explained in the initial section.

In simpleterms, an Android platform is made of Android Linux kernel as the baseto manage the platform resources. A Java-based Android framework sits ontop of Android Linux kernel, providing the necessary user experience.Some Android features lay within the kernel, and certain features areavailable only at the Android framework. In case of USB, thefunctionality is managed between the Android Linux kernel and the userspace Android framework.

The following section provides atop-level architectural view of Android USB in USB device mode,detailing the complete Android USB starting from the Android Linuxkernel to the user space Android framework. When you connect an Androiddevice to a host PC, the Android device is said to be in USB device modeand can export multiple USB functionalities like MTP, ADB, or CDC tothe host PC through its descriptors. This type of USB device is referredas a composite device, where a single USB device supports multiple USBfunctions through their interfaces.

From the architecturediagram shown in Figure 4, you can infer that the compositeinfrastructure is part of the kernel and most of the USB devicefunctions are implemented as “class drivers” within the Android Linuxkernel. There are exceptions, like ADB and MTP, which are implemented onboth sides, i.e. the kernel and user space.

In such cases, thekernel driver implements just the transport part of USB, guaranteeingdelivery of the data. The Android framework performs the functionalmanagement, implementing the classlevel protocol, which other chaptersof this book will explore in more detail later. The following sectionprovides a brief overview of the architectural blocks used in the USBdevice mode, as represented in Figure 4.

Figure 4: Android USB device framework architecture

USB Service Framework
TheUSB Service framework is the key factor and is the backbone in AndroidUSB device mode. In a way, the role of this framework is to listen toand communicate state changes in Android kernel USB driver andsubsequently pass that information on to other interested Androidframeworks. Those frameworks then pass that information further to othermodules by broadcasting their intent with only the necessaryinformation. This framework also manages USB functions that an Androiddevice has to share when connected to a host PC.

USB user space daemons
Mostof the USB functions are implemented in the Android Linux kernel space.However, USB functions like ADB or MTP are implemented as user spacedaemons integrated within the Android framework. This block representsthe daemons that implement USB Class requirements. Subsequent chapterson ADB and MTP provide a detailed view on how this module interacts withthe kernel below and other Android frameworks.

android.hardware.usb
AndroidAPIs for USBs are represented as a android.hardware.usb package and arediscussed in further detail in later sections of this article. In a USBdevice mode, these APIs have a minimal role, as there are no APIs thatallow managing a USB device’s functionality. The exception to this isAndroid accessory mode, where developers are required to writeapplications to manage external devices over USB device mode.

Other infra frameworks
Withinthe Android framework there are many other frameworks that areinterested in the USB state changes, like connection, disconnection, or aswitch of USB functionalities. This “other infra” represents Androidmodules like storage infrastructure, network daemon infrastructure, andcharging infrastructure, to name a few that are interested in USB statechanges. These other infrastructures hook themselves up to the USBframework for the Intent that the USB Service module generate.

Thismodule also represents the user interface part of Android thatcommunicates USB state changes to the user over the Notification panel.The Android USB architecture is the same in USB accessory mode and USBdevice mode, as accessory mode is nothing but the USB device mode withsome deviation.

Now that you understand how the Android frameworkin USB device mode works, you can explore the Android framework in USBhost mode. Similar to device mode, host mode keeps most of the classfunctions implemented within the Linux kernel, but classes like MTP hostmode are implemented in Android user space. It is important to notethat, unlike the device stack (gadget driver), which differs from themainline Linux kernel, the USB host stack is same as the mainline Linuxkernel.

Though Linux kernel has support for almost all USBdevices, an Android device in USB host mode might not support alldevices because the Android device is functioning as a limitedcapability USB embedded host or USB OTG host. It is important to notethat Android CDD did not define USB host functionalities like it did forthe USB device mode. Thus USB host class support, like support for the3G dongle, is determined by the Android device manufacturer.

Figure 5 provides a top-level architecture diagram of the Android USB host mode framework.

Figure 5: Android USB host framework architecture

USB host mode service
Similarto device mode, USB Service is the key part in the USB host mode. Themain role of this framework is to detect state changes like connectionand disconnection within the USB host kernel drivers, and convert thosechanges into a format that is understood in the Android space.

USB host mode classes
USBhost mode classes (functions) like MTP are implemented within theAndroid framework, and their functionality is spread across the Java andJNI layers. This USB function framework represents the classimplementation and the implementation necessary for USB Host APIs. Thus,the main role of this framework is to translate USB applicationrequests and communicate them to the USB device connected to the kernelbelow.

Libusbhost user space drivers
One of the mostpopular USB user space drivers on Linux is libusb, while libusbhost is asimilar, thinner version of it, adapted to Android USB hostrequirements. The main role of this library is to act as an interfacebetween the Linux kernel USB driver and the Android USB framework. Thisalso makes it possible to implement necessary infrastructure tofacilitate detection of any new USB device connected to the kernelbelow.
.
Kernel USB File System
In USB host mode, thekernel file system plays a key role, starting from detecting a USBdevice when it gets identified within the kernel, to transferringinformation from Android to the kernel space. To better understand theUSB host mode operation, it is important to first understand the kernelUSB file system.

Other Android infrastructure frameworks
Insidethe Android framework, there are other frameworks like audio, volumedaemon, and so on, that are interested in knowing USB state changes.Some of these infrastructures take on the role of presenting the USBfunctionality to the user.

Having understood the Android USBrequirements and the top-level blocks of Android USB framework, you’llnow explore the various USB-related APIs that the Android frameworkexposes in order to manage a USB device or functionality.

Android USB Packages
TheAndroid framework is a Java-based system, and the term “package” isused in Java programming to organize similar Java classes into anamespace. This practice enables programmers to easily manage accessrights and avoid conflicts. Along the same line of thought, Android USBfunctional implementations are collated in a single namespace, calledthe android.hardware.usb. This section explores different USB classescollated in this package, as well as the APIs that deliver these USBclasses’ exports to a programmer. The section further covers the MTPclass, a USB host function packaged separately to manage media deviceconnected to an Android device over USB.

android.hardware.usb
Theandroid.hardware.usb package is a collection of USB host APIs and USBaccessory APIs. USB host APIs were introduced as part of Android HoneyComb 3.1 version (API level 12), and the support is available on Android3.1 and higher. USB accessory APIs were introduced in AndroidHoney Comb 3.1 version (API level 12) as well, but the support wasback-ported to Android Ginger Bread 2.3.4 version (API level 10). Theback-ported version of accessory APIs can be imported using the packagename com.android.future.usb. The next sections explore the differentclasses and their functions.

UsbAccessory
This classrepresents a USB accessory device connected to an Android device that’sin USB device mode. Note that a USB accessory is an external hardwaredevice acting as a USB host, as explained in Figure 3 . When anaccessory device is connected to an Android device, applications cansearch for and get product information like the manufacturer name,model, version, and so on, from other devices that connect to theaccessory. This class provides necessary methods for an applicationdeveloper to get product information, as previously stated. Completedetails of this class are available here .

UsbDevice
Thisclass represents a USB device connected to an Android in USB host mode.A UsbDevice object contains information that describes the capabilitiesand other USB specific details of the USB device, such as protocol,class, device ID, and so on. It is important to note that a UsbDevicecan be instantiated by a UsbService implementation of theUsbHostManager. Complete details of this class are available athttp://developer.android.com/reference/android/hardware/usb/UsbDevice.html.

UsbManager
Thisclass is the core part of the Android USB package. It provides thestate information of USB and discusses the methods to communicate withthe USB devices that are connected. At this moment of writing, thisclass provides methods only for host mode. The class provides thenecessary methods in order to provide permission to the USB device andshares the intent that communicates state information. Complete detailsof this class are available athttp://developer.android.com/reference/android/hardware/usb/UsbManager.html.

UsbDeviceConnection
Thisclass is used to provide the necessary methods for the user to send andreceive data to a USB device. An instance of the usefulness of thisclass is when an application opens a USB device using the openDevicemethod. This class supports the transfer of bulk and controls datasynchronously, unlike the queue method of UsbRequest. It also providesthe requestWait method, which is used for asynchronous data transfer.Complete details of this class are available at
http://developer.android.com/reference/android/hardware/usb/UsbDeviceConnection.html.

UsbInterface
Thisclass is also used to represent an interface of a USB device connectedto the Android host. An interface in USB is used to representfunctionalities of the USB device. If a USB device has multiplefunctionalities, there will be multiple UsbInterface objects. This classprovides methods to retrieve class, protocol, and endpoint details.Complete details of this class are available athttp://developer.android.com/reference/android/hardware/usb/UsbInterface.html.

UsbEndpoint
Thisclass is used to represent the endpoint of an interface and providesmethods that can retrieve the details of an endpoint. In USB terms, thisclass provides information from a USB endpoint descriptor of aconnected device. At the time of this writing, there is no support foran isochronous endpoint. Complete details of this class are available here .

UsbRequest
Thisclass represents a USB packet used to read and write to or from aconnected USB device. An object of UsbRequest is used to transfer bulkor to interrupt data asynchronously. After “queuing” a request, aprogram has to wait for the response using the requestWait method ofUsbDeviceConnection. This class does not support control transfer overendpoint zero. At the time of this writing, support for isochronoustransfer has not been provided. Complete details of this class areavailable here .

UsbRequest.html
Theseclasses discussed previously, other than UsbAccessory, constitute theAndroid USB host APIs and are packaged as android.hardware.usb.host fordevelopers who create USB host applications. There are other packages,like android.mtp, that are derived from these set of APIs. The android.mtp class provides MTP class support for an application developer.

Conclusion
Androidis widely deployed across many platforms and different vendors, and itis important to have interoperability and to maintain quality. Androiddefines a brief requirement specification, namely the AndroidCompatibility Definition Document (CDD), to ensure that the differentvendors of an Android device can interoperate easily.

Thisarticle has provided a brief overview of the USB requirements as definedin the latest Android CDD 4.4, applicable to the Jelly Bean version ofAndroid. There have been few changes in the USB requirement, and you canexplore different CDD versions to understand how USB requirements haveevolved on the Android developer site .

Rajaram Regupathy works as a principal software engineer with Cypress Semiconductor. He has more than 15 years of professional experience in developing firmware and system software embedded products. He enjoys designing and developing new technology products from scratch. He has patents in embedded domain and is also a senior ACM member and Linux and open source enthusiast. He has published books on Linux USB stack programming and other open source articles.

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

Leave a Reply

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