Merge "Telephony: Signal Strength Changes." into honeycomb-LTE
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 060c0bb..d1b8cfc 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -184,7 +184,9 @@
                 // we need to pause the old one and re-create a new media player
                 // inside the HTML5VideoView.
                 if (mHTML5VideoView != null) {
-                    mHTML5VideoView.pauseAndDispatch(mCurrentProxy);
+                    if (!backFromFullScreenMode) {
+                        mHTML5VideoView.pauseAndDispatch(mCurrentProxy);
+                    }
                     // release the media player to avoid finalize error
                     mHTML5VideoView.release();
                 }
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 667ba75..4e363bf 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -459,7 +459,9 @@
     }
     // reply comes back in the form "powermode = XX" where XX is the
     // number we're interested in.
-    sscanf(reply, "%*s = %u", &power);
+    if (sscanf(reply, "%*s = %u", &power) != 1) {
+        return (jint)-1;
+    }
     return (jint)power;
 }
 
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 35acdd7..2f7c60c 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -304,6 +304,7 @@
             <ul>
               <li><a href="<?cs var:toroot ?>guide/topics/usb/accessory.html">Accessory</a></li>
               <li><a href="<?cs var:toroot ?>guide/topics/usb/host.html">Host</a></li>
+              <li><a href="<?cs var:toroot ?>guide/topics/usb/adk.html">Open Accessory Dev Kit</a></li>
             </ul>
           </li>
 
diff --git a/docs/html/guide/topics/usb/adk.jd b/docs/html/guide/topics/usb/adk.jd
new file mode 100644
index 0000000..c0a0f27
--- /dev/null
+++ b/docs/html/guide/topics/usb/adk.jd
@@ -0,0 +1,763 @@
+page.title=Android Open Accessory Development Kit
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+    <h2>In this document</h2>
+    <ol>
+      <li><a href="#getting-started">Getting Started with the ADK</a>
+        <ol>
+          <li><a href="#installing">Installing the Arduino software and necessary libraries</a></li>
+          <li><a href="#installing-firmware">Installing the firmware to the ADK board</a></li>
+          <li><a href="#running-demokit">Running the DemoKit Android application</a></li>
+          <li><a href="#monitoring">Monitoring the ADK board</a></li>
+        </ol>
+      </li>
+      <li><a href="#how">How an Accessory Communicates with an Android-powered Device
+      in Accessory Mode</a>
+        <ol>
+          <li><a href="#wait">Wait for and detect connected devices</a></li>
+          <li><a href="#determine">Determine the connected device's accessory mode support</a></li>
+          <li><a href="#start">Attempt to start the device in accessory mode</a></li>
+          <li><a href="#establish">Establish communication with the device</a></li>
+        </ol>
+      </li>
+      <li><a href="#firmware">How the ADK board communicates with an Android-powered Device
+      in Accessory Mode</a>
+        <ol>
+          <li><a href="#wait-adk">Wait for and detect connected devices</a></li>
+          <li><a href="#determine-adk">Determine the connected device's accessory mode support</a></li>
+          <li><a href="#start-adk">Attempt to start the device in accessory mode</a></li>
+          <li><a href="#establish-adk">Establish communication with the device</a></li>
+        </ol>
+      </li>
+    </ol>
+</div>
+</div>
+
+  <p>The Android 3.1 platform (also backported to Android 2.3.4) introduces Android Open Accessory support, which allows external USB hardware (an Android USB accessory)
+  to interact with an Android-powered device in a special "accessory" mode. When an Android-powered powered device is in accessory mode,
+  the connected accessory acts as the USB host (powers the bus and enumerates devices) and the Android-powered device acts as the device. 
+  Android USB accessories are specifically designed to attach to Android-powered devices and
+  adhere to a simple protocol (Android accessory protocol) that allows them to detect Android-powered devices that support accessory mode. Accessories must also provide 
+  500mA at 5V for charging power. Many previously released
+  Android-powered devices are only capable of acting as a USB device and cannot initiate connections with external USB devices. Android Open Accessory support
+  overcomes this limitation and allows you to build accessories that can interact with an assortment of Android-powered devices by allowing the accessory
+  initiate the connection.</p>
+  
+  <p class="note"><strong>Note:</strong> Accessory mode is ultimately dependent on the device's hardware
+  and not all devices will support accessory mode. Devices that support accessory mode can be filtered using a <code>&lt;uses-feature&gt;</code>
+  element in your corresponding application's Android manifest. For more information, see the <a href="{@docRoot}guide/topics/usb/accessory.html#manifest">USB Accessory</a> Developer
+  Guide.</p>
+  
+  <p>The Android Open Accessory Development Kit (ADK) provides an implementation of an Android USB accessory that is based on the
+  <a href="http://www.arduino.cc/">Arduino open source electronics prototyping platform</a>, the accessory's hardware design files,
+  code that implements
+  the accessory's firmware, and the Android application that interacts with the
+  accessory. The hardware design files and code are contained in the <a href="https://dl-ssl.google.com/android/adk/adk_release_0506.zip">ADK package download</a>.
+  You can <a href="http://www.rt-net.jp/products/rt-adk">buy the hardware components</a> of the ADK if you do not already have them.
+  The main hardware and software components of the ADK include:</p>
+
+  <ul>
+    <li>A USB micro-controller board that is based on the Arduino Mega2560 and Circuits@Home USB Host
+    Shield designs (now referred to as the ADK board), which you will later implement as an Android USB accessory.
+    The ADK board provides input and output pins that you can implement through the use of attachments called "shields."
+    Custom firmware, written in C++, is installed on the board to define the board's functionality and interaction with
+    the attached shield and Android-powered device. The hardware design files for the
+    board are located in <code>hardware/</code> directory.</li>
+
+    <li>An Android Demo Shield (ADK shield) that affixes atop the ADK board implements the
+    input and output points on the board. These implementations include a joystick, LED
+    outputs, and temperature and light sensors. You can create or buy your own shields or wire
+    your own features to the ADK board to implement custom functionality. 
+    The hardware design files for the shield are located in <code>hardware/</code>.</li>
+
+    <li>A library based on the <a href=
+    "http://www.circuitsathome.com/arduino_usb_host_shield_projects">Arduino USB Host Shield</a>
+    library provides the logic for the USB micro-controller board to act as a USB Host. This allows
+    the board to initiate transactions with USB devices. Describing how to
+    use this entire library is out of the scope of this document. Where needed, this document
+    points out important interactions with the library. For more information, see the source code
+    for the Arduino USB Host Shield library in the
+    <code>firmware/arduino_libs/USB_Host_Shield</code> directory.</li>
+
+    <li>An Arduino sketch, <code>firmware/demokit/demokit.pde</code>, defines the firmware that
+    runs on the ADK board and is written in C++. The sketch calls the Android accessory protocol library
+    to interact with the Android-powered device. It also sends data from the ADK board and shield to the Android application
+    and receives data from the Android application and outputs it to the ADK board and shield.</li>
+
+    <li>The Android accessory protocol library, which is located in the
+    <code>firmware/arduino_libs/AndroidAccessory</code> directory. This library defines how to
+    enumerate the bus, find a connected Android-powered device that supports accessory mode, and
+    how to setup communication with the device.</li>
+
+    <li>Other third party libraries to support the ADK board's functionality:
+
+      <ul>
+        <li><a href="http://www.arduino.cc/playground/Main/CapSense">CapSense library</a></li>
+
+        <li><a href="http://www.arduino.cc/playground/Learning/I2C">I2C / TWI (Two-Wire Interface)
+        library</a></li>
+
+        <li><a href="http://www.arduino.cc/playground/ComponentLib/Servo">Servo library</a></li>
+
+        <li><a href="http://www.arduino.cc/playground/Code/Spi">Spi library</a></li>
+
+        <li><a href="http://www.arduino.cc/en/Reference/Wire">Wire library</a></li>
+      </ul>
+    </li>
+
+    <li>An Android application, DemoKit, that communicates with the ADK board and shield. The
+    source for this project is in the <code>app/</code> directory.</li>
+  </ul>
+
+  <h2 id="getting-started">Getting Started with the ADK</h2>
+
+  <p>The following sections describe how to install the Arduino software on your computer, use the Arduino software
+  to install the ADK board's firmware, and install and run the accompanying Android application for the ADK board.
+  Before you begin, download the following items to set up your development environment:</p>
+
+  <ul>
+    <li><a href="http://www.arduino.cc/en/Main/software">Arduino Software</a>: contains libraries
+    and an IDE for coding and installing firmware to the ADK board.</li>
+
+    <li><a href="http://www.arduino.cc/playground/Main/CapSense">CapSense library</a>: contains the
+    libraries to sense human capacitance. This is needed for the capacative button that is located
+    on the ADK shield.</li>
+
+    <li><a href="">The ADK package</a>: contains the firmware for the ADK board and
+    hardware design files for the ADK board and shield.</li>
+  </ul>
+
+<h3 id="installing">Installing the Arduino software and necessary libraries</h3>
+<p>To install the Arduino software:</p>
+  <ol>
+    <li><a href="http://arduino.cc/en/Guide/HomePage">Download and install</a> the Arduino Software
+    as described on the Arduino website.
+    
+    <p class="note"><strong>Note:</strong> If you are on a Mac, install the FTDI USB Serial Driver
+    that is included in the Arduino package,
+    even though the installation instructions say otherwise.</p>
+    </li>
+
+    <li><a href="https://dl-ssl.google.com/android/adk/adk_release_0506.zip">Download</a> and extract the ADK package to a directory of your choice. You should have
+    an <code>app</code>, <code>firmware</code>, and <code>hardware</code> directories.</li>
+
+    <li>Extract the CapSense download to a directory of your choice.</li>
+
+    <li>Install the necessary libraries:
+      <p>On Windows:</p>
+      <ol type="a">
+        <li>Copy the <code>firmware/arduino_libs/AndroidAccessory</code> and
+        <code>firmware/arduino_libs/USB_Host_Shield</code> directories (the complete directories,
+        not just the files within) to the <code>&lt;arduino_installation_root&gt;/libraries/</code>
+        directory.</li>
+
+        <li>Create a CapSense directory in the
+        <code>&lt;arduino_installation_root&gt;/libraries/</code> directory</li>
+
+        <li>Copy <code>CapSense.cpp</code> and <code>CapSense.h</code> from the unzipped CapSense
+        download to the <code>CapSense</code> directory.</li>
+      </ol>
+
+      <p>On Mac:</p>
+      <ol type="a">
+        <li>Right-click on the Arduino application in Finder and select <strong>Show Package
+        Contents</strong>.</li>
+
+        <li>Copy the <code>firmware/arduino_libs/AndroidAccessory</code> and
+        <code>firmware/arduino_libs/USB_Host_Shield</code> directories (the complete directories,
+        not just the files within) to the <code>Contents/Resources/Java/libraries</code>
+        directory inside the Arduino application.</li>
+
+        <li>Create a <code>CapSense</code> directory in the
+        <code>Contents/Resources/Java/libraries</code> directory.</li>
+
+        <li>Copy <code>CapSense.cpp</code> and <code>CapSense.h</code> from the unzipped CapSense
+        download to the <code>CapSense</code> directory.</li>
+        
+      </ol>
+      
+      <p>On Linux (Ubuntu):</p>
+       <ol type="a">
+        <li>Copy the <code>firmware/arduino_libs/AndroidAccessory</code> and
+        <code>firmware/arduino_libs/USB_Host_Shield</code> directories (the complete directories,
+        not just the files within) to the <code>&lt;arduino_installation_root&gt;/libraries/</code> directory.</li>
+
+        <li>Create a <code>CapSense</code> directory in the
+        <code>&lt;arduino_installation_root&gt;/libraries/</code> directory.</li>
+
+        <li>Copy <code>CapSense.cpp</code> and <code>CapSense.h</code> from the unzipped CapSense
+        download to the <code>CapSense</code> directory.</li>
+        
+        <li>Install the avr-libc library by entering <code>sudo apt-get install avr-libc</code> from a shell prompt.</li>
+      </ol>
+
+</li>
+</ol>
+      <p>You should now have three new directories in the Arduino libraries directory:
+      <code>AndroidAccessory</code>, <code>USB_Host_Shield</code>, and <code>CapSense</code>.</p>
+
+<h3 id="installing-firmware">Installing the firmware to the ADK board</h3>
+<p>To install the firmware to the ADK board:</p>
+<ol>
+    <li>Connect the ADK board to your computer using the micro-USB port, which allows two-way communication and provides power to the ADK board.</li>
+
+    <li>Launch Arduino.</li>
+
+    <li>Click <strong>Tools &gt; Board &gt; Arduino Mega 2560</strong> to specify the ADK board's type.</li>
+
+    <li>Select the appropriate USB port:
+    <ul>
+    <li>On Windows: click <strong>Tools &gt; Serial Port &gt; COM#</strong> to specify the port of
+    communication. The COM port number varies depending on your computer. COM1 is usually reserved for serial port
+    connections. You most likely want COM2 or COM3.  </li>  
+    
+    <li>On Mac: Click <strong>Tools &gt; Serial Port &gt; dev/tty.usbserial-###</strong> to specify the
+    port of communication.</li>
+    
+    <li>On Linux (Ubuntu): Click <strong>Tools &gt; Serial Port &gt; dev/ttyUSB#</strong> to specify the
+    port of communication.</li>
+    </ul></li>
+
+    <li>To open the firmware code (a sketch), click <strong>File &gt; Open</strong> and select
+    <code>firmware/demokit/demokit.pde</code>.</li>
+
+    <li>Click <strong>Sketch &gt; Compile/Verify</strong> to ensure that the sketch has no
+    errors.</li>
+
+    <li>Select <strong>File &gt; Upload to I/O Board</strong>. When Arduino outputs <strong>Done uploading.</strong>, the board 
+    is ready to communicate with your Android-powered device.</li>
+    
+    </ol>
+    
+
+<h3 id="running-demokit">Running the DemoKit Android application</h3>
+
+  <p>The DemoKit Android application runs on your Android-powered device and communicates with the
+  ADK board. The ADK board receives commands such as lighting up the board's LEDs or sends data
+  from the board such as joystick movement and temperature readings.</p>
+
+  <p>To install and run the application in Eclipse:</p>
+
+  <ol>
+    <li><a href="http://code.google.com/android/add-ons/google-apis/installing.html">Install the Google APIs API Level 10 add-on library</a>, 
+    which includes the Open Accessory library for 2.3.4 devices that support accessory mode.
+    This library is also forward compatible with Android 3.1 or newer devices that support accessory mode. If you only care
+    about Android 3.1 or newer devices, all you need is API Level 12. For more information
+    on deciding which API level to use, see the <a href="{@docRoot}guide/topics/USB/accessory.html#choosing">USB Accessory</a> documentation.</li>
+    <li>Click <strong>File &gt; New &gt; Project...</strong>, then select <strong>Android &gt; Android Project</strong></li>
+    <li>In the <strong>Project name:</strong> field, type DemoKit.
+    <li>Choose <strong>Create project from existing source</strong>, click <strong>Browse</strong>, select the
+    <code>app</code> directory, and click <strong>Finish</strong>.</li>
+
+    <li>For Build Target, select <strong>Google APIs</strong> (Platform 2.3.3, API Level 10).
+    <p class="note"><strong>Note:</strong> Even though the add-on is labeled as 
+    <strong>2.3.3</strong>, the newest Google API add-on library for API level 10 adds
+    USB Open Accessory API support for 2.3.4 devices.</li>
+
+    <li>Click <strong>Finish</strong>.</li>
+    <li>Install the application to your device.</li>
+
+    <li>Connect the ADK board (USB-A) to your Android-powered device (micro-USB). Ensure that the power cable to the
+    accessory is plugged in or that the micro-USB port on the accesory is connected to your computer
+    for power (this also allows you to <a href="monitoring">monitor the ADK board</a>). When
+    connected, accept the prompt that asks for whether or not to open the
+    DemoKit application to connect to the accessory. If the prompt does not show up, connect and reconnect the accessory.</li>
+  </ol>
+  <p>You can now interact with the ADK board by moving the color LED or servo sliders (make sure the servos are connected) 
+  or by pressing the relay buttons in the application. On the ADK shield, you can press the
+  buttons and move the joystick to see their outputs displayed in the application.</p>
+
+<h3 id="monitoring">Monitoring the ADK Board</h3>
+<p>The ADK firmware consists of a few files that you should be looking at if you want to build your own accessory.
+The files in the <code>firmware/arduino_libs/AndroidAccessory</code> directory are the most important files and have the logic to detect and connect
+to Android-powered devices that support accessory mode. Feel free to add debug statements (Arduino <code>Serial.print()</code> statements) to the code located in the
+<code>arduino_libraries_directory/AndroidAccessory</code> directory and <code>firmware/demokit/demokit.pde</code> sketch and re-upload the sketch to the ADK board to discover more
+about how the firmware works.</p>
+
+<p>You can view the debug statements in the Arduino Serial Monitor by clicking
+<strong>Tools > Serial Monitor</strong> and setting the baud to 115200.
+The following sections about how accessories communicate with Android-powered
+devices describe much of what you should be doing in your own accessory.</p>
+</p>
+
+  <h2 id="how">How an Accessory Communicates with an Android-powered Device in Accessory Mode</h2>
+
+  <p>When you connect an accessory to an Android-powered device, the accessory's firmware must
+  carry out some standard steps to set up communication with the Android-powered device. If you are building an
+  accessory along with an application, this section goes over some general steps that your firmware
+  should carry out.</p>
+
+  <p>In general, an accessory should carry out the following steps:</p>
+
+  <ol>
+    <li>Wait for and detect connected devices</li>
+
+    <li>Determine the device's accessory mode support</li>
+
+    <li>Attempt to start the device in accessory mode if needed</li>
+
+    <li>Establish communication with the device if it supports the Android accessory protocol</li>
+  </ol>
+
+  <h3 id="wait"><p>Wait for and detect connected devices</h3>Your accessory should have logic to
+  continuously check for connected Android-powered devices. When a device is connected, your accessory should
+  determine if the device supports accessory mode.</p>
+
+  <h3 id="determine"><p>Determine the device's accessory mode support</h3>
+  <p>When an Android-powered device is connected, it can be in one of three states:</p>
+
+  <ol type="a">
+  
+    <li>The attached device supports Android accessory mode and is already in accessory mode.</li>
+    <li>The attached device supports Android accessory mode, but it is not in accessory mode.</li>
+    <li>The attached device does not support Android accessory mode.</li>
+
+    
+  </ol>
+
+  <p>During the initial connection, the accessory should check the vendor and product IDs of the connected device's USB
+  device descriptor. The vendor ID should match Google's ID (0x18D1) and the product ID should be
+  0x2D00 or 0x2D01 if the device is already in accessory mode (case A). If so, the accessory can now <a href=
+  "#establish">establish communication with the device</a> through bulk transfer endpoints with its
+  own communication protocol. There is no need to start the device in accessory mode.</p>
+
+  <p class="note"><strong>Note:</strong> 0x2D00 is reserved for Android-powered devices that
+  support accessory mode. 0x2D01 is reserved for devices that support accessory mode as well as the
+  ADB (Android Debug Bridge) protocol, which exposes a second interface with two bulk endpoints for
+  ADB. You can use these endpoints for debugging the accessory application if you are simulating
+  the accessory on a computer. In general, do not use this interface unless your accessory is
+  implementing a passthrough to ADB on the device.</p>
+
+  <p>If the vendor and product ID do not match, there is no way to distinguish between states b and
+  c, so the accessory <a href="#start">attempts to start the device in accessory mode</a> to
+  figure out if the device is supported.</p>
+
+  <h3 id="start">Attempt to start the device in accessory mode</h3>
+
+  <p>If the vendor and product IDs do not correspond to an Android-powered device in accessory mode, the accessory
+  cannot discern whether the device supports accessory mode and is not in that state, or if the
+  device does not support accessory mode at all. This is because devices that support accessory mode but aren't in it
+  initially report the device's manufacturer vendor ID and product ID, and not the special Google ones.
+  In either case, the accessory should try to start the device
+  into accessory mode to figure out if the device supports it. The following steps explain how to do this:</p>
+  
+  <ol>
+  <li>Send a 51 control request ("Get Protocol") to figure out if the device supports
+  the Android accessory protocol. A non-zero number is returned if the protocol is supported, which
+  represents the version of the protocol that the device supports (currently, only version 1
+  exists). This request is a control request on endpoint 0 with the following characteristics:
+  <pre>
+requestType:    USB_DIR_IN | USB_TYPE_VENDOR
+request:        51
+value:          0
+index:          0
+data:           protocol version number (16 bits little endian sent from the device to the accessory)
+</pre>
+</li>
+
+  <li>If the device returns a proper protocol version, send identifying string information to the device.
+  This information allows the device to figure out an appropriate application for this accessory and also present the user
+  with a URL if an appropriate application does not exist. These requests
+  are control requests on endpoint 0 (for each string ID) with the following characteristics:
+  <pre>
+requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+request:        52
+value:          0
+index:          string ID
+data            zero terminated UTF8 string sent from accessory to device
+</pre>
+
+  <p>The following string IDs are supported, with a maximum size of 256 bytes for each string (must
+  be zero terminated with \0).</p>
+<pre>
+manufacturer name:  1
+model name:         2
+description:        3
+version:            4
+URI:                5
+serial number:      6
+</pre>
+</li>
+
+  <li>When the identifying strings are sent, request the device start up in accessory mode.
+  This request is a control request on endpoint 0 with the following
+  characteristics:
+  <pre>
+requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+request:        53
+value:          0
+index:          0
+data:           none
+</pre>
+</li>
+</ol>
+  <p>After sending the final control request, the connected USB device should re-introduce itself on the bus
+  in accessory mode and the accessory can re-enumerate the connected devices. The algorithm jumps back to
+  <a href="#determine">determining the device's accessory mode support</a> to check for the
+  vendor and product ID. The vendor ID and product ID of the device will be different if the device
+  successfully switched to accessory mode and will now correspond to Google's vendor and product
+  IDs instead of the device manufacturer's IDs. The accessory can now <a href="#establish">establish communication with the device</a>.</p>
+
+  <p>If at any point these steps fail, the device does not support Android accessory mode and the
+  accessory should wait for the next device to be connected.</p>
+  
+
+  <h3 id="establish">Establish communication with the device</h3>
+
+  <p>If an Android-powered device in accessory mode is detected, the accessory can query the device's interface and
+  endpoint descriptors to obtain the bulk endpoints to communicate with the device. An
+  Android-powered device that has a product ID of 0x2D00 has one interface with two bulk endpoints for
+  input and output communication. A device with product ID of 0x2D01 has two interfaces with two bulk endpoints
+  each for input and output communication. The first interface is for standard communication while the second
+  interface is for ADB communication. To communicate on an interface, all you need to do is find the first bulk input and output endpoints,
+  set the device's configuration to a value of 1 with a SET_CONFIGURATION (0x09) device request, then communicate using the endpoints.</p>
+
+  
+
+  <h2 id="firmware">How the ADK board communicates with an Android-powered Device in Accessory Mode</h2>
+
+  <p>If you have access to the ADK board and shield, the following sections describe the firmware code that you installed onto the ADK board. The firmware demonstrates a practical
+  example of how to communicate with an Android-powered device. Even if you do not have the ADK board and shield, reading through how the hardware detects
+  and interacts with devices in accessory mode is still useful if you want to port the code over for your own accessories.</p>
+
+  <p>The important pieces of the firmware are the <code>accessory/demokit/demokit/demokit.pde</code> sketch, which is the code that
+  receives and sends data to the DemoKit application running on the Android-powered device. The
+  code to detect and set up communication with the Android-powered device is contained in the
+  <code>accessory/arduino_libs/AndroidAccessory/AndroidAccessory.h</code> and <code>accessory/arduino_libs/AndroidAccessory/AndroidAccessory.cpp</code>
+  files. This code includes most of the logic that will help you implement your own accessory's firmware.
+  It might be useful to have all three of these files open in a text editor as you read through these next sections.</p>
+
+  <p>The following sections describe the firmware code in the context of the
+  algorithm described in <a href="#how">How an Accessory Communicates with an Android-powered
+  Device in Accessory Mode</a>.</p>
+
+  <h3 id="wait-adk">Wait for and detect connected devices</h3>
+
+  <p>In the firmware code (<code>demokit.pde</code>), the
+  <code>loop()</code> function runs repeatedly and calls
+  <code>AndroidAccessory::isConnected()</code> to check for any connected devices. If there is a
+  connected device, it continuously updates the input and output streams going to and from the
+  board and application. If nothing is connected, it continuously checks for a device to be connected:</p>
+  <pre>
+...
+
+AndroidAccessory acc("Google, Inc.",
+                     "DemoKit",
+                     "DemoKit Arduino Board",
+                     "1.0",
+                     "http://www.android.com",
+                     "0000000012345678");
+                     
+...
+void loop()
+{
+...
+    if (acc.isConnected()) {  
+        //communicate with Android application 
+    }
+    else{
+        //set the accessory to its default state
+    }
+...
+}
+</pre>
+
+  <h3 id="determine-adk">Determine the connected device's accessory mode support</h3>
+
+  <p>When a device is connected to the ADK board, it can already be in accessory mode,
+  support accessory mode and is not in that mode, or does not support accessory mode. The
+  <code>AndroidAccessory::isConnected()</code> method checks for these cases and responds
+  accordingly when the <code>loop()</code> function calls it. This function first checks to see if
+  the device that is connected hasn't already been handled. If not, it gets the connected device's
+  device descriptor to figure out if the device is already in accessory mode by calling
+  <code>AndroidAccessory::isAccessoryDevice()</code>. This method checks the vendor and product ID
+  of the device descriptor. A device in accessory mode has a vendor ID of 0x18D1 and a product ID
+  of 0x2D00 or 0x2D01. If the device is in accessory mode, then the ADK board can
+  <a href="#establish-a">establish communication with the device</a>. If not, the board <a href=
+  "start-a">attempts to start the device in accessory mode</a>.</p>
+  <pre>
+bool AndroidAccessory::isConnected(void)
+{
+    USB_DEVICE_DESCRIPTOR *devDesc = (USB_DEVICE_DESCRIPTOR *) descBuff;
+    byte err;
+
+    max.Task();
+    usb.Task();
+
+    if (!connected &amp;&amp;
+        usb.getUsbTaskState() &gt;= USB_STATE_CONFIGURING &amp;&amp;
+        usb.getUsbTaskState() != USB_STATE_RUNNING) {
+        Serial.print("\nDevice addressed... ");
+        Serial.print("Requesting device descriptor.");
+
+        err = usb.getDevDescr(1, 0, 0x12, (char *) devDesc);
+        if (err) {
+            Serial.print("\nDevice descriptor cannot be retrieved. Program Halted\n");
+            while(1);
+        }
+
+        if (isAccessoryDevice(devDesc)) {
+            Serial.print("found android accessory device\n");
+
+            connected = configureAndroid();
+        } else {
+            Serial.print("found possible device. switching to serial mode\n");
+            switchDevice(1);
+        }
+    } else if (usb.getUsbTaskState() == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
+        connected = false;
+    }
+
+    return connected;
+}
+</pre>
+
+  <h3 id="start-adk">Attempt to start the device in accessory mode</h3>
+
+  <p>If the device is not already in accessory mode, then the ADK board must
+  determine whether or not it supports it by sending control request 51 to check the version of the
+  USB accessory protocol that the device supports (see
+  <code>AndroidAccessory::getProtocol()</code>). Protocol version 1 is the only version for now, but this can
+  be an integer greater than zero in the future. If
+  the appropriate protocol version is returned, the board sends control request 52 (one for each
+  string with <code>AndroidAcessory:sendString()</code>) to send it's identifying information, and
+  tries to start the device in accessory mode with control request 53. The
+  <code>AndroidAccessory::switchDevice()</code> method takes care of this:</p>
+  <pre>
+bool AndroidAccessory::switchDevice(byte addr)
+{
+    int protocol = getProtocol(addr);
+    if (protocol == 1) {
+        Serial.print("device supports protocol 1\n");
+    } else {
+        Serial.print("could not read device protocol version\n");
+        return false;
+    }
+
+    sendString(addr, ACCESSORY_STRING_MANUFACTURER, manufacturer);
+    sendString(addr, ACCESSORY_STRING_MODEL, model);
+    sendString(addr, ACCESSORY_STRING_DESCRIPTION, description);
+    sendString(addr, ACCESSORY_STRING_VERSION, version);
+    sendString(addr, ACCESSORY_STRING_URI, uri);
+    sendString(addr, ACCESSORY_STRING_SERIAL, serial);
+
+    usb.ctrlReq(addr, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE,
+                ACCESSORY_START, 0, 0, 0, 0, NULL);
+    return true;
+}
+</pre>If this method returns false, the board waits until a new device is connected. If it is
+successful, the device displays itself on the USB bus as being in accessory mode when the ADK board
+re-enumerates the bus. When the device is in accessory mode, the accessory then <a href=
+"establish-a">establishes communication with the device</a>.
+
+  <h3 id="establish-adk">Establish communication with the device</h3>
+
+  <p>If a device is detected as being in accessory mode, the accessory must find the proper bulk
+  endpoints and set up communication with the device. When the ADK board detects an
+  Android-powered device in accessory mode, it calls the
+  <code>AndroidAccessory::configureAndroid()</code> function:</p>
+  <pre>
+...
+if (isAccessoryDevice(devDesc)) {
+            Serial.print("found android acessory device\n");
+
+            connected = configureAndroid();
+        }
+...
+</pre>
+
+  <p>which in turn calls the <code>findEndpoints()</code> function:</p>
+  <pre>
+...
+bool AndroidAccessory::configureAndroid(void)
+{
+    byte err;
+    EP_RECORD inEp, outEp;
+
+    if (!findEndpoints(1, &amp;inEp, &amp;outEp))
+        return false;
+...
+</pre>
+
+  <p>The <code>AndroidAccessory::findEndpoints()</code> function queries the Android-powered device's
+  configuration descriptor and finds the bulk data endpoints in which to communicate with the USB
+  device. To do this, it first gets the device's first four bytes of the configuration
+  descriptor (only need descBuff[2] and descBuff[3]), which contains the information about the
+  total length of data returned by getting the descriptor. This data is used to determine whether
+  or not the descriptor can fit in the descriptor buffer. This descriptor also contains information
+  about all the interfaces and endpoint descriptors. If the descriptor is of appropriate size, the
+  method reads the entire configuration descriptor and fills the entire descriptor buffer with this
+  device's configuration descriptor. If for some reason the descriptor is no longer attainable,
+  an error is returned.</p>
+  <pre>
+...
+
+bool AndroidAccessory::findEndpoints(byte addr, EP_RECORD *inEp, EP_RECORD *outEp)
+{
+    int len;
+    byte err;
+    uint8_t *p;
+
+    err = usb.getConfDescr(addr, 0, 4, 0, (char *)descBuff);
+    if (err) {
+        Serial.print("Can't get config descriptor length\n");
+        return false;
+    }
+
+
+    len = descBuff[2] | ((int)descBuff[3] &lt;&lt; 8);
+    if (len &gt; sizeof(descBuff)) {
+        Serial.print("config descriptor too large\n");
+            /* might want to truncate here */
+        return false;
+    }
+
+    err = usb.getConfDescr(addr, 0, len, 0, (char *)descBuff);
+    if (err) {
+        Serial.print("Can't get config descriptor\n");
+        return false;
+    }
+    
+...
+</pre>
+
+  <p>Once the descriptor is in memory, a pointer is assigned to the first position of the buffer
+  and is used to index the buffer for reading. There are two endpoint pointers (input and output)
+  that are passed into <code>AndroidAccessory::findEndpoints()</code> and their addresses are set
+  to 0, because the code hasn't found any suitable bulk endpoints yet. A loop reads the buffer, parsing
+  each configuration, interface, or endpoint descriptor. For each descriptor,
+  Position 0 always contains the size of the descriptor in bytes and position 1 always contains the
+  descriptor type. Using these two values, the loop skips any configuration and interface
+  descriptors and increments the buffer with the <code>descLen</code> variable to get to the next
+  descriptor.</p>
+
+  <p class="note"><strong>Note:</strong> An Android-powered device in accessory mode can
+  potentially have two interfaces, one for the default communication to the device and the other
+  for ADB communication. The default communication interface is always indexed first, so finding
+  the first input and output bulk endpoints will return the default communication endpoints, which
+  is what the <code>demokit.pde</code> sketch does. If you are writing your own firmware, the logic
+  to find the appropriate endpoints for your accessory might be different.</p>
+
+  <p>When it finds the first input and output endpoint descriptors, it sets the endpoint pointers
+  to those addresses. If the findEndpoints() function finds both an input and output endpoint, it
+  returns true. It ignores any other endpoints that it finds (the endpoints for the ADB interface, if
+  present).</p>
+  <pre>
+...
+    p = descBuff;
+    inEp-&gt;epAddr = 0;
+    outEp-&gt;epAddr = 0;
+    while (p &lt; (descBuff + len)){
+        uint8_t descLen = p[0];
+        uint8_t descType = p[1];
+        USB_ENDPOINT_DESCRIPTOR *epDesc;
+        EP_RECORD *ep;
+
+        switch (descType) {
+        case USB_DESCRIPTOR_CONFIGURATION:
+            Serial.print("config desc\n");
+            break;
+
+        case USB_DESCRIPTOR_INTERFACE:
+            Serial.print("interface desc\n");
+            break;
+
+        case USB_DESCRIPTOR_ENDPOINT:
+            epDesc = (USB_ENDPOINT_DESCRIPTOR *)p;
+            if (!inEp-&gt;epAddr &amp;&amp; (epDesc-&gt;bEndpointAddress &amp; 0x80))
+                ep = inEp;
+            else if (!outEp-&gt;epAddr)
+                ep = outEp;
+            else
+                ep = NULL;
+
+            if (ep) {
+                ep-&gt;epAddr = epDesc-&gt;bEndpointAddress &amp; 0x7f;
+                ep-&gt;Attr = epDesc-&gt;bmAttributes;
+                ep-&gt;MaxPktSize = epDesc-&gt;wMaxPacketSize;
+                ep-&gt;sndToggle = bmSNDTOG0;
+                ep-&gt;rcvToggle = bmRCVTOG0;
+            }
+            break;
+
+        default:
+            Serial.print("unkown desc type ");
+            Serial.println( descType, HEX);
+            break;
+        }
+
+        p += descLen;
+    }
+
+    if (!(inEp-&gt;epAddr &amp;&amp; outEp-&gt;epAddr))
+        Serial.println("can't find accessory endpoints");
+
+    return inEp-&gt;epAddr &amp;&amp; outEp-&gt;epAddr;
+}
+
+...
+</pre>
+
+  <p>Back in the <code>configureAndroid()</code> function, if there were endpoints found, they are
+  appropriately set up for communication. The device's configuration is set to 1 and the state of the device is set to "running", which
+  signifies that the device is properly set up to communicate with your USB accessory. Setting this
+  status prevents the device from being re-detected and re-configured in the
+  <code>AndroidAccessory::isConnected()</code> function.</p>
+  <pre>
+bool AndroidAccessory::configureAndroid(void)
+{
+    byte err;
+    EP_RECORD inEp, outEp;
+
+    if (!findEndpoints(1, &amp;inEp, &amp;outEp))
+        return false;
+
+    memset(&amp;epRecord, 0x0, sizeof(epRecord));
+
+    epRecord[inEp.epAddr] = inEp;
+    if (outEp.epAddr != inEp.epAddr)
+        epRecord[outEp.epAddr] = outEp;
+
+    in = inEp.epAddr;
+    out = outEp.epAddr;
+
+    Serial.print("inEp: ");
+    Serial.println(inEp.epAddr, HEX);
+    Serial.print("outEp: ");
+    Serial.println(outEp.epAddr, HEX);
+
+    epRecord[0] = *(usb.getDevTableEntry(0,0));
+    usb.setDevTableEntry(1, epRecord);
+
+    err = usb.setConf( 1, 0, 1 );
+    if (err) {
+        Serial.print("Can't set config to 1\n");
+        return false;
+    }
+
+    usb.setUsbTaskState( USB_STATE_RUNNING );
+
+    return true;
+}
+</pre>
+
+  <p>Lastly, methods to read and write to the appropriate endpoints are needed. The
+  <code>demokit.pde</code> sketch calls these methods depending on the data that is read from the
+  Android-powered device or sent by the ADK board. For instance, moving the joystick
+  on the ADK shield writes data that is read by the DemoKit application running on the
+  Android-powered device. Moving sliders on the DemoKit application is read by the
+  <code>demokit.pde</code> sketch and changes the state of the accessory, such as lighting up or
+  changing the color of the LED lights.</p>
+  <pre>
+int AndroidAccessory::read(void *buff, int len, unsigned int nakLimit) { 
+  return usb.newInTransfer(1, in, len, (char *)buff, nakLimit); } 
+  
+int AndroidAccessory::write(void *buff, int len) { 
+  usb.outTransfer(1, out, len, (char *)buff); 
+  return len; }
+  
+</pre>
+
+  <p>See the <code>firmware/demokit/demokit.pde</code> file for information about how the Demo Shield reads and writes data.</p>
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 076db8b..0c6a747 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -72,6 +72,7 @@
     protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
     protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
     protected RegistrantList mRilConnectedRegistrants = new RegistrantList();
+    protected RegistrantList mIccRefreshRegistrants = new RegistrantList();
 
     protected Registrant mSMSRegistrant;
     protected Registrant mNITZTimeRegistrant;
@@ -86,7 +87,6 @@
     protected Registrant mCatCallSetUpRegistrant;
     protected Registrant mIccSmsFullRegistrant;
     protected Registrant mEmergencyCallbackModeRegistrant;
-    protected Registrant mIccRefreshRegistrant;
     protected Registrant mRingRegistrant;
     protected Registrant mRestrictedStateRegistrant;
     protected Registrant mGsmBroadcastSmsRegistrant;
@@ -455,16 +455,17 @@
         mIccSmsFullRegistrant.clear();
     }
 
-    public void setOnIccRefresh(Handler h, int what, Object obj) {
-        mIccRefreshRegistrant = new Registrant (h, what, obj);
+    public void registerForIccRefresh(Handler h, int what, Object obj) {
+        Registrant r = new Registrant (h, what, obj);
+        mIccRefreshRegistrants.add(r);
     }
 
     public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
         mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj);
     }
 
-    public void unSetOnIccRefresh(Handler h) {
-        mIccRefreshRegistrant.clear();
+    public void unregisterForIccRefresh(Handler h) {
+        mIccRefreshRegistrants.remove(h);
     }
 
     public void setOnCallRing(Handler h, int what, Object obj) {
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 1d574ca..f87d188 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -352,14 +352,13 @@
 
     /**
      * Sets the handler for SIM Refresh notifications.
-     * Unlike the register* methods, there's only one notification handler
      *
      * @param h Handler for notification message.
      * @param what User-defined message code.
      * @param obj User object.
      */
-    void setOnIccRefresh(Handler h, int what, Object obj);
-    void unSetOnIccRefresh(Handler h);
+    void registerForIccRefresh(Handler h, int what, Object obj);
+    void unregisterForIccRefresh(Handler h);
 
     /**
      * Sets the handler for RING notifications.
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 6edd0b6..242a322 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2602,8 +2602,8 @@
             case RIL_UNSOL_SIM_REFRESH:
                 if (RILJ_LOGD) unsljLogRet(response, ret);
 
-                if (mIccRefreshRegistrant != null) {
-                    mIccRefreshRegistrant.notifyRegistrant(
+                if (mIccRefreshRegistrants != null) {
+                    mIccRefreshRegistrants.notifyRegistrants(
                             new AsyncResult (null, ret, null));
                 }
                 break;
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index 87b0c60..a6fd966 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -87,7 +87,7 @@
         p.mCM.registerForRUIMReady(this, EVENT_RUIM_READY, null);
         p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
         // NOTE the EVENT_SMS_ON_RUIM is not registered
-        p.mCM.setOnIccRefresh(this, EVENT_RUIM_REFRESH, null);
+        p.mCM.registerForIccRefresh(this, EVENT_RUIM_REFRESH, null);
 
         // Start off by setting empty state
         onRadioOffOrNotAvailable();
@@ -98,7 +98,7 @@
         //Unregister for all events
         phone.mCM.unregisterForRUIMReady(this);
         phone.mCM.unregisterForOffOrNotAvailable( this);
-        phone.mCM.unSetOnIccRefresh(this);
+        phone.mCM.unregisterForIccRefresh(this);
     }
 
     @Override
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 8b032ff..7fb250f 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -184,7 +184,7 @@
         p.mCM.registerForOffOrNotAvailable(
                         this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
         p.mCM.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
-        p.mCM.setOnIccRefresh(this, EVENT_SIM_REFRESH, null);
+        p.mCM.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);
 
         // Start off by setting empty state
         onRadioOffOrNotAvailable();
@@ -195,7 +195,7 @@
         //Unregister for all events
         phone.mCM.unregisterForSIMReady(this);
         phone.mCM.unregisterForOffOrNotAvailable( this);
-        phone.mCM.unSetOnIccRefresh(this);
+        phone.mCM.unregisterForIccRefresh(this);
     }
 
     protected void finalize() {