Merge "Add "Avoiding priority inversion"" into jb-mr2-dev
diff --git a/Android.mk b/Android.mk
index 481de01..df4cad8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -6,8 +6,9 @@
 LOCAL_DROIDDOC_HTML_DIR:=src
 # Droiddoc needs java source to run. Just pointing to a dummy location
 # and deleting output later in delete-ref target
-LOCAL_ADDITIONAL_JAVA_DIR:=frameworks/base/core/java/android/annotation
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sac
+LOCAL_ADDITIONAL_JAVA_DIR := frameworks/base/core/java/android/annotation
+# FIXME FIXME FIXME LOCAL_ADDITIONAL_DEPENDENCIES := tradefed-docs
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := build/tools/droiddoc/templates-sac
 LOCAL_MODULE := online-sac
 LOCAL_DROIDDOC_OPTIONS:= \
         -toroot / \
@@ -31,3 +32,4 @@
 	$(hide) rm -rf $(OUT_DOCS)/online-sac/reference
 	$(hide) cp -R ../tradefed/out/target/common/docs/tradefed/reference $(OUT_DOCS)/online-sac
 	$(hide) cp ../tradefed/out/target/common/docs/tradefed/navtree_data.js $(OUT_DOCS)/online-sac/navtree_data.js
+
diff --git a/scripts/micro-httpd.py b/scripts/micro-httpd.py
index 1cffa08..2292abc 100755
--- a/scripts/micro-httpd.py
+++ b/scripts/micro-httpd.py
@@ -19,7 +19,7 @@
 import os
 
 
-outdir = os.path.join(os.path.dirname(__file__), '..', 'out')
+outdir = os.environ.get('OUTDIR', os.path.join(os.path.dirname(__file__), '..', 'out'))
 os.chdir(outdir)
 PORT = int(os.environ.get('HTTP_PORT', 8080))
 Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
diff --git a/src/devices/devices_toc.cs b/src/devices/devices_toc.cs
index 316d02e..5aae255 100644
--- a/src/devices/devices_toc.cs
+++ b/src/devices/devices_toc.cs
@@ -167,9 +167,19 @@
           </a>
         </div>
         <ul>
-          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/tutorial.html">Tutorial</a></li>
-          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/commandfile_format.html">Command File Format</a></li>          
-           <li id="tradefed-tree-list" class="nav-section">
+          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/index.html"
+            >Start Here</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/machine_setup.html"
+            >Machine Setup</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/devices.html"
+            >Working with Devices</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/lifecycle.html"
+            >Test Lifecycle</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/fundamentals/options.html"
+            >Option Handling</a></li>
+          <li><a href="<?cs var:toroot ?>devices/tech/test_infra/tradefed/full_example.html"
+            >An End-to-End Example</a></li>
+          <li id="tradefed-tree-list" class="nav-section">
             <div class="nav-section-header">
               <a href="<?cs var:toroot ?>reference/packages.html">
             <span class="en">Reference</span>
diff --git a/src/devices/tech/storage/index.jd b/src/devices/tech/storage/index.jd
index 71ea31c..0f1b267 100644
--- a/src/devices/tech/storage/index.jd
+++ b/src/devices/tech/storage/index.jd
@@ -26,8 +26,10 @@
 <p>External storage is managed by a combination of the <code>vold</code> init service and
 <code>MountService</code> system service.</p>
 <p>Mounting of physical external storage volumes is handled by <code>vold</code>, which
-performs staging operations to prepare the media before exposing it to apps.
-The device-specific <code>vold.fstab</code> configuration file defines mappings from sysfs
+performs staging operations to prepare the media before exposing it to apps.</p>
+
+<p>For Android 4.2.2 and earlier, the device-specific <code>vold.fstab</code>
+configuration file defines mappings from sysfs
 devices to filesystem mount points, and each line follows this format:</p>
 <pre><code>dev_mount &lt;label&gt; &lt;mount_point&gt; &lt;partition&gt; &lt;sysfs_path&gt; [flags]
 </code></pre>
@@ -40,6 +42,25 @@
 <li><code>flags</code>: Optional comma separated list of flags, must not contain <code>/</code>.
 Possible values include <code>nonremovable</code> and <code>encryptable</code>.</li>
 </ul>
+<p>For Android releases 4.3 and later, the various fstab files used by init, vold and
+recovery were unified in the <code>/fstab.&lt;device&gt;</code> file.  For external
+storage volumes that are managed by <code>vold</code>, the entries should have the
+following format:</p>
+<pre><code>&lt;src&gt; &lt;mnt_point&gt; &lt;type&gt; &lt;mnt_flags&gt; &lt;fs_mgr_flags&gt;
+</code></pre>
+<ul>
+<li><code>src</code>: A path under sysfs (usually mounted at /sys) to the device that
+can provide the mount point.  The path must start with <code>/</code>.</li> <li><code>mount_point</code>: Filesystem path where the volume should be mounted.</li>
+<li><code>type</code>: The type of the filesystem on the volume.  For external cards,
+this is usually <code>vfat</code>.</li>
+<li><code>mnt_flags</code>: <code>Vold</code> ignores this field and it should be set
+to <code>defaults</code></li>
+<li><code>fs_mgr_flags</code>: <code>Vold</code> ignores any lines in the unified fstab
+that do not include the <code>voldmanaged=</code> flag in this field.  This flag must
+be followed by a label describing the card, and a partition number or the word
+<code>auto</code>.  Here is an example: <code>voldmanaged=sdcard:auto</code>.
+Other possible flags are <code>nonremovable</code> and <code>encryptable=sdcard</code>.
+</ul>
 <p>External storage interactions at and above the framework level are handled
 through <code>MountService</code>.  The device-specific <code>storage_list.xml</code> configuration
 file, typically provided through a <code>frameworks/base</code> overlay, defines the
@@ -74,13 +95,18 @@
 storage.  The <code>/sdcard</code> path must also resolve to the same location, possibly
 through a symlink.  If a device adjusts the location of external storage between
 platform updates, symlinks should be created so that old paths continue working.</p>
-<p>As an example, here’s the storage configuration for Xoom, which uses a FUSE
-daemon to provide primary external storage, and includes a physical SD card as
+<p>As an example for Android 4.2.2 and earlier, here's the storage configuration for Xoom,
+which uses a FUSE daemon to provide primary external storage, and includes a physical SD card as
 secondary external storage:</p>
 <ul>
 <li><a href="https://android.googlesource.com/device/moto/wingray/+/master/vold.fstab">vold.fstab</a></li>
 <li><a href="https://android.googlesource.com/device/moto/wingray/+/master/overlay/frameworks/base/core/res/res/xml/storage_list.xml">storage_list.xml</a></li>
 </ul>
+<p>As an example for Android 4.3 and later devices, here's the <code>fstab.goldfish</code> file
+for the Android emulator, which emulates an external SD card as primary external storage:</p>
+<ul>
+<li><a href="https://android.googlesource.com/device/generic/goldfish/+/master/fstab.goldfish">fstab.goldfish</a></li>
+</ul>
 <p>Access to external storage is protected by various Android permissions.
 Starting in Android 1.0, write access is protected with the
 <code>WRITE_EXTERNAL_STORAGE</code> permission, implemented using the <code>sdcard_rw</code> GID.
@@ -113,7 +139,7 @@
 it bind mounts the appropriate user-specific subdirectory from under the FUSE
 daemon to <code>EMULATED_STORAGE_TARGET</code> so that external storage paths resolve
 correctly for the app.  Because an app lacks accessible mount points for other
-users’ storage, they can only access storage for the user it was started as.</p>
+users' storage, they can only access storage for the user it was started as.</p>
 <p>This implementation also uses the shared subtree kernel feature to propagate
 mount events from the default root namespace into app namespaces, which ensures
 that features like ASEC containers and OBB mounting continue working correctly.
diff --git a/src/devices/tech/test_infra/tradefed/commandfile_format.jd b/src/devices/tech/test_infra/tradefed/commandfile_format.jd
deleted file mode 100644
index cd5102a..0000000
--- a/src/devices/tech/test_infra/tradefed/commandfile_format.jd
+++ /dev/null
@@ -1,121 +0,0 @@
-page.title=Command File Format
-@jd:body
-
-<!--
-    Copyright 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.
--->
-<p>A command file allows one to specify sets of TF commands (that is, configurations with their
-associated arguments) to be specified all at once.  Further, the format used in the command file
-supports simple macro expansions, which makes it very useful without being unwieldy.  You can see a
-relatively involved example at the bottom of the page, as well as more gradual documentation
-immediately below.</p>
-<h2 id="lines">Lines</h2>
-<p>The format is line-based.</p>
-<ul>
-<li>Each output line will be considered as the arguments for a single Configuration for Trade
-    Federation to run.</li>
-<li>Each input line will turn into one or more output lines.</li>
-</ul>
-<p>In essence, the command file format combinatorially creates a sequence of Configuration specifications that it passes to Trade Federation to run.  Blank lines are ignored.  Comments are delimited by the "#" character and may only be preceded by whitespace.</p>
-<h2 id="macros">Macros</h2>
-<p>The specific syntax for defining a macro is discussed below in the Short Macro and Long Macro sections.  The following rules apply to all macros</p>
-<ul>
-<li>The name of a macro must begin with an alpha character.  Each subsequent character may be any
-    alphanumeric, an underscore, or a hyphen.</li>
-<li>A macro with name "macro_name" is invoked by adding macro_name() as an argument on some subsequent
-    line.</li>
-<li>The macro format does not support passing arguments to macros.  It allows only concatenation.</li>
-<li>A macro's expansion may contain invocations of other macros.  Technically, a macro's expansion may
-    contain invocations of itself, but in that case, the macro will never fully expand.</li>
-<li>The parser currently has a hard limit of 10 iterations of expansion.  This will be made
-    configurable at some point.</li>
-<li>During a single iteration of expansion:<ul>
-<li>All short macro invocations on a line will be expanded a single level — macro invocations
-    embedded within the first-level expansions will not be expanded yet</li>
-<li>Only one long macro invocation on a line will be expanded.  This will be the left-most long
-    macro invocation.</li>
-</ul>
-</li>
-</ul>
-<h2 id="short-macros">Short Macros</h2>
-<p>A short macro can be defined with the syntax:</p>
-<pre><code>MACRO macro_name = this is the macro expansion
-</code></pre>
-<p>The macro expansion terminates at the end of the line.  For multi-line expansion, see Long Macros
-below.</p>
-<h3 id="short-macro-expansion">Short Macro Expansion</h3>
-<ul>
-<li><code>a macro_name() invocation</code><br />
-  will be replaced by<br />
-  <code>a this is the macro expansion invocation</code></li>
-<li><code>three macro_name() A macro_name() B macro_name()</code><br />
-  will be replaced by (all during the first iteration)<br />
-  <code>three this is the macro expansion A this is the macro expansion B this is the macro expansion</code></li>
-</ul>
-<h2 id="long-macros">Long Macros</h2>
-<p>A long macro can be defined with the syntax:</p>
-<pre><code>LONG MACRO macro_name
-  expansion line 1
-  expansion line 2
-  expansion line 3
-END MACRO
-</code></pre>
-<p>The macro is then invoked with th enormal <code>macro_name()</code> syntax.  Leading whitespace/indentation
-will be ignored.</p>
-<h3 id="long-macro-expansion">Long Macro Expansion</h3>
-<p>The output of a single input line will include one line for each combination of macro expansions on
-that line.  That is, the number of output lines is multiplicatively related to the number of macro
-expansions on that line:</p>
-<ul>
-<li>Only a single long macro invocation per line will be expanded during a single iteration.  This
-    means that a line may only contain 10 long macro invocations to stay under the iteration count
-    limit.</li>
-<li>
-<p>A single invocation of a long macro on a single line will cause that line to expand to the number
-    of lines of the long macro's expansion.  On each expanded line, the invocation will be replaced
-    by the corresponding line of the macro's expansion.</p>
-</li>
-<li>
-<p>Example 1:</p>
-<pre><code>a macro_name() invocation
-</code></pre>
-<p>will be replaced by (in a single iteration)</p>
-<pre><code>a expansion line 1 invocation
-a expansion line 2 invocation
-a expansion line 3 invocation
-</code></pre>
-</li>
-<li>
-<p>Example 2:</p>
-<pre><code>alpha macro_name() beta macro_name()
-</code></pre>
-<p>will be replaced by (during the first iteration)</p>
-<pre><code>alpha expansion line 1 beta macro_name()
-alpha expansion line 2 beta macro_name()
-alpha expansion line 3 beta macro_name()
-</code></pre>
-<p>which will be replaced by (during the second iteration)</p>
-<pre><code>alpha expansion line 1 beta expansion line 1
-alpha expansion line 1 beta expansion line 2
-alpha expansion line 1 beta expansion line 3
-alpha expansion line 2 beta expansion line 1
-alpha expansion line 2 beta expansion line 2
-alpha expansion line 2 beta expansion line 3
-alpha expansion line 3 beta expansion line 1
-alpha expansion line 3 beta expansion line 2
-alpha expansion line 3 beta expansion line 3
-</code></pre>
-</li>
-</ul>
diff --git a/src/devices/tech/test_infra/tradefed/full_example.jd b/src/devices/tech/test_infra/tradefed/full_example.jd
new file mode 100644
index 0000000..9733d77
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/full_example.jd
@@ -0,0 +1,440 @@
+page.title=End-to-End Test Example
+@jd:body
+
+<!--
+    Copyright 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.
+-->
+
+<p>This tutorial guides you through the construction of a "hello world" Trade Federation test
+configuration, and gives you a hands-on introduction to the Trade Federation framework.  Starting
+from the TF development environment, it guides you through the process of creating a simple Trade
+Federation config and gradually adding more features to it.</p>
+
+<p>The tutorial presents the TF test development process as a set of exercises, each consisting of
+several steps.  The exercises demonstrate how to gradually build and refine your configuration, and
+provide all the sample code you need to complete the test configuration.  The title of each
+exercise is annotated with a letter describing which roles are involved in that step: <b>D</b> for
+Developer, <b>I</b> for Integrator, and/or <b>R</b> for Test Runner.</p>
+
+<p>When you are finished with the tutorial, you will have created a functioning TF configuration and
+will have learned many of the most important concepts in the TF framework.</p>
+
+<h2>Set up TradeFederation development environment</h2>
+<p>See the <a href="/devices/tech/test_infra/tradefed/fundamentals/machine_setup.html"
+>Machine Setup</a> page for how to setup the development environment. The rest of this tutorial
+assumes you have a shell open that has been initialized to the Trade Federation environment.</p>
+
+<p>For simplicity, this tutorial will illustrate adding a configuration and its classes to the
+Trade Federation framework core library.  This can be extended to developing modules outside the
+source tree by simply compiling the tradefed JAR, and compiling your modules against that JAR.</p>
+
+<h2>Creating a test class (D)</h2>
+<p>Lets create a hello world test that just dumps a message to stdout. A tradefed test will
+generally implement the <a href="/reference/com/android/tradefed/testtype/IRemoteTest.html"
+>IRemoteTest</a> interface.</p>
+
+<p>Here's an implementation for the HelloWorldTest:</p>
+<pre><code>package com.android.tradefed.example;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.testtype.IRemoteTest;
+
+public class HelloWorldTest implements IRemoteTest {
+    &#64;Override
+    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+        System.out.println("Hello, TF World!");
+    }
+}
+</code></pre>
+
+<p>Save this sample code to
+<code>&lt;tree&gt;/tools/tradefederation/prod-tests/src/com/android/tradefed/example/HelloWorldTest.java</code>
+and rebuild tradefed from your shell:</p>
+<pre><code>m -jN</code></pre>
+
+<p>If the build does not succeed, consult the
+<a href="/devices/tech/test_infra/tradefed/fundamentals/machine_setup.html">Machine Setup</a> page
+to ensure that you didn't miss any steps.</p>
+
+<h2>Creating a Configuration (I)</h2>
+<p>Trade Federation tests are made executable by creating a <b>Configuration</b>, which is an XML file
+that instructs tradefed on which test (or tests) to run, as well as which other modules to
+execute, and in what order.</p>
+
+<p>Lets create a new Configuration for our HelloWorldTest:</p>
+<pre><code>&lt;configuration description="Runs the hello world test"&gt;
+    &lt;test class="com.android.tradefed.example.HelloWorldTest" /&gt;
+&lt;/configuration&gt;</code></pre>
+
+<p>TF will parse the Configuration XML file (aka <b>config</b>), load the specified class using
+reflection, instantiate it, cast it to a <code>IRemoteTest</code>, and call its <code>run</code>
+method.</p>
+
+<p>Note that we've specified the full class name of the HelloWorldTest. Save this data to a
+<code>helloworld.xml</code> file anywhere on your local filesystem (eg <code>/tmp/helloworld.xml</code>).</p>
+
+<h2>Running the config (R)</h2>
+<p>From your shell, launch the tradefed console</p>
+<pre><code>$ tradefed.sh
+</code></pre>
+
+<p>Ensure that a device is connected to the host machine and is visible to tradefed</p>
+<pre><code>tf &gt;list devices
+Serial            State      Product   Variant   Build   Battery  
+004ad9880810a548  Available  mako      mako      JDQ39   100
+</code></pre>
+
+<p>Configurations can be executed using the <code>run &lt;config&gt;</code> console command.  Try this:</p>
+<p>FIXME: redo this</p>
+<pre><code>tf&gt; run /tmp/helloworld.xml
+05-12 13:19:36 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548
+Hello, TF World!
+</code></pre>
+<p>You should see "Hello, TF World!" outputted on the terminal.</p>
+
+<h2>Adding the config to the Classpath (D, I, R)</h2>
+<p>For convenience of deployment, you can also bundle configs into the tradefed jars
+themselves. Tradefed will automatically recognize all configurations placed in 'config' folders on
+the classpath.</p>
+
+<p>Lets illustrate this now by moving the helloworld.xml into the tradefed core library.</p>
+<p>Move the <code>helloworld.xml</code> file into 
+<code>&lt;tree&gt;/tools/tradefederation/prod-tests/res/config/example/helloworld.xml</code>.</p>
+<p>Rebuild tradefed, and restart the tradefed console. </p>
+<p>Ask tradefed to display the list of configurations from the classpath:</p>
+<pre><code>tf&gt; list configs
+[…]
+example/helloworld: Runs the hello world test
+</code></pre>
+
+<p>You can now run the helloworld config via the following command</p>
+<pre><code>tf &gt;run example/helloworld
+05-12 13:21:21 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548
+Hello, TF World!
+</code></pre>
+
+<h2>Interacting with a Device (D, R)</h2>
+<p>So far our hello world test isn't doing anything interesting. Tradefed's specialty is running
+tests using Android devices, so lets add an Android device to the test.</p>
+
+<p>Tests can get a reference to an Android device by implementing the
+<a href="/reference/com/android/tradefed/testtype/IDeviceTest.html">IDeviceTest</a> interface.</p>
+
+<p>Here's a sample implementation of what this looks like:</p>
+<pre><code>public class HelloWorldTest implements IRemoteTest, IDeviceTest {
+    private ITestDevice mDevice;
+    &#64;Override
+    public void setDevice(ITestDevice device) {
+        mDevice = device;
+    }
+
+    &#64;Override
+    public ITestDevice getDevice() {
+        return mDevice;
+    }
+…
+}
+</code></pre>
+
+<p>The Trade Federation framework will inject the <code>ITestDevice</code> reference into your
+test via the <code>IDeviceTest#setDevice</code> method, before the <code>IRemoteTest#run</code>
+method is called.</p>
+
+<p>Let's modify the HelloWorldTest print message to display the serial number of the device.</p>
+<pre><code>&#64;Override
+public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+    System.out.println("Hello, TF World! I have device " + getDevice().getSerialNumber());
+}
+</code></pre>
+
+<p>Now rebuild tradefed, and check the list of devices:</p>
+<pre><code>$ tradefed.sh
+tf &gt;list devices
+Serial            State      Product   Variant   Build   Battery  
+004ad9880810a548  Available  mako      mako      JDQ39   100
+</code></pre>
+
+<p>Take note of the serial number listed as Available above. That is the device that should be
+allocated to HelloWorld.</p>
+<pre><code>tf &gt;run example/helloworld
+05-12 13:26:18 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548
+Hello, TF World! I have device 004ad9880810a548
+</code></pre>
+
+<p>You should see the new print message displaying the serial number of the device.</p>
+
+<h2>Sending Test Results (D)</h2>
+<p><code>IRemoteTest</code>s report results by calling methods on the
+<a href="/reference/com/android/tradefed/result/ITestInvocationListener.html"
+>ITestInvocationListener</a> instance provided to their <code>#run</code> method.  Note that the
+TF framework itself is responsible for reporting the start and end of each Invocation, (via
+the <a href="/reference/com/android/tradefed/result/ITestInvocationListener.html#invocationStarted(com.android.tradefed.build.IBuildInfo)"
+>ITestInvocationListener#invocationStarted</a> and
+<a href="/reference/com/android/tradefed/result/ITestInvocationListener.html#invocationEnded(long)"
+>ITestInvocationListener#invocationEnded</a> methods, respectively).</p>
+
+<p>A <b>test run</b> is a logical collection of tests. To report test results,
+<code>IRemoteTest</code>s are responsible
+for reporting the start of a test run, the start and end of each test, and the end of the test run.</p>
+
+<p>Here's what the HelloWorldTest implementation might look like with a single failed test result.</p>
+<pre><code>&#64;Override
+public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+    System.out.println("Hello, TF World! I have device " + getDevice().getSerialNumber());
+
+    TestIdentifier testId = new TestIdentifier("com.example.TestClassName", "sampleTest");
+    listener.testRunStarted("helloworldrun", 1);
+    listener.testStarted(testId);
+    listener.testFailed(TestFailure.FAILURE, testId, "oh noes, test failed");
+    listener.testEnded(testId, Collections.emptyMap());
+    listener.testRunEnded(0, Collections.emptyMap());
+}</code></pre>
+
+<p>Note that Trade Federation also includes several <code>IRemoteTest</code> implementations that
+you can reuse instead of writing your own from scratch.  These include, for instance,
+<a href="/reference/com/android/tradefed/testtype/InstrumentationTest.html"
+>InstrumentationTest</a>, which can run an Android application's tests remotely on an Android
+device, parse the results, and forward them to the <code>ITestInvocationListener</code>). See the
+<a href="/reference/com/android/tradefed/testtype/package-summary.html">Test Types
+documentation</a> for more details.</p>
+
+<h2>Storing Test Results (I)</h2>
+<p>By default, a TF config will use the
+<a href="/reference/com/android/tradefed/result/TextResultReporter.html">TextResultReporter</a> as
+the test listener implementation.  <code>TextResultReporter</code> will dump the results of an
+invocation to stdout. To illustrate, try running the hello-world config from the previous
+section:</p>
+<pre><code>$ ./tradefed.sh
+tf &gt;run example/helloworld
+05-16 20:03:15 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548
+Hello, TF World! I have device 004ad9880810a548
+05-16 20:03:15 I/InvocationToJUnitResultForwarder: run helloworldrun started: 1 tests
+Test FAILURE: com.example.TestClassName#sampleTest 
+ stack: oh noes, test failed 
+05-16 20:03:15 I/InvocationToJUnitResultForwarder: run ended 0 ms
+</code></pre>
+
+<p>If you want to store the results of an invocation elsewhere, such as in a file, you need to
+specify a custom <code>ITestInvocationListener</code> implementation by using the
+<code>result_reporter</code> tag in your configuration.</p>
+
+<p>Trade Federation includes the
+<a href="/reference/com/android/tradefed/result/XmlResultReporter.html">XmlResultReporter</a>
+listener, which will write test results to an XML file, in a format similar to that used by the
+<em>ant</em> JUnit XML writer.</p>
+
+<p>Let's specify the result_reporter in the configuration now. Edit the
+<code>…/res/config/example/helloworld.xml</code> config like this:</p>
+<pre><code>&lt;configuration description="Runs the hello world test"&gt;
+    &lt;test class="com.android.tradefed.example.HelloWorldTest" /&gt;
+    &lt;result_reporter class="com.android.tradefed.result.XmlResultReporter" /&gt;
+&lt;/configuration&gt;
+</code></pre>
+
+<p>Now rebuild tradefed and re-run the hello world sample:</p>
+<pre><code>tf &gt;run example/helloworld
+05-16 21:07:07 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548
+Hello, TF World! I have device 004ad9880810a548
+05-16 21:07:07 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_2991649128735283633/device_logcat_6999997036887173857.txt
+05-16 21:07:07 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_2991649128735283633/host_log_6307746032218561704.txt
+05-16 21:07:07 I/XmlResultReporter: XML test result file generated at /tmp/0/inv_2991649128735283633/test_result_536358148261684076.xml. Total tests 1, Failed 1, Error 0
+</code></pre>
+
+<p>Notice the log message stating that an XML file has been generated. The generated file should look like this:</p>
+<pre><code>&lt;?xml version='1.0' encoding='UTF-8' ?&gt;
+&lt;testsuite name="stub" tests="1" failures="1" errors="0" time="9" timestamp="2011-05-17T04:07:07" hostname="localhost"&gt;
+  &lt;properties /&gt;
+  &lt;testcase name="sampleTest" classname="com.example.TestClassName" time="0"&gt;
+    &lt;failure&gt;oh noes, test failed
+    &lt;/failure&gt;
+  &lt;/testcase&gt;
+&lt;/testsuite&gt;
+</code></pre>
+
+<p>You can also write your own custom invocation listeners. It just needs to implement the
+<a href="/reference/com/android/tradefed/result/ITestInvocationListener.html"
+>ITestInvocationListener</a> interface.</p>
+
+<p>Also note that tradefed supports multiple invocation listeners, meaning that you can send test
+results to multiple independent destinations. Just specify multiple
+<code>&lt;result_reporter&gt;</code> tags in your config to do this.</p>
+
+<h2>Logging (D, I, R)</h2>
+<p>TradeFederation includes two logging facilities:</p>
+<ol>
+<li>ability to capture logs from the device (aka device logcat)</li>
+<li>ability to record logs from the TradeFederation framework running on the host machine (aka the
+    host log)</li>
+</ol>
+<p>Lets focus on #2 for now. Trade Federation's host logs are reported using the
+<a href="/reference/com/android/tradefed/log/LogUtil.CLog.html">CLog wrapper</a> for the
+ddmlib Log class.</p>
+
+<p>Let's convert the previous <code>System.out.println</code> call in HelloWorldTest to a
+<code>CLog</code> call:</p>
+<pre><code>&#64;Override
+public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+    CLog.i("Hello, TF World! I have device %s", getDevice().getSerialNumber());
+</code></pre>
+
+<p>Note that <code>CLog</code> handles string interpolation directly, akin to
+<code>String.format</code>.  At this point, when you rebuild and rerun TF, you should see the
+log message on stdout.</p>
+<pre><code>tf&gt; run example/helloworld
+…
+05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
+…
+</code></pre>
+
+<p>By default, tradefed will
+<a href"/reference/com/android/tradefed/log/StdoutLogger.html">output host log messages to
+stdout</a>. TF also includes a log implementation that will write messages to a file:
+<a href="/reference/com/android/tradefed/log/FileLogger.html">FileLogger</a>. To add file logging,
+add a <code>logger</code> tag to the config, specifying the full class name of
+<code>FileLogger</code>.</p>
+<pre><code>&lt;configuration description="Runs the hello world test"&gt;
+    &lt;test class="com.android.tradefed.example.HelloWorldTest" /&gt;
+    &lt;result_reporter class="com.android.tradefed.result.XmlResultReporter" /&gt;
+    &lt;logger class="com.android.tradefed.log.FileLogger" /&gt;
+&lt;/configuration&gt;
+</code></pre>
+
+<p>Now rebuild and run the helloworld example again.</p>
+<pre><code>tf &gt;run example/helloworld 
+…
+05-16 21:38:21 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_6390011618174565918/device_logcat_1302097394309452308.txt
+05-16 21:38:21 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
+…
+</code></pre>
+<p>Note the log message indicating the path of the host log. View the contents of that file, and you
+should see your HelloWorldTest log message</p>
+<pre><code>$ more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
+…
+05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
+</code></pre>
+
+<p>The TradeFederation framework will also automatically capture the logcat from the allocated device,
+and send it the invocation listener for processing. <code>XmlResultReporter</code> will save the
+captured device logcat as a file.</p>
+
+<h2>Option Handling (D, I, R)</h2>
+<p>Objects loaded from a Trade Federation Configuration (aka <b>Configuration objects</b>) also have the
+ability to receive data from command line arguments.</p>
+<p>This is accomplished via the <code>@Option</code> annotation. To participate, a Configuration object class
+would apply the <code>@Option</code> annotation to a member field, and provide it a unique name. This would
+allow that member field's value to be populated via a command line option, and would also
+automatically add that option to the configuration help system (Note: not all field types are
+supported: see the
+<a href="/reference/com/android/tradefed/config/OptionSetter.html">OptionSetter javadoc</a> for a
+description of supported types).</p>
+
+<p>Let's add an <code>@Option</code> to the HelloWorldTest:</p>
+<pre><code>@Option(name="my_option",
+        shortName='m',
+        description="this is the option's help text",
+        // always display this option in the default help text
+        importance=Importance.ALWAYS)
+private String mMyOption = "thisisthedefault";
+</code></pre>
+
+<p>And let's add a log message to display the value of the option in HelloWorldTest, so we can
+demonstrate that it was received correctly.</p>
+<pre><code>&#64;Override
+public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+    …
+    CLog.logAndDisplay(LogLevel.INFO, "I received option '%s'", mMyOption);
+</code></pre>
+
+<p>Rebuild TF and run helloworld; you should see a log message with <code>my_option</code>'s
+default value.</p>
+<pre><code>tf&gt; run example/helloworld
+…
+05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'
+</code></pre>
+
+<h3>Passing Values from the Command Line</h3>
+<p>Now pass in a value for my_option: you should see my_option getting populated with that value</p>
+<pre><code>tf&gt; run example/helloworld --my_option foo
+…
+05-24 18:33:44 I/HelloWorldTest: I received option 'foo'
+</code></pre>
+
+<p>TF configurations also include a help system, which automatically displays help text for
+<code>@Option</code> fields. Try it now, and you should see the help text for
+<code>my_option</code>:</p>
+<pre><code>tf&gt; run --help example/helloworld
+Printing help for only the important options. To see help for all options, use the --help-all flag
+
+  cmd_options options:
+    --[no-]help          display the help text for the most important/critical options. Default: false.
+    --[no-]help-all      display the full help text for all options. Default: false.
+    --[no-]loop          keep running continuously. Default: false.
+
+  test options:
+    -m, --my_option      this is the option's help text Default: thisisthedefault.
+
+  'file' logger options:
+    --log-level-display  the minimum log level to display on stdout. Must be one of verbose, debug, info, warn, error, assert. Default: error.
+</code></pre>
+
+<p>Note the message at the top about "printing only the important options." To reduce option help
+clutter, TF uses the <code>Option#importance</code> attribute to determine whether to show a
+particular <code>@Option</code> field's help text
+when <code>--help</code> is specified. <code>--help-all</code> will always show help for all
+<code>@Option</code> fields, regardless of importance. See the
+<a href="/reference/com/android/tradefed/config/Option.Importance.html"
+>Option.Importance javadoc</a> for details.</p>
+
+<h3>Passing Values from a Configuration</h3>
+<p>You can also specify an Option's value within the config by adding a
+<code>&lt;option name="" value=""&gt;</code> element. Let's see how this looks in
+<code>helloworld.xml</code>:</p>
+<pre><code>&lt;test class="com.android.tradefed.example.HelloWorldTest" &gt;
+    &lt;option name="my_option" value="fromxml" /&gt;
+&lt;/test&gt;
+</code></pre>
+
+<p>Re-building and running helloworld should now produce this output:</p>
+<pre><code>05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'
+</code></pre>
+
+<p>The configuration help should also be updated to indicate my_option's new default value:</p>
+<pre><code>tf&gt; run --help example/helloworld
+  test options:
+    -m, --my_option      this is the option's help text Default: fromxml.
+</code></pre>
+<p>Also note that other configuration objects included in the helloworld config, such as
+<code>FileLogger</code>, also accept options. The option <code>--log-level-display</code> is
+interesting because it filters the logs that show up on stdout. You may have noticed from earlier
+in the tutorial that the "Hello, TF World! I have device …' log message stopped being displayed
+on stdout once we switched to using <code>FileLogger</code>. You can increase the verbosity of
+logging to stdout by passing in the <code>--log-level-display</code> arg.</p>
+
+<p>Try this now, and you should see the 'I have device' log message reappear on stdout, in
+addition to being logged to a file.</p>
+<pre><code>tf &gt;run --log-level-display info example/helloworld
+…
+05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
+</code></pre>
+
+<h2>That's All, Folks!</h2>
+<p>As a reminder, if you're stuck on something, the
+<a href="https://android.googlesource.com/platform/tools/tradefederation/+/master"
+>Trade Federation source code</a> has a lot of useful information that isn't
+exposed in the documentation.  And if all else fails, try asking on the
+<a href="/source/community/index.html">android-platform</a> Google Group, with "Trade Federation"
+in the message subject.</p>
+
diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/devices.jd b/src/devices/tech/test_infra/tradefed/fundamentals/devices.jd
new file mode 100644
index 0000000..c7d3da8
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/fundamentals/devices.jd
@@ -0,0 +1,58 @@
+page.title=Working with Devices
+@jd:body
+
+<!--
+    Copyright 2013 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.
+-->
+
+<p>Trade Federation uses an abstraction called
+<code><a href="/reference/com/android/tradefed/device/ITestDevice.html">ITestDevice</a></code> to
+run tests.  This abstraction objectifies the lowest-common-denominator Android device:</p>
+<ul>
+<li>It has a serial number</li>
+<li>It has a state: Online, Available, Recovery, or Not Available</li>
+<li>It has some notion of reliability.  For instance, if we run a command, we can differentiate
+  between the case where the command hasn't finished yet, the case where the device doesn't support
+  running commands, and the case where the device has become unresponsive while running the
+  command.</li>
+</ul>
+
+<h2>Different Classes of Devices</h2>
+<p>The three primary implementations of <code>ITestDevice</code> represent three common
+usecases.</p>
+
+<h3>Physical Device</h3>
+<p>This is an actual piece of hardware, connected to the TF host machine either by USB, or by using
+adb's TCP feature.  The <a href="/reference/com/android/tradefed/device/TestDevice.html"
+>TestDevice</a> class sits atop the ddmlib library, which is a Java interface to adb.  So any
+physical device listed in <code>adb devices</code> can be instantiated and used as a
+<code>TestDevice</code>.
+</p>
+
+<h3>Emulator</h3>
+<p>Emulators are handled specially by TF because they live in another process.  To interact with an
+Emulator, specify the <code>--emulator</code> argument for the command.  See
+<a href="/reference/com/android/tradefed/build/LocalSdkBuildProvider.html"
+>LocalSdkBuildProvider</a> and
+<a href="/reference/com/android/tradefed/targetprep/SdkAvdPreparer.html"
+>SdkAvdPreparer</a> for more info.</p>
+
+<h3>No Device</h3>
+<p>Suppose you have a test that doesn't interact with a device at all.  For instance, it might just
+download a file from some service and verify that the file itself is valid.  The
+<a href="/reference/com/android/tradefed/device/NullDevice.html"
+>NullDevice</a> is an <code>ITestDevice</code> that is just a stub.  It has a serial number like
+<code>null-device-N</code>, and most attempted operations either no-op silently or throw.
+</p>
diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/index.jd b/src/devices/tech/test_infra/tradefed/fundamentals/index.jd
new file mode 100644
index 0000000..98ab260
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/fundamentals/index.jd
@@ -0,0 +1,75 @@
+page.title=Getting Started with TF
+@jd:body
+
+<!--
+    Copyright 2013 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.
+-->
+
+<p>Trade Federation is a large test infrastructure that can be adapted to a great variety of
+different usecases, and most people will probably only need some subset of its functionality.  First
+off, we envision that TF users will fulfill any of three primary roles: Developer, Integrator, and
+Test Runner.  A particular individual might wear any (or all) of those three hats, but we feel the
+distinction will help make it easier to navigate the documentation.</p>
+
+<h2>Developers</h2>
+<p>Developers spend the majority of their time creating TF modules that are written in Java.
+They may write configurations and execute tests, but will typically only do so to verify that their
+modules are being invoked properly and are functioning as expected.</p>
+
+<h2>Integrators</h2>
+<p>Integrators spend the majority of their time creating XML test configurations, or command
+files (which are written in a simple shell-like language).  They tie together TF modules written
+by the Developer with specific configurations that are required for particular test requirements and
+goals.</p>
+
+<h2>Test Runners</h2>
+<p>Test Runners spend the majority of their time executing tests and generally making sure
+that test results are being generated, and that the generated test results are relevant,
+reproducible, and accurate.  They spend the majority of their time interacting with tradefed's
+command line interface, and will also verify that the results make sense.</p>
+
+
+<p>In order to get the most out of Trade Federation, all three roles will need to be represented.
+It will take Developers and Integrators to make TF interoperate with other pieces of infrastructure,
+like build systems and test result repositories.  It will take Integrators and Test Runners to get
+TF to actually run the desired tests and produce the desired test results.  It will take Test
+Runners to identify results that don't make sense, and to work with the Developers and
+Integrators to figure out where the bugs may lie and get them fixed.</p>
+
+<h2>What's Next</h2>
+<p>People in all three roles should at least glance through all the rest of the docs.
+<a href="/devices/tech/test_infra/tradefed/fundamentals/machine_setup.html"
+>Machine Setup</a> will get you to the point where you can run TF.
+<a href="/devices/tech/test_infra/tradefed/fundamentals/devices.html"
+>Working with Devices</a> will explain how to run tests with a physical device, with an emulator, or
+with no device at all.  The
+<a href="/devices/tech/test_infra/tradefed/fundamentals/lifecycle.html"
+>Test Lifecycle</a> page will explain from a theoretical perspective how the roles of the
+Developer, Integrator, and Test Runner interact, and then
+<a href="/devices/tech/test_infra/tradefed/fundamentals/options.html"
+>Option Handling</a> will demonstrate how to put that theory into practice.</p>
+
+
+<p>Finally, the <a href="/devices/tech/test_infra/tradefed/full_example.html"
+>End-to-End Example</a> takes you through the development, integration, and deployment of a sample
+test.  It involves aspects of each role, and should offer hints at how to do more complicated
+things that aren't directly discussed in the documentation.</p>
+
+<p>If you've gotten through everything here and still have unanswered questions, first try taking
+a look at the <a href="https://android.googlesource.com/platform/tools/tradefederation/+/master"
+>Trade Federation source code.</a>.  Beyond that, feel free to try asking on the
+<a href="/source/community/index.html">android-platform</a> Google Group.  For best results, make
+sure to mention "Trade Federation" (or "tradefed", or "TF") in the message subject.</p>
+
diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/lifecycle.jd b/src/devices/tech/test_infra/tradefed/fundamentals/lifecycle.jd
new file mode 100644
index 0000000..2b8664d
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/fundamentals/lifecycle.jd
@@ -0,0 +1,60 @@
+page.title=Test Lifecycle
+@jd:body
+
+<!--
+    Copyright 2013 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.
+-->
+
+<p>The lifecycle of a test executed using TradeFederation is composed of four separate stages, designed
+around formally defined interfaces.</p>
+<ul>
+<li><a href="/reference/com/android/tradefed/build/IBuildProvider.html"
+  >Build Provider</a>: Provides a build to test, downloading appropriate files if necessary</li>
+<li><a href="/reference/com/android/tradefed/targetprep/ITargetPreparer.html"
+  >Target Preparer</a>: Prepares the test environment, possibly including software installation and
+  device configuration</li>
+<li><a href="/reference/com/android/tradefed/testtype/IRemoteTest.html"
+  >Test</a>: Executes test(s) and gathers test results.  This may be any JUnit Test, although our
+  <a href="/reference/com/android/tradefed/testtype/IRemoteTest.html"
+  >IRemoteTest</a> interface is specifically designed to work well in the Trade Federation
+  environment.</li>
+<li><a href="/reference/com/android/tradefed/result/ITestInvocationListener.html"
+  >Test Invocation Listener</a>: Listens for test results, usually for the purpose of forwarding the
+  test results to a repository or displaying them to the Test Runner</li>
+</ul>
+
+<p>The fundamental testing entity in TF is a <b>Configuration</b> (config). A config is an XML file
+that declares the lifecycle components of a test.</p>
+
+<p>This separation of the test's lifecycle is intended to allow for reuse.  Using this design, the
+Developer can create a Test once, and then the Integrator can create different Configurations to
+run that Test in different environments. For example,
+they could create a Configuration that will run a test on a local machine and dump the result to
+stdout.  They could then create a second Configuration that would execute that same test, but use a
+different Test Invocation Listener to store the test results in a database.  A third Configuration
+might be designed run that test continuously from a test lab somewhere.</p>
+
+<p>It's convenient to note here that a Configuration along with its command-line arguments (as
+provided by the Test Runner) is known as a <b>Command</b>.  When TF takes pairs a Command with an
+<code>ITestDevice</code> and executes it, the subsequent object is known as an <b>Invocation</b>.
+In short, an Invocation encompasses a complete TF test execution, across its entire lifecycle.</p>
+
+<h3>Additional Components of a Configuration</h3>
+<ul>
+<li><a href="/reference/com/android/tradefed/device/IDeviceRecovery.html"
+  >Device Recovery</a>: mechanism to recover device communication if lost</li>
+<li><a href="/reference/com/android/tradefed/log/package-summary.html">Logger</a>: collects tradefed logging data</li>
+</ul>
+
diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/machine_setup.jd b/src/devices/tech/test_infra/tradefed/fundamentals/machine_setup.jd
new file mode 100644
index 0000000..112d359
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/fundamentals/machine_setup.jd
@@ -0,0 +1,55 @@
+page.title=Development Environment
+@jd:body
+
+<!--
+    Copyright 2013 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.
+-->
+
+<p>The Trade Federation source is stored in git along with the rest of the Android platform, and
+uses the Android platform build system to create its binary.  First and foremost, 
+<a href="/source/initializing.html">follow these instructions</a> to set up your machine to be
+able to compile and run things from the Android tree.</p>
+
+<h2>Getting the Source</h2>
+<p>The TF source lives in the Android codebase, but you need to specify an extra option to get at it.
+<a href="/source/downloading.html">Follow these instructions</a> to download the source, but use
+the branch <code>tradefed</code> to actually pull down the Trade Federation source.  The actual
+command you run should look something like</p>
+<pre><code>$ repo init -u https://…/manifest -b tradefed</code></pre>
+
+<h3>Building</h3>
+<p>Trade Federation is set up in a lightweight "unbundled" branch that uses slightly different build
+commands from the platform source.  In particular, unbundled branches use the <code>tapas</code>
+command to set up the build environment, rather than the <code>lunch</code> command.  So starting
+from the root directory of the source tree you checked out, try:</p>
+<pre><code>$ . build/envsetup.sh
+$ tapas tradefed-all
+$ m -j8
+</pre></code>
+
+Note that once the <code>$ . build/envsetup.sh</code> step is done, the other two commands will run
+equally well from anywhere in the tree.
+
+<h2>Running from Command Line</h2>
+<p>First and foremost, tradefed requires the <code>adb</code> utility to be in your current
+<code>$PATH</code>.</p>
+<pre><code>$ export PATH=$PATH:&lt;path to adb&gt;</pre></code>
+
+<p>Building TF using the steps mentioned above will add the <code>tradefed.sh</code> launcher script
+to your path.  So to launch the TF console, run</p>
+<pre><code>$ tradefed.sh</pre></code>
+
+<p>At this point, your environment is set up for Trade Federation.</p>
+
diff --git a/src/devices/tech/test_infra/tradefed/fundamentals/options.jd b/src/devices/tech/test_infra/tradefed/fundamentals/options.jd
new file mode 100644
index 0000000..930be9e
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/fundamentals/options.jd
@@ -0,0 +1,100 @@
+page.title=Option Handling
+@jd:body
+
+<!--
+    Copyright 2013 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.
+-->
+
+<p>Option handling lies at the heart of Trade Federation's modular approach.  In particular, options
+are the mechanism by which the Developer, Integrator, and Test Runner can work together without
+having to duplicate each-other's work.  Put simply, our implementation of option handling allows the
+Developer to mark a Java class member as being configurable, at which point the value of that member
+may be augmented or overridden by the Integrator, and may be subsequently augmented or overridden by
+the Test Runner.  This mechanism works for all Java intrinsic types, as well as for any
+<code>Map</code>s or <code>Collection</code>s of intrinsic types.</p>
+
+<p><em>Note:</em> the option-handling mechanism only works for classes implementing one of the
+interfaces included in the <a href="lifecycle.html">Test Lifecycle</a>, and only when that class is
+<em>instantiated</em> by the lifecycle machinery.</p>
+
+<h2>Developer</h2>
+<p>To start off, the developer marks a member with the
+<code><a href="https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/config/Option.java"
+>@Option</a></code> annotation.  <!-- note: javadoc for the Option class is broken -->
+They specify (at a minimum) the <code>name</code> and <code>description</code> values, which
+specify the argument name associated with that Option, and the description that will be displayed on
+the TF console when the command is run with <code>--help</code> or <code>--help-all</code>.</p>
+
+<p>As an example, let's say we want to build a functional phone test which will dial a variety of
+phone numbers, and will expect to receive a sequence of DTMF tones from each number after it
+connects.</p>
+<code><pre>public class PhoneCallFuncTest extends IRemoteTest {
+    &#64;Option(name = "timeout", description = "How long to wait for connection, in millis")
+    private long mWaitTime = 30 * 1000;  // 30 seconds
+
+    &#64;Option(name = "call", description = "Key: Phone number to attempt.  " +
+            "Value: DTMF to expect.  May be repeated.")
+    private Map&lt;String, String&gt; mCalls = new HashMap&lt;String, String&gt;;
+
+    public PhoneCallFuncTest() {
+        mCalls.add("123-456-7890", "01134");  // default
+    }</pre></code>
+
+<p>That's all that's required for the Developer to set up two points of configuration for that
+test.  They could then go off and use <code>mWaitTime</code> and <code>mCalls</code> as normal,
+without paying much attention to the fact that they're configurable.  Because the
+<code>@Option</code> fields are set after the class is instantiated, but before the
+<code>run</code> method is called, that provides an easy way for implementors to set up defaults for
+or perform some kind of filtering on <code>Map</code> and <code>Collection</code> fields, which are
+otherwise append-only.</p>
+
+<h2>Integrator</h2>
+<p>The Integrator works in the world of Configurations, which are written in XML.  The config format
+allows the Integrator to set (or append) a value for any <code>@Option</code> field.  For instance,
+suppose the Integrator wanted to define a lower-latency test that calls the default number, as well
+as a long-running test that calls a variety of numbers.  They could create a pair of configurations
+that might look like the following:</p>
+
+<code><pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;configuration description="low-latency default test; low-latency.xml"&gt;
+    &lt;test class="com.example.PhoneCallFuncTest"&gt;
+        &lt;option name="timeout" value="5000" /&gt;
+    &lt;/test&gt;
+&lt;/configuration&gt;</pre></code>
+
+<code><pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;configuration description="call a bunch of numbers; many-numbers.xml"&gt;
+    &lt;test class="com.example.PhoneCallFuncTest"&gt;
+        &lt;option name="call" key="111-111-1111" value="#*#*TEST1*#*#" /&gt;
+        &lt;option name="call" key="222-222-2222" value="#*#*TEST2*#*#" /&gt;
+        &lt;!-- ... --&gt;
+    &lt;/test&gt;
+&lt;/configuration&gt;</pre></code>
+
+<h2>Test Runner</h2>
+<p>The Test Runner also has access to these configuration points via the Trade Federation console.
+First and foremost, they will run a Command (that is, a config and all of its arguments) with the
+<code>run command &lt;name&gt;</code> instruction (or <code>run &lt;name&gt;</code> for short).
+Beyond that, they can specify any list of arguments are part of the command, which may replace or
+append to fields specified by Lifecycle Objects within each config.</p>
+
+<p>To run the low-latency test with the <code>many-numbers</code> phone numbers, the Test Runner
+could execute:</p>
+<code><pre>tf >run low-latency.xml --call 111-111-1111 #*#*TEST1*#*# --call 222-222-2222 #*#*TEST2*#*#</pre></code>
+
+<p>Or, to get a similar effect from the opposite direction, the Test Runner could reduce the wait time
+for the <code>many-numbers</code> test:</p>
+<code><pre>tf >run many-numbers.xml --timeout 5000</code></pre>
+
diff --git a/src/devices/tech/test_infra/tradefed/getting_started.jd b/src/devices/tech/test_infra/tradefed/getting_started.jd
deleted file mode 100644
index 8219ee7..0000000
--- a/src/devices/tech/test_infra/tradefed/getting_started.jd
+++ /dev/null
@@ -1,203 +0,0 @@
-page.title=Getting Started
-@jd:body
-
-<!--
-    Copyright 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.
--->
-<h2 id="using-the-console">Using the console</h2>
-<p>TF is based around an interactive console.  You can fire up the console by going to the
-<code>tools/tradefederation/</code> directory and running</p>
-<pre><code>$ ./tradefed.sh
-</code></pre>
-<p>You should end up at a <code>tf &gt;</code> prompt.</p>
-<p>The console is self-documenting.  Try entering "help"</p>
-<pre><code>tf &gt;help
-Enter 'q' or 'exit' to exit
-Enter 'kill' to attempt to forcibly exit, by shutting down adb
-
-Enter 'help list'  for help with 'list' commands
-[...]
-</code></pre>
-<p>As the help text suggests, the help menus are organized hierarchically</p>
-<pre><code>tf &gt;help list
-l(?:ist)? help:
-    i[nvocations]  List all invocation threads
-    d[evices]      List all detected or known devices
-[...]
-</code></pre>
-<p>The majority of commands have a convenient short form, which the help text displays.  The
-<code>l(?:ist)?</code> is a regular expression.  As an example, here are the four equivalent ways to list
-invocations:
-<em> <code>list invocations</code>
-</em> <code>list i</code>
-<em> <code>l invocations</code>
-</em> <code>l i</code></p>
-<h2 id="running-a-configcommand">Running a config/command</h2>
-<p>This is documented by the <code>help run</code> command in the console.</p>
-<p>As a reminder, a command is a config along with all of its command-line arguments.  A command <em>must</em>
-begin with the name of the respective config.</p>
-<p>As a quick example, you could run the calculator unit tests like so:</p>
-<pre><code>$./tradefed.sh
-tf &gt;run instrument --package com.android.calculator2.tests
-</code></pre>
-<p>As a shortcut, if you specify any arguments to <code>tradefed.sh</code>, it will attempt to execute them as if
-they were typed on the commandline.  So the short version of the above would be</p>
-<pre><code>$./tradefed.sh run instrument --package com.android.calculator2.tests
-</code></pre>
-<p>In both of these cases, the name of the config is "instrument", and
-"--class com.android.calculator2.tests" is a command-line argument.  The command that is being run
-is "instrument --class com.android.calculator2.tests".</p>
-<p>TF can run both configs that are compiled in (such as the "instrument" config above), as well as
-configs that exist as xml files on the local filesystem.  You can see a list of compiled-in configs
-with the <code>list configs</code> console command.  Furthermore, you can investigate any config (compiled-in
-or local) by passing the "--help" or "--help-all" command-line arguments.  The "--help" argument
-will only show "important" arguments, and "--help-all" will show all arguments, regardless of
-whether they've been marked as "important" or not.  To take the final step, you can tell TF to print
-the contents of any config (compiled-in or local) with the <code>dump config &lt;configname&gt;</code> console
-command.</p>
-<h3 id="so-lets-say-you-want-to-run-the-calculator-instrumentation-tests-but-dont-know-where-to-start">So, let's say you want to run the calculator instrumentation tests, but don't know where to start.</h3>
-<p>You could try something like this sequence of steps.  First, look for a config that looks like it
-might do what you want:</p>
-<pre><code>tf &gt;list configs
-Use 'run command --help &lt;configuration_name&gt;' to get list of options for a configuration
-Use 'dump config &lt;configuration_name&gt;' to display the configuration's XML content.
-
-Available configurations include:
-[...]
-  instrument: Runs a single Android instrumentation test on an existing device
-[...]
-</code></pre>
-<p>Now that you've found something reasonable-looking, see what options it takes.  The <code>list configs</code> output suggests trying <code>run command instrument --help</code></p>
-<pre><code>tf &gt;run command --help instrument
-'instrument' configuration: Runs a single Android instrumentation test on an existing device
-
-Printing help for only the important options. To see help for all options, use the --help-all flag
-[...]
-  'instrumentation' test options:
-    -p, --package        The manifest package name of the Android test application to run.
-</code></pre>
-<p>As the message suggests, if you need more options, use the "--help-all" flag instead of "--help".  In this case, we've got all we need.  You could figure out the package by checking with <code>runtest</code>, or reading testdefs.xml directly.  We use <code>runtest -n</code> to simply show what would be run without actually running it:</p>
-<pre><code>$runtest -n calculator
-adb root
-ONE_SHOT_MAKEFILE="packages/apps/Calculator/Android.mk" make -j4 -C "/srv/xsdg/master2" files
-adb sync
-adb  shell am instrument -w com.android.calculator2.tests/android.test.InstrumentationTestRunner
-</code></pre>
-<p>The argument to <code>am instrument</code> that comes before the slash is the manifest package.  <code>android.test.InstrumentationTestRunner</code> is the default runner, so no need to set it if that's the
-right one.  Otherwise, using "--help-all" will tell you about the "--runner" argument, which you can
-use to specify an alternate runner.  Ok, so at this point, we've got the following command, which
-you'll recognize from above</p>
-<pre><code>tf &gt;run instrument --package com.android.calculator2.tests
-</code></pre>
-<h2 id="interacting-with-a-device">Interacting with a device</h2>
-<h3 id="generic-device-behavior-in-tf">Generic device behavior in TF</h3>
-<p>The running version of a command is called in <code>invocation</code>.  First and foremost, every invocation
-requires a device before it can run.  In addition to physical Android devices, TF can run tests with
-a mock device (by specifying the "-n" argument for the command), or with the Android emulator (by
-specifying the "-e" argument").</p>
-<p>The primary console command to figure out what devices are up to is <code>list devices</code>:</p>
-<pre><code>$./tradefed.sh
-06-07 17:03:22 I/: Detected new device 016B756E03018007
-06-07 17:03:22 I/: Detected new device 1700614743c14397
-06-07 17:03:22 I/: Detected new device 3531C342606300EC
-tf &gt;l d
-Serial            State      Product   Variant   Build   Battery
-016B756E03018007  Available  tuna      toro      MASTER  100
-1700614743c14397  Available  stingray  stingray  MASTER  100
-3531C342606300EC  Available  herring   crespo4g  MASTER  92
-</code></pre>
-<p>As far as the invocations are concerned, there are three device states: available, unavailable, and
-allocated.  An <code>Available</code> device is ready to be allocated for an invocation.  An <code>Unavailable</code>
-device is not ready for allocation, for any of a variety of reasons — TF may have deemed to the
-device as unstable, the device may be critically low on storage, or something else may be amiss.
-Finally, an <code>Allocated</code> device is a device that is already being used by an invocation.</p>
-<p>When you start TF, all detected physical devices will be checked for responsiveness with a simple
-shell command.  If the command completes successfully, the device will be listed as Available.  If
-the command fails, the device state will be shown as Unavailable.  Thereafter, a device will typically bounce between the Available and Allocated states as invocation requirements dictate.</p>
-<p>Finally, once invocations are already underway, you can see what's going on with the <code>list
-invocations</code> command</p>
-<pre><code>tf &gt;run instrument --package com.android.calculator2.tests
-06-07 17:18:31 I/TestInvocation: Starting invocation for 'stub' on build '0' on device 1700614743c14397
-[...]
-tf &gt;l d
-Serial            State      Product   Variant   Build   Battery
-1700614743c14397  Allocated  stingray  stingray  MASTER  100
-3531C342606300EC  Available  herring   crespo4g  JRN11   93
-016B756E03018007  Available  tuna      toro      MASTER  100
-
-tf &gt;l i
-Command Id  Exec Time  Device            State
-1           0m:02      1700614743c14397  running stub on build 0
-</code></pre>
-<h3 id="running-invocations-on-specific-devices">Running invocations on specific devices</h3>
-<p>TF supports a number of filtering mechanisms for specifying which device or devices to use for a
-particular invocation.  Since the filtering mechanisms are run before a command turns into an
-invocation, you can find all of the filtering options in the help for any config:</p>
-<p>tf &gt;run instrument --help-all
-[...]
-  device_requirements options:
-    -s, --serial         run this test on a specific device with given serial number(s).
-    --exclude-serial     run this test on any device except those with this serial number(s).
-    --product-type       run this test on device with this product type(s).  May also filter by variant using product:variant.
-    --property           run this test on device with this property value. Expected format <propertyname>=<propertyvalue>.
-    -e, --[no-]emulator  force this test to run on emulator. Default: false.
-    -d, --[no-]device    force this test to run on a physical device, not an emulator. Default: false.
-    --[no-]new-emulator  allocate a placeholder emulator. Should be used when config intends to launch an emulator Default: false.
-    -n, --[no-]null-device
-                         do not allocate a device for this test. Default: false.
-    --min-battery        only run this test on a device whose battery level is at least the given amount. Scale: 0-100
-    --max-battery        only run this test on a device whose battery level is strictly less than the given amount. Scale: 0-100
-[...]</p>
-<p>The built-in help should be pretty self-explanatory.  All of the filtering options excluding "-n",
-"-e", and "-d" may be specified as many times as needed.  So, for instance, to run an invocation
-using any Verizon Galaxy Nexus, you could do the following:</p>
-<pre><code>tf &gt;run instrument --package com.android.calculator2.tests --product-type tuna:toro
-</code></pre>
-<p>As another example, to run on a GSM device with a SIM, you could do the following:</p>
-<pre><code>tf &gt;run instrument --package com.android.calculator2.tests --property gsm.sim.state=READY
-</code></pre>
-<p>The filtering works by exclusion from the pool of Available devices, so the "--serial" option simply
-excludes devices that aren't in the list of required serials, and --exclude-serial excludes devices
-that <em>are</em> in its list.  As such, an argument like --exclude-serial XXX --serial XXX will simply
-make the respective command un-runnable — it will never match any device, since all devices are
-excluded.</p>
-<h2 id="logging">Logging</h2>
-<p>There are a few different aspects to logging in TF.  First and foremost, TF has a built-in logging
-infrastructure that's based on DDMLib's Log class.  For the common case, where the log tag is just
-the classname of the current class, you can use our CLog convenience shim.  In short, if you might
-have originally done this:</p>
-<pre><code>class ClassName {
-private static final LOG_TAG = "ClassName";
-[...]
-Log.v(LOG_TAG, "This is a simple verbose log message");
-Log.w(LOG_TAG, String.format("This warning message brought to you by the number %d", 17));
-</code></pre>
-<p>You can now accomplish the same thing with the shim like this:</p>
-<pre><code>class ClassName {
-[...]
-CLog.v("This is a simple verbose log message");
-CLog.w("This warning message brought to you by the number %d", 17);
-</code></pre>
-<p>Each Invocation has its own ThreadGroup.  Any host-side logging that happens inside of that thread
-group is associated with the Invocation, and will be reported as that invocation's "host_log" after
-the Invocation completes.</p>
-<p>Device logging is performed as part of TradeFed's device wrapper.  We keep a buffer of up to 20 MB
-that captures log data as the device churns it out.  In particular, we are not limited by the size
-of the on-device logcat buffer.</p>
-<p>The next important piece is the ITestInvocationListener.  This is one of the components of an
-Invocation that handles results reporting.  Each reporter has the option to implement the #testLog
-method, which will be used to pass logfiles to that result reporter.  Among the files that are
-passed by TF itself will be the aforementioned host_log, as well as the device logcat for the device
-associated with the Invocation.</p>
diff --git a/src/devices/tech/test_infra/tradefed/index.jd b/src/devices/tech/test_infra/tradefed/index.jd
index 9331369..ad7367a 100644
--- a/src/devices/tech/test_infra/tradefed/index.jd
+++ b/src/devices/tech/test_infra/tradefed/index.jd
@@ -16,37 +16,92 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<p>TradeFederation (tradefed or TF for short) is a continuous test framework designed for running tests
-on Android devices. Its a Java application which runs on a host computer, and communicates to one or
+<p>Trade Federation (tradefed or TF for short) is a continuous test framework designed for running tests
+on Android devices. It's a Java application which runs on a host computer, and communicates to one or
 more Android devices using ddmlib (the library behind DDMS) over adb.</p>
-<h2 id="features">Features</h2>
+
+<p>We've listed some of TF's main features below, along with a couple sample usecases.  That said,
+if you want to jump right in and get started, you can head straight for the
+<a href="/devices/tech/test_infra/tradefed/fundamentals/index.html">Start Here</a> page.</p>
+
+<h2>Features</h2>
 <ul>
-<li>modular, flexible design</li>
-<li>has built in support for running many different types of Android tests: instrumentation, native/gtest, host-based JUnit, etc</li>
-<li>provides reliability and recovery mechanism on top of adb</li>
+<li>modular, flexible, scalable design</li>
+<li>has built in support for running many different types of Android tests:
+  <a href="http://developer.android.com/tools/testing/testing_android.html#Instrumentation">instrumentation</a>,
+  <a href="http://developer.android.com/tools/testing/testing_ui.html">uiautomator</a>,
+  native/gtest, host-based JUnit, etc</li>
+<li>provides reliability and recovery mechanisms on top of adb</li>
 <li>supports scheduling and running tests on multiple devices in parallel</li>
 </ul>
-<h2 id="fundamentals">Fundamentals</h2>
-<p>The lifecycle of a test executed using TradeFederation is composed of four separate stages, designed
-around formally defined interfaces.</p>
-<ul>
-<li><a href="bp.html">Build provider</a>: Provides a build to test, downloading appropriate files if necessary</li>
-<li><a href="tp.html">Target preparer</a>: Prepares the test environment, e.g. software installation and setup</li>
-<li><a href="test.html">Test</a>: Executes test(s) and gathers test results</li>
-<li><a href="result.html">Result reporter</a>: Listens for test results, usually for the purpose of forwarding
-  test results to a repository</li>
-</ul>
-<p>The fundamental entity in TradeFederation is a Configuration. A Configuration is an XML file that
-declares the lifecycle components of a test.</p>
-<p>This separation of the test's lifecycle is intended to allow for reuse.  Using this design, you can
-create a Test, and then different Configurations to run it in different environments. For example,
-you could create a Configuration that will run a test on your local machine, and dump the result to
-stdout.  You could then create a second Configuration that would execute that same test, but use a
-different Result reporter to store the test results in a database.</p>
-<h3 id="additional-components-of-a-configuration">Additional components of a configuration</h3>
-<ul>
-<li><a href="recovery.html">Device recovery</a>: mechanism to recover device communication if lost</li>
-<li><a href="logger.html">Logger</a>: collects tradefed logging data</li>
-</ul>
-<p>A complete TradeFederation test execution, across its entire lifecycle, is referred to as an
-Invocation.</p>
\ No newline at end of file
+
+<h2>Sample Trade Federation Usecases</h2>
+<p>Trade Federation's modularity makes it straightforward to slot into environments with existing
+build, test, and reporting infrastructures.  We list below a few demonstrative
+usecases where tradefed could enable efficient, scalable test practices.</p>
+
+<p>First, it is useful to consider the landscape of potential usecases in terms of the question
+"which parts are modifiable, and what parts are static?"  For instance, a Device OEM can modify the
+framework, the system, and the hardware, but has little or no influence over existing applications.
+An application developer, on the other hand, can modify the app, but has little control over most
+aspects of the system or the framework.</p>
+
+<p>As a result, an entity in each usecase will have different testing goals, and will have different
+options in the case of a set of test failures.  Despite these differences, Trade Federation can
+help make each of their test processes efficient, flexible, and scalable.</p>
+
+<h3>Device OEM</h3>
+<p>A Device OEM builds hardware, and will often tweak the Android system and frameworks to run well
+on that hardware.  The OEM might strive to accomplish those goals while retaining stability
+and performance at the hardware and system levels, and making sure the framework changes don't break
+compatibility with existing applications.</p>
+
+<p>The OEM could implement a device flashing module that will execute during the Target Setup stage
+of the <a href="/devices/tech/test_infra/tradefed/fundamentals/lifecycle.html">lifecycle</a>.  That
+module would have complete control over the device during its execution period, which would allow
+it to potentially force the device into the bootloader, flash, and then force the device to reboot
+back into userspace mode.  Combined with a module to tie into a continuous build system, this would
+allow the OEM to run tests on their device as they make changes to the system-level firmware and
+Java-level frameworks.</p>
+
+<p>Once the device is fully booted, the OEM would be able to leverage existing JUnit-based tests,
+or write new ones, to verify the functionality of interest.  Finally, they could write one or more
+result reporting modules to tie into existing test-result repositories, or to report results
+directly (for instance,
+<a href="/reference/com/android/tradefed/result/EmailResultReporter.html">by email</a>).</p>
+
+<h3>App Developer</h3>
+<p>An Application Developer builds an app which needs to run well across a variety of platform
+versions and a variety of devices.  If an issue comes up on a particular platform version and/or
+device, the only remedy is to add a workaround and move on.  For larger developers, the test
+process might be incorporated into a continuous build sequence.  For smaller developers, it
+might be kicked off periodically or by hand.</p>
+
+<p>Most app developers would use the apk test installation modules that already exist in TF.
+There's a version that <a href="/reference/com/android/tradefed/targetprep/InstallApkSetup.html"
+>installs from the local filesystem</a>, as well as a version that can
+<a href="/reference/com/android/tradefed/targetprep/InstallBuildEnvApkSetup.html">install
+apks downloaded from a build service</a>.  It is important to note that the latter version would
+continue to work properly with arbitrarily many TF instances running on the same host machine.</p>
+
+<p>Because of TF's proficiency at dealing with multiple devices, it would be straightforward to
+classify each test result by the type of device that was used for that test.  Thus, TF could
+potentially generate a 2-dimensional (or multi-dimensional) compatibility matrix for every
+build of the application.</p>
+
+<h3>Testing Service</h3>
+<p>A Test Service might, for instance, allow app developers to submit apps and run tests on devices
+instrumented with power-measurement tools to determine power usage for the app.  This differs from
+the prior two usecases in that the service builder does not control the devices or the applications
+that are being run</p>
+
+<p>Because Trade Federation can run any Java class that implements the simple
+<a href="/reference/com/android/tradefed/testtype/IRemoteTest.html">IRemoteTest</a> interface, it's
+trivial to write drivers that can coordinate some external piece of hardware with the test case
+that's being run on the device.  The driver itself can spawn Threads, send requests to other
+servers, or do anything else that it might need.  Moreover, the simplicity and versatility of the
+result reporting interface,
+<a href="/reference/com/android/tradefed/result/ITestInvocationListener.html"
+>ITestInvocationListener</a>, means that it is likewise straightforward to
+represent arbitrary test results (including, for instance, numerical power metrics) into the
+standard result reporting pipeline.</p>
diff --git a/src/devices/tech/test_infra/tradefed/template.jd b/src/devices/tech/test_infra/tradefed/template.jd
new file mode 100644
index 0000000..3d6677f
--- /dev/null
+++ b/src/devices/tech/test_infra/tradefed/template.jd
@@ -0,0 +1,24 @@
+page.title=Template
+@jd:body
+
+<!--
+    Copyright 2013 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.
+-->
+
+<p>Write some stuff</p>
+
+<h2>Hey, it's a header!</h2>
+<p>Write some more stuff</p>
+
diff --git a/src/devices/tech/test_infra/tradefed/tutorial.jd b/src/devices/tech/test_infra/tradefed/tutorial.jd
deleted file mode 100644
index eb42aa0..0000000
--- a/src/devices/tech/test_infra/tradefed/tutorial.jd
+++ /dev/null
@@ -1,334 +0,0 @@
-page.title=Tutorial
-@jd:body
-
-<!--
-    Copyright 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.
--->
-<p>This tutorial guides you through the construction of a "hello world" Trade Federation test
-configuration, and gives you a hands-on introduction to the Trade Federation framework.  Starting
-from the Tf development environment, it guides you through the process of creating a simple Trade
-Federation config and gradually adding more features to it.</p>
-<p>The tutorial presents the TF test development process as a set of exercises, each consisting of
-several steps.  The exercises demonstrate how to gradually build and refine your configuration, and
-provide all the sample code you need to complete the test configuration.</p>
-<p>When you are finished with the tutorial, you will have created a functioning TF configuration and
-will have learned many of the most important concepts in the TF framework.</p>
-<h2 id="set-up-tradefederation-development-environment">Set up TradeFederation development environment</h2>
-<p>See (FIXME: link) for how to setup the development environment. The rest of this tutorial assumes you have a shell open that has been initialized to the TradeFederation environment. </p>
-<p>For simplicity, this tutorial will illustrate adding a configuration and its classes to the TradeFederation framework core library. Later tutorials/documentation will show how to create your own library that extends TradeFederation.</p>
-<h2 id="creating-a-test-class">Creating a test class</h2>
-<p>Lets create a hello world test that just dumps a message to stdout. A TradeFederation test must
-implement the (FIXME: link) IRemoteTest interface.</p>
-<p>Here's an implementation for the HelloWorldTest:</p>
-<pre><code>package com.android.tradefed.example;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IRemoteTest;
-
-public class HelloWorldTest implements IRemoteTest {
-    &#64;Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        System.out.println("Hello, TF World!");
-    }
-}
-</code></pre>
-<p>FIXME: prod-tests
-Save this sample code to
-<code>&lt;git home&gt;/tools/tradefederation/prod-tests/src/com/android/tradefed/example/HelloWorldTest.java</code>
-and rebuild tradefed from your shell:</p>
-<pre><code>m -j6
-</code></pre>
-<p>If the build does not succeed, please consult the (FIXME: link)Development Environment page to
-ensure you did not miss any steps.</p>
-<h2 id="creating-a-configuration">Creating a configuration</h2>
-<p>Trade Federation tests are defined in a "Configuration". A Configuration is an XML file that
-instructs tradefed which test (or set of tests) to run.</p>
-<p>Lets create a new Configuration for our HelloWorldTest.</p>
-<pre><code>&lt;configuration description="Runs the hello world test"&gt;
-    &lt;test class="com.android.tradefed.example.HelloWorldTest" /&gt;
-&lt;/configuration&gt;
-</code></pre>
-<p>TF will parse the Configuration XML file, load the specified class using reflection, instantiate it,
-cast it to a IRemoteTest, and call its 'run' method.</p>
-<p>Note that we've specified the full class name of the HelloWorldTest. Save this data to a
-<code>helloworld.xml</code> file anywhere on your local filesystem (eg <code>/tmp/helloworld.xml</code>).</p>
-<h2 id="running-the-configuration">Running the configuration</h2>
-<p>From your shell, launch the tradefed console</p>
-<pre><code>$ ./tradefed.sh
-</code></pre>
-<p>Ensure a device is connected to the host machine that is visible to tradefed</p>
-<pre><code>tf&gt; list devices
-</code></pre>
-<p>Configurations can be run using the <code>run &lt;config&gt;</code> console command.  Try this now</p>
-<p>FIXME: redo this</p>
-<pre><code>tf&gt; run /tmp/helloworld.xml
-05-12 13:19:36 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
-Hello, TF World!
-</code></pre>
-<p>You should see "Hello, TF World!" outputted on the terminal.</p>
-<h2 id="adding-the-configuration-to-the-classpath">Adding the configuration to the classpath</h2>
-<p>FIXME: prod-tests
-For convenience of deployment, you can also bundle configuration files into the TradeFederation jars
-themselves. Tradefed will automatically recognize all configurations placed in 'config' folders on
-the classpath.</p>
-<p>Lets illustrate this now by moving the helloworld.xml into the tradefed core library.</p>
-<p>Move the <code>helloworld.xml</code> file into 
-<code>&lt;git root&gt;/tools/tradefederation/prod-tests/res/config/example/helloworld.xml</code>.</p>
-<p>Rebuild tradefed, and restart the tradefed console. </p>
-<p>Ask tradefed to display the list of configurations on the classpath:</p>
-<pre><code>tf&gt; list configs
-[…]
-example/helloworld: Runs the hello world test
-</code></pre>
-<p>You can now run the helloworld config via the following command</p>
-<pre><code>tf &gt;run example/helloworld
-05-12 13:21:21 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
-Hello, TF World!
-</code></pre>
-<h2 id="interacting-with-a-device">Interacting with a device</h2>
-<p>So far our hello world test isn't doing anything interesting. Tradefed is intended to run tests using Android devices, so lets add an Android device to the test.</p>
-<p>Tests can get a reference to an Android device by implementing the IDeviceTest interface. </p>
-<p>Here's a sample implementation of what this looks like:</p>
-<pre><code>public class HelloWorldTest implements IRemoteTest, IDeviceTest {
-    private ITestDevice mDevice;
-    &#64;Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    &#64;Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-…
-}
-</code></pre>
-<p>The TradeFederation framework will inject the ITestDevice reference into your test via the
-IDeviceTest#setDevice method, before the IRemoteTest#run method is called.</p>
-<p>Lets add an additional print message to the HelloWorldTest displaying the serial number of the
-device.</p>
-<pre><code>&#64;Override
-public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-    System.out.println("Hello, TF World! I have a device " + getDevice().getSerialNumber());
-}
-</code></pre>
-<p>Now rebuild tradefed, and do (FIXME: update)</p>
-<pre><code>$ tradefed.sh
-tf&gt; list devices
-Available devices:   [30315E38655500EC]
-…
-</code></pre>
-<p>Take note of the serial number listed in Available devices above. That is the device that should be allocated to HelloWorld.</p>
-<pre><code>tf &gt;run example/helloworld
-05-12 13:26:18 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
-Hello world, TF! I have a device 30315E38655500EC
-</code></pre>
-<p>You should see the new print message displaying the serial number of the device.</p>
-<h2 id="sending-test-results">Sending test results</h2>
-<p>IRemoteTests report results by calling methods on the ITestInvocationListener instance provided to
-their <code>#run</code> method.</p>
-<p>The TradeFederation framework is responsible for reporting the start and end of an Invocation (via
-the ITestInvocationListener#invocationStarted and ITestInvocationListener#invocationEnded methods
-respectively).</p>
-<p>A <code>test run</code> is a logical collection of tests. To report test results, IRemoteTests are responsible
-for reporting the start of a test run, the start and end of each test, and the end of the test run.</p>
-<p>Here's what the HelloWorldTest implementation looks like with a single failed test result.</p>
-<pre><code>&#64;SuppressWarnings("unchecked")
-&#64;Override
-public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-    System.out.println("Hello, TF World! I have a device " + getDevice().getSerialNumber());
-
-    TestIdentifier testId = new TestIdentifier("com.example.MyTestClassName", "sampleTest");
-    listener.testRunStarted("helloworldrun", 1);
-    listener.testStarted(testId);
-    listener.testFailed(TestFailure.FAILURE, testId, "oh noes, test failed");
-    listener.testEnded(testId, Collections.EMPTY_MAP);
-    listener.testRunEnded(0, Collections.EMPTY_MAP);
-}
-</code></pre>
-<p>Note that TradeFederation also includes several IRemoteTest implementations that you can reuse
-instead of writing your own from scratch. (such as InstrumentationTest, which can run an Android
-application's tests remotely on an Android device, parse the results, and forward them to the
-ITestInvocationListener). See the Test Types documentation for more details.</p>
-<h2 id="storing-test-results">Storing test results</h2>
-<p>By default, a TradeFederation configuration will use the TextResultReporter as the test listener
-implementation for the configuration.  TextResultReporter will dump the results of an invocation to
-stdout. To illustrate, try running the hello-world config from previous section now:</p>
-<pre><code>$ ./tradefed.sh
-tf &gt;run example/helloworld
-05-16 20:03:15 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
-Hello world, TF! I have a device 30315E38655500EC
-05-16 20:03:15 I/InvocationToJUnitResultForwarder: run helloworldrun started: 1 tests
-Test FAILURE: com.example.MyTestClassName#sampleTest 
- stack: oh noes, test failed 
-05-16 20:03:15 I/InvocationToJUnitResultForwarder: run ended 0 ms
-</code></pre>
-<p>If you want to store the results of an invocation elsewhere, say to a file, you would need to
-specify a custom "result_reporter" in your configuration, that specifies the custom
-ITestInvocationListener class you want to use.</p>
-<p>The TradeFederation framework includes a result_reporter (XmlResultReporter)  that will write test
-results to an XML file, in a format similar to the ant JUnit XML writer. </p>
-<p>Lets specify the result_reporter in the configuration now. Edit the
-<code>tools/tradefederation/res/config/example/helloworld.xml</code> like this:</p>
-<pre><code>&lt;configuration description="Runs the hello world test"&gt;
-    &lt;test class="com.android.tradefed.example.HelloWorldTest" /&gt;
-    &lt;result_reporter class="com.android.tradefed.result.XmlResultReporter" /&gt;
-&lt;/configuration&gt;
-</code></pre>
-<p>Now rebuild tradefed and re-run the hello world sample:
-FIXME: paths</p>
-<pre><code>tf &gt;run example/helloworld
-05-16 21:07:07 I/TestInvocation: Starting invocation for target stub on build 0 on device 30315E38655500EC
-Hello world, TF! I have a device 30315E38655500EC
-05-16 21:07:07 I/XmlResultReporter: Saved device_logcat log to /var/folders/++/++2Pz+++6+0++4RjPqRgNE+-4zk/-Tmp-/0/inv_2991649128735283633/device_logcat_6999997036887173857.txt
-05-16 21:07:07 I/XmlResultReporter: Saved host_log log to /var/folders/++/++2Pz+++6+0++4RjPqRgNE+-4zk/-Tmp-/0/inv_2991649128735283633/host_log_6307746032218561704.txt
-05-16 21:07:07 I/XmlResultReporter: XML test result file generated at /var/folders/++/++2Pz+++6+0++4RjPqRgNE+-4zk/-Tmp-/0/inv_2991649128735283633/test_result_536358148261684076.xml. Total tests 1, Failed 1, Error 0
-</code></pre>
-<p>Notice the log message stating an XML file has been generated. The generated file should look like this:</p>
-<pre><code>&lt;?xml version='1.0' encoding='UTF-8' ?&gt;
-&lt;testsuite name="stub" tests="1" failures="1" errors="0" time="9" timestamp="2011-05-17T04:07:07" hostname="localhost"&gt;
-  &lt;properties /&gt;
-  &lt;testcase name="sampleTest" classname="com.example.MyTestClassName" time="0"&gt;
-    &lt;failure&gt;oh noes, test failed
-    &lt;/failure&gt;
-  &lt;/testcase&gt;
-&lt;/testsuite&gt;
-</code></pre>
-<p>Note that you can write your own custom result_reporter. It just needs to implement the
-ITestInvocationListener interface. </p>
-<p>Also note that Tradefed supports multiple result_reporters, meaning that you can send test results
-to multiple independent destinations. Just specify multiple <result_reporter> tags in your config to
-do this.</p>
-<h2 id="logging">Logging</h2>
-<p>TradeFederation includes two logging facilities:</p>
-<ol>
-<li>ability to capture logs from the device (aka device logcat)</li>
-<li>ability to record logs from the TradeFederation framework running on the host machine (aka the
-    host log)</li>
-</ol>
-<p>Lets focus on 2 for now. Trade Federation's host logs are reported using the CLog wrapper for the
-ddmlib Log class. </p>
-<p>Lets convert the previous System.out.println call in HelloWorldTest to a CLog call:</p>
-<pre><code>&#64;Override
-public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-    CLog.i("Hello world, TF! I have a device " + getDevice().getSerialNumber());
-</code></pre>
-<p>Now rebuild and rerun. You should see the log message on stdout. </p>
-<pre><code>tf&gt; run example/helloworld
-…
-05-16 21:30:46 I/HelloWorldTest: Hello world, TF! I have a device 30315E38655500EC
-…
-</code></pre>
-<p>By default, TradeFederation will output host log messages to stdout. TradeFederation also includes a
-log implementation that will write messages to a file: FileLogger. To add file logging, add a
-'logger' tag to the configuration xml, specifying the full class name of FileLogger.</p>
-<pre><code>&lt;configuration description="Runs the hello world test"&gt;
-    &lt;test class="com.android.tradefed.example.HelloWorldTest" /&gt;
-    &lt;result_reporter class="com.android.tradefed.result.XmlResultReporter" /&gt;
-    &lt;logger class="com.android.tradefed.log.FileLogger" /&gt;
-&lt;/configuration&gt;
-</code></pre>
-<p>Now rebuild and run the helloworld example again.</p>
-<pre><code>tf &gt;run example/helloworld 
-…
-05-16 21:38:21 I/XmlResultReporter: Saved device_logcat log to /var/folders/++/++2Pz+++6+0++4RjPqRgNE+-4zk/-Tmp-/0/inv_6390011618174565918/device_logcat_1302097394309452308.txt
-05-16 21:38:21 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
-…
-</code></pre>
-<p>Note the log message indicating the path of the host log. View the contents of that file, and you
-should see your HelloWorldTest log message</p>
-<pre><code>$ more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
-…
-05-16 21:38:21 I/HelloWorldTest: Hello world, TF! I have a device 30315E38655500EC
-</code></pre>
-<p>The TradeFederation framework will also automatically capture the logcat from the allocated device,
-and send it the the result_reporter for processing. XmlResultReporter will save the captured device
-logcat as a file.</p>
-<h2 id="command-line-options">Command line options</h2>
-<p>Objects loaded from a TradeFederation Configuration (aka "Configuration objects") also have the
-ability to receive data from command line arguments.</p>
-<p>This is accomplished via the <code>@Option</code> annotation. To participate, a Configuration object class
-would apply the <code>@Option</code> annotation to a member field, and provide it a unique name. This would
-allow that member field's value to be populated via a command line option, and would also
-automatically add that option to the configuration help system (Note: not all field types are
-supported: see the OptionSetter javadoc for a description of supported types).</p>
-<p>Lets add an Option to the HelloWorldTest.</p>
-<pre><code>@Option(name="my_option",
-        shortName='m',
-        description="this is the option's help text",
-        // always display this option in the default help text
-        importance=Importance.ALWAYS)
-private String mMyOption = "thisisthedefault";
-</code></pre>
-<p>And lets add a log message to display the value of the option in HelloWorldTest, so we can
-demonstrate that it was received correctly.</p>
-<pre><code>@SuppressWarnings("unchecked")
-&#64;Override
-public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-    …
-    Log.logAndDisplay(LogLevel.INFO, "HelloWorldTest", "I received this option " + mMyOption);
-</code></pre>
-<p>Rebuild TF and run helloworld: you should see a log message with the my_option's default value.</p>
-<pre><code>tf&gt; run example/helloworld
-…
-05-24 18:30:05 I/HelloWorldTest: I received this option thisisthedefault
-</code></pre>
-<p>Now pass in a value for my_option: you should see my_option getting populated with that value</p>
-<pre><code>tf&gt; run example/helloworld --my_option foo
-…
-05-24 18:33:44 I/HelloWorldTest: I received this option foo
-</code></pre>
-<p>TF configurations also include a help system, which automatically displays help text for @Option
-fields. Try it now, and you should see the help text for 'my_option':</p>
-<pre><code>tf&gt; run --help example/helloworld
-Printing help for only the important options. To see help for all options, use the --help-all flag
-
-  cmd_options options:
-    --[no-]help          display the help text for the most important/critical options. Default: false.
-    --[no-]help-all      display the full help text for all options. Default: false.
-    --[no-]loop          keep running continuously. Default: false.
-
-  test options:
-    -m, --my_option      this is the option's help text Default: thisisthedefault.
-
-  'file' logger options:
-    --log-level-display  the minimum log level to display on stdout. Must be one of verbose, debug, info, warn, error, assert. Default: error.
-</code></pre>
-<p>FIXME: redo with enum help</p>
-<p>Note the message at the top about 'printing only the important options'. To reduce option help
-clutter, TF uses the Option#importance attribute to determine whether to show an Option's help text
-when '--help' is specified. '--help-all' will always show all options' help regardless of
-importance. See Option.Importance javadoc for details.</p>
-<p>You can also specify an Option's value within the configuration xml by adding a
-<code>&lt;option name="" value=""&gt;</code> element. Lets see how this looks in the helloworld.xml:</p>
-<pre><code>&lt;test class="com.android.tradefed.example.HelloWorldTest" &gt;
-    &lt;option name="my_option" value="fromxml" /&gt;
-&lt;/test&gt;
-</code></pre>
-<p>Re-building and running helloworld should now produce this output:</p>
-<pre><code>05-24 20:38:25 I/HelloWorldTest: I received this option fromxml
-</code></pre>
-<p>The configuration help should also be updated to indicate my_option's new default value:</p>
-<pre><code>tf&gt; run --help example/helloworld
-  test options:
-    -m, --my_option      this is the option's help text Default: fromxml.
-</code></pre>
-<p>Also note that other configuration objects included in the helloworld config, like FileLogger, also have options. '--log-level-display' is of interest because it filters the logs that show up on stdout. You may have noticed from earlier in the tutorial the 'Hello world, TF! I have a device ..' log message stopped getting displayed on stdout once we switched to using FileLogger. You can increase the verbosity of logging to stdout by passing in log-level-display arg.</p>
-<p>Try this now, and you should see the 'I have a device' log message reappear on stdout, in addition to getting logged to a file.</p>
-<pre><code>tf &gt;run --log-level-display info example/helloworld
-…
-05-24 18:53:50 I/HelloWorldTest: Hello world, TF! I have a device XXXXXX
-</code></pre>
diff --git a/src/source/known-issues.jd b/src/source/known-issues.jd
index 886055d..a68dde6 100644
--- a/src/source/known-issues.jd
+++ b/src/source/known-issues.jd
@@ -28,10 +28,10 @@
 track of the known issues around using the Android source code.</p>
 
 <h2 id="missing-cellbroadcastreceiver">Missing CellBroadcastReceiver in toro builds</h2>
-<p><strong>Symptom</strong</p>On AOSP builds for toro (up to Jelly Bean 4.2.1),
+<p><strong>Symptom</strong></p>On AOSP builds for toro (up to Jelly Bean 4.2.1),
 CellBroadcastReceiver doesn't get included in the system.</p>
 
-<p><strong>Cause</strong></p>: There's a typo in <code>vendor/samsung/toro/device-partial.mk</code>,
+<p><strong>Cause:</strong></p> There's a typo in <code>vendor/samsung/toro/device-partial.mk</code>,
 where <code>PRODUCT_PACKAGES</code> has the K replaced by an H.
 <p><strong>Fix</strong>: Use the latest packages for 4.2.2, or manually fix the typo.</p>