Merge "Add continuous focus mode constant." into kraken
diff --git a/Android.mk b/Android.mk
index 8f968d8..f63cedf 100644
--- a/Android.mk
+++ b/Android.mk
@@ -406,11 +406,15 @@
                 -samplecode $(sample_dir)/SampleSyncAdapter \
                             resources/samples/SampleSyncAdapter "Sample Sync Adapter" \
 		-samplecode $(sample_dir)/SearchableDictionary \
-		            resources/samples/SearchableDictionary "Searchable Dictionary" \
+		            resources/samples/SearchableDictionary "Searchable Dictionary v2" \
 		-samplecode $(sample_dir)/Snake \
 		            resources/samples/Snake "Snake" \
 		-samplecode $(sample_dir)/SoftKeyboard \
 		            resources/samples/SoftKeyboard "Soft Keyboard" \
+		-samplecode $(sample_dir)/Spinner  \
+		            resources/samples/Spinner "Spinner" \
+		-samplecode $(sample_dir)/SpinnerTest \
+		            resources/samples/SpinnerTest "SpinnerTest" \
 		-samplecode $(sample_dir)/Wiktionary \
 		            resources/samples/Wiktionary "Wiktionary" \
 		-samplecode $(sample_dir)/WiktionarySimple \
diff --git a/camera/libcameraservice/Android.mk b/camera/libcameraservice/Android.mk
index 624b23a..a0d6ee1 100644
--- a/camera/libcameraservice/Android.mk
+++ b/camera/libcameraservice/Android.mk
@@ -2,6 +2,11 @@
 
 # Set USE_CAMERA_STUB if you don't want to use the hardware camera.
 
+# force these builds to use camera stub only
+ifneq ($(filter sooner generic sim,$(TARGET_DEVICE)),)
+  USE_CAMERA_STUB:=true
+endif
+
 ifeq ($(USE_CAMERA_STUB),true)
   INCLUDE_CAMERA_STUB:=true
   INCLUDE_CAMERA_HARDWARE:=false
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a76c70c..86bfe94 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2257,7 +2257,7 @@
 
     <!-- Strings for tethered notification -->
     <!-- Shown when the device is tethered -->
-    <string name="tethered_notification_title">Tethering active</string>
+    <string name="tethered_notification_title">Tethering or hotspot active</string>
     <string name="tethered_notification_message">Touch to configure</string>
 
     <!-- Strings for throttling notification -->
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index c067b80..245c67c 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -7,9 +7,9 @@
 # Include all test java files.
 LOCAL_SRC_FILES := \
 	$(call all-java-files-under, src) \
+	$(call all-Iaidl-files-under, src) \
 	$(call all-java-files-under, DisabledTestApp/src) \
-	$(call all-java-files-under, EnabledTestApp/src) \
-	src/android/os/IAidlTest.aidl
+	$(call all-java-files-under, EnabledTestApp/src)
 
 LOCAL_STATIC_JAVA_LIBRARIES += android-common
 
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 30855d1..a77717f 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1179,8 +1179,11 @@
         <!-- Application components used for os tests -->
 
         <service android:name="android.os.MessengerService"
-                android:process=":messengerService">
-        </service>
+                android:process=":messengerService" />
+
+        <!-- Used by BinderThreadPriorityTest -->
+        <service android:name="android.os.BinderThreadPriorityService"
+                android:process=":BinderThreadPriorityService" />
 
         <!-- Application components used for search manager tests -->
 
@@ -1198,13 +1201,6 @@
                 android:authorities="android.app.SuggestionProvider">
         </provider>
 
-        <!-- Used to test IPC. -->
-        <service android:name="com.android.frameworks.coretests.binder.BinderTestService"
-                 android:process="binder.BinderTestService" />
-        <service android:name="com.android.frameworks.coretests.binder.BinderPerformanceService"
-                 android:process="binder.BinderPerformanceService" />
-        <service android:name="com.android.frameworks.coretests.binder.BinderVsMessagingService"
-                 android:process="binder.BinderVsMessagingService" />
     </application>
 
     <instrumentation
diff --git a/core/tests/coretests/src/android/os/BinderThreadPriorityService.java b/core/tests/coretests/src/android/os/BinderThreadPriorityService.java
new file mode 100644
index 0000000..47a4483
--- /dev/null
+++ b/core/tests/coretests/src/android/os/BinderThreadPriorityService.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.app.Service;
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Service used by {@link BinderThreadPriorityTest} to verify
+ * the conveyance of thread priorities over Binder.
+ */
+public class BinderThreadPriorityService extends Service {
+    private static final String TAG = "BinderThreadPriorityService";
+
+    private final IBinderThreadPriorityService.Stub mBinder =
+            new IBinderThreadPriorityService.Stub() {
+        public int getThreadPriority() {
+            return Process.getThreadPriority(Process.myTid());
+        }
+
+        public String getThreadSchedulerGroup() {
+            return BinderThreadPriorityTest.getSchedulerGroup();
+        }
+
+        public void callBack(IBinderThreadPriorityService recurse) {
+            try {
+                recurse.callBack(this);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Binder callback failed", e);
+            }
+        }
+
+        public void setPriorityAndCallBack(int priority, IBinderThreadPriorityService recurse) {
+            Process.setThreadPriority(priority);
+            try {
+                recurse.callBack(this);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Binder callback failed", e);
+            }
+        }
+    };
+
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+}
diff --git a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
new file mode 100644
index 0000000..7a4980a
--- /dev/null
+++ b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Test whether Binder calls inherit thread priorities correctly.
+ */
+public class BinderThreadPriorityTest extends AndroidTestCase {
+    private static final String TAG = "BinderThreadPriorityTest";
+    private IBinderThreadPriorityService mService;
+    private int mSavedPriority;
+
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            synchronized (BinderThreadPriorityTest.this) {
+                mService = IBinderThreadPriorityService.Stub.asInterface(service);
+                BinderThreadPriorityTest.this.notifyAll();
+            }
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+            mService = null;
+        }
+    };
+
+    private static class ServiceStub extends IBinderThreadPriorityService.Stub {
+        public int getThreadPriority() { fail(); return -999; }
+        public String getThreadSchedulerGroup() { fail(); return null; }
+        public void setPriorityAndCallBack(int p, IBinderThreadPriorityService cb) { fail(); }
+        public void callBack(IBinderThreadPriorityService cb) { fail(); }
+        private static void fail() { throw new RuntimeException("unimplemented"); }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        getContext().bindService(
+                new Intent(getContext(), BinderThreadPriorityService.class),
+                mConnection, Context.BIND_AUTO_CREATE);
+
+        synchronized (this) {
+            if (mService == null) {
+                try {
+                    wait(30000);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+                assertNotNull("Gave up waiting for BinderThreadPriorityService", mService);
+            }
+        }
+
+        mSavedPriority = Process.getThreadPriority(Process.myTid());
+        Process.setThreadPriority(mSavedPriority);  // To realign priority & cgroup, if needed
+        assertEquals(expectedSchedulerGroup(mSavedPriority), getSchedulerGroup());
+        Log.i(TAG, "Saved priority: " + mSavedPriority);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // HACK -- see bug 2665914 -- setThreadPriority() doesn't always set the
+        // scheduler group reliably unless we start out with background priority.
+        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+        Process.setThreadPriority(mSavedPriority);
+        assertEquals(mSavedPriority, Process.getThreadPriority(Process.myTid()));
+        assertEquals(expectedSchedulerGroup(mSavedPriority), getSchedulerGroup());
+
+        getContext().unbindService(mConnection);
+        super.tearDown();
+    }
+
+    public static String getSchedulerGroup() {
+        String fn = "/proc/" + Process.myPid() + "/task/" + Process.myTid() + "/cgroup";
+        try {
+            String cgroup = FileUtils.readTextFile(new File(fn), 1024, null);
+            for (String line : cgroup.split("\n")) {
+                String fields[] = line.trim().split(":");
+                    if (fields.length == 3 && fields[1].equals("cpu")) return fields[2];
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "Can't read: " + fn, e);
+        }
+        return null;  // Unknown
+    }
+
+    public static String expectedSchedulerGroup(int prio) {
+        return prio < Process.THREAD_PRIORITY_BACKGROUND ? "/" : "/bg_non_interactive";
+    }
+
+    public void testPassPriorityToService() throws Exception {
+        for (int prio = 19; prio >= -20; prio--) {
+            Process.setThreadPriority(prio);
+
+            // Local
+            assertEquals(prio, Process.getThreadPriority(Process.myTid()));
+            assertEquals(expectedSchedulerGroup(prio), getSchedulerGroup());
+
+            // Remote
+            assertEquals(prio, mService.getThreadPriority());
+            assertEquals(expectedSchedulerGroup(prio), mService.getThreadSchedulerGroup());
+        }
+    }
+
+    public void testCallBackFromServiceWithPriority() throws Exception {
+        for (int prio = -20; prio <= 19; prio++) {
+            final int expected = prio;
+            mService.setPriorityAndCallBack(prio, new ServiceStub() {
+                public void callBack(IBinderThreadPriorityService cb) {
+                    assertEquals(expected, Process.getThreadPriority(Process.myTid()));
+                    assertEquals(expectedSchedulerGroup(expected), getSchedulerGroup());
+                }
+            });
+
+            assertEquals(mSavedPriority, Process.getThreadPriority(Process.myTid()));
+
+            // BROKEN -- see bug 2665954 -- scheduler group doesn't get reset
+            // properly after a back-call with a different priority.
+            // assertEquals(expectedSchedulerGroup(mSavedPriority), getSchedulerGroup());
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/os/IBinderThreadPriorityService.aidl b/core/tests/coretests/src/android/os/IBinderThreadPriorityService.aidl
new file mode 100644
index 0000000..b30f04c
--- /dev/null
+++ b/core/tests/coretests/src/android/os/IBinderThreadPriorityService.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+interface IBinderThreadPriorityService {
+    int getThreadPriority();
+    String getThreadSchedulerGroup();
+    void callBack(IBinderThreadPriorityService recurse);
+    void setPriorityAndCallBack(int priority, IBinderThreadPriorityService recurse);
+}
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 11058a6..31d9f1a 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -1,6 +1,6 @@
-<?cs # Table of contents for Dev Guide. 
+<?cs # Table of contents for Dev Guide.
 
-       For each document available in translation, add an localized title to this TOC. 
+       For each document available in translation, add an localized title to this TOC.
        Do not add localized title for docs not available in translation.
        Below are template spans for adding localized doc titles. Please ensure that
        localized titles are added in the language order specified below.
@@ -34,7 +34,7 @@
       <!-- quick overview of what it's like to develop on Android -->
     </ul>
   </li>
-  
+
   <li>
     <h2>
       <span class="en">Framework Topics</span>
@@ -66,34 +66,34 @@
              </a></div>
         <ul>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/declaring-layout.html">
-               <span class="en">Declaring Layout</span> 
+               <span class="en">Declaring Layout</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/menus.html">
-               <span class="en">Creating Menus</span> 
+               <span class="en">Creating Menus</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/dialogs.html">
-                <span class="en">Creating Dialogs</span> 
+                <span class="en">Creating Dialogs</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/ui-events.html">
-                <span class="en">Handling UI Events</span> 
+                <span class="en">Handling UI Events</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/index.html">
-                <span class="en">Notifying the User</span> 
+                <span class="en">Notifying the User</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/themes.html">
-                <span class="en">Applying Styles and Themes</span> 
+                <span class="en">Applying Styles and Themes</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/custom-components.html">
-                <span class="en">Building Custom Components</span> 
+                <span class="en">Building Custom Components</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/binding.html">
-                <span class="en">Binding to Data with AdapterView</span> 
+                <span class="en">Binding to Data with AdapterView</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/layout-objects.html">
-                <span class="en">Common Layout Objects</span> 
+                <span class="en">Common Layout Objects</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/how-android-draws.html">
-                <span class="en">How Android Draws Views</span> 
+                <span class="en">How Android Draws Views</span>
               </a></li>
         </ul>
       </li>
@@ -229,9 +229,12 @@
             <li><a href="<?cs var:toroot?>guide/topics/search/searchable-config.html">Searchable Configuration</a></li>
           </ul>
       </li>
+      <li><a href="<?cs var:toroot?>guide/topics/testing/testing_android.html">
+            <span class="en">Testing and Instrumentation</span></a>
+            <span class="new">new!</span></li>
     </ul>
   </li>
-  
+
   <li>
     <h2><span class="en">Developing</span>
                <span class="de" style="display:none">Entwicklung</span>
@@ -246,7 +249,7 @@
   <!--<li><a href="">Developing for Android</a></li>
       signing, upgrading, selecting a package name, select device profile, touch, trackball, dpad available, etc. -->
       <li><a href="<?cs var:toroot ?>guide/developing/eclipse-adt.html">
-            <span class="en">In Eclipse, with ADT</span> 
+            <span class="en">In Eclipse, with ADT</span>
             <span class="de" style="display:none">In Eclipse, mit ADT</span>
             <span class="es" style="display:none">En Eclipse, con ADT</span>
             <span class="fr" style="display:none">Sous Eclipse, à l'aide du plugin ADT</span>
@@ -276,32 +279,30 @@
             <span class="en">Tools</span>
           </a></div>
         <ul>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/aapt.html">aapt</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html">adb</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/othertools.html#android">android</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/aapt.html">aapt</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html">adb</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/othertools.html#android">android</a></li>
       <!--<li><a href="<?cs var:toroot ?>guide/developing/tools/adt.html">ADT Plugin</a></li>-->
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">aidl</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/avd.html">AVDs</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">aidl</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/avd.html">AVDs</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a>
             <span class="new">new!</span></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/ddms.html">ddms</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/othertools.html#dx">dx</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/draw9patch.html">Draw 9-Patch</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/emulator.html">Emulator</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/hierarchy-viewer.html">Hierarchy Viewer</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/layoutopt.html">layoutopt</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/othertools.html#mksdcard">mksdcard</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/monkey.html">Monkey</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html#sqlite">sqlite3</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/traceview.html" >Traceview</a></li>
-      		<li><a href="<?cs var:toroot ?>guide/developing/tools/zipalign.html" >zipalign</a></li>
-    	  </ul>
-  	  </li>
-  <!--<li><a href="<?cs var:toroot ?>guide/developing/instrumentation/index.html">Instrumentation</a></li>
-      <li><a style="color:gray;">JUnit</a></li> -->
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/ddms.html">ddms</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/othertools.html#dx">dx</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/draw9patch.html">Draw 9-Patch</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/emulator.html">Emulator</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/hierarchy-viewer.html">Hierarchy Viewer</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/layoutopt.html">layoutopt</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/othertools.html#mksdcard">mksdcard</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/monkey.html">Monkey</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html#sqlite">sqlite3</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/traceview.html" >Traceview</a></li>
+              <li><a href="<?cs var:toroot ?>guide/developing/tools/zipalign.html" >zipalign</a></li>
+          </ul>
+        </li>
     </ul>
   </li>
-  
+
   <li>
     <h2><span class="en">Publishing</span>
         <span class="de" style="display:none">Veröffentlichung</span>
@@ -348,7 +349,7 @@
           </a></li>
     </ul>
   </li>
-  
+
   <li>
     <h2><span class="en">Best Practices</span>
                <span class="de" style="display:none">Bewährte Verfahren</span>
@@ -412,7 +413,7 @@
           </a></li>
       <li><a href="<?cs var:toroot ?>guide/appendix/market-filters.html">
             <span class="en">Market Filters </span>
-          </a><span class="new">new!</span></li>
+           </a><span class="new">new!</span></li>
       <li><a href="<?cs var:toroot ?>guide/appendix/media-formats.html">
             <span class="en">Supported Media Formats</span>
           </a></li>
diff --git a/docs/html/guide/topics/manifest/manifest-element.jd b/docs/html/guide/topics/manifest/manifest-element.jd
index 734a79d..3353755 100644
--- a/docs/html/guide/topics/manifest/manifest-element.jd
+++ b/docs/html/guide/topics/manifest/manifest-element.jd
@@ -110,7 +110,6 @@
 
 <dt><a name="install"></a>{@code android:installLocation}</dt>
 <dd>The default install location for the application.
-<p>This attribute was introduced in API Level 8.</p>
 
 <p>The following keyword strings are accepted:</p>
 
@@ -119,23 +118,31 @@
    <th>Value</th>
    <th>Description</th>
 </tr><tr>
-   <td>"{@code auto}"</td>
-   <td>Let the system decide the ideal install location. This will usually be based on the user's
-saved preference.</td>
-</tr><tr>
    <td>"{@code internalOnly}"</td>
-   <td>The application requests to be installed on the internal device storage only. If this is set,
-then the application will never be installed on the external storage (SD card). If the internal
-storage is full, then the system will not install the application.</td>
+   <td>The application must be installed on the internal device storage only. If this is set,
+the application will never be installed on the external storage. If the internal
+storage is full, then the system will not install the application. This is also the default behavior
+if you do not define {@code android:installLocation}.</td>
+</tr><tr>
+   <td>"{@code auto}"</td>
+   <td>The application may be installed on the external storage, but the system will install the
+application on the internal storage by default. If the internal storage is full, then the system
+will install it on the external storage. Once installed, the user can move the application
+to either internal or external storage through the system settings.</td>
 </tr><tr>
    <td>"{@code preferExternal}"</td>
    <td>The application prefers to be installed on the external storage (SD card). There is no
 guarantee that the system will honor this request. The application might be installed on internal
 storage if the external media is unavailable or full, or if the application uses the forward-locking
-mechanism (not supported on external storage).</td>
+mechanism (not supported on external storage). Once installed, the user can move the application to
+either internal or external storage through the system settings.</td>
 </tr>
 </table>
 
+<p class="note"><strong>Note:</strong> By default, your application will be installed on the
+internal storage and cannot be installed on the external storage unless you define this attribute
+to be either "{@code auto}" or "{@code preferExternal}".</p>
+
 <p>When an application is installed on the external storage:</p>
 <ul>
   <li>The {@code .apk} file is saved
@@ -150,8 +157,9 @@
 
 <p>The user may also request to move an application from the internal storage to the external
 storage. However, the system will not allow the user to move the application to external storage if
-this attribute is set to {@code internalOnly}.
-</p>
+this attribute is set to {@code internalOnly}, which is the default setting.</p>
+
+<p>Introduced in: API Level 8.</p>
 
 </dd>
 
@@ -164,6 +172,7 @@
 
 <p>
 <dt>see also:</dt>
-<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
+<dd><a href="{@docRoot}guide/appendix/install-location.html">App Install Location</a><br/>
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
 
 </dl>
diff --git a/docs/html/guide/topics/resources/accessing-resources.jd b/docs/html/guide/topics/resources/accessing-resources.jd
index e3e4055..cf8970c 100644
--- a/docs/html/guide/topics/resources/accessing-resources.jd
+++ b/docs/html/guide/topics/resources/accessing-resources.jd
@@ -22,12 +22,13 @@
 
   <h2>In this document</h2>
   <ol>
-    <li><a href="#ResourcesInCode">Accessing Resources in Code</a></li>
-    <li><a href="#ReferencesToResources">Accessing Resources in Other XML Resources</a>
+    <li><a href="#ResourcesFromCode">Accessing Resources from Code</a></li>
+    <li><a href="#ResourcesFromXml">Accessing Resources from XML</a>
       <ol>
         <li><a href="#ReferencesToThemeAttributes">Referencing style attributes</a></li>
       </ol>
     </li>
+    <li><a href="#PlatformResources">Accessing Platform Resources</a></li>
   </ol>
 
   <h2>See also</h2>
@@ -39,154 +40,194 @@
 </div>
 
 
-<p>There are two ways you can reference your resources for use in your application:</p>
+
+
+<p>Once you provide a resource in your application (discussed in <a
+href="providing-resources.html">Providing Resources</a>), you can apply it by
+referencing its resource ID. All resource IDs are defined in your project's {@code R} class, which
+the {@code aapt} tool automatically generates.</p>
+
+<p>When your application is compiled, {@code aapt} generates the {@code R} class, which contains
+resource IDs for all the resources in your {@code
+res/} directory. For each type of resource, there is an {@code R} subclass (for example,
+{@code R.drawable} for all drawable resources) and for each resource of that type, there is a static
+integer (for example, {@code R.drawable.icon}). This integer is the resource ID that you can use
+to retrieve your resource.</p>
+
+<p>Although the {@code R} class is where resource IDs are specified, you should never need to
+look there to discover a resource ID. A resource ID is always composed of:</p>
 <ul>
-  <li><strong>From your code:</strong> Using an integer from a sub-class in your {@code R} class,
-such as:
-    <p>{@code R.string.hello}</p>
-    <p>You will see Android APIs that accept this kind of resource identifier as a method parameter
-(usually defined as the {@code id} parameter).</p>
+  <li>The <em>resource type</em>: Each resource is grouped into a "type," such as {@code
+string}, {@code drawable}, and {@code layout}. For more about the different types, see <a
+href="available-resources.html">Resource Types</a>.
   </li>
-  <li><strong>From another resource:</strong> Using a special XML syntax that corresponds to the
-{@code R} sub-class, such as:
-    <p>{@code &#64;string/hello}</p>
-    <p>You can use this syntax in an XML resource any place where a value is expected that is
-matched by the existing resource. For example, if you need to provide a string in either an XML
-attribute or element value, you can reference a resource instead of providing a hard-coded
-string.</p>
+  <li>The <em>resource name</em>, which is either: the filename,
+excluding the extension; or the value in the XML {@code android:name} attribute, if the
+resource is a simple value (such as a string).</li>
+</ul>
+
+<p>There are two ways you can access a resource:</p>
+<ul>
+  <li><strong>In code:</strong> Using an static integer from a sub-class of your {@code R}
+class, such as:
+    <pre class="classic no-pretty-print">R.string.hello</pre>
+    <p>{@code string} is the resource type and {@code hello} is the resource name. There are many
+Android APIs that can access your resources when you provide a resource ID in this format. See
+<a href="#ResourcesFromCode">Accessing Resources in Code</a>.</p>
+  </li>
+  <li><strong>In XML:</strong> Using a special XML syntax that also corresponds to
+the resource ID defined in your {@code R} class, such as:
+    <pre class="classic no-pretty-print">&#64;string/hello</pre>
+    <p>{@code string} is the resource type and {@code hello} is the resource name. You can use this
+syntax in an XML resource any place where a value is expected that you provide in a resource. See <a
+href="#ResourcesFromXml">Accessing Resources from XML</a>.</p>
   </li>
 </ul>
 
 
 
-<h2 id="ResourcesInCode">Accessing Resources in Code </h2>
+<h2 id="ResourcesFromCode">Accessing Resources in Code </h2>
 
-<p>When your application is compiled, Android generates the {@code R.java} file (inside
-the {@code gen/} directory), which contains resource
-identifiers to all the resources in your {@code res/} directory. For each type of resource, a
-specific subclass is added to the {@code R} class (for example,
-{@code R.drawable}) and for each resource of that type, a static
-integer is added to the subclass (for example,
-{@code R.drawable.icon}). This integer is the resource ID and you can use it to retrieve
-your resource from your application code.</p>
+<p>You can use a resource in code by passing the resource ID as a method parameter. For
+example, you can set an {@link android.widget.ImageView} to use the {@code res/drawable/myimage.png}
+resource using {@link android.widget.ImageView#setImageResource(int) setImageResource()}:</p>
+<pre>
+ImageView imageView = (ImageView) findViewById(R.id.myimageview);
+imageView.setImageResource(<strong>R.drawable.myimage</strong>);
+</pre>
 
+<p>You can also retrieve individual resources using methods in {@link
+android.content.res.Resources}, which you can get an instance of
+with {@link android.content.Context#getResources()}.</p>
 
 <div class="sidebox-wrapper">
 <div class="sidebox">
 <h2>Access to Original Files</h2>
 
 <p>While uncommon, you might need access your original files and directories. If you do, then
-saving your files in {@code res/} won't work for you. Instead, you can save your resources in the
+saving your files in {@code res/} won't work for you, because the only way to read a resource from
+{@code res/} is with the resource ID. Instead, you can save your resources in the
 {@code assets/} directory.</p>
-<p>Files saved in the {@code assets/} directory will <em>not</em> be given a resource
+<p>Files saved in the {@code assets/} directory are <em>not</em> given a resource
 ID, so you can't reference them through the {@code R} class or from XML resources. Instead, you can
 query files in the {@code assets/} directory like a normal file system and read raw data using
 {@link android.content.res.AssetManager}.</p>
 <p>However, if all you require is the ability to read raw data (such as a video or audio file),
 then save the file in the {@code res/raw/} directory and read a stream of bytes using {@link
-android.content.res.Resources#openRawResource(int)}.</p>
+android.content.res.Resources#openRawResource(int) openRawResource()}.</p>
 
 </div>
 </div>
 
 
-<p class="caution"><strong>Caution:</strong> You should never modify the {@code
-R.java} file by hand&mdash;it is generated by the {@code aapt} tool when your project is
-compiled. Any changes will be overridden next time you compile.</p>
+<h3>Syntax</h3>
 
-<p>Here is the syntax to reference a resource in code:</p>
-<p>
-<code>[<em>&lt;package_name&gt;</em>.]R.<em>&lt;resource_type&gt;</em>.<em>&lt;resource_name&gt;</em></code>
-</p>
+<p>Here's the syntax to reference a resource in code:</p>
+
+<pre class="classic no-pretty-print">
+[<em>&lt;package_name&gt;</em>.]R.<em>&lt;resource_type&gt;</em>.<em>&lt;resource_name&gt;</em>
+</pre>
 
 <ul>
   <li><em>{@code &lt;package_name&gt;}</em> is the name of the package in which the resource is located (not
 required when referencing resources from your own package).</li>
   <li><em>{@code &lt;resource_type&gt;}</em> is the {@code R} subclass for the resource type.</li>
-  <li><em>{@code &lt;resource_name&gt;}</em> is either the {@code
-android:name} attribute value (for some resources defined in XML files) or the resource filename
-without the extension.</li>
+  <li><em>{@code &lt;resource_name&gt;}</em> is either the resource filename
+without the extension or the {@code android:name} attribute value in the XML element (for simple
+values).</li>
 </ul>
 <p>See <a href="resource-types.html">Resource Types</a> for
 more information about each resource type and how to reference them.</p>
 
-<p>In many cases, you can supply an API method with the resource ID. For example, to set the image
-for an {@link android.widget.ImageView}:</p>
-<pre>
-ImageView iv = (ImageView) findViewById(R.id.myimageview);
-iv.setImageResource(R.drawable.myimage);
-</pre>
 
-<p>You can also retrieve your
-resource objects using methods in {@link android.content.res.Resources}, which you can create an
-instance of with {@link android.content.Context#getResources Context.getResources()}. For example,
-to get a string:</p>
-<pre>
-Resources res = this.getResources();
-String string = res.getString(R.string.mystring);
-</pre>
+<h3>Use cases</h3>
 
-<p>You can also access resources from the platform by prefixing the {@code android}
-namespace. Android contains a number of standard resources, such as styles and themes for your
-layout, button backgrounds, and layouts. To refer to these in code, qualify your reference with the
-<code>android</code> package name. For example,
-<code>android.R.layout.simple_gallery_item</code>.</p>
+<p>There are many methods that accept a resource ID parameter and you can retrieve resources using
+methods in {@link android.content.res.Resources}. You can get an instance of  {@link
+android.content.res.Resources} with {@link android.content.Context#getResources
+Context.getResources()}.</p>
 
-<p>Here are some examples of using resources in code:</p>
+
+<p>Here are some examples of accessing resources in code:</p>
 
 <pre>
 // Load a background for the current screen from a drawable resource
 {@link android.app.Activity#getWindow()}.{@link
 android.view.Window#setBackgroundDrawableResource(int)
-setBackgroundDrawableResource}(R.drawable.my_background_image) ;
+setBackgroundDrawableResource}(<strong>R.drawable.my_background_image</strong>) ;
 
 // Set the Activity title by getting a string from the Resources object, because
 //  this method requires a CharSequence rather than a resource ID
 {@link android.app.Activity#getWindow()}.{@link android.view.Window#setTitle(CharSequence)
 setTitle}(getResources().{@link android.content.res.Resources#getText(int)
-getText}(R.string.main_title));
+getText}(<strong>R.string.main_title</strong>));
 
 // Load a custom layout for the current screen
 {@link android.app.Activity#setContentView(int)
-setContentView}(R.layout.main_screen);
+setContentView}(<strong>R.layout.main_screen</strong>);
 
 // Set a slide in animation by getting an Animation from the Resources object
 mFlipper.{@link android.widget.ViewAnimator#setInAnimation(Animation)
 setInAnimation}(AnimationUtils.loadAnimation(this,
-        R.anim.hyperspace_in));
+        <strong>R.anim.hyperspace_in</strong>));
 
 // Set the text on a TextView object using a resource ID
-TextView msgTextView = (TextView) findViewById(R.id.msg);
-msgTextView.{@link android.widget.TextView#setText(int) setText}(R.string.hello_message);
+TextView msgTextView = (TextView) findViewById(<strong>R.id.msg</strong>);
+msgTextView.{@link android.widget.TextView#setText(int)
+setText}(<strong>R.string.hello_message</strong>);
 </pre>
 
 
+<p class="caution"><strong>Caution:</strong> You should never modify the {@code
+R.java} file by hand&mdash;it is generated by the {@code aapt} tool when your project is
+compiled. Any changes are overridden next time you compile.</p>
 
 
 
+<h2 id="ResourcesFromXml">Accessing Resources from XML</h2>
 
-<h2 id="ReferencesToResources">Accessing Resources in other XML Resources</h2>
+<p>You can define values for some XML attributes and elements using a
+reference to an existing resource. You will often do this when creating layout files, to
+supply strings and images for your widgets.</p>
 
-<p>When creating an XML resource, some values for attributes and elements can be a reference to
-an existing resource. This is often used in layout files to supply strings and images.</p>
+<p>For example, if you add a {@link android.widget.Button} to your layout, you should use
+a <a href="string-resource.html">string resource</a> for the button text:</p>
+
+<pre>
+&lt;Button
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:text="<strong>@string/submit</strong>" /&gt;
+</pre>
+
+
+<h3>Syntax</h3>
 
 <p>Here is the syntax to reference a resource in an XML resource:</p>
-<p><code>@[<em>&lt;package_name&gt;</em>:]<em>&lt;resource_type&gt;</em>/<em>&lt;resource_name&gt;</em></code></p>
+
+<pre class="classic no-pretty-print">
+&#64;[<em>&lt;package_name&gt;</em>:]<em>&lt;resource_type&gt;</em>/<em>&lt;resource_name&gt;</em>
+</pre>
 
 <ul>
   <li>{@code &lt;package_name&gt;} is the name of the package in which the resource is located (not
 required when referencing resources from the same package)</li>
   <li>{@code &lt;resource_type&gt;} is the
 {@code R} subclass for the resource type</li>
-  <li>{@code &lt;resource_name&gt;} is either the {@code
-android:name} attribute value (for some resources defined in XML files) or the resource filename
-without the extension</li>
+  <li>{@code &lt;resource_name&gt;} is either the resource filename
+without the extension or the {@code android:name} attribute value in the XML element (for simple
+values).</li>
 </ul>
 
 <p>See <a href="resource-types.html">Resource Types</a> for
 more information about each resource type and how to reference them.</p>
 
-<p>For example, if you have the following resource file that includes a <a
+
+<h3>Use cases</h3>
+
+<p>In some cases you must use a resource for a value in XML (for example, to apply a drawable image
+to a widget), but you can also use a resource in XML any place that accepts a simple value. For
+example, if you have the following resource file that includes a <a
 href="more-resources.html#Color">color resource</a> and a <a
 href="string-resource.html">string resource</a>:</p>
 
@@ -206,8 +247,8 @@
 &lt;EditText xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
     android:layout_width=&quot;fill_parent&quot;
     android:layout_height=&quot;fill_parent&quot;
-    <strong>android:textColor=&quot;&#64;color/opaque_red&quot;
-    android:text=&quot;&#64;string/hello&quot;</strong> /&gt;
+    android:textColor=&quot;<strong>&#64;color/opaque_red</strong>&quot;
+    android:text=&quot;<strong>&#64;string/hello</strong>&quot; /&gt;
 </pre>
 
 <p>In this case you don't need to specify the package name in the resource reference because the
@@ -219,19 +260,18 @@
 &lt;EditText xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
     android:layout_width=&quot;fill_parent&quot;
     android:layout_height=&quot;fill_parent&quot;
-    <strong>android:textColor=&quot;&#64;android:color/secondary_text_dark&quot;</strong>
+    android:textColor=&quot;<strong>&#64;android:color/secondary_text_dark</strong>&quot;
     android:text=&quot;&#64;string/hello&quot; /&gt;
 </pre>
 
-<p class="note"><strong>Note:</strong> You should always use a string resource when supplying
-strings in a layout file, as demonstrated above, so that the strings can be localized. For
-information about creating alternative resources (such as localized strings), see <a
+<p class="note"><strong>Note:</strong> You should use string resources at all times, so that your
+application can be localized for other languages. For information about creating alternative
+resources (such as localized strings), see <a
 href="providing-resources.html#AlternativeResources">Providing Alternative
 Resources</a>.</p>
 
-<p>This facility for referencing resources between resources can also be used to create
-alias resources. For example, you can create new drawable resources that is an alias for an existing
-image:</p>
+<p>You can even use resources in XML to create aliases. For example, you can create a
+drawable resource that is an alias for another drawable resource:</p>
 
 <pre>
 &lt;?xml version="1.0" encoding="utf-8"?>
@@ -239,15 +279,14 @@
     android:src="@drawable/other_drawable" />
 </pre>
 
-<p>This is discussed further in <a href="providing-resources.html#AliasResources">Creating
-alias resources</a>.</p>
-
+<p>This sounds redundant, but can be very useful when using alternative resource. Read more about
+<a href="providing-resources.html#AliasResources">Creating alias resources</a>.</p>
 
 
 
 <h3 id="ReferencesToThemeAttributes">Referencing style attributes</h3>
 
-<p>A style attribute resource is another type of resource that allows you to reference the value
+<p>A style attribute resource allows you to reference the value
 of an attribute in the currently-applied theme. Referencing a style attribute allows you to
 customize the look of UI elements by styling them to match standard variations supplied by the
 current theme, instead of supplying a hard-coded value. Referencing a style attribute
@@ -257,28 +296,46 @@
 format, but instead of the at-symbol ({@code &#64;}), use a question-mark ({@code ?}), and the
 resource type portion is optional. For instance:</p>
 
-<p>
-<code>
+<pre class="classic">
 ?[<em>&lt;package_name&gt;</em>:][<em>&lt;resource_type&gt;</em>/]<em>&lt;resource_name&gt;</em>
-</code>
-</p>
+</pre>
 
-<p>For example, here's how you might reference an attribute in a layout,
-to set the text color to match the "primary" text color of the system theme:</p>
+<p>For example, here's how you can reference an attribute to set the text color to match the
+"primary" text color of the system theme:</p>
 
 <pre>
 &lt;EditText id=&quot;text&quot;
     android:layout_width=&quot;fill_parent&quot;
     android:layout_height=&quot;wrap_content&quot;
-    <strong>android:textColor=&quot;?android:textColorSecondary&quot;</strong>
+    android:textColor=&quot;<strong>?android:textColorSecondary</strong>&quot;
     android:text=&quot;&#64;string/hello_world&quot; /&gt;
 </pre>
 
-<p>Using this markup, you are
-supplying the name of an attribute resource that will be looked up in the theme.
-Because the system resource tool knows that an attribute resource is expected,
+<p>Here, the {@code android:textColor} attribute specifies the name of a style attribute
+in the current theme. Android now uses the value applied to the {@code android:textColorSecondary}
+style attribute as the value for {@code android:textColor} in this widget. Because the system
+resource tool knows that an attribute resource is expected in this context,
 you do not need to explicitly state the type (which would be
-<code>?android:attr/textColorSecondary</code>), so you can exclude the {@code attr} type.</p>
+<code>?android:attr/textColorSecondary</code>)&mdash;you can exclude the {@code attr} type.</p>
 
 
 
+
+<h2 id="PlatformResources">Accessing Platform Resources</h2>
+
+<p>Android contains a number of standard resources, such as styles, themes, and layouts. To
+access these resource, qualify your resource reference with the
+<code>android</code> package name. For example, Android provides a layout resource you can use for
+list items in a {@link android.widget.ListAdapter}:</p>
+
+<pre>
+{@link android.app.ListActivity#setListAdapter(ListAdapter)
+setListAdapter}(new {@link
+android.widget.ArrayAdapter}&lt;String&gt;(this, <strong>android.R.layout.simple_list_item_1</strong>, myarray));
+</pre>
+
+<p>In this example, {@link android.R.layout#simple_list_item_1} is a layout resource defined by the
+platform for items in a {@link android.widget.ListView}. You can use this instead of creating
+your own layout for list items. (For more about using {@link android.widget.ListView}, see the
+<a href="{@docRoot}resources/tutorials/views/hello-listview.html">List View Tutorial</a>.)</p>
+
diff --git a/docs/html/guide/topics/resources/animation-resource.jd b/docs/html/guide/topics/resources/animation-resource.jd
index b2fab04..e0ce051 100644
--- a/docs/html/guide/topics/resources/animation-resource.jd
+++ b/docs/html/guide/topics/resources/animation-resource.jd
@@ -62,18 +62,18 @@
         android:toXScale="<em>float</em>"
         android:fromYScale="<em>float</em>"
         android:toYScale="<em>float</em>"
-        android:pivotX="<em>string</em>"
-        android:pivotY="<em>string</em>" /&gt;
+        android:pivotX="<em>float</em>"
+        android:pivotY="<em>float</em>" /&gt;
     &lt;<a href="#translate-element">translate</a>
-        android:fromX="<em>string</em>"
-        android:toX="<em>string</em>"
-        android:fromY="<em>string</em>"
-        android:toY="<em>string</em>" /&gt;
+        android:fromX="<em>float</em>"
+        android:toX="<em>float</em>"
+        android:fromY="<em>float</em>"
+        android:toY="<em>float</em>" /&gt;
     &lt;<a href="#rotate-element">rotate</a>
         android:fromDegrees="<em>float</em>"
         android:toDegrees="<em>float</em>"
-        android:pivotX="<em>string</em>"
-        android:pivotY="<em>string</em>" /&gt;
+        android:pivotX="<em>float</em>"
+        android:pivotY="<em>float</em>" /&gt;
     &lt;<a href="#set-element">set</a>&gt;
         ...
     &lt;/set&gt;
@@ -158,21 +158,21 @@
       <p class="caps">attributes:</p>
       <dl class="atn-list">
         <dt><code>android:fromXDelta</code></dt>
-          <dd><em>Float or percentage</em>. Starting X offset. Either in: pixels relative to the
-normal position, in percentage relative to the element width (%), or relative to the parent width
-(%p).</dd>
+          <dd><em>Float or percentage</em>. Starting X offset. Expressed either: in pixels relative
+to the normal position (such as {@code "5"}), in percentage relative to the element width (such as
+{@code "5%"}), or in percentage relative to the parent width (such as {@code "5%p"}).</dd>
         <dt><code>android:toXDelta</code></dt>
-          <dd><em>Float or percentage</em>. Ending X offset. Either in: pixels relative to the
-normal position, in percentage relative to the element width (%), or relative to the parent width
-(%p).</dd>
+          <dd><em>Float or percentage</em>. Ending X offset. Expressed either: in pixels relative
+to the normal position (such as {@code "5"}), in percentage relative to the element width (such as
+{@code "5%"}), or in percentage relative to the parent width (such as {@code "5%p"}).</dd>
         <dt><code>android:fromYDelta</code></dt>
-          <dd><em>Float or percentage</em>. Starting Y offset. Either in: pixels relative to the
-normal position, in percentage relative to the element height (%), or relative to the parent height
-(%p).</dd>
+          <dd><em>Float or percentage</em>. Starting Y offset. Expressed either: in pixels relative
+to the normal position (such as {@code "5"}), in percentage relative to the element height (such as
+{@code "5%"}), or in percentage relative to the parent height (such as {@code "5%p"}).</dd>
         <dt><code>android:toYDelta</code></dt>
-          <dd><em>Float or percentage</em>. Ending Y offset. Either in: pixels relative to the
-normal position, in percentage relative to the element height (%), or relative to the parent height
-(%p).</dd>
+          <dd><em>Float or percentage</em>. Ending Y offset. Expressed either: in pixels relative
+to the normal position (such as {@code "5"}), in percentage relative to the element height (such as
+{@code "5%"}), or in percentage relative to the parent height (such as {@code "5%p"}).</dd>
       </dl>
       <p>For more attributes supported by <code>&lt;translate&gt;</code>, see the
 {@link android.view.animation.Animation} class reference (of which, all XML attributes are
@@ -183,15 +183,19 @@
       <p class="caps">attributes:</p>
       <dl class="atn-list">
         <dt><code>android:fromDegrees</code></dt>
-          <dd><em>Integer</em>. Starting angular position, in degrees.</dd>
+          <dd><em>Float</em>. Starting angular position, in degrees.</dd>
         <dt><code>android:toDegrees</code></dt>
-          <dd><em>Integer</em>. Ending angular position, in degrees.</dd>
+          <dd><em>Float</em>. Ending angular position, in degrees.</dd>
         <dt><code>android:pivotX</code></dt>
-          <dd><em>Integer or percentage</em>. The X coordinate of the center of rotation, in total
-pixels (where 0 is the left edge) or percentage of the screen width.</dd>
+          <dd><em>Float or percentage</em>. The X coordinate of the center of rotation. Expressed
+either: in pixels relative to the object's left edge (such as {@code "5"}), in percentage relative
+to the object's left edge (such as {@code "5%"}), or in percentage relative to the parent
+container's left edge (such as {@code "5%p"}).</dd>
         <dt><code>android:pivotY</code></dt>
-          <dd><em>Integer or percentage</em>. The Y coordinate of the center of rotation, in total
-pixels (where 0 is the top edge) or percentage of the screen height.</dd>
+          <dd><em>Float or percentage</em>. The Y coordinate of the center of rotation. Expressed
+either: in pixels relative to the object's top edge (such as {@code "5"}), in percentage relative
+to the object's top edge (such as {@code "5%"}), or in percentage relative to the parent
+container's top edge (such as {@code "5%p"}).</dd>
         </dl>
       <p>For more attributes supported by <code>&lt;rotate&gt;</code>, see the
 {@link android.view.animation.Animation} class reference (of which, all XML attributes are
diff --git a/docs/html/guide/topics/resources/available-resources.jd b/docs/html/guide/topics/resources/available-resources.jd
index 19babee..09c55a5 100644
--- a/docs/html/guide/topics/resources/available-resources.jd
+++ b/docs/html/guide/topics/resources/available-resources.jd
@@ -18,6 +18,23 @@
 
 <p>Here's a brief summary of each resource type:</p>
 
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>{@code R.id} Is Not a Resource</h2>
+
+<p>You will often use an {@code R.id} integer to handle {@link android.view.View} objects in
+your UI. Although the {@code id} is a subclass of the {@code R} class, it is not considered a
+"resource" because it is not a reference to an externalized application resource. The {@code id}
+is simply a unique identifier that allows you to handle elements in your UI by instantiating
+objects with {@link android.app.Activity#findViewById(int) findViewById()}.</p>
+
+<p>For information about using {@code R.id} with your UI, see <a
+href="{@docRoot}guide/topics/ui/declaring-layout.html#attributes">Declaring Layout</a>.</p>
+
+</div>
+</div>
+
+
 <dl>
   <dt><a href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a></dt>
     <dd>Define pre-determined animations.<br/>
diff --git a/docs/html/guide/topics/resources/drawable-resource.jd b/docs/html/guide/topics/resources/drawable-resource.jd
index ec964ed..d8de16a 100644
--- a/docs/html/guide/topics/resources/drawable-resource.jd
+++ b/docs/html/guide/topics/resources/drawable-resource.jd
@@ -463,11 +463,11 @@
         android:centerX="<em>integer</em>"
         android:centerY="<em>integer</em>"
         android:centerColor="<em>integer</em>"
+        android:endColor="<em>color</em>"
         android:gradientRadius="<em>integer</em>"
-        android:type=""
-        android:usesLevel=""
         android:startColor="<em>color</em>"
-        android:endColor="<em>color</em>" />
+        android:type=["linear" | "radial" | "sweep"]
+        android:usesLevel=["true" | "false"] />
     &lt;<a href="#solid-element">solid</a>
         android:color="<em>color</em>" />
     &lt;<a href="#stroke-element">stroke</a>
@@ -544,18 +544,6 @@
     <dd>Specifies a gradient color for the shape.
       <p class="caps">attributes:</p>
       <dl class="atn-list">
-        <dt><code>android:type</code></dt>
-        <dd><em>Keyword</em>. The type of gradient pattern to apply. Valid values are:
-          <table>
-            <tr><th>Value</th><th>Description</th></tr>
-            <tr><td>{@code "linear"}</td>
-                <td>A linear gradient. This is the default.</td></tr>
-            <tr><td>{@code "radial"}</td>
-                <td>A radial gradient. The start color is the center color.</td></tr>
-            <tr><td>{@code "sweep"}</td>
-                <td>A sweeping line gradient. </td></tr>
-          </table>
-        </dd>
         <dt><code>android:angle</code></dt>
         <dd><em>Integer</em>. The angle for the gradient, in degrees. 0 is left to right, 90 is
 bottom to top. It must be a multiple of 45. Default is 0.</dd>
@@ -568,18 +556,30 @@
         <dt><code>android:centerColor</code></dt>
         <dd><em>Color</em>. Optional color that comes between the start and end colors, as a
 hexadecimal value or <a href="more-resources.html#Color">color resource</a>.</dd>
-        <dt><code>android:gradientRadius</code></dt>
-        <dd><em>Float</em>. The radius for the gradient. Only applied when {@code
-android:type="radial"}.</dd>
-        <dt><code>android:useLevel</code></dt>
-        <dd><em>Boolean</em>. "true" if this is used as a {@link
-android.graphics.drawable.LevelListDrawable}.</dd>
-        <dt><code>android:startColor</code></dt>
-        <dd><em>Color</em>. The starting color, as a hexadecimal
-value or <a href="more-resources.html#Color">color resource</a>.</dd>
         <dt><code>android:endColor</code></dt>
         <dd><em>Color</em>. The ending color, as a hexadecimal
 value or <a href="more-resources.html#Color">color resource</a>.</dd>
+        <dt><code>android:gradientRadius</code></dt>
+        <dd><em>Float</em>. The radius for the gradient. Only applied when {@code
+android:type="radial"}.</dd>
+        <dt><code>android:startColor</code></dt>
+        <dd><em>Color</em>. The starting color, as a hexadecimal
+value or <a href="more-resources.html#Color">color resource</a>.</dd>
+        <dt><code>android:type</code></dt>
+        <dd><em>Keyword</em>. The type of gradient pattern to apply. Valid values are:
+          <table>
+            <tr><th>Value</th><th>Description</th></tr>
+            <tr><td>{@code "linear"}</td>
+                <td>A linear gradient. This is the default.</td></tr>
+            <tr><td>{@code "radial"}</td>
+                <td>A radial gradient. The start color is the center color.</td></tr>
+            <tr><td>{@code "sweep"}</td>
+                <td>A sweeping line gradient. </td></tr>
+          </table>
+        </dd>
+        <dt><code>android:useLevel</code></dt>
+        <dd><em>Boolean</em>. "true" if this is used as a {@link
+android.graphics.drawable.LevelListDrawable}.</dd>
       </dl>
     </dd>
   <dt id="solid-element"><code>&lt;solid&gt;</code></dt>
diff --git a/docs/html/guide/topics/resources/index.jd b/docs/html/guide/topics/resources/index.jd
index f602a04..2aa697e 100644
--- a/docs/html/guide/topics/resources/index.jd
+++ b/docs/html/guide/topics/resources/index.jd
@@ -27,14 +27,14 @@
 to provide this functionality, you must organize resources in your project's {@code res/}
 directory, using various sub-directories that group resources by type and configuration.</p>
 
-<div class="figure" style="width:441px">
+<div class="figure" style="width:421px">
 <img src="{@docRoot}images/resources/resource_devices_diagram1.png" height="137" alt="" />
 <p class="img-caption">
 <strong>Figure 1.</strong> Two device configurations, both using default
 resources.</p>
 </div>
 
-<div class="figure" style="width:441px">
+<div class="figure" style="width:421px">
 <img src="{@docRoot}images/resources/resource_devices_diagram2.png" height="137" alt="" />
 <p class="img-caption">
 <strong>Figure 2.</strong> Two device configurations, one using alternative
diff --git a/docs/html/guide/topics/resources/layout-resource.jd b/docs/html/guide/topics/resources/layout-resource.jd
index a6b177f..2c51d54 100644
--- a/docs/html/guide/topics/resources/layout-resource.jd
+++ b/docs/html/guide/topics/resources/layout-resource.jd
@@ -36,14 +36,14 @@
 &lt;?xml version="1.0" encoding="utf-8"?>
 &lt;<a href="#viewgroup-element"><em>ViewGroup</em></a> xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/<em>name</em>"
-    android:layout_height="@+id/<em>string_name</em>"
-    android:layout_width="@+id/<em>string_name</em>"
-    [<em>other attributes</em>] &gt;
+    android:layout_height=["<em>dimension</em>" | "fill_parent" | "wrap_content"]
+    android:layout_width=["<em>dimension</em>" | "fill_parent" | "wrap_content"]
+    [<em>ViewGroup-specific attributes</em>] &gt;
     &lt;<a href="#view-element"><em>View</em></a>
         android:id="@+id/<em>name</em>"
-        android:layout_height="@+id/<em>string_name</em>"
-        android:layout_width="@+id/<em>string_name</em>"
-        [<em>other attributes</em>] &gt;
+        android:layout_height=["<em>dimension</em>" | "fill_parent" | "wrap_content"]
+        android:layout_width=["<em>dimension</em>" | "fill_parent" | "wrap_content"]
+        [<em>View-specific attributes</em>] &gt;
         &lt;<a href="#requestfocus-element">requestFocus</a>/&gt;
     &lt;/<em>View</em>&gt;
     &lt;<a href="#viewgroup-element"><em>ViewGroup</em></a> &gt;
diff --git a/docs/html/guide/topics/resources/menu-resource.jd b/docs/html/guide/topics/resources/menu-resource.jd
index c9f27fa..badc403 100644
--- a/docs/html/guide/topics/resources/menu-resource.jd
+++ b/docs/html/guide/topics/resources/menu-resource.jd
@@ -35,12 +35,12 @@
 <pre>
 &lt;?xml version="1.0" encoding="utf-8"?>
 &lt;<a href="#menu-element">menu</a> xmlns:android="http://schemas.android.com/apk/res/android">
-    &lt;<a href="#item-element">item</a> android:id="<em>resource ID</em>"
+    &lt;<a href="#item-element">item</a> android:id="@+id/<em>id_name</em>"
           android:menuCategory=["container" | "system" | "secondary" | "alternative"]
           android:orderInCategory="<em>integer</em>"
           android:title="<em>string</em>"
           android:titleCondensed="<em>string</em>"
-          android:icon="<em>drawable resource</em>"
+          android:icon="@[package:]drawable/<em>drawable_resource_name</em>"
           android:alphabeticShortcut="<em>string</em>"
           android:numericShortcut="<em>string</em>"
           android:checkable=["true" | "false"]
@@ -172,22 +172,22 @@
 <dd>XML file saved at <code>res/menu/example_menu.xml</code>:
 <pre>
 &lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
-    &lt;item android:id="@+id/example_item"
-          android:title="Example Item"
-          android:icon="@drawable/example_item_icon" />
-    &lt;group android:id="@+id/example_group">
+    &lt;item android:id="@+id/item1"
+          android:title="@string/item1"
+          android:icon="@drawable/group_item1_icon" />
+    &lt;group android:id="@+id/group">
         &lt;item android:id="@+id/group_item1"
-              android:title="Group Item 1"
-              android:icon="@drawable/example_item1_icon" />
+              android:title="@string/group_item1"
+              android:icon="@drawable/group_item1_icon" />
         &lt;item android:id="@+id/group_item2"
-              android:title="Group Item 2"
-              android:icon="@drawable/example_item2_icon" />
+              android:title="G@string/group_item2"
+              android:icon="@drawable/group_item2_icon" />
     &lt;/group>
     &lt;item android:id="@+id/submenu"
-          android:title="Sub Menu" >
+          android:title="@string/submenu_title" >
         &lt;menu>
-            &lt;item android:id="@+id/submenu_item"
-                  android:title="Sub Menu Item" />
+            &lt;item android:id="@+id/submenu_item1"
+                  android:title="@string/submenu_item1" />
         &lt;/menu>
     &lt;/item>
 &lt;/menu>
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index b495eb8..0f3d389 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -7,13 +7,15 @@
 <div id="qv">
   <h2>Quickview</h2>
   <ul>
-    <li>Different types of resources belong in different sub-directories of {@code res/}</li>
+    <li>Different types of resources belong in different subdirectories of {@code res/}</li>
     <li>Alternative resources provide configuration-specific resource files</li>
   </ul>
   <h2>In this document</h2>
   <ol>
+    <li><a href="#ResourceTypes">Grouping Resource Types</a></li>
     <li><a href="#AlternativeResources">Providing Alternative Resources</a>
       <ol>
+        <li><a href="#QualifierRules">Qualifier name rules</a></li>
         <li><a href="#AliasResources">Creating alias resources</a></li>
       </ol>
     </li>
@@ -24,17 +26,30 @@
   <ol>
     <li><a href="accessing-resources.html">Accessing Resources</a></li>
     <li><a href="available-resources.html">Resource Types</a></li>
+    <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
   </ol>
 </div>
 </div>
 
-<p>There are several types of resource files you can
-include in your application and each type belongs in a specific sub-directory of your project's
-{@code res/} directory. Absolutely no files should be saved directly inside {@code res/}.</p>
+<p>You should always externalize application resources such as images and strings from your
+code, so that you can maintain them independently. You can also provide alternative resources for
+specific device configurations, by grouping them in specially-named resource directories. Android
+will then automatically apply the appropriate resource based on the current configuration. For
+instance, you might want to provide a different UI layout depending on the screen size.</p>
 
-<p>For example, here's the file hierarchy for a simple project:</p>
+<p>Once you save your resources external to your application code, you can access them
+using resource IDs that are generated in your project's {@code R} class. How to use
+resources in your application is discussed in <a href="accessing-resources.html">Accessing
+Resources</a>.</p>
 
-<pre class="no-pretty-print">
+
+<h2 id="ResourceTypes">Grouping Resource Types</h2>
+
+<p>You should place each type of resource in a specific subdirectory of your project's
+{@code res/} directory. For example, here's the file hierarchy for a simple project:</p>
+
+<pre class="classic no-pretty-print">
 MyProject/
     src/  <span style="color:black">
         MyActivity.java  </span>
@@ -42,23 +57,23 @@
         drawable/  <span style="color:black">
             icon.png  </span>
         layout/  <span style="color:black">
-            main_layout.xml  </span>
+            main.xml
+            info.xml</span>
         values/  <span style="color:black">
             strings.xml  </span>
 </pre>
 
-<p>This project includes an image resource, a layout resource, and string resource file.</p>
+<p>The {@code res/} directory contains all the resources (in subdirectories): an image resource, two
+layout resources, and a string resource file. The resource directory names are important and are
+described in table 1.</p>
 
-<p>Table 1 lists the different {@code res/} sub-directories supported
-and describes the types of resource files that belong in each one.</p>
-
-<p class="table-caption" id="table1"><strong>Table 1.</strong> Resource directories. Each directory
-belongs inside the project {@code res/} directory.</p>
+<p class="table-caption" id="table1"><strong>Table 1.</strong> Resource directories
+supported inside project {@code res/} directory.</p>
 
 <table>
   <tr>
     <th scope="col">Directory</th>
-    <th scope="col">Resource Types</th>
+    <th scope="col">Resource Type</th>
   </tr>
 
   <tr>
@@ -70,13 +85,13 @@
   <tr>
     <td><code>color/</code></td>
     <td>XML files that define a state list of colors. See <a href="color-list-resource.html">Color
-State List Resources</a></td>
+State List Resource</a></td>
   </tr>
 
   <tr>
     <td><code>drawable/</code></td>
     <td><p>Bitmap files ({@code .png}, {@code .9.png}, {@code .jpg}, {@code .gif}) or XML files that
-are compiled into the following Drawable resource subtypes:</p>
+are compiled into the following drawable resource subtypes:</p>
       <ul>
         <li>Bitmap files</li>
         <li>Nine-Patches (re-sizable bitmaps)</li>
@@ -107,37 +122,35 @@
 system. To open these resources with a raw {@link java.io.InputStream}, call {@link
 android.content.res.Resources#openRawResource(int)
 Resources.openRawResource()} with the resource ID, which is {@code R.raw.<em>filename</em>}.</p>
-      <p>However, if you require direct access to original file names and file hierarchy, instead of
-using a resource ID to access your files, you might consider saving some resources in the {@code
-assets/} directory, instead of {@code res/raw/}. You can query data in the {@code assets/} directory
-like an ordinary file system, search through the directory and read raw data using {@link
-android.content.res.AssetManager}.</p></td>
+      <p>However, if you need access to original file names and file hierarchy, you might consider
+saving some resources in the {@code
+assets/} directory (instead of {@code res/raw/}). Files in {@code assets/} are not given a
+resource ID, so you can read them only using {@link android.content.res.AssetManager}.</p></td>
   </tr>
 
   <tr>
     <td><code>values/</code></td>
     <td><p>XML files that contain simple values, such as strings, integers, and colors.</p>
-      <p>Unlike the other {@code res/} subdirectories, this one
-      can hold files that contain descriptions of more than one resource, rather than
-just one resource for the file. The XML element types of an XML file in {@code values/} control
-how these resources are defined in the {@code R} class. For example, a {@code &lt;string&gt;}
-element will create an
-{@code R.string} resource, and a  {@code &lt;color&gt;} element will create an {@code R.color}
+      <p>Whereas XML resource files in other {@code res/} subdirectories define a single resource
+based on the XML filename, files in the {@code values/} directory describe multiple resources.
+For a file in this directory, each child of the {@code &lt;resources&gt;} element defines a single
+resource. For example, a {@code &lt;string&gt;} element creates an
+{@code R.string} resource and a  {@code &lt;color&gt;} element creates an {@code R.color}
 resource.</p>
-      <p>While the name of a file in this directory is arbitrary and not related to the name given
-to a resource produced, you might want to separate different types of resources into different
-files for easier maintenance. Here are some filename conventions for some of the different types
-of resources you can save here:</p>
+      <p>Because each resource is defined with its own XML element, you can name the file
+whatever you want and place different resource types in one file. However, for clarity, you might
+want to place unique resource types in different files. For example, here are some filename
+conventions for resources you can create in this directory:</p>
       <ul>
-        <li>arrays.xml to define resource arrays (<a
+        <li>arrays.xml for resource arrays (<a
 href="more-resources.html#TypedArray">typed arrays</a>).</li>
-        <li>colors.xml to define <a
+        <li>colors.xml for <a
 href="more-resources.html#Color">color values</a></li>
-        <li>dimens.xml to define <a
+        <li>dimens.xml for <a
 href="more-resources.html#Dimension">dimension values</a>.</li>
-        <li>strings.xml to define <a href="string-resource.html">string
+        <li>strings.xml for <a href="string-resource.html">string
 values</a>.</li>
-        <li>styles.xml to define <a href="style-resource.html">styles</a>.</li>
+        <li>styles.xml for <a href="style-resource.html">styles</a>.</li>
       </ul>
       <p>See <a href="string-resource.html">String Resources</a>,
         <a href="style-resource.html">Style Resource</a>, and
@@ -147,38 +160,42 @@
 
   <tr>
     <td><code>xml/</code></td>
-    <td>Arbitrary XML files that are compiled and can be read at runtime by calling {@link
+    <td>Arbitrary XML files that can be read at runtime by calling {@link
 android.content.res.Resources#getXml(int) Resources.getXML()}. Various XML configuration files
-must also be saved here, such as a <a
+must be saved here, such as a <a
 href="{@docRoot}guide/topics/search/searchable-config.html">searchable configuration</a>.
 <!-- or preferences configuration. --></td>
   </tr>
 </table>
 
+<p class="note"><strong>Note:</strong> You should never save resource files directly inside the
+{@code res/} directory.</p>
+
 <p>For more information about certain types of resources, see the <a
 href="available-resources.html">Resource Types</a> documentation.</p>
 
-
-
+<p>How to access resources in the {@code res/} subdirectories is discussed in <a
+href="accessing-resources.html">Accessing Resources</a>.
+</p>
 
 
 
 <h2 id="AlternativeResources">Providing Alternative Resources</h2>
 
 
-<div class="figure" style="width:441px">
+<div class="figure" style="width:421px">
 <img src="{@docRoot}images/resources/resource_devices_diagram2.png" height="137" alt="" />
 <p class="img-caption">
 <strong>Figure 1.</strong> Two device configurations, one using alternative resources.</p>
 </div>
 
 <p>Almost every application should provide alternative resources to support specific device
-configurations. For instance, you should include different drawable resources for different
-screen densities and different string resources for different languages. At runtime, Android
-will automatically detect the current device configuration and then load the appropriate
+configurations. For instance, you should include alternative drawable resources for different
+screen densities and alternative string resources for different languages. At runtime, Android
+automatically detects the current device configuration and loads the appropriate
 resources.</p>
 
-<p>For each set of resources for which you want to provide configuration-specific alternatives:</p>
+<p>To specify configuration-specific alternatives for a set of resources:</p>
 <ol>
   <li>Create a new directory in {@code res/} named in the form {@code
 <em>&lt;resources_name&gt;</em>-<em>&lt;config_qualifier&gt;</em>}.
@@ -191,13 +208,13 @@
     <p>You can append more than one <em>{@code &lt;config_qualifier&gt;}</em>. Separate each
 one with a dash.</p>
   </li>
-  <li>Save your alternative resources in this directory, named exactly the same as the default
-resource files.</li>
+  <li>Save your alternative resources in this new directory. The resource files must be named
+exactly the same as the default resource files.</li>
 </ol>
 
 <p>For example, here are some default and alternative resources:</p>
 
-<pre class="no-pretty-print">
+<pre class="classic no-pretty-print">
 res/
     drawable/   <span style="color:black">
         icon.png
@@ -207,22 +224,23 @@
         background.png  </span>
 </pre>
 
-<p>The {@code hdpi} qualifier indicates that the resources are for devices with a high-density
-screen. While the images in each directory are different, the filenames are
-identical. This way, the resource ID that you use to reference the {@code icon.png} image is
-always the same. When you request the {@code icon} drawable, Android will select the
+<p>The {@code hdpi} qualifier indicates that the resources in that directory are for devices with a
+high-density screen. While the images in each drawable directory are sized for a specific screen
+density, the filenames are
+the same. This way, the resource ID that you use to reference the {@code icon.png} or {@code
+background.png} image is always the same, but Android selects the
 version of that drawable that best matches the current device configuration.</p>
 
 <p>Android supports several configuration qualifiers and you can
-add multiple qualifiers to one directory name in order to further specify the configuration, by
-separating the qualifiers with dashes. Table 2 lists the valid configuration qualifiers, in order
-of precedence&mdash;they must be specified in the directory name in the order that they are listed
-in the table.</p>
+add multiple qualifiers to one directory name, by separating each qualifier with a dash. Table 2
+lists the valid configuration qualifiers, in order of precedence&mdash;if you use multiple
+qualifiers, they must be added to the directory name in the order they are listed in the
+table.</p>
 
 
 <p class="table-caption" id="table2"><strong>Table 2.</strong> Alternative resource qualifier
 names.</p>
-<table border="1">
+<table>
     <tr>
         <th>Qualifier</th>
         <th>Values</th>
@@ -237,18 +255,22 @@
         etc.
       </td>
       <td>
-        <p>Specifies resources based on the mobile country code (MCC), optionally followed by mobile
-network code (MNC)
-        from the SIM in the device. For example, <code>mcc310</code> is U.S. on any carrier,
+        <p>The mobile country code (MCC), optionally followed by mobile network code (MNC)
+        from the SIM card in the device. For example, <code>mcc310</code> is U.S. on any carrier,
         <code>mcc310-mnc004</code> is U.S. on Verizon, and <code>mcc208-mnc00</code> is France on
         Orange.</p>
-        <p>If the device uses a radio connection (GSM phone), the MCC will come
-        from the SIM, and the MNC will come from the  network to which the
-        device is attached.</p>
-        <p>You might sometimes use the MCC alone, for example to include country-specific legal
-resources in your application, but if you only need to specify based on language, then use the
-language and region qualifier below. If you decide to use the MCC and MNC qualifier, you
-should do so with great care and completely test that it works as expected.</p></td>
+        <p>If the device uses a radio connection (GSM phone), the MCC comes
+        from the SIM, and the MNC comes from the network to which the
+        device is connected.</p>
+        <p>You can also use the MCC alone (for example, to include country-specific legal
+resources in your application). If you need to specify based on the language only, then use the
+<em>language and region</em> qualifier instead (discussed next). If you decide to use the MCC and
+MNC qualifier, you should do so with care and test that it works as expected.</p>
+        <p>Also see the configuration fields {@link
+android.content.res.Configuration#mcc}, and {@link
+android.content.res.Configuration#mnc}, which indicate the current mobile country code
+and mobile network code, respectively.</p>
+      </td>
     </tr>
     <tr>
       <td>Language and region</td>
@@ -260,22 +282,24 @@
         <code>fr-rCA</code><br/>
         etc.
       </td>
-      <td><p>This is defined by a two-letter <a
+      <td><p>The language is defined by a two-letter <a
 href="http://www.loc.gov/standards/iso639-2/php/code_list.php">ISO
               639-1</a> language code, optionally followed by a two letter
               <a
 href="http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO
-              3166-1-alpha-2</a> region code (preceded by lowercase &quot;r&quot;).
+              3166-1-alpha-2</a> region code (preceded by lowercase &quot;{@code r}&quot;).
         </p><p>
         The codes are <em>not</em> case-sensitive; the {@code r} prefix is used to
         distinguish the region portion.
         You cannot specify a region alone.</p>
         <p>This can change during the life
-of your application if the user changes their language in the system settings. See <a
+of your application if the user changes his or her language in the system settings. See <a
 href="runtime-changes.html">Handling Runtime Changes</a> for information about
 how this can affect your application during runtime.</p>
         <p>See <a href="localization.html">Localization</a> for a complete guide to localizing
 your application for other langauges.</p>
+        <p>Also see the {@link android.content.res.Configuration#locale} configuration field, which
+indicates the current locale.</p>
       </td>
     </tr>
     <tr>
@@ -286,24 +310,27 @@
         <code>large</code>
       </td>
       <td>
-        <ul>
-        <li> <b>Small screens</b> are based on the space available on a
-        QVGA low density screen.  Considering a portrait HVGA display, this has
-        the same available width but less height -- it is 3:4 vs. HVGA's
+        <ul class="nolist">
+        <li>{@code small}: Screens based on the space available on a
+        low-density QVGA screen.  Considering a portrait HVGA display, this has
+        the same available width but less height&mdash;it is 3:4 vs. HVGA's
         2:3 aspect ratio.  Examples are QVGA low density and VGA high
         density.</li>
-        <li> <b>Normal screens</b> are based on the traditional Android HVGA
-        medium density screen.  A screen is considered to be normal if it is
+        <li>{@code normal}: Screens based on the traditional
+        medium-density HVGA screen.  A screen is considered to be normal if it is
         at least this size (independent of density) and not larger.  Examples
         of such screens a WQVGA low density, HVGA medium density, WVGA
         high density.</li>
-        <li> <b>Large screens</b> are based on the space available on a
-        VGA medium density screen.  Such a screen has significantly more
+        <li>{@code large}: Screens based on the space available on a
+        medium-density VGA screen.  Such a screen has significantly more
         available space in both width and height than an HVGA display.
         Examples are VGA and WVGA medium density screens.</li>
         </ul>
         <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
 Screens</a> for more information.</p>
+        <p>Also see the {@link android.content.res.Configuration#screenLayout} configuration field,
+which indicates whether the screen is small, normal,
+or large.</p>
       </td>
     </tr>
     <tr>
@@ -313,12 +340,14 @@
         <code>notlong</code>
       </td>
       <td>
-        <p>This is based purely on the aspect ratio of the screen (a "long" screen is wider):
-        <ul>
-          <li><strong>Long</strong>: WQVGA, WVGA, FWVGA</li>
-          <li><strong>Not long</strong>: QVGA, HVGA, and VGA</li>
+        <ul class="nolist">
+          <li>{@code long}: Long screens, such as WQVGA, WVGA, FWVGA</li>
+          <li>{@code notlong}: Not long screens, such as QVGA, HVGA, and VGA</li>
         </ul>
-        <p>This is not related to the screen orientation.</p>
+        <p>This is based purely on the aspect ratio of the screen (a "long" screen is wider). This
+is not related to the screen orientation.</p>
+        <p>Also see the {@link android.content.res.Configuration#screenLayout} configuration field,
+which indicates whether the screen is long.</p>
       </td>
     </tr>
     <tr>
@@ -329,11 +358,16 @@
         <code>square</code>  -->
       </td>
       <td>
-        <p>Portrait orientation ({@code port}) is vertical and landscape orientation
-({@code land}) is horizontal. <!-- Square mode is currently not used. --> </p>
+        <ul class="nolist">
+          <li>{@code port}: Device is in portrait orientation (vertical)</li>
+          <li>{@code land}: Device is in landscape orientation (horizontal)</li>
+          <!-- Square mode is currently not used. -->
+        </ul>
         <p>This can change during the life of your application if the user rotates the
 screen. See <a href="runtime-changes.html">Handling Runtime Changes</a> for information about
 how this affects your application during runtime.</p>
+        <p>Also see the {@link android.content.res.Configuration#orientation} configuration field,
+which indicates the current device orientation.</p>
       </td>
     </tr>
     <tr>
@@ -343,12 +377,15 @@
         <code>desk</code>
       </td>
       <td>
-        <p>These configurations can be initiated when the device is placed in a dock.</p>
+        <ul class="nolist">
+          <li>{@code car}: Device is in a car dock</li>
+          <li>{@code desk}: Device is in a desk dock</li>
+        </ul>
         <p><em>Added in API Level 8.</em></p>
         <p>This can change during the life of your application if the user places the device in a
-dock. See <a href="runtime-changes.html">Handling Runtime Changes</a> for
-information about how this affects your application during runtime. Also see {@link
-android.app.UiModeManager}.</p>
+dock. You can eneable or disable this mode using {@link
+android.app.UiModeManager}. See <a href="runtime-changes.html">Handling Runtime Changes</a> for
+information about how this affects your application during runtime.</p>
       </td>
     </tr>
     <tr>
@@ -358,13 +395,16 @@
         <code>notnight</code>
       </td>
       <td>
-        <p>
-        These configurations can be initiated by the device light sensor (if available).</p>
+        <ul class="nolist">
+          <li>{@code night}: Night time</li>
+          <li>{@code notnight}: Day time</li>
+        </ul>
         <p><em>Added in API Level 8.</em></p>
-        <p>This can change during the life of your application if the device determines that the
-user environment is a "night" (dark) setting. See <a href="runtime-changes.html">Handling Runtime
-Changes</a> for information about how this affects your application during runtime. You can
-also explicitly set this mode using {@link android.app.UiModeManager}.</p>
+        <p>This can change during the life of your application if night mode is left in
+auto mode (default), in which case the mode changes based on the time of day.  You can eneable
+or disable this mode using {@link android.app.UiModeManager}. See <a
+href="runtime-changes.html">Handling Runtime Changes</a> for information about how this affects your
+application during runtime.</p>
       </td>
     </tr>
     <tr>
@@ -376,24 +416,27 @@
         <code>nodpi</code>
       </td>
       <td>
-        <p>The medium
-         density of traditional HVGA screens (mdpi) is defined to be approximately
-         160dpi; low density (ldpi) is 120, and high density (hdpi) is 240.  There
-         is thus a 4:3 scaling factor between each density, so a 9x9 bitmap
-         in ldpi would be 12x12 in mdpi and 16x16 in hdpi.  The special
-         <code>nodpi</code> density can be used with bitmap resources to prevent
-         them from being scaled at load time to match the device density.
-        </p><p>
-         When Android selects which resource files to use,
-         it handles screen density  differently than the other qualifiers.
+        <ul class="nolist">
+          <li>{@code ldpi}: Low-density screens; approximately 120dpi.</li>
+          <li>{@code mdpi}: Medium-density (on traditional HVGA) screens; approximately
+160dpi.</li>
+          <li>{@code hdpi}: High-density screens; approximately 240dpi.</li>
+          <li>{@code nodpi}: This can be used for bitmap resources that you do not want to be scaled
+to match the device density.</li>
+        </ul>
+        <p>There is thus a 4:3 scaling factor between each density, so a 9x9 bitmap
+         in ldpi is 12x12 in mdpi and 16x16 in hdpi.</p>
+        <p>When Android selects which resource files to use,
+         it handles screen density differently than the other qualifiers.
          In step 1 of <a href="#BestMatch">How Android finds the best
          matching directory</a> (below), screen density is always considered to
          be a match. In step 4, if the qualifier being considered is screen
-         density, Android will select the best final match at that point,
+         density, Android selects the best final match at that point,
          without any need to move on to step 5.
          </p>
         <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
-Screens</a> for more information.</p>
+Screens</a> for more information about how to handle screen sizes and how Android might scale
+your bitmaps.</p>
        </td>
     </tr>
     <tr>
@@ -403,25 +446,45 @@
         <code>stylus</code><br/>
         <code>finger</code>
       </td>
-      <td><p>If the device has a resistive touch screen that's suited for use with a stylus,
-then it may use the {@code stylus} resources.</p>
+      <td>
+        <ul class="nolist">
+          <li>{@code notouch}: Device does not have a touchscreen.</li>
+          <li>{@code stylus}: Device has a resistive touchscreen that's suited for use with a
+stylus.</li>
+          <li>{@code finger}: Device has a touchscreen.</li>
+        </ul>
+        <p>Also see the {@link android.content.res.Configuration#touchscreen} configuration field,
+which indicates the type of touchscreen on the device.</p>
       </td>
     </tr>
     <tr>
       <td>Keyboard availability</td>
       <td>
         <code>keysexposed</code><br/>
-        <code>keyshidden</code><br/>
         <code>keyssoft</code>
       </td>
       <td>
-        <p>If your application has specific resources that should only be used with a soft keyboard,
-use the <code>keyssoft</code> value. If you do not provide <code>keyssoft</code> resources, but do
-provide <code>keysexposed</code> and <code>keyshidden</code>, and the device shows a soft keyboard,
-the system will use <code>keysexposed</code> resources.</p>
-        <p>This can change during the life of your application if the user opens a keyboard. See <a
-href="runtime-changes.html">Handling Runtime Changes</a> for information about how this affects your
-application during runtime.</p>
+        <ul class="nolist">
+          <li>{@code keysexposed}: Device has a keyboard available. If the device has a
+software keyboard enabled (which is likely), this may be used even when the hardware keyboard is
+<em>not</em> exposed to the user, even if the device has no hardware keyboard. If no software
+keyboard is provided or it's disabled, then this is only used when a hardware keyboard is
+exposed.</li>
+          <li>{@code keyshidden}: Device has a hardware keyboard available but it is
+hidden <em>and</em> the device does <em>not</em> have a software keyboard enabled.</li>
+          <li>{@code keyssoft}: Device has a software keyboard enabled, whether it's
+visible or not.</li>
+        </ul>
+        <p>If you provide <code>keysexposed</code> resources, but not <code>keyssoft</code>
+resources, the system uses the <code>keysexposed</code> resources regardless of whether a
+keyboard is visible, as long as the system has a software keyboard enabled.</p>
+        <p>This can change during the life of your application if the user opens a hardware
+keyboard. See <a href="runtime-changes.html">Handling Runtime Changes</a> for information about how
+this affects your application during runtime.</p>
+        <p>Also see the configuration fields {@link
+android.content.res.Configuration#hardKeyboardHidden} and {@link
+android.content.res.Configuration#keyboardHidden}, which indicate the visibility of a hardware
+keyboard and and the visibility of any kind of keyboard (including software), respectively.</p>
       </td>
     </tr>
     <tr>
@@ -431,9 +494,17 @@
         <code>qwerty</code><br/>
         <code>12key</code>
       </td>
-      <td><p>If the device has no hardware keys for text input, then it may use the {@code
-nokeys} resources. Even if the device has a QWERTY keyboard but it is currently hidden, it may use
-the {@code qwerty} resources.</td>
+      <td>
+        <ul class="nolist">
+          <li>{@code nokeys}: Device has no hardware keys for text input.</li>
+          <li>{@code qwert}: Device has a hardware qwerty keyboard, whether it's visible to the user
+or not.</li>
+          <li>{@code 12key}: Device has a hardware 12-key keyboard, whether it's visible to the user
+or not.</li>
+        </ul>
+        <p>Also see the {@link android.content.res.Configuration#keyboard} configuration field,
+which indicates the primary text input method available.</p>
+      </td>
     </tr>
     <tr>
       <td>Navigation key availability</td>
@@ -442,13 +513,16 @@
         <code>navhidden</code>
       </td>
       <td>
-        <p>
-        If the device's navigation keys are currently available to
-        the user, it may use the {@code navexposed} resources; if they are not
-        available (such as behind a closed lid), it may use the {@code navhidden} resources.</p>
+        <ul class="nolist">
+          <li>{@code navexposed}: Navigation keys are available to the user.</li>
+          <li>{@code navhidden}: Navigation keys are not available (such as behind a closed
+lid).</li>
+        </ul>
         <p>This can change during the life of your application if the user reveals the navigation
 keys. See <a href="runtime-changes.html">Handling Runtime Changes</a> for
 information about how this affects your application during runtime.</p>
+        <p>Also see the {@link android.content.res.Configuration#navigationHidden} configuration
+field, which indicates whether navigation keys are hidden.</p>
       </td>
     </tr>
     <tr>
@@ -459,8 +533,16 @@
         <code>trackball</code><br/>
         <code>wheel</code>
       </td>
-      <td><p>If the device has no navigation facility other than using the touchscreen, then it
-may use the {@code nonav} resources.</p>
+      <td>
+        <ul class="nolist">
+          <li>{@code nonav}: Device has no navigation facility other than using the
+touchscreen.</li>
+          <li>{@code dpad}: Device has a directional-pad (d-pad) for navigation.</li>
+          <li>{@code trackball}: Device has a trackball for navigation.</li>
+          <li>{@code wheel}: Device has a directional wheel(s) for navigation (uncommon).</li>
+        </ul>
+        <p>Also see the {@link android.content.res.Configuration#navigation} configuration field,
+which indicates the type of navigation method available.</p>
       </td>
     </tr>
 <!-- DEPRECATED
@@ -495,20 +577,23 @@
     </tr>
 </table>
 
-<p>Here are some important rules about using resource qualifier names:</p>
+
+<h3 id="QualifierRules">Qualifier name rules</h3>
+
+<p>Here are some rules about using resource qualifier names:</p>
 
 <ul>
     <li>You can specify multiple qualifiers for a single set of resources, separated by dashes. For
 example, <code>drawable-en-rUS-land</code> applies to US-English devices in landscape
 orientation.</li>
-    <li>The qualifiers must be in the order listed in <a href="#table2">Table 2</a> above. For
+    <li>The qualifiers must be in the order listed in <a href="#table2">table 2</a>. For
 example:
       <ul>
         <li>Wrong: <code>drawable-hdpi-port/</code></li>
         <li>Correct: <code>drawable-port-hdpi/</code></li>
       </ul>
     </li>
-    <li>Qualified directories cannot be nested. For example, you cannot have
+    <li>Alternative resource directories cannot be nested. For example, you cannot have
 <code>res/drawable/drawable-en/</code>.</li>
     <li>Values are case-insensitive.  The resource compiler converts directory names
     to lower case before processing to avoid problems on case-insensitive
@@ -517,36 +602,41 @@
 the same drawable files for Spain and France, you <em>cannot</em> have a directory named
 <code>drawable-rES-rFR/</code>. Instead you need two resource directories, such as
 <code>drawable-rES/</code> and <code>drawable-rFR/</code>, which contain the appropriate files.
-However, you are not required to actually duplicate the same files in both locations (which
-could multiply the size of your package if the files are large). Instead, you can create a
-reference to one instance of the resources. See <a href="#AliasResources">Creating
-alias resources</a>, below.</li>
+However, you are not required to actually duplicate the same files in both locations. Instead, you
+can create an alias to a resource. See <a href="#AliasResources">Creating
+alias resources</a> below.</li>
 </ul>
 
+<p>After you save alternative resources into directories named with
+these qualifiers, Android automatically applies the resources in your application based on the
+current device configuration. Each time a resource is requested, Android checks for alternative
+resource directories that contain the requested resource file, then <a href="#BestMatch">finds the
+best-matching resource</a> (discussed below).</p>
+
 
 
 <h3 id="AliasResources">Creating alias resources</h3>
 
 <p>When you have a resource that you'd like to use for more than one device
-configuration (but not for all configurations), you <em>don't</em> have to put the same resource in
-each of the alternative resource directories. Instead, you can (in some cases) create an alternative
+configuration (but not for all configurations), you do not need to put the same resource in
+each alternative resource directory. Instead, you can (in some cases) create an alternative
 resource that acts as an alias for a resource saved in your default resource directory.</p>
 
-<p>For example, imagine you have an image, {@code icon.png}, and you have different versions of it
-for different locales, but two locales, English-Canadian and French-Canadian, need to
-use the same version. You might assume that you need to copy the Canadian version of the
-icon into the alternative resource directory for both English-Canadian and French-Canadian, but it's
-not true. What you can do instead is save the Canadian version as {@code icon_ca.png} (any name
-other than {@code icon.png}) and put
+<p class="note"><strong>Note:</strong> Not all resources offer a mechanism by which you can
+create an alias to another resource. In particular, animation, menu, raw, and other unspecified
+resources in the {@code xml/} directory do not offer this feature.</p>
+
+<p>For example, imagine you have an application icon, {@code icon.png}, and need unique version of
+it for different locales. However, two locales, English-Canadian and French-Canadian, need to
+use the same version. You might assume that you need to copy the same image
+into the resource directory for both English-Canadian and French-Canadian, but it's
+not true. Instead, you can save the image that's used for both as {@code icon_ca.png} (any
+name other than {@code icon.png}) and put
 it in the default {@code res/drawable/} directory. Then create an {@code icon.xml} file in {@code
 res/drawable-en-rCA/} and {@code res/drawable-fr-rCA/} that refers to the {@code icon_ca.png}
 resource using the {@code &lt;bitmap&gt;} element. This allows you to store just one version of the
 PNG file and two small XML files that point to it. (An example XML file is shown below.)</p>
 
-<p class="note"><strong>Note:</strong> Not all resources offer a mechanism by which you can
-create an alias to another resource. In particular, animation, menu, raw, and other unspecified
-resources in the {@code xml/} directory don't provide this kind of feature.</p>
-
 
 <h4>Drawable</h4>
 
@@ -559,9 +649,10 @@
     android:src="@drawable/icon_ca" />
 </pre>
 
-<p>If you save this file as {@code icon.xml}, it will be compiled into a resource that you
+<p>If you save this file as {@code icon.xml} (in an alternative resource directory, such as
+{@code res/drawable-en-rCA/}), it is compiled into a resource that you
 can reference as {@code R.drawable.icon}, but is actually an alias for the {@code
-R.drawable.icon_ca} resource.</p>
+R.drawable.icon_ca} resource (which is saved in {@code res/drawable/}).</p>
 
 
 <h4>Layout</h4>
@@ -576,7 +667,7 @@
 &lt;/merge>
 </pre>
 
-<p>If you save this file as {@code main.xml}, it will be compiled into a resource you can reference
+<p>If you save this file as {@code main.xml}, it is compiled into a resource you can reference
 as {@code R.layout.main}, but is actually an alias for the {@code R.layout.main_ltr}
 resource.</p>
 
@@ -614,24 +705,24 @@
 
 <h2 id="BestMatch">How Android Finds the Best-matching Resource</h2>
 
-<p>Once you have saved alternative resources for your application, Android will pick which of the
-various underlying resource files should be used at runtime for each resource
-requested, depending on the current device configuration. To demonstrate how Android will select the
-resource to use, assume the following drawables are available:</p>
+<p>When you request a resource for which you provide alternatives, Android selects which
+alternative resource to use at runtime, depending on the current device configuration. To
+demonstrate how Android selects an alternative resource, assume the following drawable directories
+each contain different versions of the same images:</p>
 
-<pre class="no-pretty-print">
-res/drawable/
-res/drawable-en/
-res/drawable-fr-rCA/
-res/drawable-en-port/
-res/drawable-en-notouch-12key/
-res/drawable-port-ldpi/
-res/drawable-port-notouch-12key
+<pre class="classic no-pretty-print">
+drawable/
+drawable-en/
+drawable-fr-rCA/
+drawable-en-port/
+drawable-en-notouch-12key/
+drawable-port-ldpi/
+drawable-port-notouch-12key/
 </pre>
 
 <p>And assume the following is the device configuration:</p>
 
-<p style="margin-left:2em;">
+<p style="margin-left:1em;">
 Locale = <code>en-GB</code> <br/>
 Screen orientation = <code>port</code> <br/>
 Screen pixel density = <code>hdpi</code> <br/>
@@ -639,85 +730,93 @@
 Primary text input method = <code>12key</code>
 </p>
 
+<p>By comparing the device configuration to the available alternative resources, Android selects
+drawables from {@code drawable-en-port}. It arrives at this decision using the following logic:</p>
 
-<p>Here is how Android makes the drawable selection and how a drawable will be selected from the
-configuration above: </p>
+
+<div class="figure" style="width:280px">
+<img src="{@docRoot}images/resources/res-selection-flowchart.png" alt="" height="590" />
+<p class="img-caption"><strong>Figure 2.</strong> Flowchart of how Android finds the
+best-matching resource.</p>
+</div>
+
 
 <ol>
   <li>Eliminate resource files that contradict the device configuration.
-    <p>The <code>drawable-fr-rCA/</code> directory will be eliminated, because it
-contradicts the locale of the device.</p>
-<pre class="no-pretty-print">
+    <p>The <code>drawable-fr-rCA/</code> directory is eliminated, because it
+contradicts the <code>en-GB</code> locale.</p>
+<pre class="classic no-pretty-print">
 drawable/
 drawable-en/
 <strike>drawable-fr-rCA/</strike>
 drawable-en-port/
 drawable-en-notouch-12key/
 drawable-port-ldpi/
-drawable-port-notouch-12key
+drawable-port-notouch-12key/
 </pre>
-<p class="note"><strong>Exception: </strong>Screen pixel density is the one qualifier that is not
-used to eliminate files. Even though the screen density of the device is mdpi,
+<p class="note"><strong>Exception:</strong> Screen pixel density is the one qualifier that is not
+eliminated due to a contradiction. Even though the screen density of the device is mdpi,
 <code>drawable-port-ldpi/</code> is not eliminated because every screen density is
-considered to be a match at this point.</p></li>
+considered to be a match at this point. More information is available in the <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a> document.</p></li>
 
-  <li>From <a href="#table2">Table 2</a>, pick the (next) highest-precedence qualifier in
-the list. (Start with MCC, then move down through the list.) </li>
-  <li>Do any of the available resource directories include this qualifier?  </li>
+  <li>Pick the (next) highest-precedence qualifier in the list (<a href="#table2">table 2</a>).
+(Start with MCC, then move down.) </li>
+  <li>Do any of the resource directories include this qualifier?  </li>
     <ul>
-      <li>If No, return to step 2 and look at the next qualifier. In the example,
-  the answer is &quot;no&quot; until the language qualifier is reached.</li>
-      <li>If Yes, move on to step 4.</li>
+      <li>If No, return to step 2 and look at the next qualifier. (In the example,
+  the answer is &quot;no&quot; until the language qualifier is reached.)</li>
+      <li>If Yes, continue to step 4.</li>
     </ul>
   </li>
 
   <li>Eliminate resource directories that do not include this qualifier. In the example, the system
 eliminates all the directories that do not include a language qualifier:</li>
-<pre class="no-pretty-print">
+<pre class="classic no-pretty-print">
 <strike>drawable/</strike>
 drawable-en/
 drawable-en-port/
 drawable-en-notouch-12key/
 <strike>drawable-port-ldpi/</strike>
-<strike>drawable-port-notouch-12key</strike>
+<strike>drawable-port-notouch-12key/</strike>
 </pre>
 <p class="note"><strong>Exception:</strong> If the qualifier in question is screen pixel density,
-Android will
-select the option that most closely matches the device, and the selection process will be complete.
-In general, Android will prefer scaling down a larger original image to scaling  up a smaller
-original image.</p>
+Android
+selects the option that most closely matches the device, and the selection process is complete.
+In general, Android prefers scaling down a larger original image to scaling  up a smaller
+original image. See <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a>.</p>
   </li>
 
-  <li>Go back and repeat steps 2, 3, and 4 until only one choice remains. In the example, screen
+  <li>Go back and repeat steps 2, 3, and 4 until only one directory remains. In the example, screen
 orientation is the next qualifier for which there are any matches.
 So, resources that do not specify a screen orientation are eliminated:
-<pre class="no-pretty-print">
+<pre class="classic no-pretty-print">
 <strike>drawable-en/</strike>
 drawable-en-port/
 <strike>drawable-en-notouch-12key/</strike>
 </pre>
-<p>Only one choice remains, so the drawable will be taken from the {@code drawable-en-port}
-directory.</p>
+<p>The remaining directory is {@code drawable-en-port}.</p>
   </li>
 </ol>
 
-<p>Though this procedure is executed for each resource requested, the system will further optimize
+<p>Though this procedure is executed for each resource requested, the system further optimizes
 some aspects. One such optimization is that once the device configuration is known, it might
-completely eliminate alternative resources that can never match. For example, if the configuration
+eliminate alternative resources that can never match. For example, if the configuration
 language is English ("en"), then any resource directory that has a language qualifier set to
-something other than English will never be included in the pool of resources checked (though a
+something other than English is never included in the pool of resources checked (though a
 resource directory <em>without</em> the language qualifier is still included).</p>
 
 <p class="note"><strong>Note:</strong> The <em>precedence</em> of the qualifier (in <a
-href="#table2">Table 2</a>) is more important
+href="#table2">table 2</a>) is more important
 than the number of qualifiers that exactly match the device. For example, in step 4 above, the last
 choice on the list includes three qualifiers that exactly match the device (orientation, touchscreen
 type, and input method), while <code>drawable-en</code> has only one parameter that matches
 (language). However, language has a higher precedence than these other qualifiers, so
-<code>drawable-port-notouch-12key</code>
-is out.</p>
+<code>drawable-port-notouch-12key</code> is out.</p>
 
-<p>The following flowchart summarizes how Android selects the resource directory to use.</p>
-<p><img src="{@docRoot}images/resources/res-selection-flowchart.png" alt=""
-height="471" /></p>
+<p>To learn more about how to use resources in your application, continue to <a
+href="accessing-resources.html">Accessing Resources</a>.</p>
+
 
diff --git a/docs/html/guide/topics/resources/runtime-changes.jd b/docs/html/guide/topics/resources/runtime-changes.jd
index dff664c..d75ff4d 100644
--- a/docs/html/guide/topics/resources/runtime-changes.jd
+++ b/docs/html/guide/topics/resources/runtime-changes.jd
@@ -8,7 +8,7 @@
 
   <h2>In this document</h2>
   <ol>
-    <li><a href="#CarryingAnObject">Carrying an Object During a Configuration Change</a></li>
+    <li><a href="#RetainingAnObject">Retaining an Object During a Configuration Change</a></li>
     <li><a href="#HandlingTheChange">Handling the Configuration Change Yourself</a>
   </ol>
 
@@ -24,80 +24,80 @@
 
 <p>Some device configurations can change during runtime
 (such as screen orientation, keyboard availability, and language). When such a change occurs,
-Android's default behavior is to restart the running
+Android restarts the running
 Activity ({@link android.app.Activity#onDestroy()} is called, followed by {@link
-android.app.Activity#onCreate(Bundle) onCreate()}). In doing so, the system re-queries your
-application resources for alternatives that might apply to the new configuration.</p>
+android.app.Activity#onCreate(Bundle) onCreate()}). The restart behavior is designed to help your
+application adapt to new configurations by automatically reloading your application with
+alternative resources.</p>
 
-<p>It is important that your Activity safely handles restarts and restores its previous
+<p>To properly handle a restart, it is important that your Activity restores its previous
 state through the normal <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Activity
-lifecycle</a>. In fact, it's a useful field test to invoke configuration changes (such as changing
-the screen orientation) during various states of your application to be sure that it properly
-restarts itself with the application state intact. So it's in the best interest of your application
-to allow the system to restart your application during any configuration change&mdash;this behavior
-is in place to help you by automatically handling configuration changes and adapting your
-application as necessary.</p>
+lifecycle</a>, in which Android calls
+{@link android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} before it destroys
+your Activity so that you can save data about the application state. You can then restore the state
+during {@link android.app.Activity#onCreate(Bundle) onCreate()} or {@link
+android.app.Activity#onRestoreInstanceState(Bundle) onRestoreInstanceState()}. To test
+that your application restarts itself with the application state intact, you should
+invoke configuration changes (such as changing the screen orientation) while performing various
+tasks in your application.</p>
+
+<p>Your application should be able to restart at any time without loss of user data or
+state in order to handle events such as when the user receives an incoming phone call and then
+returns to your application (read about the
+<a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Activity lifecycle</a>).</p>
 
 <p>However, you might encounter a situation in which restarting your application and
-restoring significant amounts of data can be costly, create a slow user experience, and
-using {@link android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} does not
-suffice. In such a situation, you have two options:</p>
+restoring significant amounts of data can be costly and create a poor user experience. In such a
+situation, you have two options:</p>
 
 <ol type="a">
-  <li><a href="#CarryingAnObject">Carrying an Object During a Configuration Change</a>
-  <p>Allow your
-application to restart so that the appropriate configuration changes can take effect, but also
-implement {@link android.app.Activity#onRetainNonConfigurationInstance()} paired with {@link
-android.app.Activity#getLastNonConfigurationInstance()} to carry an {@link java.lang.Object} over
-to the new instance of your Activity.</p>
-  <p>This is the recommended technique if you're facing performance issues during the
-configuration restart. It allows your Activity to properly restart and reload resources for
-the new configuration and also allows you to carry your arbitrary data that may be expensive to
-collect again.</p>
+  <li><a href="#RetainAnObject">Retain an object during a configuration change</a>
+  <p>Allow your Activity to restart when a configuration changes, but carry a stateful
+{@link java.lang.Object} to the new instance of your Activity.</p>
+
   </li>
-  <li><a href="#HandlingTheChange">Handling the Configuration Change Yourself</a>
-  <p>Declare that your
-application will handle certain configuration changes and prevent the system from restarting your
-application when such a change occurs. For example, you can declare in your manifest that your
-Activity will handle configuration changes to the screen orientation. When the orientation
-changes, your Activity will not be restarted and your Activity will receive a call to {@link
-android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} so that you can
-perform necessary changes based on the new configuration.</p>
-  <p>This technique should be considered a last resort and temporary solution, because not all
-runtime configuration changes can be handled this way&mdash;your application will eventually
-encounter a runtime configuration in which you cannot prevent the Activity from being restarted,
-whereas the first option will handle all configuration changes.</p>
+  <li><a href="#HandlingTheChange">Handle the configuration change yourself</a>
+  <p>Prevent the system from restarting your Activity during certain configuration
+changes and receive a callback when the configurations do change, so that you can manually update
+your Activity as necessary.</p>
   </li>
 </ol>
 
-<p class="note"><strong>Note:</strong> Your application should always be able to successfully
-restart at any time without any loss of user data or state in order to handle other events such as
-when the user receives an incoming phone call and then returns to your application (read about the
-<a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Activity lifecycle</a>). The following
-techniques for handling runtime configuration changes should only be necessary to optimize
-performance during specific configuration changes.</p>
 
+<h2 id="RetainingAnObject">Retaining an Object During a Configuration Change</h2>
 
-<h2 id="CarryingAnObject">Carrying an Object During a Configuration Change</h2>
+<p>If restarting your Activity requires that you recover large sets of data, re-establish a
+network connection, or perform other intensive operations, then a full restart due to a
+configuration change might
+be an unpleasant user experience. Also, it may not be possible for you to completely
+maintain your Activity state with the {@link android.os.Bundle} that the system saves for you during
+the Activity lifecycle&mdash;it is not designed to carry large objects (such as bitmaps) and the
+data within it must be serialized then deserialized, which can consume a lot of memory and make the
+configuration change slow. In such a situation, you can alleviate the burden of reinitializing
+your Activity by retaining a stateful Object when your Activity is restarted due to a configuration
+change.</p>
 
-<p>If your application has acquired significant amounts of data during its life, which would be
-costly to recover due to a restart of the Activity, you can use {@link
-android.app.Activity#onRetainNonConfigurationInstance()} paired with {@link
-android.app.Activity#getLastNonConfigurationInstance()} to pass an {@link java.lang.Object}
-to the new Activity instance. The {@link android.app.Activity#onRetainNonConfigurationInstance()}
-method is called between {@link android.app.Activity#onStop()} and {@link
-android.app.Activity#onDestroy()} when your Activity is being shut down due to a configuration
-change. In your implementation of this method, you can return any {@link java.lang.Object} that you
-need to efficiently restore your state after the configuration change. When your Activity is
-created again, you can call {@link
-android.app.Activity#getLastNonConfigurationInstance()} to retrieve the {@link
-java.lang.Object}.</p>
+<p>To retain an Object during a runtime configuration change:</p>
+<ol>
+  <li>Override the {@link android.app.Activity#onRetainNonConfigurationInstance()} method to return
+the Object you would like to retain.</li>
+  <li>When your Activity is created again, call {@link
+android.app.Activity#getLastNonConfigurationInstance()} to recover your Object.</li>
+</ol>
+
+<p>Android calls {@link android.app.Activity#onRetainNonConfigurationInstance()} between {@link
+android.app.Activity#onStop()} and {@link
+android.app.Activity#onDestroy()} when it shuts down your Activity due to a configuration
+change. In your implementation of {@link
+android.app.Activity#onRetainNonConfigurationInstance()}, you can return any {@link
+java.lang.Object} that you need in order to efficiently restore your state after the configuration
+change.</p>
 
 <p>A scenario in which this can be valuable is if your application loads a lot of data from the
 web. If the user changes the orientation of the device and the Activity restarts, your application
-will need to re-fetch the data, which could be slow. What you can do is implement
+must re-fetch the data, which could be slow. What you can do instead is implement
 {@link android.app.Activity#onRetainNonConfigurationInstance()} to return an object carrying your
-data and then retrieve the data when your Activity restarts with {@link
+data and then retrieve the data when your Activity starts again with {@link
 android.app.Activity#getLastNonConfigurationInstance()}. For example:</p>
 
 <pre>
@@ -116,7 +116,7 @@
 means that your application maintains a hold on them and they cannot be garbage-collected, so
 lots of memory can be lost.)</p>
 
-<p>Then get the {@code data} after the restart:</p>
+<p>Then retrieve the {@code data} when your Activity starts again:</p>
 
 <pre>
 &#64;Override
@@ -132,9 +132,10 @@
 }
 </pre>
 
-<p>In this case, {@link android.app.Activity#getLastNonConfigurationInstance()} is called to get
-the data saved during the configuration change, and if it is null (which will happen if the
-Activity is started in any case other than a configuration change) then the data is loaded
+<p>In this case, {@link android.app.Activity#getLastNonConfigurationInstance()} retrieves
+the data saved by {@link android.app.Activity#onRetainNonConfigurationInstance()}. If {@code data}
+is null (which happens when the
+Activity starts due to any reason other than a configuration change) then the data object is loaded
 from the original source.</p>
 
 
@@ -146,11 +147,12 @@
 <p>If your application doesn't need to update resources during a specific configuration
 change <em>and</em> you have a performance limitation that requires you to
 avoid the Activity restart, then you can declare that your Activity handles the configuration change
-itself, which will prevent the system from restarting your Activity.</p>
+itself, which prevents the system from restarting your Activity.</p>
 
 <p class="note"><strong>Note:</strong> Handling the configuration change yourself can make it much
-more difficult to use alternative resources, because the system will not automatically apply them
-for you.</p>
+more difficult to use alternative resources, because the system does not automatically apply them
+for you. This technique should be considered a last resort and is not recommended for most
+applications.</p>
 
 <p>To declare that your Activity handles a configuration change, edit the appropriate <a
 href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> element
diff --git a/docs/html/guide/topics/testing/testing_android.jd b/docs/html/guide/topics/testing/testing_android.jd
new file mode 100755
index 0000000..fc1d223
--- /dev/null
+++ b/docs/html/guide/topics/testing/testing_android.jd
@@ -0,0 +1,494 @@
+page.title=Testing and Instrumentation
+@jd:body
+<div id="qv-wrapper">
+  <div id="qv">
+  <h2>In this document</h2>
+  <ol>
+    <li>
+        <a href="#Overview">Overview</a>
+    </li>
+    <li>
+      <a href="#TestAPI">The Testing API</a>
+      <ol>
+        <li>
+          <a href="#Extensions">JUnit test case classes</a>
+        </li>
+        <li>
+          <a href="#Instrumentation">Instrumentation test case classes</a>
+        </li>
+        <li>
+          <a href="#Assert">Assert classes</a>
+        </li>
+        <li>
+          <a href="#MockObjects">Mock object classes</a>
+        </li>
+            <li>
+                <a href="#InstrumentationTestRunner">Instrumentation Test Runner</a>
+            </li>
+      </ol>
+    </li>
+    <li>
+     <a href="#TestEnviroment">Working in the Test Environment</a>
+    </li>
+    <li>
+        <a href="#TestAreas">What to Test</a>
+    </li>
+    <li>
+      <a href="#UITesting">Appendix: UI Testing Notes</a>
+      <ol>
+        <li>
+          <a href="#RunOnUIThread">Testing on the UI thread</a>
+        </li>
+        <li>
+          <a href="#NotouchMode">Turning off touch mode</a>
+        </li>
+        <li>
+          <a href="#UnlockDevice">Unlocking the Emulator or Device</a>
+        </li>
+        <li>
+          <a href="#UITestTroubleshooting">Troubleshooting UI tests</a>
+        </li>
+      </ol>
+    </li>
+  </ol>
+  <h2>Key Classes</h2>
+    <ol>
+      <li>{@link android.test.InstrumentationTestRunner}</li>
+      <li>{@link android.test.ActivityInstrumentationTestCase2}</li>
+      <li>{@link android.test.ActivityUnitTestCase}</li>
+      <li>{@link android.test.ApplicationTestCase}</li>
+      <li>{@link android.test.ProviderTestCase2}</li>
+      <li>{@link android.test.ServiceTestCase}</li>
+    </ol>
+  <h2>Related Tutorials</h2>
+    <ol>
+        <li>
+            <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello, Testing</a>
+        </li>
+        <li>
+            <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
+        </li>
+    </ol>
+  <h2>See Also</h2>
+      <ol>
+        <li>
+          <a href="{@docRoot}guide/developing/testing_eclipse.html">Testing in Eclipse, with ADT</a>
+        </li>
+        <li>
+          <a href="{@docRoot}guide/developing/testing_otheride.html">Testing in Other IDEs</a>
+        </li>
+      </ol>
+  </div>
+</div>
+<p>
+Android includes a powerful set of testing tools that extend the industry-standard JUnit test framework with features specific to the Android environment. Although you can
+test an Android application with JUnit, the Android tools allow you to write much more sophisticated tests for every aspect of your application, both at the unit and at the framework level.
+</p>
+<p>
+Key features of the Android testing environment include:
+</p>
+<ul>
+  <li>Android extensions to the JUnit framework that provide access to Android system objects.</li>
+  <li>An instrumentation framework that lets tests control and examine the application.</li>
+  <li>Mock versions of commonly-used Android system objects.</li>
+  <li>Tools for running single tests or test suites, with or without instrumentation.</li>
+  <li>Support for managing tests and test projects in the ADT Plugin for Eclipse and at the command line.</li>
+</ul>
+<p>
+This document is an overview of the Android testing environment and the way you use it. The document assumes you have a basic knowledge of
+Android application programming and JUnit testing methodology.
+</p>
+<h2 id="Overview">Overview</h2>
+<p>
+At the heart of the Android testing environment is an instrumentation framework that your test application uses to precisely control the application under test. With instrumentation, you can
+set up mock system objects such as Contexts before the main application starts, control your application at various points of its lifecycle, send UI events to the application, and
+examine the application's state during its execution. The instrumentation framework accomplishes this by running both the main application and the test application in the same process.
+</p>
+<p>
+    Your test application's manifest file links it to the application under test. The the &lt;instrumentation&gt; attribute in the manifest file points to the application under test
+    and also tells Android how to run the test application. This is described in more detail in the section <a href="#InstrumentationTestRunner">Instrumentation Test Runner</a>.
+</p>
+<p>
+The following diagram summarizes the Android testing environment:
+</p>
+<img src="{@docRoot}images/testing/android_test_framework.png"/>
+<!--  Something about test tools in Eclipse and in other IDEs -->
+<p>
+  In Android, test applications are themselves Android applications, so you write them in much the same way as the application you are testing. The SDK tools
+  help you create a main application project and its test project at the same time. You can run Android tests within Eclipse with ADT or from the command line.
+  Eclipse with ADT provides an extensive set of tools for creating tests, running them, and viewing their results. You can also use the <code>adb</code> tool to
+  run tests, or use a built-in Ant target.
+</p>
+<p>
+  To learn how to set up and run tests in Eclipse, please refer to <a href="{@docRoot}guide/developing/testing_eclipse.html">Testing in Eclipse, with ADT</a>.
+  If you're not working in Eclipse, refer to <a href="{@docRoot}guide/developing/testing_otheride.html">Testing in Other IDEs</a>.
+</p>
+<p>
+    If you want a step-by-step introduction to Android testing, try one of the testing tutorials:
+</p>
+    <ul>
+        <li>
+            The <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello, Testing</a> tutorial introduces basic testing concepts and procedures in the
+            context of the Hello, World application.
+        </li>
+        <li>
+            The <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a> tutorial is an excellent follow-up to the Hello, Testing tutorial.
+            It guides you through a more complex testing scenario that you develop against a more realistic application.
+        </li>
+    </ul>
+<h2 id="TestAPI">The Testing API</h2>
+<p>
+    For writing tests and test applications in the Java programming language, Android provides a
+    testing API that is based in part on the JUnit test framework. Adding to that, Android includes
+    a powerful instrumentation framework that lets your tests access the state and runtime objects
+    of the application under tests.
+</p>
+<p>The sections below describe the major components of the testing API available in Android.</p>
+<h3 id="Extensions">JUnit test case classes</h3>
+<p>
+  Some of the classes in the testing API extend the JUnit {@link junit.framework.TestCase TestCase} but do not use the instrumentation framework. These classes
+  contain methods for accessing system objects such as the Context of the application under test. With this Context, you can look at its resources, files, databases,
+  and so forth. The base class is {@link android.test.AndroidTestCase}, but you usually use a subclass associated with a particular component.
+<p>
+  The subclasses are:
+</p>
+  <ul>
+    <li>
+      {@link android.test.ApplicationTestCase} - A class for testing an entire application. It allows you to inject a mock Context into the application,
+      set up initial test parameters before the application starts, and examine the application after it finishes but before it is destroyed.
+    </li>
+    <li>
+      {@link android.test.ProviderTestCase2} - A class for isolated testing of a single {@link android.content.ContentProvider}. Since it is restricted to using a
+      {@link android.test.mock.MockContentResolver} for the provider, and it injects an {@link android.test.IsolatedContext}, your provider testing is isolated
+      from the rest of the OS.
+    </li>
+    <li>
+      {@link android.test.ServiceTestCase} - a class for isolated testing of a single {@link android.app.Service}. You can inject a mock Context or
+      mock Application (or both), or let Android provide you a full Context and a {@link android.test.mock.MockApplication}.
+    </li>
+  </ul>
+<h3 id="Instrumentation">Instrumentation test case classes</h3>
+<p>
+  The API for testing activities extends the JUnit {@link junit.framework.TestCase TestCase} class and also uses the instrumentation framework. With instrumentation,
+  Android can automate UI testing by sending events to the application under test, precisely control the start of an activity, and monitor the state of the
+  activity during its life cycle.
+</p>
+<p>
+  The base class is {@link android.test.InstrumentationTestCase}. All of its subclasses have the ability to send a keystroke or touch event to the UI of the application
+  under test. The subclasses can also inject a mock Intent.
+  The subclasses are:
+</p>
+  <ul>
+    <li>
+      {@link android.test.ActivityTestCase} - A base class for activity test classes.
+    </li>
+    <li>
+      {@link android.test.SingleLaunchActivityTestCase} - A convenience class for testing a single activity.
+      It invokes {@link junit.framework.TestCase#setUp() setUp()} and {@link junit.framework.TestCase#tearDown() tearDown()} only
+      once, instead of once per method call. Use it when all of your test methods run against the same activity.
+    </li>
+    <li>
+      {@link android.test.SyncBaseInstrumentation} - A class that tests synchronization of a content provider. It uses instrumentation to cancel and disable
+      existing synchronizations before starting the test synchronization.
+    </li>
+    <li>
+      {@link android.test.ActivityUnitTestCase} - This class does an isolated test of a single activity. With it, you can inject a mock context or application, or both.
+      It is intended for doing unit tests of an activity, and is the activity equivalent of the test classes described in <a href="#Extensions">JUnit test case classes</a>.
+      <p> Unlike the other instrumentation classes, this test class cannot inject a mock Intent.</p>
+    </li>
+    <li>
+      {@link android.test.ActivityInstrumentationTestCase2} - This class tests a single activity within the normal system environment.
+      You cannot inject a mock Context, but you can inject mock Intents. Also, you can run a test method on the UI thread (the main thread of the application under test),
+      which allows you to send key and touch events to the application UI.
+    </li>
+  </ul>
+<h3 id="Assert">Assert classes</h3>
+<p>
+  Android also extends the JUnit {@link junit.framework.Assert} class that is the basis of <code>assert()</code> calls in tests.
+  There are two extensions to this class, {@link android.test.MoreAsserts} and {@link android.test.ViewAsserts}:
+</p>
+<ul>
+  <li>
+    The <code>MoreAsserts</code> class contains more powerful assertions such as {@link android.test.MoreAsserts#assertContainsRegex} that does regular expression matching.
+  </li>
+  <li>
+    The {@link android.test.ViewAsserts} class contains useful assertions about Android Views, such as {@link android.test.ViewAsserts#assertHasScreenCoordinates} that tests if a View has a particular X and Y
+    position on the visible screen. These asserts simplify testing of geometry and alignment in the UI.
+  </li>
+</ul>
+<h3 id="MockObjects">Mock object classes</h3>
+  <p>
+    Android has convenience classes for creating mock system objects such as applications, contexts, content resolvers, and resources. Android also provides
+    methods in some test classes for creating mock Intents. Use these mocks to facilitate dependency injection, since they are easier to use than creating their
+    real counterparts. These convenience classes are found in {@link android.test} and {@link android.test.mock}. They are:
+  </p>
+    <ul>
+      <li>
+        {@link android.test.IsolatedContext} - Mocks a Context so that the application using it runs in isolation.
+        At the same time, it has enough stub code to satisfy OS code that tries to communicate with contexts. This class is useful in unit testing.
+      </li>
+      <li>
+        {@link android.test.RenamingDelegatingContext} - Delegates most context functions to an existing, normal context while changing the default file and database
+        names in the context. Use this to test file and database operations with a normal system context, using test names.
+      </li>
+      <li>
+        {@link android.test.mock.MockApplication}, {@link android.test.mock.MockContentResolver}, {@link android.test.mock.MockContext},
+        {@link android.test.mock.MockDialogInterface}, {@link android.test.mock.MockPackageManager},
+        {@link android.test.mock.MockResources} - Classes that create mock Android system objects for use in testing. They expose only those methods that are
+        useful in managing the object. The default implementations of these methods simply throw an Exception. You are expected to extend the classes and
+        override any methods that are called by the application under test.
+      </li>
+    </ul>
+<h3 id="InstrumentationTestRunner">Instrumentation Test Runner</h3>
+<p>
+  Android provides a custom class for running tests with instrumentation called called
+  {@link android.test.InstrumentationTestRunner}. This class
+  controls of the application under test, runs the test application and the main application in the same process, and routes
+  test output to the appropriate place. Using instrumentation is key to the ability of <code>InstrumentationTestRunner</code> to control the entire test
+  environment at runtime. Notice that you use this test runner even if your test class does not itself use instrumentation.
+</p>
+<p>
+  When you run a test application, you first run a system utility called Activity Manager. Activity Manager uses the instrumentation framework to start and control the test runner, which in turn uses instrumentation to shut down any running instances
+  of the main application, starts the test application, and then starts the main application in the same process. This allows various aspects of the test application to work directly with the main application.
+</p>
+<p>
+  If you are developing in Eclipse, the ADT plugin assists you in the setup of <code>InstrumentationTestRunner</code> or other test runners.
+  The plugin UI prompts you to specify the test runner class to use, as well as the package name of the application under test.
+  The plugin then adds an <code>&lt;instrumentation&gt;</code> element with appropriate attributes to the manifest file of the test application.
+  Eclipse with ADT automatically starts a test application under the control of Activity Manager using instrumentation,
+  and redirects the test output to the Eclipse window's JUnit view.
+</p>
+<p>
+  If you prefer working from the command line, you can use Ant and the <code>android</code>
+  tool to help you set up your test projects. To run tests with instrumentation, you can access the
+  Activity Manager through the <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug
+  Bridge</a> (<code>adb</code>) tool and the output is directed to <code>STDOUT</code>.
+</p>
+<h2 id="TestEnviroment">Working in the Test Environment</h2>
+<p>
+    The tests for an Android application are contained in a test application, which itself is an Android application. A test application resides in a separate Android project that has the
+    same files and directories as a regular Android application. The test project is linked to the project of the application it tests
+    (known as the application under test) by its manifest file.
+</p>
+<p>
+    Each test application contains one or more test case classes based on an Android class for a
+    particular type of component. The test case class contains methods that define tests on some part of the application under test. When you run the test application, Android
+    starts it, loads the application under test into the same process, and then invokes each method in the test case class.
+</p>
+<p>
+    The tools and procedures you use with testing depend on the development environment you are using. If you use Eclipse, then the ADT plug in for Eclipse provides tools that
+    allow you to develop and run tests entirely within Eclipse. This is documented in the topic <a href="{@docRoot}guide/developing/testing_eclipse.html">Testing in Eclipse, with ADT</a>.
+    If you use another development environment, then you use Android's command-line tools, as documented in the topic <a href="{@docRoot}guide/developing/testing_otheride.html">Testing in Other IDEs</a>.
+</p>
+<h3 id="TestProjects">Working with test projects</h3>
+<p>
+    To start testing an Android application, you create a test project for it using Android tools. The tools create the project directory and the files and subdirectories needed.
+    The tools also create a manifest file that links the application in the test project to the application under test. The procedure for creating a test project in Eclipse with
+    ADT is documented in <a href="{@docRoot}guide/developing/testing_eclipse.html">Testing in Eclipse, with ADT</a>. The procedure for creating a test project for use with development
+    tools other than Eclipse is documented in <a href="{@docRoot}guide/developing/testing_otheride.html">Testing in Other IDEs</a>.
+</p>
+<h3 id="TestClasses">Working with test case classes</h3>
+<p>
+    A test application contains one or more test case classes that extend an Android test case class. You choose a test case class based on the type of Android component you are testing and the
+    tests you are doing. A test application can test different components, but each test case class is designed to test a single type of component.
+    The Android test case classes are described in the section <a href="#TestAPI">The Testing API</a>.
+</p>
+<p>
+    Some Android components have more than one associated test case class. In this case, you choose among the available classes based on the type of tests you want to do. For activities,
+    for example, you have the choice of either {@link android.test.ActivityInstrumentationTestCase2} or {@link android.test.ActivityUnitTestCase}.
+<p>
+    <code>ActivityInstrumentationTestCase2</code> is designed to do functional testing, so it tests activities in a normal system infrastructure. You can inject mocked Intents, but not
+    mocked Contexts. In general, you can't mock dependencies for the activity under test.
+</p>
+<p>
+    In comparison, <code>ActivityUnitTestCase</code> is designed for unit testing, so it tests activities in an isolated system infrastructure. You can inject mocked or wrappered dependencies for
+    the activity under test, particularly mocked Contexts. On the other hand, when you use this test case class the activity under test runs in isolation and can't interact with other activities.
+</p>
+<p>
+    As a rule of thumb, if you wanted to test an activity's interaction with the rest of Android, you would use <code>ActivityInstrumentationTestCase2</code>. If you wanted to do regression testing
+    on an activity, you would use <code>ActivityUnitTestCase</code>.
+</p>
+<h3 id="Tests">Working with test methods</h3>
+<p>
+    Each test case class provides methods that you use to set up the test environment and control the application under test. For example, all test case classes provide the JUnit {@link junit.framework.TestCase#setUp() setUp()}
+    method that you can override to set up fixtures. In addition, you add methods to the class to define individual tests. Each method you add is run once each time you run the test application. If you override the <code>setUp()</code>
+    method, it runs before each of your methods. Similarly, the JUnit {@link junit.framework.TestCase#tearDown() tearDown()} method is run once after each of your methods.
+</p>
+<p>
+    The test case classes give you substantial control over starting and stopping components. For this reason, you have to specifically tell Android to start a component before you run tests against it. For example, you use the
+    {@link android.test.ActivityInstrumentationTestCase2#getActivity()} method to start the activity under test. You can call this method once during the entire test case, or once for each test method. You can even destroy the
+    activity under test by calling its {@link android.app.Activity#finish()} method and then restart it with <code>getActivity()</code> within a single test method.
+</p>
+<h3 id="RunTests">Running tests and seeing the results</h3>
+<p>
+    To run your tests, you build your test project and then run the test application using the system utility Activity Manager with instrumentation. You provide to Activity Manager the name of the test runner (usually
+    {@link android.test.InstrumentationTestRunner}) you specified for your application; the name includes both your test application's package name and the test runner class name. Activity Manager loads and starts your
+    test application, kills any instances of the application under test, loads an instance of the application under test into the same process as the test application, and then passes control to the first test case
+    class in your test application. The test runner then takes control of the tests, running each of your test methods against the application under test until all the methods in all the classes have been run.
+</p>
+<p>
+    If you run a test within Eclipse with ADT, the output appears in a new JUnit view pane. If you run a test from the command line, the output goes to STDOUT.
+</p>
+<h2 id="TestAreas">What to Test</h2>
+<p>
+  In addition to the functional areas you would normally test, here are some areas
+  of Android application testing that you should consider:
+</p>
+  <ul>
+    <li>
+      Activity lifecycle events: You should test that your activities handle lifecycle events correctly. For example
+      an activity should respond to pause or destroy events by saving its state. Remember that even a change in screen orientation
+      causes the current activity to be destroyed, so you should test that accidental device movements don't accidentally lose the
+      application state.
+    </li>
+    <li>
+      Database operations: You should ensure that database operations correctly handle changes to the application's state.
+      To do this, use mock objects from the package {@link android.test.mock android.test.mock}.
+    </li>
+    <li>
+        Screen sizes and resolutions: Before you publish your application, make sure to test it on all of the
+        screen sizes and densities on which you want it to run. You can test the application on multiple sizes and densities using
+        AVDs, or you can test your application directly on the devices that you are targeting. For more information, see
+        the topic <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.
+    </li>
+  </ul>
+<p>
+  When possible, you should run these tests on an actual device. If this is not possible, you can
+  use the <a href="{@docRoot}guide/developing/tools/emulator.html">Android Emulator</a> with
+  <a href="{@docRoot}guide/developing/tools/avd.html">Android Virtual Devices</a> configured for
+  the hardware, screens, and versions you want to test.
+</p>
+<h2 id="UITesting">Appendix: UI Testing Notes</h2>
+<p>
+  The following sections have tips for testing the UI of your Android application, specifically
+  to help you handle actions that run in the UI thread, touch screen and keyboard events, and home
+  screen unlock during testing.
+</p>
+<h3 id="RunOnUIThread">Testing on the UI thread</h3>
+<p>
+  An application's activities run on the application's <strong>UI thread</strong>. Once the
+  UI is instantiated, for example in the activity's <code>onCreate()</code> method, then all
+  interactions with the UI must run in the UI thread. When you run the application normally, it
+  has access to the thread and does not have to do anything special.
+</p>
+<p>
+  This changes when you run tests against the application. With instrumentation-based classes,
+  you can invoke methods against the UI of the application under test. The other test classes don't allow this.
+  To run an entire test method on the UI thread, you can annotate the thread with <code>@UIThreadTest</code>.
+  Notice that this will run <em>all</em> of the method statements on the UI thread.  Methods that do not interact with the UI
+  are not allowed; for example, you can't invoke <code>Instrumentation.waitForIdleSync()</code>.
+</p>
+<p>
+  To run a subset of a test method on the UI thread, create an anonymous class of type
+  <code>Runnable</code>, put the statements you want in the <code>run()</code> method, and instantiate a new
+  instance of the class as a parameter to the method <code><em>appActivity</em>.runOnUiThread()</code>, where
+  <code><em>appActivity</em></code> is the instance of the app you are testing.
+</p>
+<p>
+  For example, this code instantiates an activity to test, requests focus (a UI action) for the Spinner displayed
+  by the activity, and then sends a key to it. Notice that the calls to <code>waitForIdleSync</code> and <code>sendKeys</code>
+  aren't allowed to run on the UI thread:</p>
+<pre>
+  private MyActivity mActivity; // MyActivity is the class name of the app under test
+  private Spinner mSpinner;
+
+  ...
+
+  protected void setUp() throws Exception {
+      super.setUp();
+      mInstrumentation = getInstrumentation();
+
+      mActivity = getActivity(); // get a references to the app under test
+
+      /*
+       * Get a reference to the main widget of the app under test, a Spinner
+       */
+      mSpinner = (Spinner) mActivity.findViewById(com.android.demo.myactivity.R.id.Spinner01);
+
+  ...
+
+  public void aTest() {
+      /*
+       * request focus for the Spinner, so that the test can send key events to it
+       * This request must be run on the UI thread. To do this, use the runOnUiThread method
+       * and pass it a Runnable that contains a call to requestFocus on the Spinner.
+       */
+      mActivity.runOnUiThread(new Runnable() {
+          public void run() {
+              mSpinner.requestFocus();
+          }
+      });
+
+      mInstrumentation.waitForIdleSync();
+
+      this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+</pre>
+
+<h3 id="NotouchMode">Turning off touch mode</h3>
+<p>
+  To control the emulator or a device with key events you send from your tests, you must turn off
+  touch mode. If you do not do this, the key events are ignored.
+</p>
+<p>
+  To turn off touch mode, you invoke <code>ActivityInstrumentationTestCase2.setActivityTouchMode(false)</code>
+  <em>before</em> you call <code>getActivity()</code> to start the activity. You must invoke the method in a test method
+  that is <em>not</em> running on the UI thread. For this reason, you can't invoke the touch mode method
+  from a test method that is annotated with <code>@UIThread</code>. Instead, invoke the touch mode method from <code>setUp()</code>.
+</p>
+<h3 id="UnlockDevice">Unlocking the emulator or device</h3>
+<p>
+  You may find that UI tests don't work if the emulator's or device's home screen is disabled with the keyguard pattern.
+  This is because the application under test can't receive key events sent by <code>sendKeys()</code>. The best
+  way to avoid this is to start your emulator or device first and then disable the keyguard for the home screen.
+</p>
+<p>
+  You can also explicitly disable the keyguard. To do this,
+  you need to add a permission in the manifest file (<code>AndroidManifest.xml</code>) and
+  then disable the keyguard in your application under test. Note, though, that you either have to remove this before
+  you publish your application, or you have to disable it programmatically in the published app.
+</p>
+<p>
+  To add the the permission, add the element <code>&lt;uses-permission android:name="android.permission.DISABLE_KEYGUARD"/&gt;</code>
+  as a child of the <code>&lt;manifest&gt;</code> element. To disable the KeyGuard, add the following code
+  to the <code>onCreate()</code> method of activities you intend to test:
+</p>
+<pre>
+  mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
+  mLock = mKeyGuardManager.newKeyguardLock("<em>activity_classname</em>");
+  mLock.disableKeyguard();
+</pre>
+<p>where <code><em>activity_classname</em></code> is the class name of the activity.</p>
+<h3 id="UITestTroubleshooting">Troubleshooting UI tests</h3>
+<p>
+  This section lists some of the common test failures you may encounter in UI testing, and their causes:
+</p>
+<dl>
+    <dt><code>WrongThreadException</code></dt>
+    <dd>
+      <p><strong>Problem:</strong></p>
+      For a failed test, the Failure Trace contains the following error message:
+      <code>
+        android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
+      </code>
+      <p><strong>Probable Cause:</strong></p>
+        This error is common if you tried to send UI events to the UI thread from outside the UI thread. This commonly happens if you send UI events
+        from the test application, but you don't use the <code>@UIThread</code> annotation or the <code>runOnUiThread()</code> method. The test method tried to interact with the UI outside the UI thread.
+      <p><strong>Suggested Resolution:</strong></p>
+        Run the interaction on the UI thread. Use a test class that provides instrumentation. See the previous section <a href="#RunOnUIThread">Testing on the UI Thread</a>
+        for more details.
+    </dd>
+    <dt><code>java.lang.RuntimeException</code></dt>
+    <dd>
+      <p><strong>Problem:</strong></p>
+      For a failed test, the Failure Trace contains the following error message:
+      <code>
+        java.lang.RuntimeException: This method can not be called from the main application thread
+      </code>
+      <p><strong>Probable Cause:</strong></p>
+        This error is common if your test method is annotated with <code>@UiThreadTest</code> but then tries to
+        do something outside the UI thread or tries to invoke <code>runOnUiThread()</code>.
+      <p><strong>Suggested Resolution:</strong></p>
+        Remove the <code>@UiThreadTest</code> annotation, remove the <code>runOnUiThread()</code> call, or re-factor your tests.
+    </dd>
+</dl>
+
diff --git a/docs/html/images/resources/res-selection-flowchart.png b/docs/html/images/resources/res-selection-flowchart.png
old mode 100755
new mode 100644
index d738b3f0..eb70074
--- a/docs/html/images/resources/res-selection-flowchart.png
+++ b/docs/html/images/resources/res-selection-flowchart.png
Binary files differ
diff --git a/docs/html/images/testing/android_test_framework.png b/docs/html/images/testing/android_test_framework.png
new file mode 100755
index 0000000..6f80530
--- /dev/null
+++ b/docs/html/images/testing/android_test_framework.png
Binary files differ
diff --git a/docs/html/images/testing/eclipse_new_android_project_complete_callouts.png b/docs/html/images/testing/eclipse_new_android_project_complete_callouts.png
new file mode 100644
index 0000000..2e15232
--- /dev/null
+++ b/docs/html/images/testing/eclipse_new_android_project_complete_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/eclipse_new_android_testproject_complete_callouts.png b/docs/html/images/testing/eclipse_new_android_testproject_complete_callouts.png
new file mode 100644
index 0000000..b287c65
--- /dev/null
+++ b/docs/html/images/testing/eclipse_new_android_testproject_complete_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/hwtest_create_test_class_menu_callouts.png b/docs/html/images/testing/hwtest_create_test_class_menu_callouts.png
new file mode 100644
index 0000000..cf7de04
--- /dev/null
+++ b/docs/html/images/testing/hwtest_create_test_class_menu_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/hwtest_junit_success.png b/docs/html/images/testing/hwtest_junit_success.png
new file mode 100644
index 0000000..7872dfc
--- /dev/null
+++ b/docs/html/images/testing/hwtest_junit_success.png
Binary files differ
diff --git a/docs/html/images/testing/hwtest_new_test_class_dialog_complete_callouts.png b/docs/html/images/testing/hwtest_new_test_class_dialog_complete_callouts.png
new file mode 100644
index 0000000..312c5ad
--- /dev/null
+++ b/docs/html/images/testing/hwtest_new_test_class_dialog_complete_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/hwtest_new_test_project_dialog_complete_callouts.png b/docs/html/images/testing/hwtest_new_test_project_dialog_complete_callouts.png
new file mode 100644
index 0000000..2f9c617
--- /dev/null
+++ b/docs/html/images/testing/hwtest_new_test_project_dialog_complete_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/hwtest_new_test_project_menu.png b/docs/html/images/testing/hwtest_new_test_project_menu.png
new file mode 100644
index 0000000..3f9a6db
--- /dev/null
+++ b/docs/html/images/testing/hwtest_new_test_project_menu.png
Binary files differ
diff --git a/docs/html/images/testing/hwtest_runas_menu_callouts.png b/docs/html/images/testing/hwtest_runas_menu_callouts.png
new file mode 100644
index 0000000..78e4fbf
--- /dev/null
+++ b/docs/html/images/testing/hwtest_runas_menu_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/spinner_create_test_class_callouts.png b/docs/html/images/testing/spinner_create_test_class_callouts.png
new file mode 100644
index 0000000..ff8247a
--- /dev/null
+++ b/docs/html/images/testing/spinner_create_test_class_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/spinnertest_junit_panel.png b/docs/html/images/testing/spinnertest_junit_panel.png
new file mode 100644
index 0000000..d6af368
--- /dev/null
+++ b/docs/html/images/testing/spinnertest_junit_panel.png
Binary files differ
diff --git a/docs/html/images/testing/spinnertest_junit_panel_fail_callouts.png b/docs/html/images/testing/spinnertest_junit_panel_fail_callouts.png
new file mode 100644
index 0000000..ee32099
--- /dev/null
+++ b/docs/html/images/testing/spinnertest_junit_panel_fail_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/spinnertest_junit_panel_failtrace_callouts.png b/docs/html/images/testing/spinnertest_junit_panel_failtrace_callouts.png
new file mode 100644
index 0000000..b20f62f
--- /dev/null
+++ b/docs/html/images/testing/spinnertest_junit_panel_failtrace_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/spinnertest_junit_success.png b/docs/html/images/testing/spinnertest_junit_success.png
new file mode 100644
index 0000000..4760224
--- /dev/null
+++ b/docs/html/images/testing/spinnertest_junit_success.png
Binary files differ
diff --git a/docs/html/images/testing/spinnertest_new_class_callouts.png b/docs/html/images/testing/spinnertest_new_class_callouts.png
new file mode 100644
index 0000000..bf0f718
--- /dev/null
+++ b/docs/html/images/testing/spinnertest_new_class_callouts.png
Binary files differ
diff --git a/docs/html/images/testing/spinnertest_runas_menu_callouts.png b/docs/html/images/testing/spinnertest_runas_menu_callouts.png
new file mode 100644
index 0000000..ac387d0
--- /dev/null
+++ b/docs/html/images/testing/spinnertest_runas_menu_callouts.png
Binary files differ
diff --git a/docs/html/resources/index.jd b/docs/html/resources/index.jd
index 5174dee..1668721 100644
--- a/docs/html/resources/index.jd
+++ b/docs/html/resources/index.jd
@@ -29,7 +29,7 @@
 <dd>Links to the Android discussion groups and information about other ways to
 collaborate with other developers. </dd>
 
-<dt><b>More</b></dt> 
+<dt><b>More</b></dt>
 <dd>Quick development tips, troubleshooting information, and frequently asked
 questions (FAQs). </dd>
 </dl>
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index 43ab562..7f05d30 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -25,7 +25,7 @@
     <ul>
       <li><a href="<?cs var:toroot ?>resources/dashboard/platform-versions.html">
             <span class="en">Platform Versions</span>
-          </a>  <span class="new">new!</span></li>
+          </a></li>
     </ul>
   </li>
 
@@ -36,7 +36,7 @@
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>resources/articles/index.html">
                <span class="en">List of Articles</span>
-             </a> <span class="new">new!</span></div>
+             </a></div>
         <ul>
         <li><a href="<?cs var:toroot ?>resources/articles/avoiding-memory-leaks.html">
                 <span class="en">Avoiding Memory Leaks</span>
@@ -85,7 +85,7 @@
                 </a></li>
         <li><a href="<?cs var:toroot ?>resources/articles/live-wallpapers.html">
                 <span class="en">Live Wallpapers</span>
-                </a> <span class="new">new!</span></li>
+                </a></li>
         <li><a href="<?cs var:toroot ?>resources/articles/on-screen-inputs.html">
                 <span class="en">Onscreen Input Methods</span>
                 </a></li>
@@ -118,7 +118,7 @@
                 </a></li>
         <li><a href="<?cs var:toroot ?>resources/articles/contacts.html">
                 <span class="en">Using the Contacts API</span>
-                </a> <span class="new">new!</span></li>
+                </a></li>
         <li><a href="<?cs var:toroot ?>resources/articles/using-webviews.html">
                 <span class="en">Using WebViews</span>
                 </a></li>
@@ -159,9 +159,17 @@
       <li><a href="<?cs var:toroot ?>resources/tutorials/localization/index.html">
             <span class="en">Hello Localization</span>
           </a></li>
+      <li><a href="<?cs var:toroot ?>resources/tutorials/testing/helloandroid_test.html">
+            <span class="en">Hello Testing</span></a>
+            <span class="new">new!</span>
+      </li>
       <li><a href="<?cs var:toroot ?>resources/tutorials/notepad/index.html">
             <span class="en">Notepad Tutorial</span>
           </a></li>
+      <li><a href="<?cs var:toroot ?>resources/tutorials/testing/activity_test.html">
+            <span class="en">Activity Testing</span></a>
+            <span class="new">new!</span>
+      </li>
     </ul>
   </li>
 
@@ -183,7 +191,7 @@
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>resources/samples/index.html">
                <span class="en">List of Samples</span>
-             </a> <span class="new">new!</span></div>
+             </a></div>
         <ul>
           <li><a href="<?cs var:toroot ?>resources/samples/ApiDemos/index.html">
                 <span class="en">API Demos</span>
@@ -208,7 +216,7 @@
               </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/CubeLiveWallpaper/index.html">
                 <span class="en">Live Wallpaper</span>
-                </a> <span class="new">new!</span></li>
+                </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/LunarLander/index.html">
                 <span class="en">Lunar Lander</span>
               </a></li>
@@ -220,16 +228,22 @@
               </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/SampleSyncAdapter/index.html">
                 <span class="en">Sample Sync Adapter</span>
-              </a> <span class="new">new!</span></li>
-          <li><a href="<?cs var:toroot ?>resources/samples/SearchableDictionary/index.html">
-                <span class="en">Searchable Dictionary</span>
               </a></li>
+          <li><a href="<?cs var:toroot ?>resources/samples/SearchableDictionary/index.html">
+                <span class="en">Searchable Dictionary v2</span>
+              </a> <span class="new">new!</span></li>
           <li><a href="<?cs var:toroot ?>resources/samples/Snake/index.html">
                 <span class="en">Snake</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/SoftKeyboard/index.html">
                 <span class="en">Soft Keyboard</span>
               </a></li>
+          <li><a href="<?cs var:toroot ?>resources/samples/Spinner/index.html">
+                <span class="en">Spinner</span>
+                </a> <span class="new">new!</span></li>
+          <li><a href="<?cs var:toroot ?>resources/samples/SpinnerTest/index.html">
+                <span class="en">SpinnerTest</span>
+                </a> <span class="new">new!</span></li>
           <li><a href="<?cs var:toroot ?>resources/samples/Wiktionary/index.html">
                 <span class="en">Wiktionary</span>
               </a></li>
diff --git a/docs/html/resources/samples/index.jd b/docs/html/resources/samples/index.jd
index 2718d0c..e917495 100644
--- a/docs/html/resources/samples/index.jd
+++ b/docs/html/resources/samples/index.jd
@@ -79,6 +79,19 @@
  <dt><a href="SoftKeyboard/index.html">Soft Keyboard</a></dt>
   <dd>An example of writing an input method for a software keyboard.</dd>
 
+ <dt><a href="Spinner/index.html">Spinner</a></dt>
+ <dd>
+    A simple application that serves as an application-under-test for the 
+    SpinnerTest sample application. 
+ </dd>
+ <dt><a href="SpinnerTest/index.html">SpinnerTest</a></dt>
+ <dd>
+    An example test application that contains test cases run against the 
+    Spinner sample application. 
+    To learn more about the application and how to run it, 
+    please read the 
+    <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a> tutorial.
+ </dd>
  <dt><a href="Wiktionary/index.html">Wiktionary</a></dt>
   <dd>An example of creating interactive widgets for display on the Android
   home screen.</dd>
diff --git a/docs/html/resources/tutorials/hello-world.jd b/docs/html/resources/tutorials/hello-world.jd
index 431a6cd..1079fb5 100644
--- a/docs/html/resources/tutorials/hello-world.jd
+++ b/docs/html/resources/tutorials/hello-world.jd
@@ -201,7 +201,7 @@
 The bold items are lines that have been added.</p>
 
 <pre>
-package com.android.helloandroid;
+package com.example.helloandroid;
 
 import android.app.Activity;
 import android.os.Bundle;
@@ -297,6 +297,7 @@
 
 <pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
 &lt;TextView xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+  android:id=&quot;@id+/textview&quot;
   android:layout_width=&quot;fill_parent&quot;
   android:layout_height=&quot;fill_parent&quot;
   android:text=&quot;@string/hello&quot;/&gt;</pre>
@@ -312,7 +313,7 @@
 application (its UI) from the application logic used to fetch and fill in data.</p>
 
 <p>In the above XML example, there's just one View element: the <code>TextView</code>, 
-which has four XML attributes.  Here's a summary of what they mean:</p>
+which has five XML attributes.  Here's a summary of what they mean:</p>
 
 <table>
     <tbody>
@@ -334,11 +335,21 @@
         </tr>
         <tr>
             <td>
+                <code>android:id</code>
+            </td>
+            <td>
+                This attribute assigns a unique identifier to the <code>TextView</code> element.
+                You can use the assigned ID to reference this View from your source code or from other 
+                XML resource declarations.
+            </td>
+        </tr>
+        <tr>
+            <td>
                 <code>android:layout_width</code>
             </td>
             <td>
                 This attribute defines how much of the available width on the screen this View should consume. 
-In this case, it's the only View so you want it to take up the entire screen, which is what a value of "fill_parent" means.<br>
+                In this case, it's the only View so you want it to take up the entire screen, which is what a value of "fill_parent" means.<br>
             </td>
         </tr>
         <tr>
@@ -397,6 +408,7 @@
 
 <pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
 &lt;TextView xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+  android:id=&quot;@id+/textview&quot;
   android:layout_width=&quot;fill_parent&quot;
   android:layout_height=&quot;fill_parent&quot;
   android:text=&quot;@string/hello&quot;/&gt;</pre>
@@ -478,6 +490,9 @@
     public static final class drawable {
         public static final int icon=0x7f020000;
     }
+    public static final class id {
+        public static final int textview=0x7f050000;
+    }
     public static final class layout {
         public static final int main=0x7f030000;
     }
@@ -512,7 +527,7 @@
 your code. Change your HelloAndroid source code to look like this:</p>
 
 <pre>
-package com.android.helloandroid;
+package com.example.helloandroid;
 
 import android.app.Activity;
 import android.os.Bundle;
@@ -568,7 +583,7 @@
   
   <pre>
 android create project \
-    --package com.android.helloandroid \
+    --package com.example.helloandroid \
     --activity HelloAndroid \ 
     --target 2 \
     --path <em>&lt;path-to-your-project></em>/HelloAndroid 
diff --git a/docs/html/resources/tutorials/testing/activity_test.jd b/docs/html/resources/tutorials/testing/activity_test.jd
new file mode 100644
index 0000000..ae4b6f3
--- /dev/null
+++ b/docs/html/resources/tutorials/testing/activity_test.jd
@@ -0,0 +1,1378 @@
+page.title=Activity Testing
+@jd:body
+ <div id="qv-wrapper">
+  <div id="qv">
+  <h2>In this document</h2>
+  <ol>
+    <li>
+      <a href="#Prerequisites">Prerequisites</a>
+    </li>
+    <li>
+      <a href="#DownloadCode">Installing the Tutorial Sample Code</a>
+    </li>
+    <li>
+        <a href="#SetupEmulator">Setting Up the Emulator</a>
+    </li>
+    <li>
+        <a href="#SetupProjects">Setting Up the Projects</a>
+    </li>
+    <li>
+      <a href="#CreateTestCaseClass">Creating the Test Case Class</a>
+      <ol>
+        <li>
+          <a href="#AddTestCaseClass">Adding the test case class file</a>
+        </li>
+        <li>
+          <a href="#AddConstructor">Adding the test case constructor</a>
+        </li>
+        <li>
+            <a href="#AddSetupMethod">Adding the setup method</a>
+        </li>
+        <li>
+            <a href="#AddPreConditionsTest">Adding an initial conditions test</a>
+        </li>
+        <li>
+            <a href="#AddUITest">Adding a UI test</a>
+        </li>
+        <li>
+            <a href="#StateManagementTests">Adding state management tests</a>
+        </li>
+      </ol>
+    </li>
+    <li>
+        <a href="#RunTests">Running the Tests and Seeing the Results</a>
+    </li>
+    <li>
+        <a href="#TestFailure">Forcing Some Tests to Fail</a>
+    </li>
+    <li>
+        <a href="#NextSteps">Next Steps</a>
+    </li>
+</ol>
+<h2 id="#Appendix">Appendix</h2>
+<ol>
+    <li>
+        <a href="#InstallCompletedTestApp">Installing the Completed Test Application Java File</a>
+    </li>
+    <li>
+        <a href="#EditorCommandLine">For Users Not Developing In Eclipse</a>
+    </li>
+</ol>
+<h2>Related Tutorials</h2>
+<ol>
+    <li>
+        <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello, Testing</a>
+    </li>
+</ol>
+<h2>See Also</h2>
+<ol>
+    <li>
+        <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Android Applications</a>
+    </li>
+    <li>
+        {@link android.test.ActivityInstrumentationTestCase2}
+    </li>
+    <li>
+        {@link junit.framework.Assert}
+    </li>
+    <li>
+        {@link android.test.InstrumentationTestRunner}
+    </li>
+</ol>
+</div>
+</div>
+<p>
+  Android includes powerful tools for testing applications. The tools extend JUnit with additional features, provide convenience classes for mock Android system objects, and use
+  instrumentation to give you control over your main application while you are testing it. The entire Android testing environment is discussed in the document
+  <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Android Applications</a>.
+</p>
+<p>
+  This tutorial demonstrates the Android testing tools by presenting a simple Android application and then leading you step-by-step through the creation of a test application for it.
+  The test application demonstrates these key points:
+</p>
+  <ul>
+    <li>
+      An Android test is itself an Android application that is linked to the application under test by entries in its <code>AndroidManifest.xml</code> file.
+    </li>
+    <li>
+      Instead of Android components, an Android test application contains one or more test cases. Each of these is a separate class definition.
+    </li>
+    <li>
+      Android test case classes extend the JUnit {@link junit.framework.TestCase} class.
+    </li>
+    <li>
+      Android test case classes for activities extend JUnit and also connect you to the application under test with instrumentation. You can send keystroke or touch events directly to the UI.
+    </li>
+    <li>
+      You choose an Android test case class based on the type of component (application, activity, content provider, or service) you are testing.
+    </li>
+    <li>
+      Additional test tools in Eclipse/ADT provide integrated support for creating test applications, running them, and viewing the results.
+    </li>
+  </ul>
+<p>
+  The test application contains methods that perform the following tests:
+</p>
+  <ul>
+    <li>
+      Initial conditions test. Tests that the application under test initializes correctly. This is also a unit test of the application's
+      {@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method. Testing initial conditions also provides a confidence measure for subsequent tests.
+    </li>
+    <li>
+      UI test. Tests that the main UI operation works correctly. This test demonstrates the instrumentation features available in activity testing.
+      It shows that you can automate UI tests by sending key events from the test application to the main application.
+    </li>
+    <li>
+      State management tests. Test the application's code for saving state. This test demonstrates the instrumentation features of the test runner, which
+      are available for testing any component.
+    </li>
+  </ul>
+<h2 id="Prerequisites">Prerequisites</h2>
+<p>
+  The instructions and code in this tutorial depend on the following:
+</p>
+  <ul>
+    <li>
+      Basic knowledge of Android programming. If you haven't yet written an Android application, do the
+      <a href="{@docRoot}resources/tutorials/hello-world.html">Hello, World</a> tutorial. If you
+      want to learn more about Spinner, the application under test, then you might want to visit the
+      <a href="{@docRoot}resources/tutorials/views/hello-spinner.html">Hello Views &gt; Spinner</a> example.
+    </li>
+    <li>
+      Some familiarity with the Android testing framework and concepts. If you haven't explored
+      Android testing yet, start by reading the Developer Guide topic <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Android Applications</a>
+      or following the <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">
+      Hello, Testing</a> tutorial.
+    </li>
+    <li>
+        Eclipse with ADT. This tutorial describes how to set up and run a test application using
+        Eclipse with ADT. If you haven't yet installed Eclipse and the ADT plugin,
+        follow the steps in <a href="{@docRoot}sdk/installing.html">Installing the SDK</a>
+        to install them before continuing. If you are not developing in Eclipse, you will
+        find instructions for setting up and running the test application in the
+        <a href="#EditorCommandLine">appendix</a> of this document.
+    </li>
+    <li>
+        Android 1.5 platform (API Level 3) or higher. You must have the Android 1.5 platform
+        (API Level 3) or higher installed in your SDK, because this tutorial uses APIs that
+        were introduced in that version.
+        <p>
+            If you are not sure which platforms are installed in your SDK,
+            open the Android SDK and AVD Manager and check in the
+            <strong>Installed Packages</strong> panel.
+            If aren't sure how to download a platform into your SDK,
+            read <a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a>.
+        </p>
+    </li>
+  </ul>
+<h2 id="DownloadCode">Installing the Tutorial Sample Code</h2>
+<p>
+    During this tutorial, you will be working with sample code that is provided as part
+    of the downloadable Samples component of the SDK. Specifically, you will be working
+    with a pair of related sample applications &mdash; an application under test and a test
+    application:
+</p>
+    <ul>
+        <li>
+            Spinner is the application under test. This tutorial focuses on the
+            common situation of writing tests for an application that already exists, so the main
+            application is provided to you.
+        </li>
+        <li>
+             SpinnerTest is the test application. In the tutorial, you create this application
+             step-by-step. If you want to run quickly through the tutorial,
+             you can install the completed SpinnerTest application first, and then follow the
+             text. You may get more from the tutorial, however, if you create the test application
+             as you go. The instructions for installing the completed test application are in the
+             section <a href="#InstallCompletedTestApp">Installing the Completed Test Application Java File</a>.
+        </li>
+    </ul>
+<p>
+    The sample applications are provided in the SDK component named
+    "Samples for SDK API 8" and in later versions of the Samples.
+</p>
+<p>
+    To get started with the tutorial, first use the Android SDK and AVD manager to install an
+    appropriate version of the Samples:
+</p>
+<ol>
+    <li>
+        In Eclipse, select <strong>Window</strong> &gt; <strong>Android SDK and AVD Manager</strong>.
+    </li>
+    <li>
+        Open the <strong>Installed Packages</strong> panel and check whether
+        &quot;Samples for SDK API 8&quot; (or higher version) is listed.
+        If so, skip to the next section,
+        <a href="#SetupProjects">Setting Up the Projects</a>, to get started with the tutorial.
+        Otherwise, continue with the next step.
+     </li>
+     <li>
+        Open the <strong>Available Packages</strong> panel.
+     </li>
+     <li>
+        Select the &quot;Samples for SDK API 8&quot; component and click <strong>Install Selected</strong>.
+     </li>
+     <li>
+        Verify and accept the component and then click <strong>Install Accepted</strong>.
+        The Samples component will now be installed into your SDK.
+     </li>
+</ol>
+<p>
+    When the installation is complete, the applications in the
+    Samples component are stored at this location on your computer:
+</p>
+<p style="margin-left:2em">
+    <code>&lt;<em>sdk</em>&gt;/samples/android-8/</code>
+</p>
+<p>
+    For general information about the Samples, see
+    <a href="{@docRoot}resources/samples/get.html">Getting the Samples</a>
+</p>
+<p class="note">
+    <strong>Note:</strong> Although the sample code for this tutorial is provided in the
+    &quot;Samples for SDK API 8&quot; component, that does not imply that you need to build or
+    run the application against the corresponding platform (Android 2.2).
+    The API level referenced in the Samples component name indicates only the origin branch from
+    which the samples were built.
+</p>
+<h2 id="SetupEmulator">Setting Up the Emulator</h2>
+<p>
+  In this tutorial, you will use the Android emulator to run applications. The emulator needs
+  an Android Virtual Device (AVD) with an API level equal to or higher than the one you set for the projects in the previous step.
+  To find out how to check this and create the right AVD if necessary, see <a href="{@docRoot}guide/developing/eclipse-adt.html#AVD">Creating an AVD</a>.
+</p>
+<p>
+    As a test of the AVD and emulator, run the SpinnerActivity application in Eclipse with ADT. When it starts,
+    click the large downward-pointing arrow to the right of the spinner text. You see the spinner expand and display the title &quot;Select a planet&quot; at the top.
+    Click one of the other planets. The spinner closes, and your selection appears below it on the screen.
+</p>
+<h2 id="SetupProjects">Setting Up the Projects</h2>
+<p>
+    When you are ready to get started with the tutorial, begin by setting up Eclipse projects for
+    both Spinner (the application under test) and SpinnerTest (the test application).
+</p>
+<p>
+    You'll be using the Spinner application as-is, without modification, so you'll be loading it
+    into Eclipse as a new Android project from existing source. In the process, you'll be
+    creating a new test project associated with Spinner that will contain the SpinnerTest
+    application. The SpinnerTest application will be completely new and you'll be
+    using the code examples in this tutorial to add test classes and tests to it.
+</p>
+<p>
+    To install the Spinner app in a new Android project from existing source, following these steps:
+</p>
+<ol>
+    <li>
+        In Eclipse, select <strong>File</strong>&nbsp;&gt;&nbsp;<strong>New</strong>&nbsp;&gt;&nbsp;<strong>Project</strong>&nbsp;&gt;&nbsp;<strong>Android</strong>&nbsp;&gt;&nbsp;<strong>Android Project</strong>,
+        then click Next. The <strong>New Android Project</strong> dialog appears.
+    </li>
+    <li>
+        In the <em>Project name</em> text box, enter &quot;SpinnerActivity&quot;. The <em>Properties</em> area is filled in automatically.
+    </li>
+    <li>
+        In the <em>Contents</em> area, set &quot;Create project from existing source&quot;.
+    </li>
+    <li>
+        For <em>Location</em>, click <strong>Browse</strong>, navigate to the directory <code>&lt;SDK_path&gt;/samples/android-8/Spinner</code>,
+        then click Open. The directory name <code>&lt;SDK_path&gt;/samples/android-8/Spinner</code> now appears in the <em>Location</em> text box.
+    </li>
+    <li>
+        In the <em>Build Target</em> area, set a API level of 3 or higher. If you are already developing with a particular target, and it is API level 3 or higher, then use that target.
+    </li>
+    <li>
+        In the <em>Properties</em> area, in the <em>Min SDK Version:</em>, enter &quot;3&quot;.
+    </li>
+    <li>
+        You should now see these values:
+        <ul>
+            <li><em>Project Name:</em> &quot;SpinnerActivity&quot;</li>
+            <li><em>Create project from existing source:</em> set</li>
+            <li><em>Location:</em> &quot;<code>&lt;SDK_path&gt;/samples/android-8/Spinner</code>&quot;</li>
+            <li><em>Build Target:</em> &quot;API level of 3 or higher&quot; (<em>Target Name</em> &quot;Android 1.5 or higher&quot;)</li>
+            <li><em>Package name:</em> (disabled, set to &quot;<code>com.android.example.spinner</code>&quot;)</li>
+            <li><em>Create Activity:</em> (disabled, set to &quot;.SpinnerActivity&quot;)</li>
+            <li><em>Min SDK Version:</em> &quot;3&quot;</li>
+        </ul>
+        <p>
+            The following screenshot summarizes these values:
+        </p>
+            <a href="{@docRoot}images/testing/eclipse_new_android_project_complete_callouts.png">
+                <img src="{@docRoot}images/testing/eclipse_new_android_project_complete_callouts.png" alt="New Android Project dialog with filled-in values" style="height:230px"/>
+            </a>
+
+    </li>
+</ol>
+<p>
+    To create a new test project for the SpinnerTest application, follow these steps:
+</p>
+<ol>
+    <li>
+        Click Next. The <strong>New Android Test Project</strong> dialog appears.
+    </li>
+    <li>
+        Set &quot;Create a Test Project&quot;.
+    </li>
+    <li>
+        Leave the other values unchanged. The result should be:
+        <ul>
+            <li><em>Create a Test Project:</em> checked</li>
+            <li><em>Test Project Name:</em> &quot;SpinnerActivityTest&quot;</li>
+            <li><em>Use default location:</em> checked (this should contain the directory name &quot;<code>workspace/SpinnerActivityTest</code>&quot;).</li>
+            <li><em>Build Target:</em> Use the same API level you used in the previous step.</li>
+            <li><em>Application name:</em> &quot;SpinnerActivityTest&quot;</li>
+            <li><em>Package name:</em> &quot;<code>com.android.example.spinner.test</code>&quot;</li>
+            <li><em>Min SDK Version:</em> &quot;3&quot;</li>
+        </ul>
+        <p>
+            The following screenshot summarizes these values:
+        </p>
+            <a href="{@docRoot}images/testing/eclipse_new_android_testproject_complete_callouts.png">
+            <img src="{@docRoot}images/testing/eclipse_new_android_testproject_complete_callouts.png" alt="New Android Test Project dialog with filled-in values" style="height:230px"/>
+            </a>
+    </li>
+    <li>
+        Click Finish. Entries for SpinnerActivity and SpinnerActivityTest should appear in the
+        <strong>Package Explorer</strong>.
+        <p class="note">
+            <strong>Note:</strong> If you set <em>Build Target</em> to an API level higher than &quot;3&quot;, you will see the warning
+            &quot;The API level for the selected SDK target does not match the Min SDK version&quot;. You do not need to change the API level or the Min SDK version.
+            The message tells you that you are building the projects with one particular API level, but specifying that a lower API level is required. This may
+            occur if you have chosen not to install the optional earlier API levels.
+        </p>
+        <p>
+            If you see errors listed in the <strong>Problems</strong> pane at the bottom of the Eclipse window, or if a red error marker appears next to
+            the entry for SpinnerActivity in the Package Explorer, highlight the SpinnerActivity entry and then select
+            <strong>Project</strong>&nbsp;&gt;&nbsp;<strong>Clean</strong>. This should fix any errors.
+        </p>
+    </li>
+</ol>
+<p>
+    You now have the application under test in the SpinnerActivity project,
+    and an empty test project in SpinnerActivityTest. You may
+    notice that the two projects are in different directories, but Eclipse with
+    ADT handles this automatically. You should have no problem in either building or running them.
+</p>
+<p>
+    Notice that Eclipse and ADT have already done some initial setup for your test application.
+    Expand the SpinnerActivityTest project, and notice that it already has an
+    Android manifest file <code>AndroidManifest.xml</code>.
+    Eclipse with ADT created this when you added the test project.
+    Also, the test application is already set up to use instrumentation. You can see this
+    by examining <code>AndroidManifest.xml</code>.
+    Open it, then at the bottom of the center pane click <strong>AndroidManifest.xml</strong>
+    to display the XML contents:
+</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.android.example.spinner.test"
+      android:versionCode="1"
+      android:versionName="1.0"&gt;
+    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
+
+    &lt;uses-library android:name="android.test.runner" /&gt;
+    &lt;/application&gt;
+    &lt;uses-sdk android:minSdkVersion="3" /&gt;
+    &lt;instrumentation
+        android:targetPackage="com.android.example.spinner"
+        android:name="android.test.InstrumentationTestRunner" /&gt;
+&lt;/manifest&gt;
+</pre>
+<p>
+    Notice the <code>&lt;instrumentation&gt;</code> element. The attribute
+    <code>android:targetPackage="com.android.example.spinner"</code> tells Android that the
+    application under test is defined in the Android package
+    <code>com.android.example.spinner</code>. Android now knows to use that
+    package's <code>AndroidManifest.xml</code> file to launch the application under test.
+    The <code>&lt;instrumentation&gt;</code> element also contains the attribute
+    <code>android:name="android.test.InstrumentationTestRunner"</code>, which tells Android
+    instrumentation to run the test application with Android's instrumentation-enabled test runner.
+</p>
+<h2 id="CreateTestCaseClass">Creating the Test Case Class</h2>
+
+<p>
+    You now have a test project SpinnerActivityTest, and the basic structure of a test
+    application also called SpinnerActivityTest. The basic structure includes all the files and
+    directories you need to build and run a test application, except for the class that
+    contains your tests (the test case class).
+</p>
+<p>
+    The next step is to define the test case class. In this tutorial, you'll be creating a
+    test case class that includes:
+</p>
+<ul>
+    <li>
+        Test setup. This use of the JUnit {@link junit.framework.TestCase#setUp() setUp()}
+        method demonstrates some of the tasks you might perform before running an Android test.
+    </li>
+    <li>
+        Testing initial conditions. This test demonstrates a good testing technique.
+        It also demonstrates that with Android instrumentation you can look at the application
+        under test <em>before</em> the main activity starts. The test checks that the application's
+        important objects have been initialized.
+        If the test fails, you then know that any other tests against the application are
+        unreliable, since the application was running in an incorrect state.
+        <p class="note">
+            <strong>Note:</strong> The purpose of testing initial conditions is not the same as
+            using <code>setUp()</code>. The JUnit {@link junit.framework.TestCase#setUp()} runs once
+            before <strong>each test method</strong>, and its purpose is to create a clean test
+            environment. The initial conditions test runs once, and its purpose is to verify that the
+            application under test is ready to be tested.
+        </p>
+    </li>
+    <li>
+        Testing the UI. This test shows how to control the main application's UI
+        with instrumentation, a powerful automation feature of Android testing.
+    </li>
+    <li>
+        Testing state management. This test shows some techniques for testing how
+        well the application maintains state in the Android environment. Remember that to
+        provide a satisfactory user experience, your application must never lose its current state,
+        even if it's interrupted by a phone call or destroyed because of memory constraints.
+        The Android activity lifecycle provides ways to maintain state, and the
+        <code>SpinnerActivity</code> application uses them. The test shows the techniques for
+        verifying that they work.
+    </li>
+</ul>
+<p>
+  Android tests are contained in a special type of Android application that contains one or more test class definitions. Each of these contains
+  one or more test methods that do the actual tests. In this tutorial, you will first add a test case class, and then add tests to it.
+</p>
+<p>
+ You first choose an Android test case class to extend. You choose from the base test case classes according to the Android component you are testing and the types of tests you are doing.
+ In this tutorial, the application under test has a single simple activity, so the test case class will be for an Activity component. Android offers several, but the one that tests in
+ the most realistic environment is {@link android.test.ActivityInstrumentationTestCase2}, so you will use it as the base class. Like all activity test case classes,
+ <code>ActivityInstrumentationTestCase2</code> offers convenience methods for interacting directly with the UI of the application under test.
+</p>
+<h3 id="AddTestCaseClass">Adding the test case class file</h3>
+<p>
+    To add <code>ActivityInstrumentationTestCase2</code> as the base test case class, follow these steps:
+</p>
+<ol>
+  <li>
+    In the Package Explorer, expand the test project SpinnerActivityTest if it is not open already.
+  </li>
+  <li>
+    Within SpinnerActivityTest, expand the <code>src/</code> folder and then the package marker for
+    <code>com.android.example.spinner.test</code>. Right-click on the package name and select <strong>New</strong> &gt; <strong>Class</strong>:<br/>
+    <a href="{@docRoot}images/testing/spinner_create_test_class_callouts.png">
+      <img alt="Menu for creating a new class in the test application" src="{@docRoot}images/testing/spinner_create_test_class_callouts.png" style="height:230px"/>
+    </a>
+    <p>
+      The <strong>New Java Class</strong> wizard appears:
+    </p>
+    <a href="{@docRoot}images/testing/spinnertest_new_class_callouts.png">
+      <img alt="New Java Class wizard dialog" src="{@docRoot}images/testing/spinnertest_new_class_callouts.png" style="height:230px"/>
+    </a>
+  </li>
+  <li>
+    In the wizard, enter the following:
+    <ul>
+      <li>
+        <em>Name:</em> &quot;SpinnerActivityTest&quot;. This becomes the name of your test class.
+      </li>
+      <li>
+        <em>Superclass:</em> &quot;<code>android.test.ActivityInstrumentationTestCase2&lt;SpinnerActivity&gt;</code>&quot;. The superclass is parameterized, so
+        you have to provide it your main application's class name.
+      </li>
+    </ul>
+    <p>
+      Do not change any of the other settings. Click Finish.
+    </p>
+  </li>
+  <li>
+    You now have a new file <code>SpinnerActivityTest.java</code> in the project.
+  </li>
+  <li>
+    To resolve the reference to SpinnerActivity, add the following import:
+<pre>
+import com.android.example.spinner.SpinnerActivity;
+</pre>
+  </li>
+</ol>
+<h3 id="AddConstructor">Adding the test case constructor</h3>
+  <p>
+    To ensure that the test application is instantiated correctly, you must set up a constructor that the test
+    runner will call when it instantiates your test class. This constructor has no parameters, and its sole
+    purpose is to pass information to the superclass's default constructor. To set up this constructor, enter the
+    following code in the class:
+  </p>
+<pre>
+  public SpinnerActivityTest() {
+    super("com.android.example.spinner", SpinnerActivity.class);
+  } // end of SpinnerActivityTest constructor definition
+</pre>
+<p>
+  This calls the superclass constructor with the Android package name (<code>com.android.example.spinner</code>)and main activity's class
+  (<code>SpinnerActivity.class</code>) for the application under test. Android uses this information to find the application and activity to test.
+</p>
+<p>
+  You are now ready to add tests, by adding test methods to the class.
+</p>
+<h3 id="AddSetupMethod">Adding the setup method</h3>
+<p>
+    The <code>setUp()</code> method is invoked before every test. You use it to initialize variables and clean up from previous tests. You can also use
+    the JUnit {@link junit.framework.TestCase#tearDown() tearDown()} method, which runs <strong>after</strong> every test method. The tutorial does not use it.
+</p>
+<p>
+    The method you are going to add does the following:
+</p>
+<ul>
+  <li>
+    <code>super.setUp()</code>. Invokes the superclass constructor for <code>setUp()</code>, which is required by JUnit.
+  </li>
+  <li>
+    Calls {@link android.test.ActivityInstrumentationTestCase2#setActivityInitialTouchMode(boolean) setActivityInitialTouchMode(false)}.
+    This turns off <strong>touch mode</strong> in the device or emulator. If any of your test methods send key events to the application,
+    you must turn off touch mode <em>before</em> you start any activities; otherwise, the call is ignored.
+  </li>
+  <li>
+    Stores references to system objects. Retrieves and stores a reference to the activity under test, the <code>Spinner</code>
+    widget used by the activity, the <code>SpinnerAdapter</code> that backs the widget, and the string value of the selection that is
+    set when the application is first installed. These objects are used in the state management test. The methods invoked are:
+    <ul>
+      <li>
+        {@link android.test.ActivityInstrumentationTestCase2#getActivity()}. Gets a reference to the activity under test (<code>SpinnerActivity</code>).
+        This call also starts the activity if it is not already running.
+      </li>
+      <li>
+        {@link android.app.Activity#findViewById(int)}. Gets a reference to the <code>Spinner</code> widget of the application under test.
+      </li>
+      <li>
+        {@link android.widget.AbsSpinner#getAdapter()}. Gets a reference to the adapter (an array of strings) backing the spinner.
+      </li>
+    </ul>
+  </li>
+</ul>
+<p>
+    Add this code to the definition of <code>SpinnerActivityTest</code>, after the constructor definition:
+</p>
+<pre>
+  &#64;Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    setActivityInitialTouchMode(false);
+
+    mActivity = getActivity();
+
+    mSpinner =
+      (Spinner) mActivity.findViewById(
+        com.android.example.spinner.R.id.Spinner01
+      );
+
+      mPlanetData = mSpinner.getAdapter();
+
+  } // end of setUp() method definition
+</pre>
+<p>
+    Add these members to the test case class:
+</p>
+<pre>
+  private SpinnerActivity mActivity;
+  private Spinner mSpinner;
+  private SpinnerAdapter mPlanetData;
+</pre>
+<p>
+  Add these imports:
+</p>
+<pre>
+import android.widget.Spinner;
+import android.widget.SpinnerAdapter;
+</pre>
+<p>
+    You now have the the complete <code>setUp()</code> method.
+</p>
+<h3 id="AddPreConditionsTest">Adding an initial conditions test</h3>
+<p>
+  The initial conditions test verifies that the application under test is initialized correctly. It is an illustration of the types of tests you can run, so it is not comprehensive.
+  It verifies the following:
+</p>
+<ul>
+  <li>
+    The item select listener is initialized. This listener is called when a selection is made from the spinner.
+  </li>
+  <li>
+    The adapter that provides values to the spinner is initialized.
+  </li>
+  <li>
+    The adapter contains the right number of entries.
+  </li>
+</ul>
+<p>
+  The actual initialization of the application under test is done in <code>setUp()</code>, which the test runner calls automatically before every test. The verifications are
+  done with JUnit {@link junit.framework.Assert} calls. As a useful convention, the method name is <code>testPreConditions()</code>:
+</p>
+<pre>
+  public void testPreConditions() {
+    assertTrue(mSpinner.getOnItemSelectedListener() != null);
+    assertTrue(mPlanetData != null);
+    assertEquals(mPlanetData.getCount(),ADAPTER_COUNT);
+  } // end of testPreConditions() method definition
+</pre>
+<p>
+  Add this member:
+</p>
+<pre>
+  public static final int ADAPTER_COUNT = 9;
+</pre>
+<h3 id="AddUITest">Adding a UI test</h3>
+<p>
+  Now create a UI test that selects an item from the <code>Spinner</code> widget. The test sends key events to the UI with key events.
+  The test confirms that the selection matches the result you expect.
+</p>
+<p>
+  This test demonstrates the power of using instrumentation in Android testing. Only an instrumentation-based test class allows you to send key events (or touch events)
+  to the application under test. With instrumentation, you can test your UI without having to take screenshots, record the screen, or do human-controlled testing.
+</p>
+<p>
+  To work with the spinner, the test has to request focus for it and then set it to a known position. The test uses {@link android.view.View#requestFocus() requestFocus()} and
+  {@link android.widget.AbsSpinner#setSelection(int) setSelection()} to do this. Both of these methods interact with a View in the application under test, so you have to call them
+  in a special way.
+</p>
+<p>
+  Code in a test application that interacts with a View of the application under test must run in the main application's thread, also
+  known as the <em>UI thread</em>. To do this, you use the {@link android.app.Activity#runOnUiThread(java.lang.Runnable) Activity.runOnUiThread()}
+  method. You pass the code to <code>runOnUiThread()</code>in an anonymous {@link java.lang.Runnable Runnable} object. To set
+  the Java statements in the <code>Runnable</code> object, you override the object's {@link java.lang.Runnable#run()} method.
+</p>
+<p>
+  To send key events to the UI of the application under test, you use the <a href="{@docRoot}reference/android/test/InstrumentationTestCase.html#sendKeys(int...)">sendKeys</a>() method.
+  This method does not have to run on the UI thread, since Android uses instrumentation to pass the key events to the application under test.
+</p>
+<p>
+  The last part of the test compares the selection made by sending the key events to a pre-determined value. This tests that the spinner is working as intended.
+</p>
+<p>
+    The following sections show you how to add the code for this test.
+</p>
+<ol>
+    <li>
+        Get focus and set selection. Create a new method <code>public void testSpinnerUI()</code>. Add
+        code to to request focus for the spinner and set its position to default or initial position, "Earth". This code is run on the UI thread of
+        the application under test:
+<pre>
+  public void testSpinnerUI() {
+
+    mActivity.runOnUiThread(
+      new Runnable() {
+        public void run() {
+          mSpinner.requestFocus();
+          mSpinner.setSelection(INITIAL_POSITION);
+        } // end of run() method definition
+      } // end of anonymous Runnable object instantiation
+    ); // end of invocation of runOnUiThread
+</pre>
+        <p>
+          Add the following member to the test case class.
+        </p>
+<pre>
+  public static final int INITIAL_POSITION = 0;
+</pre>
+    </li>
+    <li>
+      Make a selection. Send key events to the spinner to select one of the items. To do this, open the spinner by
+      "clicking" the center keypad button (sending a DPAD_CENTER key event) and then clicking (sending) the down arrow keypad button five times. Finally,
+      click the center keypad button again to highlight the desired item. Add the following code:
+<pre>
+    this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+    for (int i = 1; i &lt;= TEST_POSITION; i++) {
+      this.sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+    } // end of for loop
+
+    this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+</pre>
+    <p>
+      Add the following member to the test case class:
+    </p>
+<pre>
+  public static final int TEST_POSITION = 5;
+</pre>
+    <p>
+      This sets the final position of the spinner to "Saturn" (the spinner's backing adapter is 0-based).
+    </p>
+  </li>
+  <li>
+    Check the result. Query the current state of the spinner, and compare its current selection to the expected value.
+    Call the method {@link android.widget.AdapterView#getSelectedItemPosition() getSelectedItemPosition()} to find out the current selection position, and then
+    {@link android.widget.AdapterView#getItemAtPosition(int) getItemAtPosition()} to get the object corresponding to that position (casting it to a String). Assert that
+    this string value matches the expected value of "Saturn":
+<pre>
+    mPos = mSpinner.getSelectedItemPosition();
+    mSelection = (String)mSpinner.getItemAtPosition(mPos);
+    TextView resultView =
+      (TextView) mActivity.findViewById(
+        com.android.example.spinner.R.id.SpinnerResult
+      );
+
+    String resultText = (String) resultView.getText();
+
+    assertEquals(resultText,mSelection);
+
+  } // end of testSpinnerUI() method definition
+</pre>
+<p>
+  Add the following members to the test case class:
+</p>
+<pre>
+  private String mSelection;
+  private int mPos;
+</pre>
+  <p>
+    Add the following imports to the test case class:
+  </p>
+<pre>
+  import android.view.KeyEvent;
+  import android.widget.TextView;
+</pre>
+  </li>
+</ol>
+<p>
+  Pause here to run the tests you have. The procedure for running a test application is different
+  from running a regular Android application. You run a test application as an Android JUnit
+  application. To see how to do this, see <a href="#RunTests">Running the Tests and Seeing the Results</a>.
+</p>
+<p>
+    Eventually, you will see the <code>SpinnerActivity</code> application start, and the test
+    application controlling it by sending it key events. You will also see a new
+    <strong>JUnit</strong> view in the Explorer pane, showing the results of the
+    test. The JUnit view is documented in a following section,
+    <a href="#RunTests">Running the Test and Seeing the Results</a>.
+</p>
+<h3 id="StateManagementTests">Adding state management tests</h3>
+<p>
+  You now write two tests that verify that SpinnerActivity maintains its state when it is paused or terminated.
+  The state, in this case, is the current selection in the spinner. When users make a selection,
+  pause or terminate the application, and then resume or restart it, they should see
+  the same selection.
+</p>
+<p>
+  Maintaining state is an important feature of an application. Users may switch from the current
+  application temporarily to answer the phone, and then switch back. Android may decide to
+  terminate and restart an activity to change the screen orientation, or terminate an unused
+  activity to regain storage. In each case, users are best served by having the UI return to its
+  previous state (except where the logic of the application dictates otherwise).
+</p>
+<p>
+  SpinnerActivity manages its state in these ways:
+</p>
+  <ul>
+    <li>
+      Activity is hidden. When the spinner screen (the activity) is running but hidden by some other screen, it
+      stores the spinner's position and value in a form that persists while the application is running.
+    </li>
+    <li>
+      Application is terminated. When the activity is terminated, it stores the spinner's position and value in
+      a permanent form. The activity can read the position and value when it restarts, and restore the spinner to its previous state.
+    </li>
+    <li>
+      Activity re-appears. When the user returns to the spinner screen, the previous selection is restored.
+    </li>
+    <li>
+      Application is restarted. When the user starts the application again, the previous selection is restored.
+    </li>
+  </ul>
+<p class="note">
+    <strong>Note:</strong> An application can manage its state in other ways as well, but these are
+    not covered in this tutorial.
+</p>
+<p>
+  When an activity is hidden, it is <strong>paused</strong>. When it re-appears, it
+  <strong>resumes</strong>. Recognizing that these are key points in an activity's life cycle,
+  the Activity class provides two callback methods {@link android.app.Activity#onPause()} and
+  {@link android.app.Activity#onResume()} for handling pauses and resumes.
+  SpinnerActivity uses them for code that saves and restores state.
+</p>
+<p>
+  <strong>Note:</strong> If you would like to learn more about the difference between losing
+  focus/pausing and killing an application,
+  refer to the <a href="{@docRoot}guide/topics/fundamentals.html#actlife">Activity Lifecycle</a>
+  section.
+</p>
+<p>
+  The first test verifies that the spinner selection is maintained after the entire application is shut down and then restarted. The test uses instrumentation to
+  set the spinner's variables outside of the UI. It then terminates the activity by calling {@link android.app.Activity#finish() Activity.finish()}, and restarts it
+  using the instrumentation method {@link android.test.ActivityInstrumentationTestCase2#getActivity()}. The test then asserts that the current spinner state matches
+  the test values.
+</p>
+<p>
+  The second test verifies that the spinner selection is maintained after the activity is paused and then resumed. The test uses instrumentation to
+  set the spinner's variables outside of the UI and then force calls to the <code>onPause()</code> and <code>onResume()</code> methods. The test then
+  asserts that the current spinner state matches the test values.
+</p>
+<p>
+  Notice that these tests make limited assumptions about the mechanism by which the activity manages state. The tests use the activity's getters and
+  setters to control the spinner. The first test also knows that hiding an activity calls <code>onPause()</code>, and bringing it back to the foreground
+  calls <code>onResume()</code>. Other than this, the tests treat the activity as a "black box".
+</p>
+<p>
+    To add the code for testing state management across shutdown and restart, follow these steps:
+</p>
+ <ol>
+    <li>
+      Add the test method <code>testStateDestroy()</code>, then
+      set the spinner selection to a test value:
+<pre>
+  public void testStateDestroy() {
+    mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);
+    mActivity.setSpinnerSelection(TEST_STATE_DESTROY_SELECTION);
+</pre>
+    </li>
+    <li>
+      Terminate the activity and restart it:
+<pre>
+    mActivity.finish();
+    mActivity = this.getActivity();
+</pre>
+    </li>
+    <li>
+      Get the current spinner settings from the activity:
+<pre>
+    int currentPosition = mActivity.getSpinnerPosition();
+    String currentSelection = mActivity.getSpinnerSelection();
+</pre>
+    </li>
+    <li>
+      Test the current settings against the test values:
+<pre>
+    assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);
+    assertEquals(TEST_STATE_DESTROY_SELECTION, currentSelection);
+  } // end of testStateDestroy() method definition
+</pre>
+<p>
+  Add the following members to the test case class:
+<pre>
+  public static final int TEST_STATE_DESTROY_POSITION = 2;
+  public static final String TEST_STATE_DESTROY_SELECTION = "Earth";
+</pre>
+    </li>
+ </ol>
+<p>
+    To add the code for testing state management across a pause and resume, follow these steps:
+</p>
+<ol>
+    <li>
+      Add the test method <code>testStatePause()</code>:
+<pre>
+    &#64;UiThreadTest
+    public void testStatePause() {
+</pre>
+    <p>
+      The <code>@UiThreadTest</code> annotation tells Android to build this method so that it runs
+      on the UI thread. This allows the method to change the state of the spinner widget in the
+      application under test. This use of <code>@UiThreadTest</code> shows that, if necessary, you
+      can run an entire method on the UI thread.
+    </p>
+    </li>
+   <li>
+    Set up instrumentation. Get the instrumentation object
+    that is controlling the application under test. This is used later to
+    invoke the <code>onPause()</code> and <code>onResume()</code> methods:
+<pre>
+    Instrumentation mInstr = this.getInstrumentation();
+</pre>
+  </li>
+  <li>
+    Set the spinner selection to a test value:
+<pre>
+    mActivity.setSpinnerPosition(TEST_STATE_PAUSE_POSITION);
+    mActivity.setSpinnerSelection(TEST_STATE_PAUSE_SELECTION);
+</pre>
+  </li>
+  <li>
+    Use instrumentation to call the Activity's <code>onPause()</code>:
+<pre>
+    mInstr.callActivityOnPause(mActivity);
+</pre>
+    <p>
+      Under test, the activity is waiting for input. The invocation of
+      {@link android.app.Instrumentation#callActivityOnPause(android.app.Activity)}
+      performs a call directly to the activity's <code>onPause()</code> instead
+      of manipulating the activity's UI to force it into a paused state.
+    </p>
+  </li>
+  <li>
+    Force the spinner to a different selection:
+<pre>
+    mActivity.setSpinnerPosition(0);
+    mActivity.setSpinnerSelection("");
+</pre>
+    <p>
+      This ensures that resuming the activity actually restores the
+      spinner's state rather than simply leaving it as it was.
+    </p>
+  </li>
+  <li>
+    Use instrumentation to call the Activity's <code>onResume()</code>:
+<pre>
+    mInstr.callActivityOnResume(mActivity);
+</pre>
+    <p>
+      Invoking {@link android.app.Instrumentation#callActivityOnResume(android.app.Activity)}
+      affects the activity in a way similar to <code>callActivityOnPause</code>. The
+      activity's <code>onResume()</code> method is invoked instead of manipulating the
+      activity's UI to force it to resume.
+    </p>
+  </li>
+  <li>
+    Get the current state of the spinner:
+<pre>
+    int currentPosition = mActivity.getSpinnerPosition();
+    String currentSelection = mActivity.getSpinnerSelection();
+</pre>
+  </li>
+  <li>
+    Test the current spinner state against the test values:
+<pre>
+    assertEquals(TEST_STATE_PAUSE_POSITION,currentPosition);
+    assertEquals(TEST_STATE_PAUSE_SELECTION,currentSelection);
+  } // end of testStatePause() method definition
+</pre>
+    <p>
+      Add the following members to the test case class:
+    </p>
+<pre>
+  public static final int TEST_STATE_PAUSE_POSITION = 4;
+  public static final String TEST_STATE_PAUSE_SELECTION = "Jupiter";
+</pre>
+  </li>
+  <li>
+    Add the following imports:
+<pre>
+  import android.app.Instrumentation;
+  import android.test.UiThreadTest;
+</pre>
+  </li>
+</ol>
+<h2 id="RunTests">Running the Tests and Seeing the Results</h2>
+ <p>
+    The most simple way to run the <code>SpinnerActivityTest</code> test case is to run it directly from the Package Explorer.
+ </p>
+ <p>
+    To run the <code>SpinnerActivityTest</code> test, follow these steps:
+</p>
+ <ol>
+    <li>
+      In the Package Explorer, right-click the project SpinnerActivityTest at the top level, and then
+      select <strong>Run As</strong> &gt; <strong>Android JUnit Test</strong>:<br/>
+      <a href="{@docRoot}images/testing/spinnertest_runas_menu_callouts.png">
+        <img alt="Menu to run a test as an Android JUnit test" src="{@docRoot}images/testing/spinnertest_runas_menu_callouts.png" style="height:230px">
+      </a>
+    </li>
+    <li>
+        You will see the emulator start. When the unlock option is displayed (its appearance depends on the API level you specified for the AVD),
+        unlock the home screen.
+    </li>
+    <li>
+      The test application starts. You see a new tab for the <strong>JUnit</strong> view, next to the Package Explorer tab:<br/>
+      <a href="{@docRoot}images/testing/spinnertest_junit_panel.png">
+        <img alt="The JUnit window" src="{@docRoot}images/testing/spinnertest_junit_panel.png" style="height:230px">
+      </a>
+    </li>
+</ol>
+<p>
+    This view contains two sub-panes. The top pane summarizes the tests that were run, and the bottom pane shows failure traces for
+    highlighted tests.
+</p>
+<p>
+   At the conclusion of a successful test run, this is the view's appearance:<br/>
+   <a href="{@docRoot}images/testing/spinnertest_junit_success.png">
+    <img src="{@docRoot}images/testing/spinnertest_junit_success.png" alt="JUnit test run success" style="height:230px"/>
+   </a>
+</p>
+<p>
+    The upper pane summarizes the test:
+</p>
+    <ul>
+        <li>
+            Total time elapsed for the test application(labeled <em>Finished after &lt;x&gt; seconds</em>).
+        </li>
+        <li>
+            Number of runs (<em>Runs:</em>) - the number of tests in the entire test class.
+        </li>
+        <li>
+            Number of errors (<em>Errors:</em>) - the number of program errors and exceptions encountered during
+            the test run.
+        </li>
+        <li>
+            Number of failures (<em>Failures:</em>) - the number of test failures encountered during the test
+            run. This is the number of assertion failures. A test can fail even if the program does not encounter an error.
+        </li>
+        <li>
+            A progress bar. The progress bar extends from left to right as the tests run.
+            <p>
+               If all the tests succeed, the bar remains green. If a test fails, the bar turns from green to red.
+            </p>
+        </li>
+        <li>
+            A test method summary. Below the bar, you see a line for each class in the test application. To look at the results for the individual
+            methods in a test, click the arrow at the left to expand the line. You see the name of each test method. To the
+            right of the name, you see the time taken by the test. You can look at the test's code
+            by double-clicking its name.
+        </li>
+    </ul>
+<p>
+    The lower pane contains the failure trace. If all the tests are successful, this pane is empty. If some tests fail,
+    then if you highlight a failed test in the upper pane, the lower view contains a stack trace for the test. This is
+    demonstrated in the next section.
+</p>
+<p class="note">
+    <strong>Note:</strong> If you run the test application and nothing seems to happen, look for
+    the JUnit view. If you do not see it, you may have run the test application
+    as a regular Android application.
+    Remember that you need to run it as an Android <strong>JUnit</strong>
+    application.
+</p>
+<h2 id="TestFailure">Forcing Some Tests to Fail</h2>
+<p>
+  A test is as useful when it fails as when it succeeds. This section shows what happens in Eclipse with ADT when a test fails. You
+  can quickly see that a test class has failed, find the method or methods that failed, and then use a failure trace to find
+  the exact problem.
+</p>
+<p>
+  The example application SpinnerActivity that you downloaded passes all the tests in the test application SpinnerActivityTest.
+  To force the test to fail, you must modify the example application. You change a line of setup code in the application under test. This
+  causes the <code>testPreConditions()</code> and <code>testTextView()</code> test methods to fail.
+</p>
+<p>
+    To force the tests to fail, follow these steps:
+</p>
+<ol>
+  <li>
+    In Eclipse with ADT, go to the SpinnerActivity project and open the file <code>SpinnerActivity.java</code>.
+  </li>
+  <li>
+    At the top of <code>SpinnerActivity.java</code>, at the end of the <code>onCreate()</code> method, find the following line:
+<pre>
+    // mySpinner.setOnItemSelectedListener(null);
+</pre>
+    <p>Remove the forward slash characters at the beginning of the line to
+    uncomment the line. This sets the listener callback to null:
+    </p>
+<pre>
+    mySpinner.setOnItemSelectedListener(null);
+</pre>
+  </li>
+  <li>
+    The <code>testPreConditions()</code> method in <code>SpinnerActivityTest</code> contains the following test:
+    <code>assertTrue(mSpinner.getOnItemSelectedListener() != null);</code>. This test asserts that the listener callback is <em>not</em> null.
+    Since you have modified the application under test, this assertion now fails.
+  </li>
+  <li>
+    Run the test, as described in the previous section <a href="#RunTests">Running the Tests and Seeing the Results</a>.
+  </li>
+</ol>
+<p>
+    The JUnit view is either created or updated with the results of the test. Now, however, the progress bar is red,
+    the number of failures is 2, and small "x" icons appear in the list icons next to the testPreConditions and
+    TestSpinnerUI tests. This indicates that the tests have failed. The display is similar to this:<br/>
+    <a href="{@docRoot}images/testing/spinnertest_junit_panel_fail_callouts.png">
+      <img src="{@docRoot}images/testing/spinnertest_junit_panel_fail_callouts.png" alt="The JUnit Failure window" style="height:230px"/>
+    </a>
+</p>
+<p>
+  You now want to look at the failures to see exactly where they occurred.
+</p>
+<p>
+    To examine the failures, follow these steps:
+</p>
+<ol>
+  <li>
+    Click the testPreconditions entry. In the lower pane entitled <strong>Failure Trace</strong>,
+    you see a stack trace of the calls that led to the failure. This trace is similar to the following screenshot:<br/>
+    <a href="{@docRoot}images/testing/spinnertest_junit_panel_failtrace_callouts.png">
+      <img src="{@docRoot}images/testing/spinnertest_junit_panel_failtrace_callouts.png" alt="The JUnit failure trace" style="height:230px"/>
+    </a>
+  </li>
+  <li>
+      The first line of the trace tells you the error. In this case, a JUnit assertion failed. To look at the
+      assertion in the test code, double-click the next line (the first line of the trace). In the center pane
+      a new tabbed window opens, containing the code for the test application <code>SpinnerActivityTest</code>. The failed assertion
+      is highlighted in the middle of the window.
+  </li>
+</ol>
+<p>
+    The assertion failed because you modified the main application to set the <code>getOnItemSelectedListener</code> callback to <code>null</code>.
+</p>
+<p>
+    You can look at the failure in <code>testTextView</code> if you want. Remember, though, that <code>testPreConditions</code> is meant to verify the
+    initial setup of the application under test. If testPreConditions() fails, then succeeding tests can't be trusted. The best strategy to follow is to
+    fix the problem and re-run all the tests.
+</p>
+<p>
+    Remember to go back to <code>SpinnerActivity.java</code> and re-comment the line you uncommented in an earlier step.
+</p>
+<p>
+  You have now completed the tutorial.
+</p>
+<h2 id="NextSteps">Next Steps</h2>
+<p>
+    This example test application has shown you how to create a test project and link it to
+    the application you want to test, how to choose and add a test case class, how to write
+    UI and state management tests, and how to run the tests against the application under
+    test. Now that you are familiar with the basics of testing Android applications, here
+    are some suggested next steps:
+</p>
+<p>
+    <strong>Learn more about testing on Android</strong>
+</p>
+<ul>
+    <li>
+        If you haven't done so already, read the
+        <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Android Applications</a>
+        document in the <em>Dev Guide</em>. It provides an overview of how testing on Android
+        works. If you are just getting started with Android testing, reading that document will
+        help you understand the tools available to you, so that you can develop effective
+        tests.
+    </li>
+</ul>
+<p>
+    <strong>Review the main Android test case classes</strong>
+</p>
+<ul>
+    <li>
+        {@link android.test.ActivityInstrumentationTestCase2}
+    </li>
+    <li>
+        {@link android.test.ActivityUnitTestCase}
+    </li>
+    <li>
+        {@link android.test.ProviderTestCase2}
+    </li>
+    <li>
+        {@link android.test.ServiceTestCase}
+    </li>
+</ul>
+<p>
+    <strong>Learn more about the assert and utility classes</strong>
+</p>
+<ul>
+    <li>
+        {@link junit.framework.Assert}, the JUnit Assert class.
+    </li>
+    <li>
+        {@link android.test.MoreAsserts}, additional Android assert methods.
+    </li>
+    <li>
+        {@link android.test.ViewAsserts}, useful assertion methods for testing Views.
+    </li>
+    <li>
+        {@link android.test.TouchUtils}, utility methods for simulating touch events in an Activity.
+    </li>
+</ul>
+<p>
+    <strong>Learn about instrumentation and the instrumented test runner</strong>
+</p>
+<ul>
+    <li>
+        {@link android.app.Instrumentation}, the base instrumentation class.
+    </li>
+    <li>
+        {@link android.test.InstrumentationTestCase}, the base instrumentation test case.
+    </li>
+    <li>
+        {@link android.test.InstrumentationTestRunner}, the standard Android test runner.
+    </li>
+</ul>
+<h2 id="Appendix">Appendix</h2>
+<h3 id="InstallCompletedTestApp">Installing the Completed Test Application Java File</h3>
+<p>
+    The recommended approach to this tutorial is to follow the instructions step-by-step and
+    write the test code as you go. However, if you want to do this tutorial quickly,
+    you can install the entire Java file for the test application into the test project.
+</p>
+<p>
+    To do this, you first create a test project with the necessary structure and files by using
+    the automated tools in Eclipse. Then you exit Eclipse and copy the test application's Java file
+    from the SpinnerTest sample project into your test project. The SpinnerTest sample project is
+    part of the Samples component of the SDK.
+</p>
+<p>
+    The result is a complete test application, ready to run against the Spinner sample application.
+</p>
+<p>
+    To install the test application Java file, follow these steps:
+</p>
+<ol>
+    <li>
+        Set up the projects for the application under test and the test application, as described
+        in the section section <a href="#SetupProjects">Setting Up the Projects</a>.
+    </li>
+    <li>
+        Set up the emulator, as described in the section <a href="#SetupEmulator">Setting Up the Emulator</a>.
+    </li>
+    <li>
+        Add the test case class, as described in the section <a href="#AddTestCaseClass">Adding the test case class file</a>.
+    </li>
+    <li>
+        Close Eclipse with ADT.
+    </li>
+    <li>
+        Copy the file <code>&lt;SDK_path&gt;/samples/android-8/SpinnerTest/src/com/android/examples/spinner/test/SpinnerActivityTest.java</code>
+        to the directory <code>workspace/SpinnerActivityTest/src/com/android/examples/spinner/test/</code>.
+    </li>
+    <li>
+        Restart Eclipse with ADT.
+    </li>
+    <li>
+        In Eclipse with ADT, re-build the project <code>SpinnerActivityTest</code> by selecting it in the Package Explorer, right-clicking,
+        and selecting <em>Project</em>&nbsp;&gt;&nbsp;<em>Clean</em>.
+    </li>
+    <li>
+        The complete, working test application should now be in the <code>SpinnerActivityTest</code> project.
+    </li>
+</ol>
+<p>
+    You can now continue with the tutorial, starting at the section <a href="#AddConstructor">Adding the test case constructor</a> and
+    following along in the text.
+</p>
+<h3 id="EditorCommandLine">For Users Not Developing In Eclipse</h3>
+<p>
+    If you are not developing in Eclipse, you can still do this tutorial. Android provides tools for
+    creating test applications using a code editor and command-line tools. You use the following tools:
+</p>
+<ul>
+  <li>
+   <a href="{@docRoot}guide/developing/tools/adb.html">adb</a> - Installs and uninstalls applications and test applications to a device or the emulator. You
+   also use this tool to run the test application from the command line.
+  </li>
+  <li>
+    <a href="{@docRoot}guide/developing/tools/othertools.html#android">android</a> - Manages projects and test projects. This tool also manages AVDs and Android platforms.
+  </li>
+</ul>
+  <p>
+    You use the <code>emulator</code> tool to run the emulator from the command line.
+  </p>
+  <p>
+    Here are the general steps for doing this tutorial using an editor and the command line:
+  </p>
+<ol>
+  <li>
+    As described in the section <a href="#DownloadCode">Installing the Tutorial Sample Code</a>, get the sample code. You will then
+    have a directory <code>&lt;SDK_path&gt;/samples/android-8</code>, containing (among others) the directories <code>Spinner</code>
+    and <code>SpinnerTest</code>:
+    <ul>
+        <li>
+            <code>Spinner</code> contains the main application, also known as the <strong>application under test</strong>. This tutorial focuses on the
+            common situation of writing tests for an application that already exists, so the main application is provided to you.
+        </li>
+        <li>
+            <code>SpinnerTest</code> contains all the code for the test application. If you want to run quickly through the tutorial, you can
+            install the test code and then follow the text. You may get more from the tutorial, however, if you write the code as you go. The instructions
+            for installing the test code are in the section <a href="#InstallCompletedTestApp">Appendix: Installing the Completed Test Application</a>.
+        </li>
+        </ul>
+  </li>
+  <li>
+    Navigate to the directory <code>&lt;SDK_path&gt;/samples/android-8</code>.
+  </li>
+  <li>
+    Create a new Android application project using <code>android create project</code>:
+<pre>
+$ android create project -t &lt;APItarget&gt; -k com.android.example.spinner -a SpinnerActivity -n SpinnerActivity -p Spinner
+</pre>
+    <p>
+        The value of <code>&lt;APItarget&gt;</code> should be &quot;3&quot; (API level 3) or higher. If you are already developing with a particular API level, and it is
+        higher than 3, then use that API level.
+    </p>
+    <p>
+        This a new Android project <code>SpinnerActivity</code> in the existing <code>Spinner</code> directory. The existing source and
+        resource files are not touched, but the <code>android</code> tool adds the necessary build files.
+    </p>
+  </li>
+  <li>
+    Create a new Android test project using <code>android create test-project</code>:
+<pre>
+$ android create test-project -m ../Spinner -n SpinnerActivityTest -p SpinnerActivityTest
+</pre>
+    <p>
+        This will create a new Android test project in the <em>new</em> directory <code>SpinnerActivityTest</code>. You do this
+        so that the solution to the tutorial that is in <code>SpinnerTest</code> is left untouched. If you want to use the solution
+        code instead of entering it as you read through the tutorial, refer to the section
+        <a href="#InstallCompletedTestApp">Appendix: Installing the Completed Test Application</a>.
+    </p>
+    <p class="Note">
+      <strong>Note:</strong> Running <code>android create test-project</code> will automatically create
+      the file <code>AndroidManifest.xml</code> with the correct <code>&lt;instrumentation&gt;</code> element.
+    </p>
+  </li>
+  <li>
+    Build the sample application. If you are building with Ant, then it is easiest to use the command <code>ant debug</code> to build a debug version, since the SDK comes
+    with a debug signing key. The result will be the file <code>Spinner/bin/SpinnerActivity-debug.apk</code>.
+    You can install this to your device or emulator. Attach your device or start the emulator if you haven't already, and run the command:
+<pre>
+$ adb install Spinner/bin/SpinnerActivity-debug.apk
+</pre>
+  </li>
+  <li>
+    To create the test application, create a file <code>SpinnerActivityTest.java</code> in the directory
+    <code>SpinnerActivityTest/src/com/android/example/spinner/test/</code>.
+  </li>
+  <li>
+    Follow the tutorial, starting with the section <a href="#CreateTestCaseClass">Creating the Test Case Class</a>. When you are prompted to
+    run the sample application, go the the Launcher screen in your device or emulator and select SpinnerActivity.
+    When you are prompted to run the test application, return here to continue with the following instructions.
+  </li>
+  <li>
+    Build the test application. If you are building with Ant, then it is easiest to use the command <code>ant debug</code> to build a
+    debug version, since the SDK comes with a debug signing key. The result will be the Android file
+    <code>SpinnerActivityTest/bin/SpinnerActivityTest-debug.apk</code>. You can install this to your device or emulator.
+    Attach your device or start the emulator if you haven't already, and run the command:
+<pre>
+$ adb install SpinnerActivityTest/bin/SpinnerActivityTest-debug.apk
+</pre>
+  </li>
+  <li>
+    In your device or emulator, check that both the main application <code>SpinnerActivity</code> and the test application
+    <code>SpinnerActivityTest</code> are installed.
+  </li>
+  <li>
+    To run the test application, enter the following at the command line:
+<pre>
+$ adb shell am instrument -w com.android.example.spinner.test/android.test.InstrumentationTestRunner
+ </pre>
+  </li>
+</ol>
+<p>
+    The result of a successful test looks like this:
+</p>
+<pre>
+com.android.example.spinner.test.SpinnerActivityTest:....
+Test results for InstrumentationTestRunner=....
+Time: 10.098
+OK (4 tests)
+</pre>
+<p>
+    If you force the test to fail, as described in the previous section <a href="#TestFailure">Forcing Some Tests to Fail</a>, then
+    the output looks like this:
+</p>
+<pre>
+com.android.example.spinner.test.SpinnerActivityTest:
+Failure in testPreConditions:
+junit.framework.AssertionFailedError
+  at com.android.example.spinner.test.SpinnerActivityTest.testPreConditions(SpinnerActivityTest.java:104)
+  at java.lang.reflect.Method.invokeNative(Native Method)
+  at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)
+  at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)
+  at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:175)
+  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
+  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
+  at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)
+  at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
+Failure in testSpinnerUI:
+junit.framework.ComparisonFailure: expected:&lt;Result&gt; but was:&lt;Saturn&gt;
+  at com.android.example.spinner.test.SpinnerActivityTest.testSpinnerUI(SpinnerActivityTest.java:153)
+  at java.lang.reflect.Method.invokeNative(Native Method)
+  at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)
+  at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)
+  at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:175)
+  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
+  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
+  at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)
+  at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
+..
+Test results for InstrumentationTestRunner=.F.F..
+Time: 9.377
+FAILURES!!!
+Tests run: 4,  Failures: 2,  Errors: 0
+</pre>
diff --git a/docs/html/resources/tutorials/testing/helloandroid_test.jd b/docs/html/resources/tutorials/testing/helloandroid_test.jd
new file mode 100644
index 0000000..f06d5af
--- /dev/null
+++ b/docs/html/resources/tutorials/testing/helloandroid_test.jd
@@ -0,0 +1,506 @@
+page.title=Hello, Testing
+@jd:body
+ <div id="qv-wrapper">
+  <div id="qv">
+  <h2>In this document</h2>
+  <ol>
+    <li>
+        <a href="#CreateTestProject">Creating the Test Project</a>
+    </li>
+    <li>
+        <a href="#CreateTestClass">Creating the Test Case Class</a>
+        <ol>
+            <li>
+                <a href="#CreateTestCaseClassFile">Adding the test case class file</a>
+            </li>
+            <li>
+                <a href="#CreateConstructor">Adding the test case constructor</a>
+            </li>
+            <li>
+                <a href="#CreateSetUp">Adding a setup method</a>
+            </li>
+            <li>
+                <a href="#CreatePreConditions">Adding a preconditions test</a>
+            </li>
+            <li>
+                <a href="#CreateText">Adding a unit test</a>
+            </li>
+            <li>
+                <a href="#CompleteTest">The finished test case class</a>
+            </li>
+        </ol>
+    </li>
+    <li>
+        <a href="#RunTest">Running the Tests and Seeing the Results</a>
+    </li>
+    <li>
+        <a href="#NextSteps">Next Steps</a>
+    </li>
+  </ol>
+<h2>Related Tutorials</h2>
+<ol>
+    <li>
+        <a href="{@docRoot}resources/tutorials/hello-world.html">Hello, World</a>
+    </li>
+    <li>
+        <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
+    </li>
+</ol>
+<h2>See Also</h2>
+<ol>
+    <li>
+        <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Android Applications</a>
+    </li>
+    <li>
+        {@link android.test.ActivityInstrumentationTestCase2}
+    </li>
+    <li>
+        {@link android.test.InstrumentationTestRunner}
+    </li>
+</ol>
+
+</div>
+</div>
+<p>
+    Android offers a powerful but easy-to-use testing framework that is well integrated with the SDK tools. Because writing
+    tests is an important part of any development effort, this tutorial introduces the basics of testing and helps you get started testing quickly.
+
+    To keep things simple, this tutorial builds on the <a href="{@docRoot}resources/tutorials/hello-world.html">Hello World</a> tutorial, which you may have already completed.
+    It guides you through the process of setting up a test project, adding a test, and running the test against the Hello World application, all from inside the Eclipse environment.
+    Of course, when you are done with this tutorial, you will want to create a test project for your own app and add various types of tests to it.
+</p>
+<p>
+    If you'd like to read an overview of the test and instrumentation framework and the core test case classes available, look at
+    the <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Android Applications</a> topic.
+    If you prefer a more advanced testing tutorial, try the
+    <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a> tutorial.
+</p>
+<h2 id="Prerequisites">Prerequisites</h2>
+    <p>
+        This tutorial and its code depend on the Hello World tutorial. If you haven't completed that tutorial already,
+        do so now. You will learn the fundamentals of Android application development, and you will
+        have an Android application that is ready to be tested. The tutorial guides you through the
+        setup of an Android test project using the ADT Plugin for Eclipse and other SDK tools.
+        You will need an SDK development platform that is version 1.5
+        (API level 3) or higher.
+    </p>
+    <p>
+        If you aren't developing in Eclipse with ADT or you would like to run tests directly from the
+        command line, please see the topic <a href="{@docRoot}guide/developing/testing_otheride.html">Testing in Other IDEs</a>
+        for instructions.
+    </p>
+<h2 id="CreateTestProject">Creating the Test Project</h2>
+<p>
+    In the Hello World tutorial you created Android application project called
+    HelloAndroid. A test of an Android application is also an Android
+    application, and you create it within an Eclipse project. The Eclipse with ADT
+    <strong>New Android Test Project</strong> dialog creates a new test project and the
+    framework of a new test application at the same time.
+</p>
+<p>
+    To create the test project and test application framework in Eclipse with ADT, follow these steps
+</p>
+    <ol>
+        <li>
+            In Eclipse, select <strong>New</strong> &gt; <strong>Project</strong> &gt; <strong>Android</strong> &gt; <strong>Android Test Project</strong>.
+            <p>
+              <a href="{@docRoot}images/testing/hwtest_new_test_project_menu.png">
+                  <img alt="New Android Test Project menu" src="{@docRoot}images/testing/hwtest_new_test_project_menu.png" style="height:230px"/>
+              </a>
+            </p>
+            <p>
+              The New Android Test Project dialog appears.
+            </p>
+        </li>
+        <li>
+            Set the following values:
+            <ul>
+                <li>
+                    <em>Test Project Name:</em> &quot;HelloAndroidTest&quot;
+                </li>
+                <li>
+                    <em>Test Target:</em> Set &quot;An existing Android project&quot;, click Browse, and then
+                    select &quot;HelloAndroid&quot; from the list of projects.
+                </li>
+                <li>
+                    <em>Build Target:</em> Set a target whose platform is Android 1.5 or above.
+                </li>
+                <li>
+                    <em>Application name:</em> &quot;HelloAndroidTest&quot;
+                </li>
+                <li>
+                    <em>Package name:</em> &quot;<code>com.example.helloandroid.test</code>&quot;
+                </li>
+            </ul>
+            <p>
+                The dialog should now look like this:
+            </p>
+            <a href="{@docRoot}images/testing/hwtest_new_test_project_dialog_complete_callouts.png">
+                <img alt="New Android Test Project dialog with entries" src="{@docRoot}images/testing/hwtest_new_test_project_dialog_complete_callouts.png" style="height:230px"/>
+            </a>
+        </li>
+        <li>
+            Click Finish. The new project appears in the Package Explorer.
+        </li>
+    </ol>
+<h2 id="CreateTestClass">Creating the Test Case Class</h2>
+<p>
+    You now have a test project HelloAndroidTest, and the basic structure of a test application
+    also called HelloAndroidTest. The basic structure includes all the files and directories you
+    need to build and run a test application, <em>except for</em> the class that contains
+    your tests (the <strong>test case class</strong>).
+</p>
+<p>
+    The next step is to define the test case class. In this tutorial, you define a test case class
+    that extends one of Android's test case classes designed for Activities. The class contains
+    definitions for four methods:
+</p>
+    <ol>
+        <li>
+            <code>HelloAndroidTest</code>: This defines the constructor for the class. It is
+            required by the Android testing framework.
+        </li>
+        <li>
+            <code>setUp()</code>: This overrides the JUnit <code>setUp()</code> method. You use
+            it to initialize the environment before each test runs.
+        </li>
+        <li>
+            <code>testPreconditions()</code>: This defines a small test that ensures the Hello, Android
+            application starts up correctly.
+        </li>
+        <li>
+            <code>testText()</code>: This tests that what is displayed on the screen is the
+            same as what is contained in the application's string resources. It is an example of
+            a real unit test you would perform against an application's UI.
+        </li>
+    </ol>
+<p>
+    The following sections contain the code for the test case class and its methods.
+</p>
+
+<h3 id="CreateTestCaseClassFile">Adding the test case class file</h3>
+<p>
+  To add the Java file for the test case class, follow these steps
+</p>
+    <ol>
+        <li>
+            In Eclipse, open the HelloAndroidTest project if it is not already open.
+        </li>
+        <li>
+            Within HelloAndroidTest, expand the <code>src/</code> folder and
+            then find the package icon for <code>com.example.helloandroid.test</code>.
+            Right-click on the package icon and select <strong>New</strong> &gt; <strong>Class</strong>:
+            <p>
+              <a href="{@docRoot}images/testing/hwtest_create_test_class_menu_callouts.png">
+                  <img alt="Menu for creating a new class in the test application" src="{@docRoot}images/testing/hwtest_create_test_class_menu_callouts.png" style="height:230px"/>
+              </a>
+            </p>
+            <p>
+                The New Java Class dialog appears.
+            </p>
+        </li>
+        <li>
+            In the dialog, enter the following:
+            <ul>
+                <li>
+                    <em>Name:</em> &quot;HelloAndroidTest&quot;. This becomes the name of your test class.
+                </li>
+                <li>
+                    <em>Superclass:</em> &quot;<code>android.test.ActivityInstrumentationTestCase2&lt;HelloAndroid&gt;</code>&quot;.
+                    The superclass is parameterized by an Activity class name.
+                    <p>
+                        The dialog should now look like this:
+                    </p>
+                    <a href="{@docRoot}images/testing/hwtest_new_test_class_dialog_complete_callouts.png">
+                        <img alt="New Java Class dialog with entries" src="{@docRoot}images/testing/hwtest_new_test_class_dialog_complete_callouts.png" style="height:230px"/>
+                    </a>
+                </li>
+            </ul>
+            <p>
+                Do not change any of the other settings. Click Finish.
+            </p>
+        </li>
+        <li>
+            You now have a new file <code>HelloAndroidTest.java</code> in the project.
+            This file contains the class <code>HelloAndroidTest</code>,
+            which extends the Activity test case class
+            <code>ActivityInstrumentationTestCase2&lt;T&gt;</code>. You parameterize the
+            class with <code>HelloAndroid</code>, which is the class name of the activity under test.
+        </li>
+        <li>
+            Open <code>HelloAndroidTest.java</code>. It should look like this:
+<pre class="prettyprint">
+package com.example.helloandroid.test;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class HelloAndroidTest extends ActivityInstrumentationTestCase2&lt;HelloAndroid&gt; {
+}
+</pre>
+        </li>
+        <li>
+            The test case class depends on the <code>HelloAndroid</code> class, which is not
+            yet imported. To import the class, add the following line just before the current
+            <code>import</code> statement:
+<pre class="prettyprint">
+import com.example.helloandroid.HelloAndroid;
+</pre>
+        </li>
+    </ol>
+<h3 id="CreateConstructor">Adding the test case constructor</h3>
+<p>
+    The test case class constructor is used by the Android testing framework when you run the test.
+    It calls the super constructor with parameters that tell the framework what Android application
+    should be tested.
+</p>
+<p>
+    Add the following constructor method immediately after the class definition:
+</p>
+<pre class="prettyprint">
+    public HelloAndroidTest() {
+      super("com.example.helloandroid", HelloAndroid.class);
+    }
+</pre>
+<p>
+    Save the file <code>HelloAndroidTest.java</code>.
+</p>
+<h3 id="CreateSetUp">Adding a setup method</h3>
+<p>
+    The <code>setUp()</code> method overrides the JUnit {@link junit.framework.TestCase#setUp() setUp()}
+    method, which the Android testing framework calls prior to running each test method. You use
+    <code>setUp()</code> to initialize variables and prepare the test environment. For this
+    test case, the <code>setUp()</code> method starts the Hello, Android application,
+    retrieves the text being displayed on the screen, and retrieves the text string in the
+    resource file.
+</p>
+<p>
+    First, add the following code immediately after the constructor method:
+</p>
+<pre class="prettyprint">
+    &#064;Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = this.getActivity();
+        mView = (TextView) mActivity.findViewById(com.example.helloandroid.R.id.textview);
+        resourceString = mActivity.getString(com.example.helloandroid.R.string.hello);
+    }
+</pre>
+<p>
+    For this code to work, you must also add some class members and another import statement. To
+    add the class members, add the following code immediately after the class definition:
+</p>
+<pre class="prettyprint">
+    private HelloAndroid mActivity;
+    private TextView mView;
+    private String resourceString;
+</pre>
+<p>
+    To add the import statement, add the following statement just after the import for
+    <code>android.test.ActivityInstrumentationTestCase2</code>:
+</p>
+<pre class="prettyprint">
+  import android.widget.TextView;
+</pre>
+<h3 id="CreatePreConditions">Adding a preconditions test</h3>
+<p>
+    A preconditions test checks the initial application conditions prior to executing other tests.
+    It's similar to <code>setUp()</code>, but with less overhead, since it only runs once.
+</p>
+<p>
+    Although a preconditions test can check for a variety of different conditions,
+    in this application it only needs to check whether the application under test is
+    initialized properly and the target TextView exists.
+    To do this, it calls the inherited
+    {@link junit.framework.Assert#assertNotNull(Object) assertNotNull()}
+    method, passing a reference to the TextView.
+    The test succeeds only if the object reference is not null.
+</p>
+<pre class="prettyprint">
+    public void testPreconditions() {
+      assertNotNull(mView);
+    }
+</pre>
+<h3 id="CreateText">Adding a unit test</h3>
+<p>
+    Now add a simple unit test to the test case class.
+    The method <code>testText()</code> will call a
+    {@link junit.framework.Assert JUnit Assert}
+    method to check whether the target TextView is displaying the expected text.
+</p>
+<p>
+    For this example, the test expects that the TextView is
+    displaying the string resource that was originally declared for it in HelloAndroid's
+    <code>main.xml</code> file, referred to by the resource ID <code>hello</code>.
+    The call to
+    {@link junit.framework.Assert#assertEquals(String, String) assertEquals(String,String)}
+    compares the expected value, read directly from the <code>hello</code>string resource,
+    to the text displayed by the TextView, obtained from the
+    TextView's <code>getText()</code> method. The test succeeds only if the strings match.
+</p>
+<p>
+    To add this test, add the following code
+    immediately after the <code>testPreconditions()</code> method:
+</p>
+<pre class="prettyprint">
+    public void testText() {
+      assertEquals(resourceString,(String)mView.getText());
+    }
+</pre>
+<h3 id="CompleteTest">The finished test case class</h3>
+<p>
+    You have now finished writing the test. This is what the complete test case class
+    should look like:
+</p>
+<pre class="prettyprint">
+package com.example.helloandroid.test;
+
+import com.example.helloandroid.HelloAndroid;
+import android.test.ActivityInstrumentationTestCase2;
+import android.widget.TextView;
+
+public class HelloAndroidTest extends ActivityInstrumentationTestCase2&lt;HelloAndroid&gt; {
+    private HelloAndroid mActivity;  // the activity under test
+    private TextView mView;          // the activity's TextView (the only view)
+    private String resourceString;
+
+    public HelloAndroidTest() {
+      super("com.example.helloandroid", HelloAndroid.class);
+    }
+    &#064;Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = this.getActivity();
+        mView = (TextView) mActivity.findViewById(com.example.helloandroid.R.id.textview);
+        resourceString = mActivity.getString(com.example.helloandroid.R.string.hello);
+    }
+    public void testPreconditions() {
+      assertNotNull(mView);
+    }
+    public void testText() {
+      assertEquals(resourceString,(String)mView.getText());
+    }
+}
+</pre>
+<h2 id="RunTest">Running the Tests and Seeing the Results</h2>
+<p>
+    You can now run the tests you've created against the Hello, Android application. In Eclipse with
+    ADT, you run a test application as an <strong>Android JUnit test</strong> rather than a regular
+    Android application.
+</p>
+<p>
+    To run the test application as an Android JUnit test, in the Package Explorer right-click
+    the HelloAndroidTest project and select <strong>Run As</strong> &gt; <strong>Android JUnit Test</strong>
+</p>
+    <a href="{@docRoot}images/testing/hwtest_runas_menu_callouts.png">
+        <img alt="Menu to run Hello, World as an Android JUnit test"
+            src="{@docRoot}images/testing/hwtest_runas_menu_callouts.png" style="height:230px">
+    </a>
+<p>
+    The ADT plugin then launches the test application and the application
+    under test on a the target emulator or device. When both applications are running,
+    the testing framework runs the tests and reports the results in the JUnit view of Eclipse,
+    which appears by default as a tab next to the Package Explorer.
+</p>
+<p>
+    As shown below, the JUnit view shows test results in two separate panes:
+    an upper pane summarizes the tests that were run and a lower pane reports the failure traces
+    for the tests. In this case, the tests in this example have run successfully, so there is no
+    failure reported in the view:
+</p>
+    <a href="{@docRoot}images/testing/hwtest_junit_success.png">
+        <img src="{@docRoot}images/testing/hwtest_junit_success.png"
+            alt="JUnit test run success" style="height:230px"/>
+    </a>
+<p>
+    The upper pane summarizes the test:
+</p>
+    <ul>
+        <li>
+            &quot;Finished after <em>x</em> seconds&quot;: How long the test took to run.
+        </li>
+        <li>
+            &quot;Runs&quot;: The number of tests run.
+        </li>
+        <li>
+            &quot;Errors:&quot;: The number of program errors and exceptions encountered during
+            the test run.
+        </li>
+        <li>
+            &quot;Failures:&quot;: The number of assertion failures encountered during the
+            test run.
+        </li>
+        <li>
+            A progress bar. The progress bar extends from left to right as the tests run.
+            <p>
+              If all the tests succeed, the bar remains green.
+              If a test fails, the bar turns from green to red.
+            </p>
+        </li>
+        <li>
+            A test method summary. Below the bar, you see a line for each class in the
+            test application, labeled by its fully-qualified class name.
+            To look at the results for the individual methods in a test case class,
+            click the arrow at the left of the class to expand the line.
+            You see the name of each test method. To the right of the method name, you see the
+            time needed to run that method. You can look at the method's code by
+            double-clicking its name.
+        </li>
+     </ul>
+     <p>
+        The lower pane contains the failure trace. If all the tests are successful,
+        this pane is empty. If some tests fail, then if you select a failed test in the
+        upper pane, the lower view contains a stack trace for the test.
+     </p>
+<h2 id="NextSteps">Next Steps</h2>
+<p>
+    This simple example test application has shown you how to create a test project,
+    create a test class and test cases, and then run the tests against a target application.
+    Now that you are familiar with these fundamentals, here are some suggested next steps:
+</p>
+<p>
+    <strong>Learn more about testing on Android</strong>
+</p>
+<ul>
+    <li>
+        The
+      <a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Android Applications</a>
+        document in the <em>Dev Guide</em> provides an overview of how testing on Android works.
+        If you are just getting started with Android testing, reading that document will
+        help you understand the tools available to you, so that you can develop effective
+        tests.
+    </li>
+</ul>
+<p>
+    <strong>Learn more about the testing classes available in Android</strong>
+</p>
+<ul>
+    <li>
+        For an overview of the types of testing classes you can use,
+        browse through the reference documentation for
+        {@link android.test.ActivityInstrumentationTestCase2},
+        {@link android.test.ProviderTestCase2},
+        {@link android.test.ServiceTestCase}, and
+        {@link junit.framework.Assert}.
+    </li>
+</ul>
+<p>
+    <strong>Explore the Android instrumentation framework</strong>
+</p>
+<ul>
+    <li>
+        The {@link android.test.InstrumentationTestRunner} class contains the code that Android uses
+        to run tests against an application. The {@link android.test.InstrumentationTestCase} class
+        is the base class for test case classes that use additional instrumentation features.
+    </li>
+</ul>
+<p>
+    <strong>Follow the Activity Testing tutorial</strong>
+</p>
+<ul>
+    <li>
+        The <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
+        tutorial is an excellent follow-up to this tutorial.
+        It guides you through a more complex testing scenario that you develop against a
+        more realistic application.
+    </li>
+</ul>
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 4edfb88..207195a 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -32,11 +32,12 @@
 extern const char *MEDIA_MIMETYPE_AUDIO_MPEG;
 extern const char *MEDIA_MIMETYPE_AUDIO_AAC;
 extern const char *MEDIA_MIMETYPE_AUDIO_QCELP;
+extern const char *MEDIA_MIMETYPE_AUDIO_VORBIS;
 extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
 
 extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
 extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
-extern const char *MEDIA_MIMETYPE_CONTAINER_VORBIS;
+extern const char *MEDIA_MIMETYPE_CONTAINER_OGG;
 
 }  // namespace android
 
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 45cc4f6..dc2bd50 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -37,6 +37,8 @@
     kKeyBitRate           = 'brte',  // int32_t (bps)
     kKeyESDS              = 'esds',  // raw data
     kKeyAVCC              = 'avcc',  // raw data
+    kKeyVorbisInfo        = 'vinf',  // raw data
+    kKeyVorbisBooks       = 'vboo',  // raw data
     kKeyWantsNALFragments = 'NALf',
     kKeyIsSyncFrame       = 'sync',  // int32_t (bool)
     kKeyIsCodecConfig     = 'conf',  // int32_t (bool)
diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h
index 30c7f11..498b525 100644
--- a/include/media/stagefright/Utils.h
+++ b/include/media/stagefright/Utils.h
@@ -29,6 +29,10 @@
 uint32_t U32_AT(const uint8_t *ptr);
 uint64_t U64_AT(const uint8_t *ptr);
 
+uint16_t U16LE_AT(const uint8_t *ptr);
+uint32_t U32LE_AT(const uint8_t *ptr);
+uint64_t U64LE_AT(const uint8_t *ptr);
+
 uint64_t ntoh64(uint64_t x);
 uint64_t hton64(uint64_t x);
 
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 566428f..e6658fa 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -276,9 +276,28 @@
     GLuint textureName = mTextures[index].name;
     if (UNLIKELY(textureName == -1LU)) {
         // the texture has not been created yet, this Layer has
-        // in fact never been drawn into. this happens frequently with
-        // SurfaceView.
-        clearWithOpenGL(clip);
+        // in fact never been drawn into. This happens frequently with
+        // SurfaceView because the WindowManager can't know when the client
+        // has drawn the first time.
+
+        // If there is nothing under us, we paint the screen in black, otherwise
+        // we just skip this update.
+
+        // figure out if there is something below us
+        Region under;
+        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
+        const size_t count = drawingLayers.size();
+        for (size_t i=0 ; i<count ; ++i) {
+            const sp<LayerBase>& layer(drawingLayers[i]);
+            if (layer.get() == static_cast<LayerBase const*>(this))
+                break;
+            under.orSelf(layer->visibleRegionScreen);
+        }
+        // if not everything below us is covered, we plug the holes!
+        Region holes(clip.subtract(under));
+        if (!holes.isEmpty()) {
+            clearWithOpenGL(holes);
+        }
         return;
     }
     drawWithOpenGL(clip, mTextures[index]);
diff --git a/location/java/android/location/Address.java b/location/java/android/location/Address.java
index ac275c6..b152f48 100644
--- a/location/java/android/location/Address.java
+++ b/location/java/android/location/Address.java
@@ -500,7 +500,10 @@
             a.mAdminArea = in.readString();
             a.mSubAdminArea = in.readString();
             a.mLocality = in.readString();
+            a.mSubLocality = in.readString();
             a.mThoroughfare = in.readString();
+            a.mSubThoroughfare = in.readString();
+            a.mPremises = in.readString();
             a.mPostalCode = in.readString();
             a.mCountryCode = in.readString();
             a.mCountryName = in.readString();
@@ -544,7 +547,10 @@
         parcel.writeString(mAdminArea);
         parcel.writeString(mSubAdminArea);
         parcel.writeString(mLocality);
+        parcel.writeString(mSubLocality);
         parcel.writeString(mThoroughfare);
+        parcel.writeString(mSubThoroughfare);
+        parcel.writeString(mPremises);
         parcel.writeString(mPostalCode);
         parcel.writeString(mCountryCode);
         parcel.writeString(mCountryName);
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 0420a60..81f995b 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -31,6 +31,7 @@
         MPEG4Extractor.cpp        \
         MPEG4Writer.cpp           \
         MediaExtractor.cpp        \
+        OggExtractor.cpp          \
         Prefetcher.cpp            \
         SampleIterator.cpp        \
         SampleTable.cpp           \
@@ -39,7 +40,6 @@
         StagefrightMetadataRetriever.cpp \
         TimeSource.cpp            \
         TimedEventQueue.cpp       \
-        VorbisExtractor.cpp       \
         WAVExtractor.cpp          \
         string.cpp
 
@@ -50,7 +50,7 @@
 	$(JNI_H_INCLUDE) \
         $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
         $(TOP)/external/opencore/android \
-        $(TOP)/external/tremolo/Tremolo
+        $(TOP)/external/tremolo
 
 LOCAL_SHARED_LIBRARIES := \
         libbinder         \
@@ -70,7 +70,8 @@
         libstagefright_amrwbdec \
         libstagefright_avcdec \
         libstagefright_m4vh263dec \
-        libstagefright_mp3dec
+        libstagefright_mp3dec \
+        libstagefright_vorbisdec
 
 LOCAL_SHARED_LIBRARIES += \
         libstagefright_amrnb_common \
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 5db3201..a66f86b 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -18,7 +18,7 @@
 #include "include/MP3Extractor.h"
 #include "include/MPEG4Extractor.h"
 #include "include/WAVExtractor.h"
-#include "include/VorbisExtractor.h"
+#include "include/OggExtractor.h"
 
 #include <media/stagefright/CachingDataSource.h>
 #include <media/stagefright/DataSource.h>
@@ -93,7 +93,7 @@
     RegisterSniffer(SniffMPEG4);
     RegisterSniffer(SniffAMR);
     RegisterSniffer(SniffWAV);
-    RegisterSniffer(SniffVorbis);
+    RegisterSniffer(SniffOgg);
 }
 
 // static
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 29ec876..fd792ee 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -60,6 +60,8 @@
         int64_t timestamp;
     };
     List<SampleInfo>    mSampleInfos;
+    bool                mSamplesHaveSameSize;
+
     List<MediaBuffer *> mChunkSamples;
     List<off_t>         mChunkOffsets;
 
@@ -78,6 +80,16 @@
 
     List<int32_t> mStssTableEntries;
 
+    struct SttsTableEntry {
+
+        SttsTableEntry(uint32_t count, uint32_t duration)
+            : sampleCount(count), sampleDuration(duration) {}
+
+        uint32_t sampleCount;
+        uint32_t sampleDuration;
+    };
+    List<SttsTableEntry> mSttsTableEntries;
+
     void *mCodecSpecificData;
     size_t mCodecSpecificDataSize;
     bool mGotAllCodecSpecificData;
@@ -389,6 +401,7 @@
       mSource(source),
       mDone(false),
       mMaxTimeStampUs(0),
+      mSamplesHaveSameSize(true),
       mCodecSpecificData(NULL),
       mCodecSpecificDataSize(0),
       mGotAllCodecSpecificData(false),
@@ -562,6 +575,10 @@
     int64_t chunkTimestampUs = 0;
     int32_t nChunks = 0;
     int32_t nZeroLengthFrames = 0;
+    int64_t lastTimestamp = 0;  // Timestamp of the previous sample
+    int64_t lastDuration = 0;   // Time spacing between the previous two samples
+    int32_t sampleCount = 1;    // Sample count in the current stts table entry
+    uint32_t previousSampleSize = 0;  // Size of the previous sample
 
     MediaBuffer *buffer;
     while (!mDone && mSource->read(&buffer) == OK) {
@@ -584,11 +601,7 @@
                         (const uint8_t *)buffer->data()
                             + buffer->range_offset(),
                         buffer->range_length());
-
-                if (err != OK) {
-                    LOGE("failed to parse avc codec specific data.");
-                    break;
-                }
+                CHECK_EQ(OK, err);
             } else if (is_mpeg4) {
                 mCodecSpecificDataSize = buffer->range_length();
                 mCodecSpecificData = malloc(mCodecSpecificDataSize);
@@ -676,14 +689,9 @@
 
                 status_t err = makeAVCCodecSpecificData(
                         (const uint8_t *)tmp, size);
-
                 free(tmp);
                 tmp = NULL;
-
-                if (err != OK) {
-                    LOGE("failed to parse avc codec specific data.");
-                    break;
-                }
+                CHECK_EQ(OK, err);
 
                 mGotAllCodecSpecificData = true;
             }
@@ -712,6 +720,23 @@
         // Our timestamp is in ms.
         info.timestamp = (timestampUs + 500) / 1000;
         mSampleInfos.push_back(info);
+        if (mSampleInfos.size() > 2) {
+            if (lastDuration != info.timestamp - lastTimestamp) {
+                SttsTableEntry sttsEntry(sampleCount, lastDuration);
+                mSttsTableEntries.push_back(sttsEntry);
+                sampleCount = 1;
+            } else {
+                ++sampleCount;
+            }
+        }
+        if (mSamplesHaveSameSize) {
+            if (mSampleInfos.size() >= 2 && previousSampleSize != info.size) {
+                mSamplesHaveSameSize = false;
+            }
+            previousSampleSize = info.size;
+        }
+        lastDuration = info.timestamp - lastTimestamp;
+        lastTimestamp = info.timestamp;
 
 ////////////////////////////////////////////////////////////////////////////////
         // Make a deep copy of the MediaBuffer less Metadata
@@ -749,11 +774,13 @@
             isSync != 0) {
             mStssTableEntries.push_back(mSampleInfos.size());
         }
-        // Our timestamp is in ms.
+
         buffer->release();
         buffer = NULL;
     }
 
+    CHECK(!mSampleInfos.empty());
+
     // Last chunk
     if (!mChunkSamples.empty()) {
         ++nChunks;
@@ -762,6 +789,16 @@
         writeOneChunk(is_avc);
     }
 
+    // We don't really know how long the last frame lasts, since
+    // there is no frame time after it, just repeat the previous
+    // frame's duration.
+    if (mSampleInfos.size() == 1) {
+        lastDuration = 0;  // A single sample's duration
+    } else {
+        ++sampleCount;  // Count for the last sample
+    }
+    SttsTableEntry sttsEntry(sampleCount, lastDuration);
+    mSttsTableEntries.push_back(sttsEntry);
     mReachedEOS = true;
     LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames",
             count, nZeroLengthFrames, mSampleInfos.size());
@@ -1054,29 +1091,12 @@
 
           mOwner->beginBox("stts");
             mOwner->writeInt32(0);  // version=0, flags=0
-            mOwner->writeInt32(mSampleInfos.size());
-
-            List<SampleInfo>::iterator it = mSampleInfos.begin();
-            int64_t last = (*it).timestamp;
-            int64_t lastDuration = 1;
-
-            ++it;
-            while (it != mSampleInfos.end()) {
-                mOwner->writeInt32(1);
-                lastDuration = (*it).timestamp - last;
-                mOwner->writeInt32(lastDuration);
-
-                last = (*it).timestamp;
-
-                ++it;
+            mOwner->writeInt32(mSttsTableEntries.size());
+            for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
+                 it != mSttsTableEntries.end(); ++it) {
+                mOwner->writeInt32(it->sampleCount);
+                mOwner->writeInt32(it->sampleDuration);
             }
-
-            // We don't really know how long the last frame lasts, since
-            // there is no frame time after it, just repeat the previous
-            // frame's duration.
-            mOwner->writeInt32(1);
-            mOwner->writeInt32(lastDuration);
-
           mOwner->endBox();  // stts
 
           if (!is_audio) {
@@ -1092,11 +1112,18 @@
 
           mOwner->beginBox("stsz");
             mOwner->writeInt32(0);  // version=0, flags=0
-            mOwner->writeInt32(0);  // default sample size
+            if (mSamplesHaveSameSize) {
+                List<SampleInfo>::iterator it = mSampleInfos.begin();
+                mOwner->writeInt32(it->size);  // default sample size
+            } else {
+                mOwner->writeInt32(0);
+            }
             mOwner->writeInt32(mSampleInfos.size());
-            for (List<SampleInfo>::iterator it = mSampleInfos.begin();
-                 it != mSampleInfos.end(); ++it) {
-                mOwner->writeInt32((*it).size);
+            if (!mSamplesHaveSameSize) {
+                for (List<SampleInfo>::iterator it = mSampleInfos.begin();
+                     it != mSampleInfos.end(); ++it) {
+                    mOwner->writeInt32((*it).size);
+                }
             }
           mOwner->endBox();  // stsz
 
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index db18ab6..4b3813b 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -30,10 +30,11 @@
 const char *MEDIA_MIMETYPE_AUDIO_MPEG = "audio/mpeg";
 const char *MEDIA_MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
 const char *MEDIA_MIMETYPE_AUDIO_QCELP = "audio/qcelp";
+const char *MEDIA_MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
 const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
 
 const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
 const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/wav";
-const char *MEDIA_MIMETYPE_CONTAINER_VORBIS = "application/ogg";
+const char *MEDIA_MIMETYPE_CONTAINER_OGG = "application/ogg";
 
 }  // namespace android
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index dfddbe0..513f49c 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -22,7 +22,7 @@
 #include "include/MP3Extractor.h"
 #include "include/MPEG4Extractor.h"
 #include "include/WAVExtractor.h"
-#include "include/VorbisExtractor.h"
+#include "include/OggExtractor.h"
 
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaDefs.h>
@@ -67,8 +67,8 @@
         return new AMRExtractor(source);
     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {
         return new WAVExtractor(source);
-    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_VORBIS)) {
-        return new VorbisExtractor(source);
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {
+        return new OggExtractor(source);
     }
 
     return NULL;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index b7d6d42..ce4dd32 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -25,6 +25,7 @@
 #include "include/AVCDecoder.h"
 #include "include/M4vH263Decoder.h"
 #include "include/MP3Decoder.h"
+#include "include/VorbisDecoder.h"
 
 #include "include/ESDS.h"
 
@@ -67,6 +68,7 @@
 FACTORY_CREATE(AACDecoder)
 FACTORY_CREATE(AVCDecoder)
 FACTORY_CREATE(M4vH263Decoder)
+FACTORY_CREATE(VorbisDecoder)
 FACTORY_CREATE(AMRNBEncoder)
 
 static sp<MediaSource> InstantiateSoftwareCodec(
@@ -83,6 +85,7 @@
         FACTORY_REF(AACDecoder)
         FACTORY_REF(AVCDecoder)
         FACTORY_REF(M4vH263Decoder)
+        FACTORY_REF(VorbisDecoder)
         FACTORY_REF(AMRNBEncoder)
     };
     for (size_t i = 0;
@@ -123,6 +126,7 @@
     { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
     { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" },
 //    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
+    { MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" },
 };
 
 static const CodecInfo kEncoderInfo[] = {
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
new file mode 100644
index 0000000..699b955
--- /dev/null
+++ b/media/libstagefright/OggExtractor.cpp
@@ -0,0 +1,586 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "OggExtractor"
+#include <utils/Log.h>
+
+#include "include/OggExtractor.h"
+
+#include <cutils/properties.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+#include <utils/String8.h>
+
+extern "C" {
+    #include <Tremolo/codec_internal.h>
+
+    int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);
+    int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);
+    int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb);
+}
+
+namespace android {
+
+struct OggSource : public MediaSource {
+    OggSource(const sp<OggExtractor> &extractor);
+
+    virtual sp<MetaData> getFormat();
+
+    virtual status_t start(MetaData *params = NULL);
+    virtual status_t stop();
+
+    virtual status_t read(
+            MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+protected:
+    virtual ~OggSource();
+
+private:
+    sp<OggExtractor> mExtractor;
+    bool mStarted;
+
+    OggSource(const OggSource &);
+    OggSource &operator=(const OggSource &);
+};
+
+struct MyVorbisExtractor {
+    MyVorbisExtractor(const sp<DataSource> &source);
+    virtual ~MyVorbisExtractor();
+
+    sp<MetaData> getFormat() const;
+
+    // Returns an approximate bitrate in bits per second.
+    uint64_t approxBitrate();
+
+    status_t seekToOffset(off_t offset);
+    status_t readNextPacket(MediaBuffer **buffer);
+
+    void init();
+
+private:
+    struct Page {
+        uint64_t mGranulePosition;
+        uint32_t mSerialNo;
+        uint32_t mPageNo;
+        uint8_t mFlags;
+        uint8_t mNumSegments;
+        uint8_t mLace[255];
+    };
+
+    sp<DataSource> mSource;
+    off_t mOffset;
+    Page mCurrentPage;
+    size_t mCurrentPageSize;
+    size_t mNextLaceIndex;
+
+    vorbis_info mVi;
+    vorbis_comment mVc;
+
+    sp<MetaData> mMeta;
+
+    ssize_t readPage(off_t offset, Page *page);
+    status_t findNextPage(off_t startOffset, off_t *pageOffset);
+
+    void verifyHeader(
+            MediaBuffer *buffer, uint8_t type);
+
+    MyVorbisExtractor(const MyVorbisExtractor &);
+    MyVorbisExtractor &operator=(const MyVorbisExtractor &);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+OggSource::OggSource(const sp<OggExtractor> &extractor)
+    : mExtractor(extractor),
+      mStarted(false) {
+}
+
+OggSource::~OggSource() {
+    if (mStarted) {
+        stop();
+    }
+}
+
+sp<MetaData> OggSource::getFormat() {
+    return mExtractor->mImpl->getFormat();
+}
+
+status_t OggSource::start(MetaData *params) {
+    if (mStarted) {
+        return INVALID_OPERATION;
+    }
+
+    mStarted = true;
+
+    return OK;
+}
+
+status_t OggSource::stop() {
+    mStarted = false;
+
+    return OK;
+}
+
+status_t OggSource::read(
+        MediaBuffer **out, const ReadOptions *options) {
+    *out = NULL;
+
+    int64_t seekTimeUs;
+    if (options && options->getSeekTo(&seekTimeUs)) {
+        off_t pos = seekTimeUs * mExtractor->mImpl->approxBitrate() / 8000000ll;
+        LOGI("seeking to offset %ld", pos);
+
+        if (mExtractor->mImpl->seekToOffset(pos) != OK) {
+            return ERROR_END_OF_STREAM;
+        }
+    }
+
+    MediaBuffer *packet;
+    status_t err = mExtractor->mImpl->readNextPacket(&packet);
+
+    if (err != OK) {
+        return err;
+    }
+
+#if 0
+    int64_t timeUs;
+    if (packet->meta_data()->findInt64(kKeyTime, &timeUs)) {
+        LOGI("found time = %lld us", timeUs);
+    } else {
+        LOGI("NO time");
+    }
+#endif
+
+    *out = packet;
+
+    return OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+MyVorbisExtractor::MyVorbisExtractor(const sp<DataSource> &source)
+    : mSource(source),
+      mOffset(0),
+      mCurrentPageSize(0),
+      mNextLaceIndex(0) {
+    mCurrentPage.mNumSegments = 0;
+}
+
+MyVorbisExtractor::~MyVorbisExtractor() {
+}
+
+sp<MetaData> MyVorbisExtractor::getFormat() const {
+    return mMeta;
+}
+
+status_t MyVorbisExtractor::findNextPage(
+        off_t startOffset, off_t *pageOffset) {
+    *pageOffset = startOffset;
+
+    for (;;) {
+        char signature[4];
+        ssize_t n = mSource->readAt(*pageOffset, &signature, 4);
+
+        if (n < 4) {
+            *pageOffset = 0;
+
+            return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM;
+        }
+
+        if (!memcmp(signature, "OggS", 4)) {
+            if (*pageOffset > startOffset) {
+                LOGV("skipped %ld bytes of junk to reach next frame",
+                     *pageOffset - startOffset);
+            }
+
+            return OK;
+        }
+
+        ++*pageOffset;
+    }
+}
+
+status_t MyVorbisExtractor::seekToOffset(off_t offset) {
+    off_t pageOffset;
+    status_t err = findNextPage(offset, &pageOffset);
+
+    if (err != OK) {
+        return err;
+    }
+
+    mOffset = pageOffset;
+
+    mCurrentPageSize = 0;
+    mCurrentPage.mNumSegments = 0;
+    mNextLaceIndex = 0;
+
+    // XXX what if new page continues packet from last???
+
+    return OK;
+}
+
+ssize_t MyVorbisExtractor::readPage(off_t offset, Page *page) {
+    uint8_t header[27];
+    if (mSource->readAt(offset, header, sizeof(header))
+            < (ssize_t)sizeof(header)) {
+        LOGE("failed to read %d bytes at offset 0x%08lx", sizeof(header), offset);
+
+        return ERROR_IO;
+    }
+
+    if (memcmp(header, "OggS", 4)) {
+        return ERROR_MALFORMED;
+    }
+
+    if (header[4] != 0) {
+        // Wrong version.
+
+        return ERROR_UNSUPPORTED;
+    }
+
+    page->mFlags = header[5];
+
+    if (page->mFlags & ~7) {
+        // Only bits 0-2 are defined in version 0.
+        return ERROR_MALFORMED;
+    }
+
+    page->mGranulePosition = U64LE_AT(&header[6]);
+
+#if 0
+    printf("granulePosition = %llu (0x%llx)\n",
+           page->mGranulePosition, page->mGranulePosition);
+#endif
+
+    page->mSerialNo = U32LE_AT(&header[14]);
+    page->mPageNo = U32LE_AT(&header[18]);
+
+    page->mNumSegments = header[26];
+    if (mSource->readAt(
+                offset + sizeof(header), page->mLace, page->mNumSegments)
+            < (ssize_t)page->mNumSegments) {
+        return ERROR_IO;
+    }
+
+    size_t totalSize = 0;;
+    for (size_t i = 0; i < page->mNumSegments; ++i) {
+        totalSize += page->mLace[i];
+    }
+
+    String8 tmp;
+    for (size_t i = 0; i < page->mNumSegments; ++i) {
+        char x[32];
+        sprintf(x, "%s%u", i > 0 ? ", " : "", (unsigned)page->mLace[i]);
+
+        tmp.append(x);
+    }
+
+    LOGV("%c %s", page->mFlags & 1 ? '+' : ' ', tmp.string());
+
+    return sizeof(header) + page->mNumSegments + totalSize;
+}
+
+status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) {
+    *out = NULL;
+
+    MediaBuffer *buffer = NULL;
+    int64_t timeUs = -1;
+
+    for (;;) {
+        size_t i;
+        size_t packetSize = 0;
+        bool gotFullPacket = false;
+        for (i = mNextLaceIndex; i < mCurrentPage.mNumSegments; ++i) {
+            uint8_t lace = mCurrentPage.mLace[i];
+
+            packetSize += lace;
+
+            if (lace < 255) {
+                gotFullPacket = true;
+                ++i;
+                break;
+            }
+        }
+
+        if (mNextLaceIndex < mCurrentPage.mNumSegments) {
+            off_t dataOffset = mOffset + 27 + mCurrentPage.mNumSegments;
+            for (size_t j = 0; j < mNextLaceIndex; ++j) {
+                dataOffset += mCurrentPage.mLace[j];
+            }
+
+            size_t fullSize = packetSize;
+            if (buffer != NULL) {
+                fullSize += buffer->range_length();
+            }
+            MediaBuffer *tmp = new MediaBuffer(fullSize);
+            if (buffer != NULL) {
+                memcpy(tmp->data(), buffer->data(), buffer->range_length());
+                tmp->set_range(0, buffer->range_length());
+                buffer->release();
+            } else {
+                // XXX Not only is this not technically the correct time for
+                // this packet, we also stamp every packet in this page
+                // with the same time. This needs fixing later.
+                timeUs = mCurrentPage.mGranulePosition * 1000000ll / mVi.rate;
+                tmp->set_range(0, 0);
+            }
+            buffer = tmp;
+
+            ssize_t n = mSource->readAt(
+                    dataOffset,
+                    (uint8_t *)buffer->data() + buffer->range_length(),
+                    packetSize);
+
+            if (n < (ssize_t)packetSize) {
+                LOGE("failed to read %d bytes at 0x%08lx", packetSize, dataOffset);
+                return ERROR_IO;
+            }
+
+            buffer->set_range(0, fullSize);
+
+            mNextLaceIndex = i;
+
+            if (gotFullPacket) {
+                // We've just read the entire packet.
+
+                if (timeUs >= 0) {
+                    buffer->meta_data()->setInt64(kKeyTime, timeUs);
+                }
+
+                *out = buffer;
+
+                return OK;
+            }
+
+            // fall through, the buffer now contains the start of the packet.
+        }
+
+        CHECK_EQ(mNextLaceIndex, mCurrentPage.mNumSegments);
+
+        mOffset += mCurrentPageSize;
+        ssize_t n = readPage(mOffset, &mCurrentPage);
+
+        if (n <= 0) {
+            if (buffer) {
+                buffer->release();
+                buffer = NULL;
+            }
+
+            LOGE("readPage returned %ld", n);
+
+            return n < 0 ? n : (status_t)ERROR_END_OF_STREAM;
+        }
+
+        mCurrentPageSize = n;
+        mNextLaceIndex = 0;
+
+        if (buffer != NULL) {
+            if ((mCurrentPage.mFlags & 1) == 0) {
+                // This page does not continue the packet, i.e. the packet
+                // is already complete.
+
+                if (timeUs >= 0) {
+                    buffer->meta_data()->setInt64(kKeyTime, timeUs);
+                }
+
+                *out = buffer;
+
+                return OK;
+            }
+        }
+    }
+}
+
+void MyVorbisExtractor::init() {
+    vorbis_info_init(&mVi);
+
+    vorbis_comment mVc;
+
+    mMeta = new MetaData;
+    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_VORBIS);
+
+    MediaBuffer *packet;
+    CHECK_EQ(readNextPacket(&packet), OK);
+    LOGV("read packet of size %d\n", packet->range_length());
+    verifyHeader(packet, 1);
+    packet->release();
+    packet = NULL;
+
+    CHECK_EQ(readNextPacket(&packet), OK);
+    LOGV("read packet of size %d\n", packet->range_length());
+    verifyHeader(packet, 3);
+    packet->release();
+    packet = NULL;
+
+    CHECK_EQ(readNextPacket(&packet), OK);
+    LOGV("read packet of size %d\n", packet->range_length());
+    verifyHeader(packet, 5);
+    packet->release();
+    packet = NULL;
+}
+
+void MyVorbisExtractor::verifyHeader(
+        MediaBuffer *buffer, uint8_t type) {
+    const uint8_t *data =
+        (const uint8_t *)buffer->data() + buffer->range_offset();
+
+    size_t size = buffer->range_length();
+
+    CHECK(size >= 7);
+
+    CHECK_EQ(data[0], type);
+    CHECK(!memcmp(&data[1], "vorbis", 6));
+
+    ogg_buffer buf;
+    buf.data = (uint8_t *)data;
+    buf.size = size;
+    buf.refcount = 1;
+    buf.ptr.owner = NULL;
+
+    ogg_reference ref;
+    ref.buffer = &buf;
+    ref.begin = 0;
+    ref.length = size;
+    ref.next = NULL;
+
+    oggpack_buffer bits;
+    oggpack_readinit(&bits, &ref);
+
+    CHECK_EQ(oggpack_read(&bits, 8), type);
+    for (size_t i = 0; i < 6; ++i) {
+        oggpack_read(&bits, 8);  // skip 'vorbis'
+    }
+
+    switch (type) {
+        case 1:
+        {
+            CHECK_EQ(0, _vorbis_unpack_info(&mVi, &bits));
+
+            mMeta->setData(kKeyVorbisInfo, 0, data, size);
+            mMeta->setInt32(kKeySampleRate, mVi.rate);
+            mMeta->setInt32(kKeyChannelCount, mVi.channels);
+
+            LOGV("lower-bitrate = %ld", mVi.bitrate_lower);
+            LOGV("upper-bitrate = %ld", mVi.bitrate_upper);
+            LOGV("nominal-bitrate = %ld", mVi.bitrate_nominal);
+            LOGV("window-bitrate = %ld", mVi.bitrate_window);
+
+            off_t size;
+            if (mSource->getSize(&size) == OK) {
+                uint64_t bps = approxBitrate();
+
+                mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);
+            }
+            break;
+        }
+
+        case 3:
+        {
+            CHECK_EQ(0, _vorbis_unpack_comment(&mVc, &bits));
+            break;
+        }
+
+        case 5:
+        {
+            CHECK_EQ(0, _vorbis_unpack_books(&mVi, &bits));
+
+            mMeta->setData(kKeyVorbisBooks, 0, data, size);
+            break;
+        }
+    }
+}
+
+uint64_t MyVorbisExtractor::approxBitrate() {
+    if (mVi.bitrate_nominal != 0) {
+        return mVi.bitrate_nominal;
+    }
+
+    return (mVi.bitrate_lower + mVi.bitrate_upper) / 2;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+OggExtractor::OggExtractor(const sp<DataSource> &source)
+    : mDataSource(source),
+      mInitCheck(NO_INIT),
+      mImpl(NULL) {
+    mImpl = new MyVorbisExtractor(mDataSource);
+    CHECK_EQ(mImpl->seekToOffset(0), OK);
+    mImpl->init();
+
+    mInitCheck = OK;
+}
+
+OggExtractor::~OggExtractor() {
+    delete mImpl;
+    mImpl = NULL;
+}
+
+size_t OggExtractor::countTracks() {
+    return mInitCheck != OK ? 0 : 1;
+}
+
+sp<MediaSource> OggExtractor::getTrack(size_t index) {
+    if (index >= 1) {
+        return NULL;
+    }
+
+    return new OggSource(this);
+}
+
+sp<MetaData> OggExtractor::getTrackMetaData(
+        size_t index, uint32_t flags) {
+    if (index >= 1) {
+        return NULL;
+    }
+
+    return mImpl->getFormat();
+}
+
+sp<MetaData> OggExtractor::getMetaData() {
+    sp<MetaData> meta = new MetaData;
+
+    if (mInitCheck != OK) {
+        return meta;
+    }
+
+    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG);
+
+    return meta;
+}
+
+bool SniffOgg(
+        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
+    char tmp[4];
+    if (source->readAt(0, tmp, 4) < 4 || memcmp(tmp, "OggS", 4)) {
+        return false;
+    }
+
+    mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_OGG);
+    *confidence = 0.2f;
+
+    return true;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 34fb2bc..03287dd1 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -27,8 +27,8 @@
 #include <libsonivox/eas.h>
 
 // Ogg Vorbis includes
-#include "ivorbiscodec.h"
-#include "ivorbisfile.h"
+#include <Tremolo/ivorbiscodec.h>
+#include <Tremolo/ivorbisfile.h>
 
 namespace android {
 
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 2720f93..c563ce6 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -32,6 +32,18 @@
     return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4);
 }
 
+uint16_t U16LE_AT(const uint8_t *ptr) {
+    return ptr[0] | (ptr[1] << 8);
+}
+
+uint32_t U32LE_AT(const uint8_t *ptr) {
+    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
+}
+
+uint64_t U64LE_AT(const uint8_t *ptr) {
+    return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr);
+}
+
 // XXX warning: these won't work on big-endian host.
 uint64_t ntoh64(uint64_t x) {
     return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32);
diff --git a/media/libstagefright/VorbisExtractor.cpp b/media/libstagefright/VorbisExtractor.cpp
deleted file mode 100644
index e7b62d6..0000000
--- a/media/libstagefright/VorbisExtractor.cpp
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "VorbisExtractor"
-#include <utils/Log.h>
-
-#include "include/VorbisExtractor.h"
-
-#include <cutils/properties.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MetaData.h>
-#include <utils/String8.h>
-
-#include <ivorbisfile.h>
-
-namespace android {
-
-struct VorbisDataSource {
-    sp<DataSource> mDataSource;
-    off_t mOffset;
-    bool mSeekDisabled;
-};
-
-static bool ShouldDisableSeek(const sp<DataSource> &source) {
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("media.vorbis.always-allow-seek", value, NULL)
-            && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
-        return false;
-    }
-
-    // This is a workaround for an application streaming data through
-    // a local HTTP proxy that doesn't really conform to the HTTP/1.1
-    // specs. We have to disable seek functionality in this case.
-
-    return source->flags() & DataSource::kStreamedFromLocalHost;
-}
-
-static size_t VorbisRead(
-        void *ptr, size_t size, size_t nmemb, void *datasource) {
-    VorbisDataSource *vds = (VorbisDataSource *)datasource;
-
-    ssize_t n = vds->mDataSource->readAt(vds->mOffset, ptr, size * nmemb);
-
-    if (n < 0) {
-        return n;
-    }
-
-    vds->mOffset += n;
-
-    return n / size;
-}
-
-static int VorbisSeek(
-        void *datasource, ogg_int64_t offset, int whence) {
-    VorbisDataSource *vds = (VorbisDataSource *)datasource;
-
-    if (vds->mSeekDisabled) {
-        errno = ESPIPE;
-        return -1;
-    }
-
-    switch (whence) {
-        case SEEK_SET:
-            vds->mOffset = offset;
-            break;
-        case SEEK_END:
-        {
-            off_t size;
-            if (vds->mDataSource->getSize(&size) != OK) {
-                errno = ESPIPE;
-                return -1;
-            }
-
-            vds->mOffset = offset + size;
-            break;
-        }
-
-        case SEEK_CUR:
-        {
-            vds->mOffset += offset;
-            break;
-        }
-
-        default:
-        {
-            errno = EINVAL;
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-static int VorbisClose(void *datasource) {
-    return 0;
-}
-
-static long VorbisTell(void *datasource) {
-    VorbisDataSource *vds = (VorbisDataSource *)datasource;
-
-    return vds->mOffset;
-}
-
-static const ov_callbacks gVorbisCallbacks = {
-    &VorbisRead,
-    &VorbisSeek,
-    &VorbisClose,
-    &VorbisTell
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct VorbisSource : public MediaSource {
-    VorbisSource(const sp<VorbisExtractor> &extractor,
-                 const sp<MetaData> &meta, OggVorbis_File *file);
-
-    virtual sp<MetaData> getFormat();
-
-    virtual status_t start(MetaData *params = NULL);
-    virtual status_t stop();
-
-    virtual status_t read(
-            MediaBuffer **buffer, const ReadOptions *options = NULL);
-
-protected:
-    virtual ~VorbisSource();
-
-private:
-    enum {
-        kMaxBufferSize = 8192
-    };
-
-    sp<VorbisExtractor> mExtractor;
-    sp<MetaData> mMeta;
-    OggVorbis_File *mFile;
-    MediaBufferGroup *mGroup;
-
-    VorbisSource(const VorbisSource &);
-    VorbisSource &operator=(const VorbisSource &);
-};
-
-VorbisSource::VorbisSource(
-        const sp<VorbisExtractor> &extractor,
-        const sp<MetaData> &meta, OggVorbis_File *file)
-    : mExtractor(extractor),
-      mMeta(meta),
-      mFile(file),
-      mGroup(NULL) {
-}
-
-VorbisSource::~VorbisSource() {
-    if (mGroup) {
-        stop();
-    }
-}
-
-sp<MetaData> VorbisSource::getFormat() {
-    return mMeta;
-}
-
-status_t VorbisSource::start(MetaData *params) {
-    if (mGroup != NULL) {
-        return INVALID_OPERATION;
-    }
-
-    mGroup = new MediaBufferGroup;
-    mGroup->add_buffer(new MediaBuffer(kMaxBufferSize));
-
-    return OK;
-}
-
-status_t VorbisSource::stop() {
-    delete mGroup;
-    mGroup = NULL;
-
-    return OK;
-}
-
-status_t VorbisSource::read(
-        MediaBuffer **out, const ReadOptions *options) {
-    *out = NULL;
-
-    int64_t seekTimeUs;
-    if (options && options->getSeekTo(&seekTimeUs)) {
-        ov_time_seek(mFile, seekTimeUs / 1000ll);
-    }
-
-    MediaBuffer *buffer;
-    CHECK_EQ(OK, mGroup->acquire_buffer(&buffer));
-
-    ogg_int64_t positionMs = ov_time_tell(mFile);
-
-    int bitstream;
-    long n = ov_read(mFile, buffer->data(), buffer->size(), &bitstream);
-
-    if (n <= 0) {
-        LOGE("ov_read returned %ld", n);
-
-        buffer->release();
-        buffer = NULL;
-
-        return n < 0 ? ERROR_MALFORMED : ERROR_END_OF_STREAM;
-    }
-
-    buffer->set_range(0, n);
-    buffer->meta_data()->setInt64(kKeyTime, positionMs * 1000ll);
-
-    *out = buffer;
-
-    return OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-VorbisExtractor::VorbisExtractor(const sp<DataSource> &source)
-    : mDataSource(source),
-      mFile(new OggVorbis_File),
-      mVorbisDataSource(new VorbisDataSource),
-      mInitCheck(NO_INIT) {
-    mVorbisDataSource->mDataSource = mDataSource;
-    mVorbisDataSource->mOffset = 0;
-    mVorbisDataSource->mSeekDisabled = ShouldDisableSeek(mDataSource);
-
-    int res = ov_open_callbacks(
-            mVorbisDataSource, mFile, NULL, 0, gVorbisCallbacks);
-
-    if (res != 0) {
-        return;
-    }
-
-    mMeta = new MetaData;
-    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
-
-    vorbis_info *vi = ov_info(mFile, -1);
-    mMeta->setInt32(kKeySampleRate, vi->rate);
-    mMeta->setInt32(kKeyChannelCount, vi->channels);
-
-    ogg_int64_t durationMs = ov_time_total(mFile, -1);
-    mMeta->setInt64(kKeyDuration, durationMs * 1000ll);
-
-    LOGI("Successfully initialized.");
-
-    mInitCheck = OK;
-}
-
-VorbisExtractor::~VorbisExtractor() {
-    CHECK_EQ(0, ov_clear(mFile));
-
-    delete mVorbisDataSource;
-    mVorbisDataSource = NULL;
-
-    delete mFile;
-    mFile = NULL;
-}
-
-size_t VorbisExtractor::countTracks() {
-    return mInitCheck != OK ? 0 : 1;
-}
-
-sp<MediaSource> VorbisExtractor::getTrack(size_t index) {
-    if (index >= 1) {
-        return NULL;
-    }
-
-    return new VorbisSource(this, mMeta, mFile);
-}
-
-sp<MetaData> VorbisExtractor::getTrackMetaData(
-        size_t index, uint32_t flags) {
-    if (index >= 1) {
-        return NULL;
-    }
-
-    return mMeta;
-}
-
-sp<MetaData> VorbisExtractor::getMetaData() {
-    sp<MetaData> meta = new MetaData;
-
-    if (mInitCheck != OK) {
-        return meta;
-    }
-
-    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_VORBIS);
-
-    return meta;
-}
-
-bool SniffVorbis(
-        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
-    OggVorbis_File file;
-
-    VorbisDataSource vds;
-    vds.mDataSource = source;
-    vds.mOffset = 0;
-    vds.mSeekDisabled = ShouldDisableSeek(source);
-
-    int res = ov_test_callbacks(&vds, &file, NULL, 0, gVorbisCallbacks);
-
-    CHECK_EQ(0, ov_clear(&file));
-
-    if (res != 0) {
-        return false;
-    }
-
-    *mimeType = MEDIA_MIMETYPE_CONTAINER_VORBIS;
-    *confidence = 0.4f;
-
-    LOGV("This looks like an Ogg file.");
-
-    return true;
-}
-
-uint32_t VorbisExtractor::flags() const {
-    if (ShouldDisableSeek(mDataSource)) {
-        LOGI("This is streamed from local host, seek disabled");
-        return CAN_PAUSE;
-    } else {
-        return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE;
-    }
-}
-
-}  // namespace android
diff --git a/media/libstagefright/codecs/vorbis/Android.mk b/media/libstagefright/codecs/vorbis/Android.mk
new file mode 100644
index 0000000..2e431205
--- /dev/null
+++ b/media/libstagefright/codecs/vorbis/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/codecs/vorbis/dec/Android.mk b/media/libstagefright/codecs/vorbis/dec/Android.mk
new file mode 100644
index 0000000..5c768c8
--- /dev/null
+++ b/media/libstagefright/codecs/vorbis/dec/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+        VorbisDecoder.cpp \
+
+LOCAL_C_INCLUDES := \
+        frameworks/base/media/libstagefright/include \
+        external/tremolo
+
+LOCAL_MODULE := libstagefright_vorbisdec
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
new file mode 100644
index 0000000..5485f25
--- /dev/null
+++ b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VorbisDecoder.h"
+
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+
+extern "C" {
+    #include <Tremolo/codec_internal.h>
+
+    int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);
+    int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);
+    int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb);
+}
+
+namespace android {
+
+VorbisDecoder::VorbisDecoder(const sp<MediaSource> &source)
+    : mSource(source),
+      mStarted(false),
+      mBufferGroup(NULL),
+      mAnchorTimeUs(0),
+      mNumFramesOutput(0),
+      mState(NULL),
+      mVi(NULL) {
+    sp<MetaData> srcFormat = mSource->getFormat();
+    CHECK(srcFormat->findInt32(kKeyChannelCount, &mNumChannels));
+    CHECK(srcFormat->findInt32(kKeySampleRate, &mSampleRate));
+}
+
+VorbisDecoder::~VorbisDecoder() {
+    if (mStarted) {
+        stop();
+    }
+}
+
+static void makeBitReader(
+        const void *data, size_t size,
+        ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
+    buf->data = (uint8_t *)data;
+    buf->size = size;
+    buf->refcount = 1;
+    buf->ptr.owner = NULL;
+
+    ref->buffer = buf;
+    ref->begin = 0;
+    ref->length = size;
+    ref->next = NULL;
+
+    oggpack_readinit(bits, ref);
+}
+
+status_t VorbisDecoder::start(MetaData *params) {
+    CHECK(!mStarted);
+
+    mBufferGroup = new MediaBufferGroup;
+    mBufferGroup->add_buffer(
+            new MediaBuffer(kMaxNumSamplesPerBuffer * sizeof(int16_t)));
+
+    mSource->start();
+
+    sp<MetaData> meta = mSource->getFormat();
+
+    mVi = new vorbis_info;
+    vorbis_info_init(mVi);
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    uint32_t type;
+    const void *data;
+    size_t size;
+    CHECK(meta->findData(kKeyVorbisInfo, &type, &data, &size));
+
+    ogg_buffer buf;
+    ogg_reference ref;
+    oggpack_buffer bits;
+    makeBitReader((const uint8_t *)data + 7, size - 7, &buf, &ref, &bits);
+    CHECK_EQ(0, _vorbis_unpack_info(mVi, &bits));
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
+
+    makeBitReader((const uint8_t *)data + 7, size - 7, &buf, &ref, &bits);
+    CHECK_EQ(0, _vorbis_unpack_books(mVi, &bits));
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    mState = new vorbis_dsp_state;
+    CHECK_EQ(0, vorbis_dsp_init(mState, mVi));
+
+    mAnchorTimeUs = 0;
+    mNumFramesOutput = 0;
+    mStarted = true;
+
+    return OK;
+}
+
+status_t VorbisDecoder::stop() {
+    CHECK(mStarted);
+
+    vorbis_dsp_clear(mState);
+    delete mState;
+    mState = NULL;
+
+    vorbis_info_clear(mVi);
+    delete mVi;
+    mVi = NULL;
+
+    delete mBufferGroup;
+    mBufferGroup = NULL;
+
+    mSource->stop();
+
+    mStarted = false;
+
+    return OK;
+}
+
+sp<MetaData> VorbisDecoder::getFormat() {
+    sp<MetaData> srcFormat = mSource->getFormat();
+
+    sp<MetaData> meta = new MetaData;
+    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
+    meta->setInt32(kKeyChannelCount, mNumChannels);
+    meta->setInt32(kKeySampleRate, mSampleRate);
+
+    int64_t durationUs;
+    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
+        meta->setInt64(kKeyDuration, durationUs);
+    }
+
+    meta->setCString(kKeyDecoderComponent, "VorbisDecoder");
+
+    return meta;
+}
+
+int VorbisDecoder::decodePacket(MediaBuffer *packet, MediaBuffer *out) {
+    ogg_buffer buf;
+    buf.data = (uint8_t *)packet->data() + packet->range_offset();
+    buf.size = packet->range_length();
+    buf.refcount = 1;
+    buf.ptr.owner = NULL;
+
+    ogg_reference ref;
+    ref.buffer = &buf;
+    ref.begin = 0;
+    ref.length = packet->range_length();
+    ref.next = NULL;
+
+    ogg_packet pack;
+    pack.packet = &ref;
+    pack.bytes = packet->range_length();
+    pack.b_o_s = 0;
+    pack.e_o_s = 0;
+    pack.granulepos = 0;
+    pack.packetno = 0;
+
+    int err = vorbis_dsp_synthesis(mState, &pack, 1);
+    if (err != 0) {
+        LOGW("vorbis_dsp_synthesis returned %d", err);
+        return 0;
+    }
+
+    int numFrames = vorbis_dsp_pcmout(
+            mState, (int16_t *)out->data(), kMaxNumSamplesPerBuffer);
+
+    if (numFrames < 0) {
+        LOGE("vorbis_dsp_pcmout returned %d", numFrames);
+        return 0;
+    }
+
+    out->set_range(0, numFrames * sizeof(int16_t) * mNumChannels);
+
+    return numFrames;
+}
+
+status_t VorbisDecoder::read(
+        MediaBuffer **out, const ReadOptions *options) {
+    status_t err;
+
+    *out = NULL;
+
+    int64_t seekTimeUs;
+    if (options && options->getSeekTo(&seekTimeUs)) {
+        CHECK(seekTimeUs >= 0);
+
+        mNumFramesOutput = 0;
+    } else {
+        seekTimeUs = -1;
+    }
+
+    MediaBuffer *inputBuffer;
+    err = mSource->read(&inputBuffer, options);
+
+    if (err != OK) {
+        return ERROR_END_OF_STREAM;
+    }
+
+    int64_t timeUs;
+    if (inputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
+        mAnchorTimeUs = timeUs;
+        mNumFramesOutput = 0;
+    } else {
+        // We must have a new timestamp after seeking.
+        CHECK(seekTimeUs < 0);
+    }
+
+    MediaBuffer *outputBuffer;
+    CHECK_EQ(mBufferGroup->acquire_buffer(&outputBuffer), OK);
+
+    int numFrames = decodePacket(inputBuffer, outputBuffer);
+
+    inputBuffer->release();
+    inputBuffer = NULL;
+
+    outputBuffer->meta_data()->setInt64(
+            kKeyTime,
+            mAnchorTimeUs
+                + (mNumFramesOutput * 1000000ll) / mSampleRate);
+
+    mNumFramesOutput += numFrames;
+
+    *out = outputBuffer;
+
+    return OK;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/include/VorbisExtractor.h b/media/libstagefright/include/OggExtractor.h
similarity index 68%
rename from media/libstagefright/include/VorbisExtractor.h
rename to media/libstagefright/include/OggExtractor.h
index 2bb7deb..7066669 100644
--- a/media/libstagefright/include/VorbisExtractor.h
+++ b/media/libstagefright/include/OggExtractor.h
@@ -14,23 +14,22 @@
  * limitations under the License.
  */
 
-#ifndef VORBIS_EXTRACTOR_H_
+#ifndef OGG_EXTRACTOR_H_
 
-#define VORBIS_EXTRACTOR_H_
+#define OGG_EXTRACTOR_H_
 
 #include <media/stagefright/MediaExtractor.h>
 
-struct OggVorbis_File;
-
 namespace android {
 
 class DataSource;
 class String8;
 
-struct VorbisDataSource;
+struct MyVorbisExtractor;
+struct OggSource;
 
-struct VorbisExtractor : public MediaExtractor {
-    VorbisExtractor(const sp<DataSource> &source);
+struct OggExtractor : public MediaExtractor {
+    OggExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
     virtual sp<MediaSource> getTrack(size_t index);
@@ -38,25 +37,24 @@
 
     virtual sp<MetaData> getMetaData();
 
-    uint32_t flags() const;
-
 protected:
-    virtual ~VorbisExtractor();
+    virtual ~OggExtractor();
 
 private:
-    sp<DataSource> mDataSource;
-    struct OggVorbis_File *mFile;
-    struct VorbisDataSource *mVorbisDataSource;
-    status_t mInitCheck;
-    sp<MetaData> mMeta;
+    friend struct OggSource;
 
-    VorbisExtractor(const VorbisExtractor &);
-    VorbisExtractor &operator=(const VorbisExtractor &);
+    sp<DataSource> mDataSource;
+    status_t mInitCheck;
+
+    MyVorbisExtractor *mImpl;
+
+    OggExtractor(const OggExtractor &);
+    OggExtractor &operator=(const OggExtractor &);
 };
 
-bool SniffVorbis(
+bool SniffOgg(
         const sp<DataSource> &source, String8 *mimeType, float *confidence);
 
 }  // namespace android
 
-#endif  // VORBIS_EXTRACTOR_H_
+#endif  // OGG_EXTRACTOR_H_
diff --git a/media/libstagefright/include/VorbisDecoder.h b/media/libstagefright/include/VorbisDecoder.h
new file mode 100644
index 0000000..e9a488a
--- /dev/null
+++ b/media/libstagefright/include/VorbisDecoder.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VORBIS_DECODER_H_
+
+#define VORBIS_DECODER_H_
+
+#include <media/stagefright/MediaSource.h>
+
+struct vorbis_dsp_state;
+struct vorbis_info;
+
+namespace android {
+
+struct MediaBufferGroup;
+
+struct VorbisDecoder : public MediaSource {
+    VorbisDecoder(const sp<MediaSource> &source);
+
+    virtual status_t start(MetaData *params);
+    virtual status_t stop();
+
+    virtual sp<MetaData> getFormat();
+
+    virtual status_t read(
+            MediaBuffer **buffer, const ReadOptions *options);
+
+protected:
+    virtual ~VorbisDecoder();
+
+private:
+    enum {
+        kMaxNumSamplesPerBuffer = 8192 * 2
+    };
+
+    sp<MediaSource> mSource;
+    bool mStarted;
+
+    MediaBufferGroup *mBufferGroup;
+
+    int32_t mNumChannels;
+    int32_t mSampleRate;
+    int64_t mAnchorTimeUs;
+    int64_t mNumFramesOutput;
+
+    vorbis_dsp_state *mState;
+    vorbis_info *mVi;
+
+    int decodePacket(MediaBuffer *packet, MediaBuffer *out);
+
+    VorbisDecoder(const VorbisDecoder &);
+    VorbisDecoder &operator=(const VorbisDecoder &);
+};
+
+}  // namespace android
+
+#endif  // VORBIS_DECODER_H_
+
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index fc658f5..f17f66b 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -55,7 +55,7 @@
             printf("parcelable %s %s;\n", b->package, b->name.data);
         }
         else {
-            printf("UNKNOWN d=0x%08x d->item_type=%ld\n", (long)d, d->item_type);
+            printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type);
         }
         d = d->next;
     }