Merge "Fix some java docs." into ics-mr1
diff --git a/Android.mk b/Android.mk
index 371c370..77d9cb2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -398,6 +398,7 @@
     -since ./frameworks/base/api/12.xml 12 \
     -since ./frameworks/base/api/13.xml 13 \
     -since ./frameworks/base/api/14.txt 14 \
+    -since ./frameworks/base/api/15.txt 15 \
 		-werror -hide 113 \
 		-overview $(LOCAL_PATH)/core/java/overview.html
 
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index 95542bc..6ace709 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -83,8 +83,14 @@
 
 <table>
   <tr><th>Platform Version</th><th>API Level</th><th>VERSION_CODE</th><th>Notes</th></tr>
-  
-    <tr><td><a href="{@docRoot}sdk/android-4.0.html">Android 4.0</a></td>
+ 
+     <tr><td><a href="{@docRoot}sdk/android-4.0.3.html">Android 4.0.3</a></td>
+    <td><a href="{@docRoot}sdk/api_diff/15/changes.html" title="Diff Report">15</a></td>
+    <td>{@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1}</td>
+    <td><a href="{@docRoot}sdk/android-4.0-highlights.html">Platform
+Highlights</a></td></tr>
+
+    <tr><td><a href="{@docRoot}sdk/android-4.0.html">Android 4.0, 4.0.1, 4.0.2</a></td>
     <td><a href="{@docRoot}sdk/api_diff/14/changes.html" title="Diff Report">14</a></td>
     <td>{@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}</td>
     <td><a href="{@docRoot}sdk/android-4.0-highlights.html">Platform
diff --git a/docs/html/images/training/hierarchy-layouttimes.png b/docs/html/images/training/hierarchy-layouttimes.png
new file mode 100644
index 0000000..423f1af
--- /dev/null
+++ b/docs/html/images/training/hierarchy-layouttimes.png
Binary files differ
diff --git a/docs/html/images/training/hierarchy-linearlayout.png b/docs/html/images/training/hierarchy-linearlayout.png
new file mode 100644
index 0000000..cac4cae
--- /dev/null
+++ b/docs/html/images/training/hierarchy-linearlayout.png
Binary files differ
diff --git a/docs/html/images/training/hierarchy-relativelayout.png b/docs/html/images/training/hierarchy-relativelayout.png
new file mode 100644
index 0000000..b3408e5
--- /dev/null
+++ b/docs/html/images/training/hierarchy-relativelayout.png
Binary files differ
diff --git a/docs/html/images/training/import-progress.png b/docs/html/images/training/import-progress.png
new file mode 100644
index 0000000..bbb689b
--- /dev/null
+++ b/docs/html/images/training/import-progress.png
Binary files differ
diff --git a/docs/html/images/training/layout-listitem.png b/docs/html/images/training/layout-listitem.png
new file mode 100644
index 0000000..9cb241d
--- /dev/null
+++ b/docs/html/images/training/layout-listitem.png
Binary files differ
diff --git a/docs/html/images/training/sharing/share-text-screenshot.png b/docs/html/images/training/sharing/share-text-screenshot.png
new file mode 100644
index 0000000..089221c
--- /dev/null
+++ b/docs/html/images/training/sharing/share-text-screenshot.png
Binary files differ
diff --git a/docs/html/sdk/android-4.0-highlights.jd b/docs/html/sdk/android-4.0-highlights.jd
index c1162d4..922bb08 100644
--- a/docs/html/sdk/android-4.0-highlights.jd
+++ b/docs/html/sdk/android-4.0-highlights.jd
@@ -298,7 +298,7 @@
 linked together and integrated for easy accessibility. At the center is a new
 <strong>People app</strong> that offers richer profile information, including a
 large profile picture, phone numbers, addresses and accounts, status updates,
-events, and a new button for connecting on integrated social networks. </p>
+events, stream items, and a new button for connecting on integrated social networks. </p>
 
 <p>The user's own contact information is stored in a new <strong>"Me"
 profile</strong>, allowing easier sharing with apps and people. All of the
@@ -562,7 +562,7 @@
 instant sharing of files, photos, or other media; streaming video or audio from
 another device; or connecting to compatible printers or other devices.</p>
 
-<p>Android 4.0 also introduces built-in support for connecting to <strong>Bluetooth Health Device Profile (HDP)</strong> devices. With support from third-party apps, users can connect to wireless medical devices and sensors in hospitals, fitness centers, homes, and elsewhere. In addition, for connecting to higher quality Bluetooth audio devices, Android 4.0 adds support for Bluetooth Hands Free Profile (HFP) 1.6.</p>
+<p>Android 4.0 also introduces built-in support for connecting to <strong>Bluetooth Health Device Profile (HDP)</strong> devices. With support from third-party apps, users can connect to wireless medical devices and sensors in hospitals, fitness centers, homes, and elsewhere.</p>
 
 
 <h2 id="DeveloperApis" style="clear:right">New Developer Features</h2>
@@ -633,21 +633,21 @@
 <h3 id="communication-dev">Communication and sharing</h3>
 
 <p>Android 4.0 extends social and sharing features to any application on the
-device. Applications can integrate contacts, profile data, and calendar events
-from any of the user’s activities or social networks.</p>
+device. Applications can integrate contacts, profile data, stream items, 
+and calendar events from any of the user’s activities or social networks.</p>
 
 
 <p style="margin-top:1em;margin-bottom:.75em;"><strong>Social API</strong></p>
 
 <p>A shared social provider and API provide a new unified store for contacts,
-profile data, status updates, and photos. Any app or social network with user
+profile data, stream items, and photos. Any app or social network with user
 permission can contribute raw contacts and make them accessible to other apps
 and networks. Applications with user permission can also read profile data from
 the provider and display it in their applications.</p>
 
 <p>The social API lets applications store standard contact data as well as new
-types of content for any given contact, including large profile photos and
-recent activity feedback. Recent activity feedback is a standard way for
+types of content for any given contact, including large profile photos, stream
+items, and recent activity feedback. Recent activity feedback is a standard way for
 applications to “tag” a contact with common activity, such as when the user
 calls the contact or sends an email or SMS message. The social provider uses the
 recent activity feedback as a new signal in ranking, such as for name
diff --git a/docs/html/sdk/android-4.0.3.jd b/docs/html/sdk/android-4.0.3.jd
new file mode 100644
index 0000000..68257cd
--- /dev/null
+++ b/docs/html/sdk/android-4.0.3.jd
@@ -0,0 +1,513 @@
+page.title=Android 4.0.3 Platform
+sdk.platform.version=4.0.3
+sdk.platform.apiLevel=15
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+  <li><a href="#relnotes">Revisions</a></li>
+  <li><a href="#api">API Overview</a></li>
+  <li><a href="#Honeycomb">Previous APIs</a></li>
+  <li><a href="#api-level">API Level</a></li>
+  <li><a href="#apps">Built-in Applications</a></li>
+  <li><a href="#locs">Locales</a></li>
+  <li><a href="#skins">Emulator Skins</a></li>
+</ol>
+
+<h2>Reference</h2>
+<ol>
+<li><a
+href="{@docRoot}sdk/api_diff/14/changes.html">API
+Differences Report &raquo;</a> </li>
+</ol>
+
+</div>
+</div>
+
+<p><em>API Level:</em>&nbsp;<strong>{@sdkPlatformApiLevel}</strong></p>
+
+<p>Android {@sdkPlatformVersion} is an incremental release of the Android 4.x
+(Ice Cream Sandwich) platform family. This release includes new features for
+users and developers, API changes, and various bug fixes.</p>
+
+<p>For developers, the Android {@sdkPlatformVersion} platform is available as a
+downloadable component for the Android SDK. The development platform includes a
+fully compliant Android library and system image as well as a set of emulator
+skins, sample applications, and more. The downloadable platform includes no
+external libraries.</p>
+
+<p>To start developing or testing against Android {@sdkPlatformVersion},
+use the Android SDK Manager to download the platform into your SDK. For more
+information, see <a href="{@docRoot}sdk/adding-components.html">Adding SDK
+Components</a>. If you are new to Android, <a
+href="{@docRoot}sdk/index.html">download the SDK Starter Package</a> first.</p>
+
+<p>For a high-level overview of the new user and developer features, see the
+<a href="http://developer.android.com/sdk/android-4.0-highlights.html">Platform
+Highlights</a>.</p>
+
+
+<h2 id="relnotes">Development Platform Revisions</h2>
+
+<p>The sections below provide notes about successive revisions of the Android
+{@sdkPlatformVersion} development platform for the Android SDK, as denoted by
+revision number. To determine what revisions you have installed in your SDK
+environment, refer to the "Installed Packages" listing in the Android SDK
+Manager.</p>
+
+
+<div class="toggle-content opened" style="padding-left:1em;">
+
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-opened.png"
+class="toggle-content-img" alt="" />
+    Android {@sdkPlatformVersion}, Revision 1</a> <em>(December 2011)</em>
+  </a></p>
+
+  <div class="toggle-content-toggleme" style="padding-left:2em;">
+
+<dl>
+<dt>Initial release. SDK Tools r14 or higher is required.
+  <p class="caution"><strong>Important:</strong> To download the new Android
+  4.x system components from the Android SDK Manager, you must first update the
+  SDK tools to revision 14 or later and restart the Android SDK Manager. If you do not,
+  the Android 4.0 system components will not be available for download.</p>
+</dt>
+</dl>
+
+  </div>
+</div>
+
+
+<h2 id="api">API Overview</h2>
+
+<p>The sections below provide a technical overview of new APIs in Android 4.0.3.</p>
+
+<div class="toggle-content closed" style="padding-left:1em;">
+
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png"
+class="toggle-content-img" alt="" />
+    <strong>Table of Contents</strong>
+  </a></p>
+
+  <div class="toggle-content-toggleme" style="padding-left:2em;">
+    <ol class="toc" style="margin-left:-1em">
+      <li><a href="#contacts">Social stream API in contacts provider</a></li>
+      <li><a href="#calendar">Calendar provider</a></li>
+      <li><a href="#widgets">Home screen widgets</a></li>
+      <li><a href="#textservices">Spell-checking</a></li>
+      <li><a href="#bluetooth">Bluetooth</a></li>
+      <li><a href="#ui">UI toolkit</a></li>
+      <li><a href="#accessibility">Accessibility</a></li>
+      <li><a href="#tts">Text-to-speech</a></li>
+      <li><a href="#database">Database</a></li>
+      <li><a href="#intents">Intents</a></li>
+      <li><a href="#camera">Camera</a></li>
+      <li><a href="#permissions">Permissions</a></li>
+    </ol>
+  </div>
+</div>
+
+
+
+
+
+<h3 id="contacts">Social stream API in Contacts provider</h3>
+
+<p>Applications that use social stream data such as status updates and check-ins
+can now sync that data with each of the user’s contacts, providing items in a
+stream along with photos for each.</p>
+
+<p>The database table that contains an individual contact’s social stream is
+defined by {@link android.provider.ContactsContract.StreamItems}, the Uri for
+which is nested within the {@link android.provider.ContactsContract.RawContacts}
+directory to which the stream items belong. Each social stream table includes
+several columns for metadata about each stream item, such as an icon
+representing the source (an avatar), a label for the item, the primary text
+content, comments about the item (such as responses from other people), and
+more. Photos associated with a stream are stored in another table, defined by
+{@link android.provider.ContactsContract.StreamItemPhotos}, which is available
+as a sub-directory of the {@link android.provider.ContactsContract.StreamItems}
+Uri.</p>
+
+<p>See {@link android.provider.ContactsContract.StreamItems} and
+{@link android.provider.ContactsContract.StreamItemPhotos} for more information.</p>
+
+<p>To read or write social stream items for a contact, an application must
+request permission from the user by declaring <code>&lt;uses-permission
+android:name="android.permission.READ_SOCIAL_STREAM"&gt;</code> and/or <code>&lt;uses-permission
+android:name="android.permission.WRITE_SOCIAL_STREAM"&gt;</code> in their manifest files.</p>
+
+<h3 id="calendar">Calendar provider</h4>
+<ul>
+<li>Adds the class {@link android.provider.CalendarContract.Colors} to represent
+a color table in the Calendar provider. The class provivdes fields for accessing
+colors available for a given account. Colors are referenced by 
+{@link android.provider.CalendarContract.ColorsColumns#COLOR_KEY COLOR_KEY}
+which must be unique for a given account name/type. These values can only be
+updated by the sync adapter.</li>
+<li>Adds {@link android.provider.CalendarContract.CalendarColumns#ALLOWED_AVAILABILITY ALLOWED_AVAILABILITY}
+and 
+{@link android.provider.CalendarContract.CalendarColumns#ALLOWED_ATTENDEE_TYPES ALLOWED_ATTENDEE_TYPES}
+for exchange/sync support.</li>
+<li>Adds {@link android.provider.CalendarContract.AttendeesColumns#TYPE_RESOURCE}
+(such as conference rooms) for attendees and 
+{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY_TENTATIVE},
+as well as {@link android.provider.CalendarContract.EventsColumns#EVENT_COLOR_KEY}
+for events.</li>
+</ul>
+
+<h3 id="widgets">Home screen widgets</h3>
+
+<p>Starting from Android 4.0, home screen widgets should no longer include their
+own padding. Instead, the system now automatically adds padding for each widget,
+based the characteristics of the current screen. This leads to a more uniform,
+consistent presentation of widgets in a grid. To assist applications that host
+home screen widgets, the platform provides a new method 
+{@link android.appwidget.AppWidgetHostView#getDefaultPaddingForWidget(android.content.Context, android.content.ComponentName, android.graphics.Rect)
+getDefaultPaddingForWidget()}. Applications can call this method to get the
+system-defined padding and account for it when computing the number of cells to
+allocate to the widget.</p>
+
+<h3 id="textservices">Spell-checking</h3>
+
+<ul>
+<li>For apps that accessing spell-checker services, a new {@link
+android.view.textservice.SpellCheckerSession#cancel() cancel()} method cancels
+any pending and running spell-checker tasks in a session.</li>
+
+<li>For spell-checker services, a new suggestions flag, 
+{@link android.view.textservice.SuggestionsInfo#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS},
+lets the services distinguish higher-confidence suggestions from
+lower-confidence ones. For example, a spell-checker could set the flag if an
+input word is not in the user dictionary but has likely suggestions, or not set
+the flag if an input word is not in the dictionary and has suggestions that are
+likely to be less useful.
+
+<p>Apps connected to the spell-checker can use the {@link
+android.view.textservice.SuggestionsInfo#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS}
+flag in combination with other suggestion attributes, as well as the {@link
+android.view.textservice.SuggestionsInfo#getSuggestionsAttributes()} and {@link
+android.view.textservice.SuggestionsInfo#getSuggestionsCount()} methods, to
+determine whether to mark input words as typos and offer suggestions.</p></li>
+
+<li>A new {@link android.text.style.SuggestionSpan#FLAG_AUTO_CORRECTION} style
+for text spans indicates that auto correction is about to be applied to a
+word/text that the user is typing/composing. This type of suggestion is rendered
+differently, to indicate the auto correction is happening.</li>
+</ul>
+
+<h3 id="bluetooth">Bluetooth</h3>
+<p>New public methods {@link
+android.bluetooth.BluetoothDevice#fetchUuidsWithSdp()} and {@link
+android.bluetooth.BluetoothDevice#getUuids()} let apps determine the features
+(UUIDs) supported by a remote device. In the case of {@link
+android.bluetooth.BluetoothDevice#fetchUuidsWithSdp()}, the system performs a
+service discovery on the remote device to get the UUIDs supported, then
+broadcasts the result in an {@link
+android.bluetooth.BluetoothDevice#ACTION_UUID} intent.</p>
+
+<h3 id="ui">UI toolkit</h3>
+
+<p>New methods {@link android.app.Fragment#setUserVisibleHint(boolean) setUserVisibleHint()} and
+{@link android.app.Fragment#getUserVisibleHint() getUserVisibleHint()} allow a
+fragment to set a hint of whether or not it is currently user-visible. The
+system defers the start of fragments that are not user-visible until the loaders
+for visible fragments have run. The visibility hint is "true" by default.</li>
+</p>
+
+<h3 id="graphics">Graphics</h3>
+
+<ul>
+<li>New method {@link android.graphics.SurfaceTexture#setDefaultBufferSize(int
+width, int height)} in SurfaceTexture sets the default size of the image
+buffers. This method may be used to set the image size when producing images
+with {@link android.graphics.Canvas} (via {@link
+android.view.Surface#lockCanvas}), or OpenGL ES (via an EGLSurface).</li>
+<li>Adds definitions for the enums of the GL_OES_EGL_image_external OpenGL ES extension &mdash;
+{@link android.opengl.GLES11Ext#GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES},
+{@link android.opengl.GLES11Ext#GL_SAMPLER_EXTERNAL_OES},
+{@link android.opengl.GLES11Ext#GL_TEXTURE_BINDING_EXTERNAL_OES}, and
+{@link android.opengl.GLES11Ext#GL_TEXTURE_EXTERNAL_OES}.</li>
+</ul>
+
+<h3 id="accessibility">Accessibility</h3>
+
+<ul>
+<li>Clients of {@link android.widget.RemoteViews} can now use the method {@link
+android.widget.RemoteViews#setContentDescription(int, java.lang.CharSequence)
+setContentDescription()} to set and get the content description of any View in
+the inflated layout.</li>
+
+<li>The methods {@link android.view.accessibility.AccessibilityRecord#getMaxScrollX()},
+{@link android.view.accessibility.AccessibilityRecord#getMaxScrollY()},
+{@link android.view.accessibility.AccessibilityRecord#setMaxScrollX(int) setMaxScrollX()}, and
+{@link android.view.accessibility.AccessibilityRecord#setMaxScrollY(int) setMaxScrollY()}
+allow apps to get and set the maximum scroll offset for an
+{@link android.view.accessibility.AccessibilityRecord} object.</li>
+
+<li>When touch-exploration mode is enabled, a new secure setting 
+{@link android.provider.Settings.Secure#ACCESSIBILITY_SPEAK_PASSWORD} 
+indicates whether the user requests the IME to speak text entered in password fields, even when
+a headset is not in use. By default, no password text is spoken unless a headset
+is in use.</li>
+</ul>
+
+<h3 id="tts">Text-to-speech</h3>
+
+<ul>
+<li>Adds the new method {@link
+android.speech.tts.TextToSpeech.Engine#getFeatures(java.util.Locale)
+getFeatures()}for querying and enabling network TTS support.
+<li>Adds a new listener class, {@link
+android.speech.tts.UtteranceProgressListener}, that engines can register to
+receive notification of speech-sythesis errors.</li>
+</ul>
+
+<h3 id="database">Database</h3>
+
+<ul>
+<li>A new {@link android.database.CrossProcessCursorWrapper} class lets content
+providers return results for a cross-process query more effieciently. The new
+class is a useful building block for wrapping cursors that will be sent to
+processes remotely. It can also transform normal {@link android.database.Cursor}
+objects into {@link android.database.CrossProcessCursor} objects
+transparently.
+
+<p>The {@link android.database.CrossProcessCursorWrapper} class fixes common
+performance issues and bugs that applications have encountered when
+implementing content providers.</p></li>
+
+<li>The {@link android.database.CursorWindow#CursorWindow(java.lang.String)}
+constructor now takes a name string as input. The system no longer distinguishes
+between local and remote cursor windows, so {@link
+android.database.CursorWindow#CursorWindow(boolean)} is now deprecated.</li>
+</ul>
+
+<h3 id="intents">Intents</h3>
+
+<p>Adds  for categories for targeting common types of applications on the
+device, such as {@link android.content.Intent#CATEGORY_APP_BROWSER}, {@link
+android.content.Intent#CATEGORY_APP_CALENDAR}, {@link
+android.content.Intent#CATEGORY_APP_MAPS}, and more.</li>
+
+<h3 id="camera">Camera</h3>
+
+<ul>
+<li>{@link android.media.MediaMetadataRetriever} adds the new constant
+{@link android.media.MediaMetadataRetriever#METADATA_KEY_LOCATION} to let apps
+access retrieve location information for an image or video. </li>
+
+<li>{@link android.media.CamcorderProfile} adds the QVGA (320x240) resolution
+profiles. Quality level is represented by the
+{@link android.media.CamcorderProfile#QUALITY_QVGA}.and
+{@link android.media.CamcorderProfile#QUALITY_TIME_LAPSE_QVGA} constants.</li>
+
+<li>New methods {@link android.hardware.Camera.Parameters#setVideoStabilization(boolean) setVideoStabilization()},
+{@link android.hardware.Camera.Parameters#getVideoStabilization() setVideoStabilization()}, and {android.hardware.Camera.Parameters#isVideoStabilizationSupported() isVideoStabilizationSupported()}
+let you check and manage video stabilization for a {@link android.hardware.Camera}.</li>
+</ul>
+
+<h3 id="Permissions">Permissions</h3>
+
+<p>The following are new permissions:</p>
+<ul>
+<li>{@link android.Manifest.permission#READ_SOCIAL_STREAM} and 
+{@link android.Manifest.permission#WRITE_SOCIAL_STREAM}: Allow a sync
+adapter to read and write social stream data to a contact in the shared
+contacts provider.</li>
+</ul>
+
+
+<div class="special" style="margin-top:2em">
+<p>For a detailed view of all API changes in Android {@sdkPlatformVersion} (API Level
+{@sdkPlatformApiLevel}), see the <a
+href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API Differences Report</a>.</p>
+</div>
+
+
+<h2 id="api-level">API Level</h2>
+
+<p>The Android {@sdkPlatformVersion} API is assigned an integer
+identifier&mdash;<strong>{@sdkPlatformApiLevel}</strong>&mdash;that is stored in the system itself.
+This identifier, called the "API level", allows the system to correctly determine whether an
+application is compatible with the system, prior to installing the application. </p>
+
+<p>To use APIs introduced in Android {@sdkPlatformVersion} in your application, you need compile the
+application against an Android platform that supports API level {@sdkPlatformApiLevel} or
+higher. Depending on your needs, you might also need to add an
+<code>android:minSdkVersion="{@sdkPlatformApiLevel}"</code> attribute to the
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a>
+element.</p>
+
+<p>For more information, see the <a href="{@docRoot}guide/appendix/api-levels.html">API Levels</a>
+document. </p>
+
+
+<h2 id="apps">Built-in Applications</h2>
+
+<p>The system image included in the downloadable platform provides these
+built-in applications:</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+<ul>
+<li>API Demos</li>
+<li>Browser</li>
+<li>Calculator</li>
+<li>Calendar</li>
+<li>Camera</li>
+<li>Clock</li>
+<li>Custom Locale</li>
+<li>Dev Tools</li>
+<li>Downloads</li>
+<li>Email</li>
+<li>Gallery</li>
+</ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+<ul>
+<li>Gestures Builder</li>
+<li>Messaging</li>
+<li>Music</li>
+<li>People</li>
+<li>Phone</li>
+<li>Search</li>
+<li>Settings</li>
+<li>Speech Recorder</li>
+<li>Widget Preview</li>
+</ul>
+</td>
+</tr>
+</table>
+
+
+<h2 id="locs" style="margin-top:.75em;">Locales</h2>
+
+<p>The system image included in the downloadable SDK platform provides a variety of built-in
+locales. In some cases, region-specific strings are available for the locales. In other cases, a
+default version of the language is used. The languages that are available in the Android 3.0 system
+image are listed below (with <em>language</em>_<em>country/region</em> locale descriptor).</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+<ul>
+<li>Arabic, Egypt (ar_EG)</li>
+<li>Arabic, Israel (ar_IL)</li>
+<li>Bulgarian, Bulgaria (bg_BG)</li>
+<li>Catalan, Spain (ca_ES)</li>
+<li>Czech, Czech Republic (cs_CZ)</li>
+<li>Danish, Denmark(da_DK)</li>
+<li>German, Austria (de_AT)</li>
+<li>German, Switzerland (de_CH)</li>
+<li>German, Germany (de_DE)</li>
+<li>German, Liechtenstein (de_LI)</li>
+<li>Greek, Greece (el_GR)</li>
+<li>English, Australia (en_AU)</li>
+<li>English, Canada (en_CA)</li>
+<li>English, Britain (en_GB)</li>
+<li>English, Ireland (en_IE)</li>
+<li>English, India (en_IN)</li>
+<li>English, New Zealand (en_NZ)</li>
+<li>English, Singapore(en_SG)</li>
+<li>English, US (en_US)</li>
+<li>English, Zimbabwe (en_ZA)</li>
+<li>Spanish (es_ES)</li>
+<li>Spanish, US (es_US)</li>
+<li>Finnish, Finland (fi_FI)</li>
+<li>French, Belgium (fr_BE)</li>
+<li>French, Canada (fr_CA)</li>
+<li>French, Switzerland (fr_CH)</li>
+<li>French, France (fr_FR)</li>
+<li>Hebrew, Israel (he_IL)</li>
+<li>Hindi, India (hi_IN)</li>
+</ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+<li>Croatian, Croatia (hr_HR)</li>
+<li>Hungarian, Hungary (hu_HU)</li>
+<li>Indonesian, Indonesia (id_ID)</li>
+<li>Italian, Switzerland (it_CH)</li>
+<li>Italian, Italy (it_IT)</li>
+<li>Japanese (ja_JP)</li>
+<li>Korean (ko_KR)</li>
+<li>Lithuanian, Lithuania (lt_LT)</li>
+<li>Latvian, Latvia (lv_LV)</li>
+<li>Norwegian bokmål, Norway (nb_NO)</li>
+<li>Dutch, Belgium (nl_BE)</li>
+<li>Dutch, Netherlands (nl_NL)</li>
+<li>Polish (pl_PL)</li>
+<li>Portuguese, Brazil (pt_BR)</li>
+<li>Portuguese, Portugal (pt_PT)</li>
+<li>Romanian, Romania (ro_RO)</li>
+<li>Russian (ru_RU)</li></li>
+<li>Slovak, Slovakia (sk_SK)</li>
+<li>Slovenian, Slovenia (sl_SI)</li>
+<li>Serbian (sr_RS)</li>
+<li>Swedish, Sweden (sv_SE)</li>
+<li>Thai, Thailand (th_TH)</li>
+<li>Tagalog, Philippines (tl_PH)</li>
+<li>Turkish, Turkey (tr_TR)</li>
+<li>Ukrainian, Ukraine (uk_UA)</li>
+<li>Vietnamese, Vietnam (vi_VN)</li>
+<li>Chinese, PRC (zh_CN)</li>
+<li>Chinese, Taiwan (zh_TW)</li>
+</td>
+</tr>
+</table>
+
+<p class="note"><strong>Note:</strong> The Android platform may support more
+locales than are included in the SDK system image. All of the supported locales
+are available in the <a href="http://source.android.com/">Android Open Source
+Project</a>.</p>
+
+<h2 id="skins">Emulator Skins</h2>
+
+<p>The downloadable platform includes the following emulator skins:</p>
+
+<ul>
+  <li>
+    QVGA (240x320, low density, small screen)
+  </li>
+  <li>
+    WQVGA400 (240x400, low density, normal screen)
+  </li>
+  <li>
+    WQVGA432 (240x432, low density, normal screen)
+  </li>
+  <li>
+    HVGA (320x480, medium density, normal screen)
+  </li>
+  <li>
+    WVGA800 (480x800, high density, normal screen)
+  </li>
+  <li>
+    WVGA854 (480x854 high density, normal screen)
+  </li>
+  <li>
+    WXGA720 (1280x720, extra-high density, normal screen) 
+  </li>
+  <li>
+    WSVGA (1024x600, medium density, large screen) 
+  </li>
+  <li>
+    WXGA (1280x800, medium density, xlarge screen)
+  </li>
+</ul>
+
+<p>To test your application on an emulator that represents the latest Android device, you can create
+an AVD with the new WXGA720 skin (it's an xhdpi, normal screen device). Note that the emulator
+currently doesn't support the new on-screen navigation bar for devices without hardware navigation
+buttons, so when using this skin, you must use keyboard keys <em>Home</em> for the Home button,
+<em>ESC</em> for the Back button, and <em>F2</em> or <em>Page-up</em> for the Menu button.</p>
+
+<p>However, due to performance issues in the emulator when running high-resolution screens such as
+the one for the WXGA720 skin, we recommend that you primarily use the traditional WVGA800 skin
+(hdpi, normal screen) to test your application.</p>
+
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 791e7aa..f0651ea 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -76,11 +76,11 @@
     </ul>
     <ul>
       <li class="toggle-list">
-        <div><a href="<?cs var:toroot ?>sdk/android-4.0.html">
-        <span class="en">Android 4.0 Platform</span></a> <span class="new">new!</span></div>
+        <div><a href="<?cs var:toroot ?>sdk/android-4.0-highlights.html">
+        <span class="en">Android 4.0.x Platform</span></a> <span class="new">new!</span></div>
         <ul>
-          <li><a href="<?cs var:toroot ?>sdk/android-4.0-highlights.html">Platform Highlights</a></li>
-          <li><a href="<?cs var:toroot ?>sdk/api_diff/14/changes.html">API Differences Report &raquo;</a></li>
+          <li><a href="<?cs var:toroot ?>sdk/android-4.0.3.html">Android 4.0.3 Platform</a> <span class="new">new!</span></li>
+          <li><a href="<?cs var:toroot ?>sdk/android-4.0.html">Android 4.0 Platform</a> </li>
         </ul>
       </li>
       <li class="toggle-list">
diff --git a/docs/html/training/improving-layouts/index.jd b/docs/html/training/improving-layouts/index.jd
new file mode 100644
index 0000000..4cc6963
--- /dev/null
+++ b/docs/html/training/improving-layouts/index.jd
@@ -0,0 +1,58 @@
+page.title=Improving Performance of Layouts
+
+trainingnavtop=true
+startpage=true
+next.title=Optimizing Layout
+next.link=optimizing-layout.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
+<h2>Dependencies and prerequisites</h2>
+<ul>
+ <li>Android 1.5 (API Level 3) or higher</li>
+</ul>
+
+<!-- related docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a></li>
+</ul>
+
+</div>
+</div>
+
+
+
+<p>Layouts are a key part of Android applications that directly affect the user experience. If
+implemented poorly, your layout can lead to a memory hungry application with slow UIs. The Android
+SDK includes tools to help you identify problems in your layout performance, which when combined the
+lessons here, you will be able to implement smooth scrolling interfaces with a minimum memory
+footprint.</p>
+
+
+
+<h2>Lessons</h2>
+
+<dl>
+  <dt><b><a href="optimizing-layout.html">Optimizing Layout Hierarchies</a></b></dt>
+    <dd>In the same way a complex web page can slow down load time, your layout hierarchy
+if too complex can also cause performance problems. This lesson shows how you can use SDK tools
+to inspect your layout and discover performance bottlenecks.</dd>
+  <dt><b><a href="reusing-layouts.html">Re-using Layouts with &lt;include/&gt;</a></b></dt>
+    <dd>If your application UI repeats certain layout constructs in multiple places, this lesson
+shows you how to create efficient, re-usable layout constructs, then include them in the appropriate
+UI layouts.</dd>
+  <dt><b><a href="loading-ondemand.html">Loading Views On Demand</a></b></dt>
+    <dd>Beyond simply including one layout component within another layout, you might want to
+make the included layout visible only when it's needed, sometime after the activity is running.
+This lesson shows how you can improve your layout's initialization performance by loading
+portions of your layout on demand.</dd>
+  <dt><b><a href="smooth-scrolling.html">Making ListView Scrolling Smooth</a></b></dt>
+    <dd>If you've built an instance of {@link android.widget.ListView} that contains complex or
+data-heavy content in each list item, the scroll performance of the list might suffer. This
+lesson provides some tips about how you can make your scrolling performance more smooth.</dd>
+</dl>
\ No newline at end of file
diff --git a/docs/html/training/improving-layouts/loading-ondemand.jd b/docs/html/training/improving-layouts/loading-ondemand.jd
new file mode 100644
index 0000000..659b1ec3
--- /dev/null
+++ b/docs/html/training/improving-layouts/loading-ondemand.jd
@@ -0,0 +1,86 @@
+page.title=Loading Views On Demand
+parent.title=Improving Performance of Layouts
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Re-using Layouts with &lt;include/&gt;
+previous.link=reusing-layouts.html
+next.title=Making ListView Scrolling Smooth
+next.link=smooth-scrolling.html
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#ViewStub">Define a ViewStub</a></li>
+  <li><a href="#Load">Load the ViewStub Layout</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}resources/articles/layout-tricks-stubs.html">Using ViewStubs</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>Sometimes your layout might require complex views that are rarely used. Whether
+they are item details, progress indicators, or undo messages, you can reduce memory usage and speed
+up rendering by loading the views only when they are needed.</p>
+
+
+<h2 id="ViewStub">Define a ViewStub</h2>
+
+<p>{@link android.view.ViewStub} is a lightweight view with no dimension and doesn’t draw anything
+or participate in the layout. As such, it's cheap to inflate and cheap to leave in a view hierarchy.
+Each {@link android.view.ViewStub} simply needs to include the {@code android:layout} attribute to
+specify the layout to inflate.</p>
+
+<p>The following {@link android.view.ViewStub} is for a translucent progress bar overlay. It should
+be visible only when new items are being imported into the application.</p>
+
+<pre>
+&lt;ViewStub
+    android:id="@+id/stub_import"
+    android:inflatedId="@+id/panel_import"
+    android:layout="@layout/progress_overlay"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="bottom" /&gt;
+</pre>
+
+
+<h2 id="Load">Load the ViewStub Layout</h2>
+
+<p>When you want to load the layout specified by the {@link android.view.ViewStub}, either set it
+visible by calling {@link android.view.View#setVisibility setVisibility(View.VISIBLE)} or call
+{@link android.view.ViewStub#inflate()}.</p>
+
+<pre>
+((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
+// or
+View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();
+</pre>
+
+<p class="note"><strong>Note:</strong> The {@link android.view.ViewStub#inflate()} method returns
+the inflated {@link android.view.View} once complete. so you don't need to call {@link
+android.app.Activity#findViewById findViewById()} if you need to interact with the layout.</p>
+
+<p>Once visible/inflated, the {@link android.view.ViewStub} element is no longer part of the view
+hierarchy. It is replaced by the inflated layout and the ID for the root view of that layout is
+the one specified by the {@code android:inflatedId} attribute of the ViewStub. (The ID {@code
+android:id} specified for the {@link android.view.ViewStub} is valid only until the {@link
+android.view.ViewStub} layout is visible/inflated.)</p>
+
+<p class="note"><strong>Note:</strong> One drawback of {@link android.view.ViewStub} is that it
+doesn’t currently support the {@code &lt;merge/&gt;} tag in the layouts to be inflated.</p>
+
+
+
diff --git a/docs/html/training/improving-layouts/optimizing-layout.jd b/docs/html/training/improving-layouts/optimizing-layout.jd
new file mode 100644
index 0000000..3237780
--- /dev/null
+++ b/docs/html/training/improving-layouts/optimizing-layout.jd
@@ -0,0 +1,156 @@
+page.title=Optimizing Layout Hierarchies
+parent.title=Improving Performance of Layouts
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Re-using Layouts with &lt;include/&gt;
+next.link=reusing-layouts.html
+
+@jd:body
+
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Inspect">Inspect Your Layout</a></li>
+  <li><a href="#Revise">Revise Your Layout</a></li>
+  <li><a href="#Layoutopt">Use Layoutopt</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a></li>
+  <li><a
+href="{@docRoot}guide/topics/resources/layout-resource.html#include- element">Layout
+Resource</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>It is a common misconception that using the basic layout structures leads to the most efficient
+layouts. However, each widget and layout you add to your application requires initialization,
+layout, and drawing. For example, using nested instances of {@link android.widget.LinearLayout} can
+lead to an excessively deep view hierarchy. Furthermore, nesting several instances of {@link
+android.widget.LinearLayout} that use the {@code layout_weight} parameter can be especially
+expensive as each child needs to be measured twice. This is particularly important when the layout
+is inflated repeatedly, such as when used in a {@link android.widget.ListView} or {@link
+android.widget.GridView}.</p>
+
+<p>In this lesson you'll learn to use <a
+href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Heirachy Viewer</a> and <a
+href="{@docRoot}guide/developing/tools/layoutopt.html">Layoutopt</a> to examine and optimize your
+layout.</p>
+
+
+
+<h2 id="Inspect">Inspect Your Layout</h2>
+
+<p>The Android SDK tools include a tool called <a
+href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Heirachy Viewer</a> that allows
+you to analyze your layout while your application is running. Using this tool helps you discover
+bottlenecks in the layout performance.</p>
+
+<p>Hierarchy Viewer works by allowing you to select running processes on a connected device or
+emulator, then display the layout tree. The traffic lights on each block represent its Measure,
+Layout and Draw performance, helping you identify potential issues.</p>
+
+<p>For example, figure 1 shows a layout that's used as an item in a {@link
+android.widget.ListView}. This layout shows a small bitmap image on the left and two stacked items
+of text on the right. It is especially important that layouts that will be inflated multiple
+times&mdash;such as this one&mdash;are optimized as the performance
+benefits will be multiplied.</p>
+
+<img src="{@docRoot}images/training/layout-listitem.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> Conceptual layout for an item in a {@link
+android.widget.ListView}.</p>
+
+<p>The {@code hierarchyviewer} tool is available in  {@code &lt;sdk&gt;/tools/}. When opened,
+the Hierarchy Viewer shows a list of available devices and its running components. Click
+<strong>Load View Hierarchy</strong> to view the layout hierarchy of the selected component. For
+example, figure 2 shows the layout for the list item illustrated by figure 1.</p>
+
+<div style="float:left;width:455px">
+<img src="{@docRoot}images/training/hierarchy-linearlayout.png" alt="" />
+<p class="img-caption"><strong>Figure 2.</strong> Layout hierarchy for the layout in figure 1,
+using nested instances of {@link android.widget.LinearLayout}.</p>
+</div>
+
+<div style="float:left;width:155px;margin-left:2em">
+<img src="{@docRoot}images/training/hierarchy-layouttimes.png" alt="" />
+<p class="img-caption"><strong>Figure 3.</strong> Clicking a hierarchy node shows its
+performance times.</p>
+</div>
+
+<p style="clear:left">In figure 2, you can see there is a 3-level hierarchy with some problems
+laying out the text items. Clicking on the items shows the time taken for each stage of the process
+(figure 3). It becomes clear which items are taking the longest to measure, layout, and render, and
+where you should spend time optimizing.</p>
+
+<p>The timings for rendering a complete list item using this layout are:</p>
+<ul>
+  <li>Measure: 0.977ms</li>
+  <li>Layout: 0.167ms</li>
+  <li>Draw: 2.717ms</li>
+</ul>
+
+
+<h2 id="Revise">Revise Your Layout</h2>
+
+<p>Because the layout performance above slows down due to a nested {@link
+android.widget.LinearLayout}, the performance might improve by flattening the layout&mdash;make
+the layout shallow and wide, rather than narrow and deep. A {@link android.widget.RelativeLayout} as
+the root node allows for such layouts. So, when this design is converted to use {@link
+android.widget.RelativeLayout}, you can see that the layout becomes a 2-level hierarchy. Inspection
+of the new layout looks like this:</p>
+
+<img src="{@docRoot}images/training/hierarchy-relativelayout.png" alt="" />
+<p class="img-caption"><strong>Figure 4.</strong> Layout hierarchy for the layout in figure 1,
+using {@link android.widget.RelativeLayout}.</p>
+
+<p>Now rendering a list item takes:</p>
+<ul>
+  <li>Measure: 0.598ms</li>
+  <li>Layout: 0.110ms</li>
+  <li>Draw: 2.146ms</li>
+</ul>
+
+<p>Might seem like a small improvement, but this time is multiplied several times because this
+layout is used for every item in a list.</p>
+
+<p>Most of this time difference is due to the use of {@code layout_weight} in the {@link
+android.widget.LinearLayout} design, which can slow down the speed of measurement. It is just one
+example of how each layout has appropriate uses and you should carefully consider whether using 
+layout weight is necessary.</p>
+
+
+<h2 id="Layoutopt">Use Layoutopt</h2>
+
+<p>It is always good practice to also run the <a
+href="{@docRoot}guide/developing/tools/layoutopt.html">layoutopt</a> tool on your final layout files
+to search for places in your view hierarchy that may be optimized. Layoutopt is also in your SDK
+{@code tools/} directory and takes a layout directory name or a space-separated list of layout files
+that you'd like to inspect.</p>
+
+<p>When you run {@code layoutopt} on a layout file, it prints a line number for each issue found, a
+description of the issue, and for some types of issues it also suggests a resolution. For
+example:</p>
+
+<pre class="no-pretty-print classic">
+$ layoutopt samples/
+samples/compound.xml
+   7:23 The root-level &lt;FrameLayout/&gt; can be replaced with &lt;merge/&gt;
+   11:21 This LinearLayout layout or its FrameLayout parent is useless
+samples/simple.xml
+   7:7 The root-level &lt;FrameLayout/&gt; can be replaced with &lt;merge/&gt;
+</pre>
+
+<p>After you apply the suggested layout optimizations, run Hierarchy Viewer again to inspect the
+performance changes.</p>
+
diff --git a/docs/html/training/improving-layouts/reusing-layouts.jd b/docs/html/training/improving-layouts/reusing-layouts.jd
new file mode 100644
index 0000000..8f9729a
--- /dev/null
+++ b/docs/html/training/improving-layouts/reusing-layouts.jd
@@ -0,0 +1,150 @@
+page.title=Re-using Layouts with &lt;include/&gt;
+parent.title=Improving Performance of Layouts
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Optimizing Layout Hierarchies
+previous.link=optimizing-layout.html
+next.title=Loading Views On Demand
+next.link=loading-ondemand.html
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Create">Create a Re-usable Layout</a></li>
+  <li><a href="#Include">Use the &lt;include&gt; Tag</a></li>
+  <li><a href="#Merge">Use the &lt;merge&gt; Tag</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}resources/articles/layout-tricks-reuse.html">Creating Reusable UI
+Components</a></li>
+  <li><a href="{@docRoot}resources/articles/layout-tricks-merge.html">Merging Layouts</a></li>
+  <li><a
+href="{@docRoot}guide/topics/resources/layout-resource.html#include-element">Layout
+Resource</a></li>
+</ul>
+
+</div>
+</div>
+
+
+
+<p>Although Android offers a variety of widgets to provide small and re-usable interactive elements,
+you might also need to re-use larger components that require a special layout. To efficiently
+re-use complete layouts, you can use the {@code &lt;include/&gt;} and {@code &lt;merge/&gt;} tags
+to embed another layout inside the current layout.</p>
+
+<p>Reusing layouts is particularly powerful as it allows you create reusable complex layouts. For
+example, a yes/no button panel, or custom progress bar with description text.
+It also means that any elements of your application that are common across multiple layouts can be
+extracted, managed separately, then included in each layout. So while 
+you can create individual UI components by writing a custom {@link android.view.View}, you can
+do it even more easily by re-using a layout file.</p>
+
+
+<h2 id="Create">Create a Re-usable Layout</h2>
+
+<p>If you already know the layout that you want to re-use, create a new XML file and define the
+layout. For example, here's a layout from the G-Kenya codelab that defines a title bar to be
+included in each activity (<code>titlebar.xml</code>):</p>
+
+<pre>
+&lt;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width=”match_parent”
+    android:layout_height="wrap_content"
+    android:background="&#64;color/titlebar_bg">
+
+    &lt;ImageView android:layout_width="wrap_content"
+               android:layout_height="wrap_content" 
+               android:src="&#64;drawable/gafricalogo" />
+&lt;/FrameLayout>
+</pre>
+
+<p>The root {@link android.view.View} should be exactly how you'd like it to appear in each
+layout to which you add this layout.</p>
+
+
+<h2 id="Include">Use the &lt;include&gt; Tag</h2>
+
+<p>Inside the layout to which you want to add the re-usable component, add the {@code
+&lt;include/&gt;} tag. For example, here's a layout from the
+G-Kenya codelab that includes the title bar from above:</p>
+
+<p>Here's the layout file:</p>
+
+<pre>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" 
+    android:layout_width=”match_parent”
+    android:layout_height=”match_parent”
+    android:background="&#64;color/app_bg"
+    android:gravity="center_horizontal">
+
+    <strong>&lt;include layout="&#64;layout/titlebar"/></strong>
+
+    &lt;TextView android:layout_width=”match_parent”
+              android:layout_height="wrap_content"
+              android:text="&#64;string/hello"
+              android:padding="10dp" />
+
+    ...
+
+&lt;/LinearLayout>
+</pre>
+
+<p>You can also override all the layout parameters (any {@code android:layout_*} attributes) of the
+included layout's root view by specifying them in the {@code &lt;include/&gt;} tag. For
+example:</p>
+
+<pre>
+&lt;include android:id=”&#64;+id/news_title”
+         android:layout_width=”match_parent”
+         android:layout_height=”match_parent”
+         layout=”@layout/title”/>
+</pre>
+
+
+
+<h2 id="Merge">Use the &lt;merge&gt; Tag</h2>
+
+<p>The {@code &lt;merge />} tag helps eliminate redundant view groups in your view hierarchy
+when including one layout within another. For example, if your main layout is a vertical {@link
+android.widget.LinearLayout} in which two consecutive views can be
+re-used in multiple layouts, then the re-usable layout in which you place the two views requires its
+own root view. However, using another {@link android.widget.LinearLayout} as the root for the
+re-usable layout would result in a vertical {@link android.widget.LinearLayout} inside a
+vertical {@link android.widget.LinearLayout}. The nested {@link android.widget.LinearLayout}
+serves no real purpose other than to slow down your UI performance.</p>
+
+<p>To avoid including such a redundant view group, you can instead use the
+{@code &lt;merge&gt;} element as the root view for the re-usable layout. For example:</p>
+
+<pre>
+&lt;merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    &lt;Button
+        android:layout_width="fill_parent" 
+        android:layout_height="wrap_content"
+        android:text="@string/add"/>
+
+    &lt;Button
+        android:layout_width="fill_parent" 
+        android:layout_height="wrap_content"
+        android:text="@string/delete"/>
+
+&lt;/merge>
+</pre>
+
+<p>Now, when you include this layout in another layout (using the {@code &lt;include/&gt;} tag), the
+system ignores the {@code &lt;merge&gt;} element and places the two buttons directly in the
+layout, in place of the {@code &lt;include/&gt;} tag.</p>
+
diff --git a/docs/html/training/improving-layouts/smooth-scrolling.jd b/docs/html/training/improving-layouts/smooth-scrolling.jd
new file mode 100644
index 0000000..bc90dd2
--- /dev/null
+++ b/docs/html/training/improving-layouts/smooth-scrolling.jd
@@ -0,0 +1,124 @@
+page.title=Making ListView Scrolling Smooth
+parent.title=Optimizing Performance of Layouts
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Loading Views On Demand
+previous.link=loading-ondemand.html
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#AsyncTask">Use a Background Thread</a></li>
+  <li><a href="#ViewHolder">Hold View Objects in a View Holder</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}resources/articles/listview-backgrounds.html">ListView
+Backgrounds: An Optimization</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>The key to a smoothly scrolling {@link android.widget.ListView} is to keep the application’s main
+thread (the UI thread) free from heavy processing. Ensure you do any disk access, network access, or
+SQL access in a separate thread. To test the status of your app, you can enable {@link
+android.os.StrictMode}.</p>
+
+
+<h2 id="AsyncTask">Use a Background Thread</h2>
+
+<p>Using a background thread ("worker thread") removes strain from the main thread so it can focus
+on drawing the UI. In many cases, using {@link android.os.AsyncTask} provides a simple way to
+perform your work outside the main thread. {@link android.os.AsyncTask} automatically queues up all
+the {@link android.os.AsyncTask#execute execute()} requests and performs them serially. This
+behavior is global to a particular process and means you don’t need to worry about creating your
+own thread pool.</p>
+
+<p>In the sample code below, an {@link android.os.AsyncTask} is used to load
+images in a background thread, then apply them to the UI once finished. It also shows a
+progress spinner in place of the images while they are loading.</p>
+
+<pre>
+// Using an AsyncTask to load the slow images in a background thread
+new AsyncTask&lt;ViewHolder, Void, Bitmap>() {
+    private ViewHolder v;
+
+    &#64;Override
+    protected Bitmap doInBackground(ViewHolder... params) {
+        v = params[0];
+        return mFakeImageLoader.getImage();
+    }
+
+    &#64;Override
+    protected void onPostExecute(Bitmap result) {
+        super.onPostExecute(result);
+        if (v.position == position) {
+            // If this item hasn't been recycled already, hide the
+            // progress and set and show the image
+            v.progress.setVisibility(View.GONE);
+            v.icon.setVisibility(View.VISIBLE);
+            v.icon.setImageBitmap(result);
+        }
+    }
+}.execute(holder);
+</pre>
+
+<p>Beginning with Android 3.0 (API level 11), an extra feature is available in {@link
+android.os.AsyncTask} so you can enable it to run across multiple processor cores. Instead of
+calling {@link android.os.AsyncTask#execute execute()} you can specify {@link
+android.os.AsyncTask#executeOnExecutor executeOnExecutor()} and multiple requests can be executed at
+the same time depending on the number of cores available.</p>
+
+
+<h2 id="ViewHolder">Hold View Objects in a View Holder</h2>
+
+<p>Your code might call {@link android.app.Activity#findViewById findViewById()} frequently
+during the scrolling of {@link android.widget.ListView}, which can slow down performance. Even when
+the {@link
+android.widget.Adapter} returns an inflated view for recycling, you still need to look up the
+elements
+and update them. A way around repeated use of {@link android.app.Activity#findViewById
+findViewById()} is to use the "view holder" design pattern.</p>
+
+<p>A {@code ViewHolder} object stores each of the component views inside the tag field of the
+Layout, so you can immediately access them without the need to look them up repeatedly. First, you
+need to create a class to hold your exact set of views. For example:</p>
+
+<pre>
+static class ViewHolder {
+  TextView text;
+  TextView timestamp;
+  ImageView icon;
+  ProgressBar progress;
+  int position;
+}
+</pre>
+
+<p>Then populate the {@code ViewHolder} and store it inside the layout.</p>
+
+<pre>
+ViewHolder holder = new ViewHolder();
+holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
+holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
+holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
+holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);
+convertView.setTag(holder);
+</pre>
+
+<p>Now you can easily access each view without the need for the look-up, saving valuable processor
+cycles.</p>
+
+
+
+
+
diff --git a/docs/html/training/managing-audio/audio-focus.jd b/docs/html/training/managing-audio/audio-focus.jd
new file mode 100644
index 0000000..07a4465
--- /dev/null
+++ b/docs/html/training/managing-audio/audio-focus.jd
@@ -0,0 +1,183 @@
+page.title=Managing Audio Focus
+parent.title=Managing Audio Playback and Focus
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Controlling Your App's Volume and Playback
+previous.link=volume-playback.html
+next.title=Dealing with Audio Output Hardware
+next.link=audio-output.html
+
+@jd:body
+
+
+<div id="tb-wrapper"> 
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#RequestFocus">Request the Audio Focus</a></li>
+  <li><a href="#HandleFocusLoss">Handle the Loss of Audio Focus</a></li>
+  <li><a href="#DUCK">Duck!</a></li>
+</ol>
+
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a></li>
+</ul>
+
+</div> 
+</div>
+ 
+
+<p>With multiple apps potentially playing audio it's important to think about how they should
+interact. To avoid every music app playing at the same time, Android uses audio focus to moderate
+audio playback&mdash;only apps that hold the audio focus should play audio.</p>
+
+<p>Before your app starts playing audio it should request&mdash;and receive&mdash;the audio focus. 
+Likewise, it should know how to listen for a loss of audio focus and respond appropriately when that
+happens.</p>
+
+ 
+<h2 id="RequestFocus">Request the Audio Focus</h2> 
+ 
+<p>Before your app starts playing any audio, it should hold the audio focus for the stream
+it will be using. This is done with a call to {@link android.media.AudioManager#requestAudioFocus
+requestAudioFocus()} which returns
+{@link android.media.AudioManager#AUDIOFOCUS_REQUEST_GRANTED} if your request is successful.</p>
+
+<p>You must specify which stream you're using and whether you expect to require transient or
+permanent audio focus. Request transient focus when you expect to play audio for only a short time
+(for example when playing navigation instructions). Request permanent audio focus when you
+plan to play audio for the foreseeable future (for example, when playing music).</p>
+
+<p>The following snippet requests permanent audio focus on the music audio stream. You should
+request the audio focus immediately before you begin playback, such as when the user presses
+play or the background music for the next game level begins.</p>
+  
+<pre>
+AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
+...
+
+// Request audio focus for playback
+int result = am.requestAudioFocus(afChangeListener,
+                                 // Use the music stream.
+                                 AudioManager.STREAM_MUSIC,
+                                 // Request permanent focus.
+                                 AudioManager.AUDIOFOCUS_GAIN);
+   
+if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+    am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
+    // Start playback.
+}
+</pre>
+
+<p>Once you've finished playback be sure to call {@link
+android.media.AudioManager#abandonAudioFocus abandonAudioFocus()}. This notifies
+the system that you no longer require focus and unregisters the associated {@link
+android.media.AudioManager.OnAudioFocusChangeListener}. In the case of abandoning transient focus,
+this allows any interupted app to continue playback.</p>
+
+<pre>
+// Abandon audio focus when playback complete    
+am.abandonAudioFocus(afChangeListener);
+</pre>
+
+<p>When requesting transient audio focus you have an additional option: whether or not you want to
+enable "ducking." Normally, when a well-behaved audio app loses audio focus it immediately
+silences its playback. By requesting a transient audio focus that allows ducking you tell other
+audio apps that it’s acceptable for them to keep playing, provided they lower their volume until the
+focus returns to them.</p>
+
+<pre>
+// Request audio focus for playback
+int result = am.requestAudioFocus(afChangeListener,
+                             // Use the music stream.
+                             AudioManager.STREAM_MUSIC,
+                             // Request permanent focus.
+                             AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
+   
+if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+    // Start playback.
+}
+</pre>
+
+<p>Ducking is particularly suitable for apps that use the audio stream intermittently, such as for
+audible driving directions.</p>
+
+<p>Whenever another app requests audio focus as described above, its choice between permanent and
+transient (with or without support for ducking) audio focus is received by the listener you
+registered when requesting focus.</p>
+
+
+<h2 id="HandleFocusLoss">Handle the Loss of Audio Focus</h2> 
+
+<p>If your app can request audio focus, it follows that it will in turn lose that focus when another
+app requests it. How your app responds to a loss of audio focus depends on the manner of that
+loss.</p>
+
+<p>The {@link android.media.AudioManager.OnAudioFocusChangeListener#onAudioFocusChange
+onAudioFocusChange()} callback method of they audio focus change listener you registered when
+requesting audio focus receives a parameter that describes the focus change event. Specifically,
+the possible focus loss events mirror the focus request types from the previous
+section&mdash;permanent loss, transient loss, and transient with ducking permitted.</p>
+
+<p>Generally speaking, a transient (temporary) loss of audio focus should result in your app
+silencing it’s audio stream, but otherwise maintaining the same state. You should continue to
+monitor changes in audio focus and be prepared to resume playback where it was paused once you’ve
+regained the focus.</p>
+
+<p>If the audio focus loss is permanent, it’s assumed that another application is now being used to
+listen to audio and your app should effectively end itself. In practical terms, that means stopping
+playback, removing media button listeners&mdash;allowing the new audio player to exclusively handle
+those events&mdash;and abandoning your audio focus. At that point, you would expect a user action
+(pressing play in your app) to be required before you resume playing audio.</p>
+
+<p>In the following code snippet, we pause the playback or our media player object if the audio
+loss is transien and resume it when we have regained the focus. If the loss is permanent, it
+unregisters our media button event receiver and stops monitoring audio focus changes.<p>
+
+<pre>
+OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
+    public void onAudioFocusChange(int focusChange) {
+        if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT
+            // Pause playback
+        } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
+            // Resume playback 
+        } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
+            am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
+            am.abandonAudioFocus(afChangeListener);
+            // Stop playback
+        }
+    }
+};
+</pre>
+ 
+<p>In the case of a transient loss of audio focus where ducking is permitted, rather than pausing
+playback, you can "duck" instead.</p>
+
+
+<h2 id="DUCK">Duck!</h2> 
+
+<p>Ducking is the process of lowering your audio stream output volume to make transient audio from
+another app easier to hear without totally disrupting the audio from your own application.</p>
+
+<p>In the following code snippet lowers the volume on our media player object when we temporarily
+lose focus, then returns it to its previous level when we regain focus.</p>
+
+<pre>
+OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
+    public void onAudioFocusChange(int focusChange) {
+        if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
+            // Lower the volume
+        } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
+            // Raise it back to normal
+        }
+    }
+};
+</pre>
+
+<p>A loss of audio focus is the most important broadcast to react to, but not the only one. The
+system broadcasts a number of intents to alert you to changes in user’s audio experience.
+The next lesson demonstrates how to monitor them to improve the user’s overall experience.</p>
diff --git a/docs/html/training/managing-audio/audio-output.jd b/docs/html/training/managing-audio/audio-output.jd
new file mode 100644
index 0000000..d5d7e4b
--- /dev/null
+++ b/docs/html/training/managing-audio/audio-output.jd
@@ -0,0 +1,88 @@
+page.title=Dealing with Audio Output Hardware
+parent.title=Managing Audio Playback and Focus
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Managing Audio Focus
+previous.link=audio-focus.html
+
+@jd:body
+
+ 
+<div id="tb-wrapper"> 
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#CheckHardware">Check What Hardware is Being Used</a></li>
+  <li><a href="#HandleChanges">Handle Changes in the Audio Output Hardware</a></li>
+</ol>
+
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a></li>
+</ul>
+
+
+</div> 
+</div>
+
+<p>Users have a number of alternatives when it comes to enjoying the audio from their Android
+devices. Most devices have a built-in speaker, headphone jacks for wired headsets, and many also
+feature Bluetooth connectivity and support for A2DP audio. </p>
+
+ 
+<h2 id="CheckHardware">Check What Hardware is Being Used</h2> 
+ 
+<p>How your app behaves might be affected by which hardware its output is being routed to.</p>
+
+<p>You can query the {@link android.media.AudioManager} to determine if the audio is currently
+being routed to the device speaker, wired headset, or attached Bluetooth device as shown in the
+following snippet:</p>
+
+<pre>
+if (isBluetoothA2dpOn()) {
+    // Adjust output for Bluetooth.
+} else if (isSpeakerphoneOn()) {
+    // Adjust output for Speakerphone.
+} else if (isWiredHeadsetOn()) {
+    // Adjust output for headsets
+} else { 
+    // If audio plays and noone can hear it, is it still playing?
+}
+</pre>
+
+
+<h2 id="HandleChanges">Handle Changes in the Audio Output Hardware</h2> 
+
+<p>When a headset is unplugged, or a Bluetooth device disconnected, the audio stream
+automatically reroutes to the built in speaker. If you listen to your music at as high a volume as I
+do, that can be a noisy surprise.</p>
+
+<p>Luckily the system broadcasts an {@link android.media.AudioManager#ACTION_AUDIO_BECOMING_NOISY}
+intent when this happens. It’s good practice to register a {@link android.content.BroadcastReceiver}
+that listens for this intent whenever you’re playing audio. In the case of music players, users
+typically expect the playback to be paused&mdash;while for games you may choose to significantly
+lower the volume.</p>
+ 
+<pre>
+private class NoisyAudioStreamReceiver extends BroadcastReceiver {
+    &#64;Override
+    public void onReceive(Context context, Intent intent) {
+        if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
+            // Pause the playback
+        }
+    }
+}
+
+private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
+
+private void startPlayback() {
+    registerReceiver(myNoisyAudioStreamReceiver(), intentFilter);
+}
+
+private void stopPlayback() {
+    unregisterReceiver(myNoisyAudioStreamReceiver);
+}
+</pre>
diff --git a/docs/html/training/managing-audio/index.jd b/docs/html/training/managing-audio/index.jd
new file mode 100644
index 0000000..c7df39b
--- /dev/null
+++ b/docs/html/training/managing-audio/index.jd
@@ -0,0 +1,62 @@
+page.title=Managing Audio Playback and Focus
+
+trainingnavtop=true
+startpage=true
+next.title=Controlling Your App's Volume and Playback
+next.link=volume-playback.html
+
+@jd:body
+
+<div id="tb-wrapper"> 
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2> 
+<ul>
+  <li>Android 2.0 (API level 5) or higher</li>
+  <li>Experience with <a href="{@docRoot}guide/topics/media/mediaplayer.html">Media
+Playback</a></li>
+</ul>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a></li>
+</ul>
+
+</div> 
+</div>
+
+
+<p>If your app plays audio, it’s important that your users can control the audio in a predictable
+manner. To ensure a great user experience, it’s also important that your app manages the audio focus
+to ensure multiple apps aren’t playing audio at the same time.</p> 
+
+<p>After this class, you will be able to build apps that respond to hardware audio key presses, 
+which request audio focus when playing audio, and which respond appropriately to changes in audio
+focus caused by the system or other applications.</p> 
+
+
+
+
+<h2>Lessons</h2> 
+ 
+<!-- Create a list of the lessons in this class along with a short description of each lesson.
+These should be short and to the point. It should be clear from reading the summary whether someone
+will want to jump to a lesson or not.--> 
+ 
+<dl>
+  <dt><b><a href="volume-playback.html">Controlling Your App’s Volume and
+Playback</a></b></dt>
+  <dd>Learn how to ensure your users can control the volume of your app using the hardware or
+software volume controls and where available the play, stop, pause, skip, and previous media
+playback keys.</dd> 
+ 
+  <dt><b><a href="audio-focus.html">Managing Audio Focus</a></b></dt>
+  <dd>With multiple apps potentially playing audio it's important to think about how they should
+interact. To avoid every music app playing at the same time, Android uses audio focus to moderate
+audio playback. Learn how to request the audio focus, listen for a loss of audio focus, and how to
+respond when that happens.</dd> 
+ 
+  <dt><b><a href="audio-output.html">Dealing with Audio Output Hardware</a></b></dt>
+  <dd>Audio can be played from a number of sources. Learn how to find out where the audio is being
+played and how to handle a headset being disconnected during playback.</dd> 
+ </dl> 
\ No newline at end of file
diff --git a/docs/html/training/managing-audio/volume-playback.jd b/docs/html/training/managing-audio/volume-playback.jd
new file mode 100644
index 0000000..7038ddf
--- /dev/null
+++ b/docs/html/training/managing-audio/volume-playback.jd
@@ -0,0 +1,156 @@
+page.title=Controlling Your App’s Volume and Playback
+parent.title=Managing Audio Playback and Focus
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Managing Audio Focus
+next.link=audio-focus.html
+
+@jd:body
+
+ 
+<div id="tb-wrapper"> 
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#IdentifyStream">Identify Which Audio Stream to Use</a></li>
+  <li><a href="#HardwareVolumeKeys">Use Hardware Volume Keys to Control Your App’s Audio
+Volume</a></li>
+  <li><a href="#PlaybackControls">Use Hardware Playback Control Keys to Control Your App’s Audio
+Playback</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a></li>
+</ul>
+
+</div> 
+</div>
+
+
+ 
+<p>A good user experience is a predictable one. If your app plays media it’s important that your
+users can control the volume of your app using the hardware or software volume controls of their
+device, bluetooth headset, or headphones.</p>
+
+<p>Similarly, where appropriate and available, the play, stop, pause, skip, and previous media
+playback keys should perform their respective actions on the audio stream used by your app.</p>
+
+ 
+<h2 id="IdentifyStream">Identify Which Audio Stream to Use</h2> 
+ 
+<p>The first step to creating a predictable audio experience is understanding which audio stream
+your app will use.</p>
+
+<p>Android maintains a separate audio stream for playing music, alarms, notifications, the incoming
+call ringer, system sounds, in-call volume, and DTMF tones. This is done primarily to allow users to
+control the volume of each stream independently.</p>
+
+<p>Most of these streams are restricted to system events, so unless your app is a replacement alarm
+clock, you’ll almost certainly be playing your audio using the {@link
+android.media.AudioManager#STREAM_MUSIC} stream.</p>
+
+
+<h2 id="HardwareVolumeKeys">Use Hardware Volume Keys to Control Your App’s Audio Volume</h2> 
+
+<p>By default, pressing the volume controls modify the volume of the active audio stream. If your
+app isn't currently playing anything, hitting the volume keys adjusts the ringer volume.<p>
+    
+<p>If you've got a game or music app, then chances are good that when the user hits the volume keys
+they want to control the volume of the game or music, even if they’re currently between songs or
+there’s no music in the current game location.</p>
+
+<p>You may be tempted to try and listen for volume key presses and modify the volume of your
+audio stream that way. Resist the urge. Android provides the handy {@link
+android.app.Activity#setVolumeControlStream setVolumeControlStream()} method to direct volume key
+presses to the audio stream you specify.<p> 
+  
+<p>Having identified the audio stream your application
+will be using, you should set it as the volume stream target. You should make this call early in
+your app’s lifecycle&mdash;because you only need to call it once during the activity lifecycle, you
+should typically call it within the {@code onCreate()} method (of the {@link
+android.app.Activity} or {@link android.app.Fragment} that controls
+your media). This ensures that whenever your app is visible, the
+volume controls function as the user expects.<p>
+
+<pre>
+setVolumeControlStream(AudioManager.STREAM_MUSIC);
+</pre>
+
+
+<p>From this point onwards, pressing the volume keys on the device affect the audio stream you
+specify (in this case “music”) whenever the target activity or fragment is visible.</p>
+
+
+<h2 id="PlaybackControls">Use Hardware Playback Control Keys to Control Your App’s Audio
+Playback</h2> 
+
+<p>Media playback buttons such as play, pause, stop, skip, and previous are available on some
+handsets and many connected or wireless headsets. Whenever a user presses one of these hardware
+keys, the system broadcasts an intent with the {@link android.content.Intent#ACTION_MEDIA_BUTTON}
+action.</p>
+
+<p>To respond to media button clicks, you need to register a {@link
+android.content.BroadcastReceiver} in your manifest that listens for this action broadcast as shown
+below.</p>
+
+<pre>
+&lt;receiver android:name=".RemoteControlReceiver">
+    &lt;intent-filter>
+        &lt;action android:name="android.intent.action.MEDIA_BUTTON" />
+    &lt;/intent-filter>
+&lt;/receiver>
+</pre>
+
+<p>The receiver implementation itself needs to extract which key was pressed to cause the broadcast.
+The {@link android.content.Intent} includes this under the {@link
+android.content.Intent#EXTRA_KEY_EVENT} key, while the {@link android.view.KeyEvent} class includes
+a list {@code KEYCODE_MEDIA_*} static constants that represents each of the possible media
+buttons, such as {@link android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE} and {@link
+android.view.KeyEvent#KEYCODE_MEDIA_NEXT}.</p>
+
+<p>The following snippet shows how to extract the media button pressed and affects the media playback accordingly.</p>
+
+<pre>
+public class RemoteControlReceiver extends BroadcastReceiver {
+    &#64;Override
+    public void onReceive(Context context, Intent intent) {
+        if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
+            KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+            if (KeyEvent.KEYCODE_MEDIA_PLAY == event.getKeyCode()) {
+                // Handle key press.
+            }
+        }
+    }
+}
+</pre>
+
+<p>Because multiple applications might want to listen for media button presses, you must
+also programmatically control when your app should receive media button press events.</p>
+
+<p>The following code can be used within your app to register and de-register your media button
+event receiver using the {@link android.media.AudioManager}. When registered, your broadcast
+receiver is the exclusive receiver of all media button broadcasts.<p>
+
+<pre>
+AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
+...
+
+// Start listening for button presses
+am.registerMediaButtonEventReceiver(RemoteControlReceiver);
+...
+
+// Stop listening for button presses
+am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
+</pre>
+
+<p>Typically, apps should unregister most of their receivers whenever they become inactive or
+invisible (such as during the {@link android.app.Activity#onStop onStop()} callback). However, it’s
+not that simple for media playback apps&mdash;in fact, responding to media playback buttons is most
+important when your application isn’t visible and therefore can’t be controlled by the on-screen
+UI.</p>
+
+<p>A better approach is to register and unregister the media button event receiver when your
+application gains and losses the audio focus. This is covered in detail in the next lesson.</p>
diff --git a/docs/html/training/monitoring-device-state/battery-monitoring.jd b/docs/html/training/monitoring-device-state/battery-monitoring.jd
new file mode 100644
index 0000000..a442140
--- /dev/null
+++ b/docs/html/training/monitoring-device-state/battery-monitoring.jd
@@ -0,0 +1,156 @@
+page.title=Monitoring the Battery Level and Charging State
+parent.title=Monitoring Device State to Optimize Battery Life
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Determining and Monitoring the Docking State and Type
+next.link=docking-monitoring.html
+
+@jd:body
+ 
+<div id="tb-wrapper"> 
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#DetermineChargeState">Determine the Current Charging State</a></li>
+  <li><a href="#MonitorChargeState">Monitor Changes in Charging State</a></li>
+  <li><a href="#CurrentLevel">Determine the Current Battery Level</a></li>
+  <li><a href="#MonitorLevel">Monitor Significant Changes in Battery Level</a></li>
+</ol>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+</ul>
+
+</div> 
+</div>
+ 
+<p>When you're altering the frequency of your background updates to reduce the effect of those
+updates on battery life, checking the current battery level and charging state is a good place to
+start.</p>
+
+<p>The battery-life impact of performing application updates depends on the battery level and
+charging state of the device. The impact of performing updates while the device is charging over AC
+is negligible, so in most cases you can maximize your refresh rate whenever the device is connected
+to a wall charger. Conversely, if the device is discharging, reducing your update rate helps
+prolong the battery life.</p>
+
+<p>Similarly, you can check the battery charge level, potentially reducing the frequency of&mdash;or
+even stopping&mdash;your updates when the battery charge is nearly exhausted.</p>
+
+
+<h2 id="DetermineChargeState">Determine the Current Charging State</h2> 
+ 
+<p>Start by determining the current charge status. The {@link android.os.BatteryManager}
+broadcasts all battery and charging details in a sticky {@link android.content.Intent} that includes
+the charging status.</p>
+
+<p>Because it's a sticky intent, you don't need to register a {@link
+android.content.BroadcastReceiver}&mdash;by simply calling {@code registerReceiver} passing in
+{@code null} as the receiver as shown in the next snippet, the current battery status intent is
+returned. You could pass in an actual {@link android.content.BroadcastReceiver} object here, but
+we'll be handling updates in a later section so it's not necessary.</p>
+
+<pre>IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+Intent batteryStatus = context.registerReceiver(null, ifilter);</pre>
+
+<p>You can extract both the current charging status and, if the device is being charged, whether
+it's charging via USB or AC charger:<p>
+
+<pre>// Are we charging / charged?
+int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
+boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
+                     status == BatteryManager.BATTERY_STATUS_FULL;
+
+// How are we charging?
+int chargePlug = battery.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
+boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
+boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;</pre>
+
+<p>Typically you should maximize the rate of your background updates in the case where the device is
+connected to an AC charger, reduce the rate if the charge is over USB, and lower it
+further if the battery is discharging.</p>
+
+
+<h2 id="MonitorChargeState">Monitor Changes in Charging State</h2> 
+
+<p>The charging status can change as easily as a device can be plugged in, so it's important to
+monitor the charging state for changes and alter your refresh rate accordingly.</p>
+
+<p>The {@link android.os.BatteryManager} broadcasts an action whenever the device is connected or
+disconnected from power. It's important to to receive these events even while your app isn't
+running&mdash;particularly as these events should impact how often you start your app in order to
+initiate a background update&mdash;so you should register a {@link
+android.content.BroadcastReceiver} in your manifest to listen for both events by defining the
+{@link android.content.Intent#ACTION_POWER_CONNECTED} and {@link
+android.content.Intent#ACTION_POWER_DISCONNECTED} within an intent filter.</p>
+
+<pre>&lt;receiver android:name=".PowerConnectionReceiver">
+  &lt;intent-filter>
+    &lt;action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
+    &lt;action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
+  &lt;/intent-filter>
+&lt;/receiver></pre>
+
+<p>Within the associated {@link android.content.BroadcastReceiver} implementation, you can extract
+the current charging state and method as described in the previous step.</p>
+
+<pre>public class PowerConnectionReceiver extends BroadcastReceiver {
+    &#64;Override
+    public void onReceive(Context context, Intent intent) { 
+        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
+        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
+                            status == BatteryManager.BATTERY_STATUS_FULL;
+    
+        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
+        boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
+        boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;
+    }
+}</pre>
+
+
+<h2 id="CurrentLevel">Determine the Current Battery Level</h2> 
+
+<p>In some cases it's also useful to determine the current battery level. You may choose to reduce
+the rate of your background updates if the battery charge is below a certain level.</p>
+
+<p>You can find the current battery charge by extracting the current battery level and scale from
+the battery status intent as shown here:</p>
+
+<pre>int level = battery.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
+int scale = battery.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
+
+float batteryPct = level / (float)scale;</pre>
+
+
+<h2 id="MonitorLevel">Monitor Significant Changes in Battery Level</h2> 
+
+<p>You can't easily continually monitor the battery state, but you don't need to.</p>
+
+<p>Generally speaking, the impact of constantly monitoring the battery level has a greater
+impact on the battery than your app's normal behavior, so it's good practice to only monitor
+significant changes in battery level&mdash;specifically when the device enters or exits a low
+battery state.</p>
+
+<p>The manifest snippet below is extracted from the intent filter element within a broadcast
+receiver. The receiver is triggered whenever the device battery becomes low or exits the low
+condition by listening for {@link android.content.Intent#ACTION_BATTERY_LOW} and {@link
+android.content.Intent#ACTION_BATTERY_OKAY}.</p>
+
+<pre>&lt;receiver android:name=".BatteryLevelReceiver">
+&lt;intent-filter>
+  &lt;action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
+  &lt;action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
+  &lt;/intent-filter>
+&lt;/receiver></pre>
+
+<p>It is generally good practice to disable all your background updates when the battery is
+critically low. It doesn't matter how fresh your data is if the phone turns itself off before you
+can make use of it.</p>
+
+<p>In many cases, the act of charging a device is coincident with putting it into a dock. The next
+lesson shows you how to determine the current dock state and monitor for changes in device
+docking.</p>
+
diff --git a/docs/html/training/monitoring-device-state/connectivity-monitoring.jd b/docs/html/training/monitoring-device-state/connectivity-monitoring.jd
new file mode 100644
index 0000000..4c71279
--- /dev/null
+++ b/docs/html/training/monitoring-device-state/connectivity-monitoring.jd
@@ -0,0 +1,90 @@
+page.title=Determining and Monitoring the Connectivity Status
+parent.title=Monitoring Device State to Optimize Battery Life
+parent.link=index.html
+
+trainingnavtop=true
+
+previous.title=Determining and Monitoring the Docking State and Type
+previous.link=docking-monitoring.html
+next.title=Manipulating Broadcast Receivers On Demand
+next.link=manifest-receivers.html
+
+@jd:body
+
+<div id="tb-wrapper"> 
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#DetermineConnection">Determine if you Have an Internet Connection</a></li>
+  <li><a href="#DetermineType">Determine the Type of your Internet Connection</a></li>
+  <li><a href="#MonitorChanges">Monitor for Changes in Connectivity</a></li>
+</ol>
+
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+</ul>
+
+</div> 
+</div>
+
+<p>Some of the most common uses for repeating alarms and background services is to schedule regular
+updates of application data from Internet resources, cache data, or execute long running downloads.
+But if you aren't connected to the Internet, or the connection is too slow to complete your
+download, why both waking the device to schedule the update at all?</p>
+
+<p>You can use the {@link android.net.ConnectivityManager} to check that you're actually
+connected to the Internet, and if so, what type of connection is in place.</p>
+
+
+<h2 id="DetermineConnection">Determine if You Have an Internet Connection</h2> 
+ 
+<p>There's no need to schedule an update based on an Internet resource if you aren't connected to
+the Internet. The following snippet shows how to use the {@link android.net.ConnectivityManager} 
+to query the active network and determine if it has Internet connectivity.</p>
+
+<pre>ConnectivityManager cm =
+        (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ 
+NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
+boolean isConnected = activeNetwork.isConnectedOrConnecting();</pre>
+
+
+<h2 id="DetermineType">Determine the Type of your Internet Connection</h2> 
+
+<p>It's also possible to determine the type of Internet connection currently available.</p>
+
+<p>Device connectivity can be provided by mobile data, WiMAX, Wi-Fi, and ethernet connections. By
+querying the type of the active network, as shown below, you can alter your refresh rate based on
+the bandwidth available.</p>
+
+<pre>boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;</pre>
+
+<p>Mobile data costs tend to be significantly higher than Wi-Fi, so in most cases, your app's update
+rate should be lower when on mobile connections. Similarly, downloads of significant size should be
+suspended until you have a Wi-Fi connection.</p>
+
+<p>Having disabled your updates, it's important that you listen for changes in connectivity in order
+to resume them once an Internet connection has been established.</p>
+
+
+<h2 id="MonitorChanges">Monitor for Changes in Connectivity</h2> 
+
+<p>The {@link android.net.ConnectivityManager} broadcasts the {@link
+android.net.ConnectivityManager#CONNECTIVITY_ACTION} ({@code
+"android.net.conn.CONNECTIVITY_CHANGE"}) action whenever the connectivity details have changed. You
+can register a broadcast receiver in your manifest to listen for these changes and resume (or
+suspend) your background updates accordingly.</p>
+
+<pre>&lt;action android:name="android.net.conn.CONNECTIVITY_CHANGE"/></pre>
+
+<p>Changes to a device's connectivity can be very frequent&mdash;this broadcast is triggered
+every time you move between mobile data and Wi-Fi. As a result, it's good practice to monitor
+this broadcast only when you've previously suspended updates or downloads in order to resume them.
+It's generally sufficient to simply check for Internet connectivity before beginning an update and,
+should there be none, suspend further updates until connectivity is restored.</p>
+
+<p>This technique requires toggling broadcast receivers you've declard in the manifest, which is
+described in the next lesson.</p>
diff --git a/docs/html/training/monitoring-device-state/docking-monitoring.jd b/docs/html/training/monitoring-device-state/docking-monitoring.jd
new file mode 100644
index 0000000..6a4a9a8
--- /dev/null
+++ b/docs/html/training/monitoring-device-state/docking-monitoring.jd
@@ -0,0 +1,90 @@
+page.title=Determining and Monitoring the Docking State and Type
+parent.title=Monitoring Device State to Optimize Battery Life
+parent.link=index.html
+
+trainingnavtop=true
+previous.title= Monitoring the Battery Level and Charging State
+previous.link=battery-monitoring.html
+next.title= Determining and Monitoring the Connectivity Status
+next.link=connectivity-monitoring.html
+
+@jd:body
+
+<div id="tb-wrapper"> 
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#CurrentDockState">Request the Audio Focus</a></li>
+  <li><a href="#DockType">Determine the Current Dock Type</a></li>
+  <li><a href="#MonitorDockState">Monitor for Changes in the Dock State or Type</a></li>
+</ol>
+
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+</ul>
+
+</div> 
+</div>
+
+<p>Android devices can be docked into several different kinds of docks. These include car or home
+docks and digital versus analog docks. The dock-state is typically closely linked to the charging
+state as many docks provide power to docked devices.</p>
+
+<p>How the dock-state of the phone affects your update rate depends on your app. You may choose
+to increase the update frequency of a sports center app when it's in the desktop dock, or disable
+your updates completely if the device is car docked. Conversely, you may choose to maximize your
+updates while car docked if your background service is updating traffic conditions.</p>
+
+<p>The dock state is also broadcast as a sticky {@link android.content.Intent}, allowing you to
+query if the device is docked or not, and if so, in which kind of dock.</p>
+
+
+<h2 id="CurrentDockState">Determine the Current Docking State</h2> 
+ 
+<p>The dock-state details are included as an extra in a sticky broadcast of the {@link
+android.content.Intent#ACTION_DOCK_EVENT} action. Because it's sticky, you don't need to register a
+{@link android.content.BroadcastReceiver}. You can simply call {@link
+android.content.Context#registerReceiver registerReceiver()} passing in {@code null} as the
+broadcast receiver as shown in the next snippet.</p>
+
+<pre>IntentFilter ifilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
+Intent dockStatus = context.registerReceiver(null, ifilter);</pre>
+
+<p>You can extract the current docking status from the {@code EXTRA_DOCK_STATE} extra:<p>
+
+<pre>int dockState = battery.getIntExtra(EXTRA_DOCK_STATE, -1);
+boolean isDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;</pre>
+
+
+<h2 id="DockType">Determine the Current Dock Type</h2> 
+
+<p>If a device is docked, it can be docked in any one of four different type of dock: 
+<ul><li>Car</li>
+<li>Desk</li>
+<li>Low-End (Analog) Desk</li>
+<li>High-End (Digital) Desk</li></ul></p>
+
+<p>Note that the latter two options were only introduced to Android in API level 11, so it's good
+practice to check for all three where you are only interested in the type of dock rather than it
+being digital or analog specifically:</p>
+
+<pre>boolean isCar = dockState == EXTRA_DOCK_STATE_CAR;
+boolean isDesk = dockState == EXTRA_DOCK_STATE_DESK || 
+                 dockState == EXTRA_DOCK_STATE_LE_DESK ||
+                 dockState == EXTRA_DOCK_STATE_HE_DESK;</pre>
+
+
+<h2 id="MonitorDockState">Monitor for Changes in the Dock State or Type</h2> 
+
+<p>Whenever the the device is docked or undocked, the {@link
+android.content.Intent#ACTION_DOCK_EVENT} action is broadcast. To monitor changes in the
+device's dock-state, simply register a broadcast receiver in your application manifest as shown in
+the snippet below:</p>
+
+<pre>&lt;action android:name="android.intent.action.ACTION_DOCK_EVENT"/></pre>
+
+<p>You can extract the dock type and state within the receiver implementation using the same
+techniques described in the previous step.</p>
diff --git a/docs/html/training/monitoring-device-state/index.jd b/docs/html/training/monitoring-device-state/index.jd
new file mode 100644
index 0000000..e92e1e8
--- /dev/null
+++ b/docs/html/training/monitoring-device-state/index.jd
@@ -0,0 +1,63 @@
+page.title=Monitoring Device State to Optimize Battery Life
+
+trainingnavtop=true
+startpage=true
+next.title=Monitoring the Battery Level and Charging State
+next.link=battery-monitoring.html
+
+@jd:body
+
+<div id="tb-wrapper"> 
+<div id="tb">
+
+<h2>Dependencies and prerequisites</h2> 
+<ul>
+  <li>Android 2.0 (API level 5) or higher</li>
+  <li>Experience with <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a></li>
+</ul>
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a>
+</ul>
+
+</div> 
+</div>
+
+<p>For your app to be a good citizen, it should seek to limit its impact on the battery life of its
+host device. After this class you will be able to build apps that monitor modify their functionality
+and behavior based on the state of the host device.</p>
+
+<p>By taking steps such as disabling background service updates when you lose connectivity, or
+reducing the rate of such updates when the battery level is low, you can ensure that the impact of
+your app on battery life is minimized, without compromising the user experience.</p>
+
+<h2>Lessons</h2> 
+ 
+<!-- Create a list of the lessons in this class along with a short description of each lesson.
+These should be short and to the point. It should be clear from reading the summary whether someone
+will want to jump to a lesson or not.--> 
+ 
+<dl>
+  <dt><b><a href="battery-monitoring.html">Monitoring the Battery Level and Charging State</a></b></dt>
+  <dd>Learn how to alter your app's update rate by determining, and monitoring, the current battery
+level and changes in charging state.</dd>
+
+  <dt><b><a href="docking-monitoring.html">Determining and Monitoring the Docking State and
+Type</a></b></dt>
+  <dd>Optimal refresh rates can vary based on how the host device is being used. Learn how to
+determine, and monitor, the docking state and type of dock being used to affect your app's
+behavior.</dd>
+
+  <dt><b><a href="connectivity-monitoring.html">Determining and Monitoring the Connectivity
+Status</a></b></dt>
+  <dd>Without Internet connectivity you can't update your app from an online source. Learn how to  
+check the connectivity status to alter your background update rate. You'll also learn to check for
+Wi-Fi or mobile connectivity before beginning high-bandwidth operations.</dd>
+
+  <dt><b><a href="manifest-receivers.html">Manipulating Broadcast Receivers On Demand</a></b></dt>
+  <dd>Broadcast receivers that you've declared in the manifest can be toggled at runtime to disable
+those that aren't necessary due to the current device state. Learn to improve
+efficiency by toggling and cascading state change receivers and delay actions until the device is in
+a specific state.</dd>
+</dl> 
\ No newline at end of file
diff --git a/docs/html/training/monitoring-device-state/manifest-receivers.jd b/docs/html/training/monitoring-device-state/manifest-receivers.jd
new file mode 100644
index 0000000..bf5462a
--- /dev/null
+++ b/docs/html/training/monitoring-device-state/manifest-receivers.jd
@@ -0,0 +1,64 @@
+page.title=Manipulating Broadcast Receivers On Demand
+parent.title=Monitoring Device State to Optimize Battery Life
+parent.link=index.html
+
+trainingnavtop=true
+
+previous.title=Determining and Monitoring the Connectivity Status
+previous.link=connectivity-monitoring.html
+
+@jd:body
+
+<div id="tb-wrapper"> 
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="ToggleReceivers">Toggle and Cascade State Change Receivers to Improve
+Efficiency</a></li>
+</ol>
+
+
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+</ul>
+
+</div> 
+</div>
+
+<p>The simplest way to monitor device state changes is to create a {@link
+android.content.BroadcastReceiver} for each state you're monitoring and register each of them in
+your application manifest. Then within each of these receivers you simply reschedule your recurring
+alarms based on the current device state.</p>
+
+<p>A side-effect of this approach is that your app will wake the device each time any of these
+receivers is triggered&mdash;potentially much more frequently than required.</p>
+
+<p>A better approach is to disable or enable the broadcast receivers at runtime. That way you can
+use the receivers you declared in the manifest as passive alarms that are triggered by system events
+only when necessary.</p>
+ 
+
+<h2 id="ToggleReceivers">Toggle and Cascade State Change Receivers to Improve Efficiency </h2> 
+ 
+<p>Use can use the {@link android.content.pm.PackageManager} to toggle the enabled state on any
+component defined in the manifest, including whichever broadcast receivers you wish to enable or
+disable as shown in the snippet below:</p>
+
+<pre>ComponentName receiver = new ComponentName(context, myReceiver.class);
+
+PackageManager pm = context.getPackageManager();
+
+pm.setComponentEnabledSetting(receiver,
+        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+        PackageManager.DONT_KILL_APP)</pre>
+
+<p>Using this technique, if you determine that connectivity has been lost, you can disable all of
+your receivers except the connectivity-change receiver. Conversely, once you are connected you can
+stop listening for connectivity changes and simply check to see if you're online immediately before
+performing an update and rescheduling a recurring update alarm.</p>
+
+<p>You can use the same technique to delay a download that requires higher bandwidth to complete.  
+Simply enable a broadcast receiver that listens for connectivity changes and initiates the
+download only after you are connected to Wi-Fi.</p>
diff --git a/docs/html/training/sharing/index.jd b/docs/html/training/sharing/index.jd
new file mode 100644
index 0000000..cb133c3
--- /dev/null
+++ b/docs/html/training/sharing/index.jd
@@ -0,0 +1,46 @@
+page.title=Sharing Content
+
+trainingnavtop=true
+startpage=true
+next.title=Sending Content to Other Apps
+next.link=send.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
+<h2>Dependencies and prerequisites</h2>
+<ul>
+  <li>Android 1.0 or higher (greater requirements where noted)</li>
+  <li>Experience with <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
+Intent Filters</a></li>
+</ul>
+
+</div>
+</div>
+
+ 
+<p>One of the great things about Android applications is their ability to communicate and
+integrate with each other. Why reinvent functionality that isn't core to your application when it
+already exists in another application?</p> 
+
+<p>This class shows some common ways you can send and receive content between
+applications using {@link android.content.Intent} APIs and the {@link
+android.view.ActionProvider}.</p>
+
+
+<h2>Lessons</h2>
+ 
+<dl> 
+  <dt><b><a href="send.html">Sending Content to Other Apps</a></b></dt> 
+    <dd>Learn how to set up your application to be able to send text and binary data to other
+applications with intents.</dd> 
+ 
+  <dt><b><a href="receive.html">Receiving Content from Other Apps</a></b></dt> 
+    <dd>Learn how to set up your application to receive text and binary data from intents.</dd> 
+                                    
+  <dt><b><a href="shareaction.html">Adding an Easy Share Action</a></b></dt> 
+    <dd>Learn how to add a "share" action item to your action bar.</dd> 
+</dl> 
diff --git a/docs/html/training/sharing/receive.jd b/docs/html/training/sharing/receive.jd
new file mode 100644
index 0000000..b2cac30
--- /dev/null
+++ b/docs/html/training/sharing/receive.jd
@@ -0,0 +1,149 @@
+page.title=Receiving Content from Other Apps
+parent.title=Sharing Content
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Sending Content to Other Apps
+previous.link=send.html
+next.title=Adding an Easy Share Action
+next.link=shareaction.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#update-manifest">Update Your Manifest</a></li>
+  <li><a href="#handling-content">Handle the Incoming Content</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
+Intent Filters</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>Just as your application can send data to other applications, so too can it easily receive data 
+from applications. Think about how users interact with your application, and what data types you 
+want to receive from other applications. For example, a social networking application would likely 
+be interested in receiving text content, like an interesting web URL, from another app. The 
+<a href="https://market.android.com/details?id=com.google.android.apps.plus">Google+ Android
+application</a> 
+accepts both text <em>and</em> single or multiple images. With this app, a user can easily start a 
+new Google+ post with photos from the Android Gallery app.</p>
+
+
+<h2 id="update-manifest">Update Your Manifest</h2>
+
+<p>Intent filters inform the system what intents an application component is willing to accept. 
+Just as you constructed an intent with action {@link android.content.Intent#ACTION_SEND} in the 
+<a href="{@docRoot}training/sharing/send.html">Send Content to Other Apps Using Intents</a> 
+lesson, you create intent filters in order to be able to receive intents with this action. You 
+define an intent filter in your manifest, using the 
+<code><a
+href="{@docRoot}guide/topics/intents/intents-filters.html#ifs">&lt;intent-filter&gt;</a></code> 
+element. For example, if your application handles receiving text content, a single image of any 
+type, or multiple images of any type, your manifest would look like:</p>
+
+<pre>
+&lt;activity android:name=&quot;.ui.MyActivity&quot; &gt;
+    &lt;intent-filter&gt;
+        &lt;action android:name=&quot;android.intent.action.SEND&quot; /&gt;
+        &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
+        &lt;data android:mimeType=&quot;image/*&quot; /&gt;
+    &lt;/intent-filter&gt;
+    &lt;intent-filter&gt;
+        &lt;action android:name=&quot;android.intent.action.SEND&quot; /&gt;
+        &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
+        &lt;data android:mimeType=&quot;text/plain&quot; /&gt;
+    &lt;/intent-filter&gt;
+    &lt;intent-filter&gt;
+        &lt;action android:name=&quot;android.intent.action.SEND_MULTIPLE&quot; /&gt;
+        &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
+        &lt;data android:mimeType=&quot;image/*&quot; /&gt;
+    &lt;/intent-filter&gt;
+&lt;/activity&gt;
+</pre>
+
+<p class="note"><strong>Note:</strong> For more information on intent filters and intent resolution 
+please read <a href="{@docRoot}guide/topics/intents/intents-filters.html#ifs">Intents and Intent
+Filters</a></p>
+
+<p>When another application tries to share any of these things by constructing an intent and passing
+it to {@link android.content.Context#startActivity(android.content.Intent) startActivity()}, your
+application will be listed as an option in the intent chooser (see figure 1). If the user selects
+your application, the corresponding activity (<code>.ui.MyActivity</code> in the example above) will
+be started. It is then up to you to handle the content appropriately within your code and UI.</p>
+
+
+<h2 id="handling-content">Handle the Incoming Content</h2>
+
+<p>To handle the content delivered by an {@link android.content.Intent}, start by calling {@link
+android.content.Intent#getIntent(String) getIntent()} 
+to get {@link android.content.Intent} object. Once you have the object, you can examine its 
+contents to determine what to do next. Keep in mind that if this activity can be started from other 
+parts of the system, such as the launcher, then you will need to take this into consideration when 
+examining the intent.</p>
+
+<pre>
+void onCreate (Bundle savedInstanceState) {
+    ...
+    // Get intent, action and MIME type
+    Intent intent = getIntent();
+    String action = intent.getAction();
+    String type = intent.getType();
+
+    if (Intent.ACTION_SEND.equals(action) &amp;&amp; type != null) {
+        if (&quot;text/plain&quot;.equals(type)) {
+            handleSendText(intent); // Handle text being sent
+        } else if (type.startsWith(&quot;image/&quot;)) {
+            handleSendImage(intent); // Handle single image being sent
+        }
+    } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) &amp;&amp; type != null) {
+        if (type.startsWith(&quot;image/&quot;)) {
+            handleSendMultipleImages(intent); // Handle multiple images being sent
+        }
+    } else {
+        // Handle other intents, such as being started from the home screen
+    }
+    ...
+}
+
+void handleSendText(Intent intent) {
+    String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
+    if (sharedText != null) {
+        // Update UI to reflect text being shared
+    }
+}
+
+void handleSendImage(Intent intent) {
+    Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
+    if (imageUri != null) {
+        // Update UI to reflect image being shared
+    }
+}
+
+void handleSendMultipleImages(Intent intent) {
+    ArrayList&lt;Uri&gt; imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+    if (imageUris != null) {
+        // Update UI to reflect multiple images being shared
+    }
+}
+</pre>
+
+<p class="caution"><strong>Caution:</strong> Take extra care to check the incoming data, you never
+know what some other application may send you. For example, the wrong MIME type might be set, or the
+image being sent might be extremely large. Also, remember to process binary data in a separate
+thread rather than the main ("UI") thread.</p>
+
+<p>Updating the UI can be as simple as populating an {@link android.widget.EditText}, or it can 
+be more complicated like applying an interesting photo filter to an image. It's really specific 
+to your application what happens next.</p>
+
diff --git a/docs/html/training/sharing/send.jd b/docs/html/training/sharing/send.jd
new file mode 100644
index 0000000..d151ed0
--- /dev/null
+++ b/docs/html/training/sharing/send.jd
@@ -0,0 +1,194 @@
+page.title=Sending Content to Other Apps
+parent.title=Sharing Content
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Receiving Content from Other Apps
+next.link=receive.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#send-text-content">Send Text Content</a></li>
+  <li><a href="#send-binary-content">Send Binary Content</a></li>
+  <li><a href="#send-multiple-content">Send Multiple Pieces of Content</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
+Intent Filters</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>When you construct an intent, you must specify the action you want the intent to "trigger." 
+Android defines several actions, including {@link android.content.Intent#ACTION_SEND} which, as 
+you can probably guess, indicates that the intent is sending data from one activity to another, 
+even across process boundaries. To send data to another activity, all you need to do is speicify 
+the data and its type, the system will identify compatible receiving activities and display them 
+to the user (if there are multiple options) or immediately start the activity (if there is only 
+one option). Similarly, you can advertise the data types that your activities support receiving 
+from other applications by specifying them in your manifest.</p>
+
+<p>Sending and receiving data between applications with intents is most commonly used for social 
+sharing of content. Intents allow users to share information quickly and easily, using their 
+favorite social applications.</p>
+
+<p><strong>Note:</strong> The best way to add a share action item to an 
+{@link android.app.ActionBar} is to use {@link android.widget.ShareActionProvider}, which became 
+available in API level 14. {@link android.widget.ShareActionProvider} is discussed in the lesson 
+about <a href="shareaction.html">Adding an Easy Share Action</a>.</p>
+
+
+<h2 id="send-text-content">Send Text Content</h2>
+
+<div class="figure" style="width:220px">
+<img src="{@docRoot}images/training/sharing/share-text-screenshot.png" alt="" id="figure1" />
+<p class="img-caption">
+  <strong>Figure 1.</strong> Screenshot of {@link android.content.Intent#ACTION_SEND} intent chooser
+on a handset.
+</p>
+</div>
+
+<p>The most straightforward and common use of the {@link android.content.Intent#ACTION_SEND} 
+action is sending text content from one activity to another. For example, the built-in Browser 
+app can share the URL of the currently-displayed page as text with any application. This is useful 
+for sharing an article or website with friends via email or social networking. Here is the code to 
+implement this type of sharing:</p>
+
+<pre>
+Intent sendIntent = new Intent();
+sendIntent.setAction(Intent.ACTION_SEND);
+sendIntent.putExtra(Intent.EXTRA_TEXT, &quot;This is my text to send.&quot;);
+sendIntent.setType(&quot;text/plain&quot;);
+startActivity(sendIntent);
+</pre>
+
+<p>If there's an installed application with a filter that matches 
+{@link android.content.Intent#ACTION_SEND} and MIME type text/plain, the Android system will run 
+it; if more than one application matches, the system displays a disambiguation dialog (a "chooser") 
+that allows the user to choose an app. If you call 
+{@link android.content.Intent#createChooser(android.content.Intent, CharSequence)
+Intent.createChooser()} 
+for the intent, Android will <strong>always</strong> display the chooser. This has some
+advantages:</p>
+
+<ul>
+  <li>Even if the user has previously selected a default action for this intent, the chooser will
+still be displayed.</li>
+  <li>If no applications match, Android displays a system message.</li>
+  <li>You can specify a title for the chooser dialog.</li>
+</ul>
+
+<p>Here's the updated code:</p>
+
+<pre>
+Intent sendIntent = new Intent();
+sendIntent.setAction(Intent.ACTION_SEND);
+sendIntent.putExtra(Intent.EXTRA_TEXT, &quot;This is my text to send.&quot;);
+sendIntent.setType(&quot;text/plain&quot;);
+startActivity(<strong>Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)</strong>);
+</pre>
+
+<p>The resulting dialog is shown in figure 1.</p>
+
+<p>Optionally, you can set some standard extras for the intent: 
+{@link android.content.Intent#EXTRA_EMAIL}, {@link android.content.Intent#EXTRA_CC}, 
+{@link android.content.Intent#EXTRA_BCC}, {@link android.content.Intent#EXTRA_SUBJECT}. However, 
+if the receiving application is not designed to use them, nothing will happen. You can use 
+custom extras as well, but there's no effect unless the receiving application understands them. 
+Typically, you'd use custom extras defined by the receiving application itself.</p>
+
+<p class="note"><strong>Note:</strong> Some e-mail applications, such as Gmail, expect a 
+{@link java.lang.String String[]} for extras like {@link android.content.Intent#EXTRA_EMAIL} and 
+{@link android.content.Intent#EXTRA_CC}, use 
+{@link android.content.Intent#putExtra(String,String[]) putExtra(String, String[])} to add these 
+to your intent.</p>
+
+
+<h2 id="send-binary-content">Send Binary Content</h2>
+
+<p>Binary data is shared using the {@link android.content.Intent#ACTION_SEND} action combined with
+setting the appropriate MIME type and placing the URI to the data in an extra named {@link
+android.content.Intent#EXTRA_STREAM}. This is commonly used to share an image but can be used to
+share any type of binary content:</p>
+
+<pre>
+Intent shareIntent = new Intent();
+shareIntent.setAction(Intent.ACTION_SEND);
+shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
+shareIntent.setType(&quot;image/jpeg&quot;);
+startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
+</pre>
+
+<p>Note the following:</p>
+<ul>
+  <li>You can use a MIME type of {@code "*/*"}, but this will only match activities that are able to
+handle generic data streams.</li>
+  <li>The receiving application needs permission to access the data the {@link android.net.Uri}
+points to. There are a number of ways to handle this:
+  <ul>
+    <li>Write the data to a file on external/shared storage (such as the SD card), which all apps
+can read. Use {@link android.net.Uri#fromFile(java.io.File) Uri.fromFile()} to create the
+{@link android.net.Uri} that can be passed to the share intent. However, keep in mind that not
+all applications process a {@code file://} style {@link android.net.Uri}.</li>
+    <li>Write the data to a file in your own application directory using {@link
+android.content.Context#openFileOutput(java.lang.String, int) openFileOutput()} with mode {@link
+android.content.Context#MODE_WORLD_READABLE} after which {@link
+android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()} can be used to
+return a {@link java.io.File}. As with the previous option, {@link
+android.net.Uri#fromFile(java.io.File) Uri.fromFile()} will create a {@code file://} style {@link
+android.net.Uri} for your share intent.</li>
+    <li>Media files like images, videos and audio can be scanned and added to the system {@link
+android.provider.MediaStore} using {@link
+android.media.MediaScannerConnection#scanFile(android.content.Context, java.lang.String[],
+java.lang.String[], android.media.MediaScannerConnection.OnScanCompletedListener) scanFile()}. The
+{@link
+android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted(java.lang.String,
+android.net.Uri) onScanCompleted()} callback returns a {@code content://} style {@link
+android.net.Uri} suitable for including in your share intent.</li>
+    <li>Images can be inserted into the system {@link android.provider.MediaStore} using {@link
+android.provider.MediaStore.Images.Media#insertImage(android.content.ContentResolver,
+android.graphics.Bitmap, java.lang.String, java.lang.String) insertImage()} which will return a
+{@code content://} style {@link android.net.Uri} suitable for including in a share intent.</li>
+    <li>Store the data in your own {@link android.content.ContentProvider}, make sure that other
+apps have the correct permission to access your provider (or use <a
+href="{@docRoot}guide/topics/security/security.html#uri">per-URI permissions</a>).</li>
+  </ul>
+  </li>
+</ul>
+
+
+<h2 id="send-multiple-content">Send Multiple Pieces of Content</h2>
+
+<p>To share multiple pieces of content, use the {@link android.content.Intent#ACTION_SEND_MULTIPLE}
+action together with a list of URIs pointing to the content. The MIME type varies according to the
+mix of content you're sharing. For example, if you share 3 JPEG images, the type is still {@code
+"image/jpeg"}. For a mixture of image types, it should be {@code "image/*"} to match an activity
+that handles any type of image. You should only use {@code "*/*"} if you're sharing out a wide
+variety of types. As previously stated, it's up to the receiving application to parse and process
+your data. Here's an example:</p>
+
+<pre>
+ArrayList&lt;Uri&gt; imageUris = new ArrayList&lt;Uri&gt;();
+imageUris.add(imageUri1); // Add your image URIs here
+imageUris.add(imageUri2);
+
+Intent shareIntent = new Intent();
+shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
+shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
+shareIntent.setType(&quot;image/*&quot;);
+startActivity(Intent.createChooser(shareIntent, &quot;Share images to..&quot;));
+</pre>
+
+<p>As before, make sure the provided {@link android.net.Uri URIs} point to data that a receiving
+application can access.</p>
+
diff --git a/docs/html/training/sharing/shareaction.jd b/docs/html/training/sharing/shareaction.jd
new file mode 100644
index 0000000..f6be745
--- /dev/null
+++ b/docs/html/training/sharing/shareaction.jd
@@ -0,0 +1,115 @@
+page.title=Adding an Easy Share Action
+parent.title=Sharing Content
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Receiving Content from Other Apps
+previous.link=receive.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#update-menus">Update Menu Declarations</a></li>
+  <li><a href="#set-share-intent">Set the Share Intent</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>Implementing an effective and user friendly share action in your {@link android.app.ActionBar} 
+is made even easier with the introduction of {@link  android.view.ActionProvider} in Android 4.0
+(API Level 14). An {@link android.view.ActionProvider}, once attached to a menu item in the action
+bar, handles both the appearance and behavior of that item. In the case of {@link
+android.widget.ShareActionProvider}, you provide a share intent and it does the rest.</p>
+
+<p class="note"><strong>Note:&nbsp;</strong> {@link android.widget.ShareActionProvider} is available
+starting with API Level 14 and higher.</p>
+
+
+<div class="figure" style="width:200px">
+<img src="{@docRoot}images/ui/actionbar-shareaction.png" alt="" id="figure1" />
+<p class="img-caption">
+  <strong>Figure 1.</strong> The {@link android.widget.ShareActionProvider} in the Gallery app.
+</p>
+</div>
+
+<h2 id="update-menus">Update Menu Declarations</h2>
+
+<p>To get started with {@link android.widget.ShareActionProvider ShareActionProviders}, define the <code>android:actionProviderClass</code> attribute for the corresponding <code>&lt;item&gt;</code> in your <a href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a> file:</p>
+
+<pre>
+&lt;menu xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;
+    &lt;item android:id=&quot;@+id/menu_item_share&quot;
+        android:showAsAction=&quot;ifRoom&quot;
+        android:title=&quot;Share&quot;
+        <strong>android:actionProviderClass=&quot;android.widget.ShareActionProvider&quot;</strong> /&gt;
+    ...
+&lt;/menu&gt;
+</pre>
+
+<p>This delegates responsibility for the item's appearance and function to 
+{@link android.widget.ShareActionProvider}. However, you will need to tell the provider what you 
+would like to share.</p>
+
+
+<h2 id="set-share-intent">Set the Share Intent</h2>
+
+<p>In order for {@link android.widget.ShareActionProvider} to function, you must provide it a share
+intent. This share intent should be the same as described in the <a
+href="{@docRoot}training/sharing/send.html">Sending Content to Other Apps</a>
+lesson, with action {@link android.content.Intent#ACTION_SEND} and additional data set via extras
+like {@link android.content.Intent#EXTRA_TEXT} and {@link android.content.Intent#EXTRA_STREAM}. To
+assign a share intent, first find the corresponding {@link android.view.MenuItem} while inflating
+your menu resource in your {@link android.app.Activity} or {@link android.app.Fragment}. Next, call
+{@link android.view.MenuItem#getActionProvider() MenuItem.getActionProvider()} to retreive an
+instance of {@link android.widget.ShareActionProvider}. Use {@link
+android.widget.ShareActionProvider#setShareIntent(android.content.Intent) setShareIntent()} to
+update the share intent associated with that action item. Here's an example:</p>
+
+<pre>
+private ShareActionProvider mShareActionProvider;
+...
+
+&#64;Override
+public boolean onCreateOptionsMenu(Menu menu) {
+    // Inflate menu resource file.
+    getMenuInflater().inflate(R.menu.share_menu, menu);
+
+    // Locate MenuItem with ShareActionProvider
+    MenuItem item = menu.findItem(R.id.menu_item_share);
+
+    // Fetch and store ShareActionProvider
+    mShareActionProvider = (ShareActionProvider) item.getActionProvider();
+
+    // Return true to display menu
+    return true;
+}
+
+// Call to update the share intent
+private void setShareIntent(Intent shareIntent) {
+    if (mShareActionProvider != null) {
+        mShareActionProvider.setShareIntent(shareIntent);
+    }
+}
+</pre>
+
+<p>You may only need to set the share intent once during the creation of your menus, or you may 
+want to set it and then update it as the UI changes. For example, when you view photos full screen 
+in the Gallery app, the sharing intent changes as you flip between photos.</p>
+
+<p>For further discussion about the {@link android.widget.ShareActionProvider}, see the <a
+href="{@docRoot}guide/topics/ui/actionbar.html#ActionProvider">Action Bar</a> guide.</p>
+
+