diff --git a/cmds/am/Android.mk b/cmds/am/Android.mk
index f8350dc..5586dd4 100644
--- a/cmds/am/Android.mk
+++ b/cmds/am/Android.mk
@@ -3,8 +3,11 @@
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src) \
+    $(call all-proto-files-under, proto)
 LOCAL_MODULE := am
+LOCAL_PROTOC_OPTIMIZE_TYPE := stream
 include $(BUILD_JAVA_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -13,3 +16,14 @@
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_PREBUILT)
+
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+    $(call all-proto-files-under, proto)
+LOCAL_MODULE := libinstrumentation
+LOCAL_PROTOC_OPTIMIZE_TYPE := full
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(call intermediates-dir-for,STATIC_LIBRARIES,libinstrumentation,HOST,,,)/proto/$(LOCAL_PATH)/proto
+include $(BUILD_HOST_STATIC_LIBRARY)
+
diff --git a/cmds/am/proto/instrumentation_data.proto b/cmds/am/proto/instrumentation_data.proto
new file mode 100644
index 0000000..12a18a2
--- /dev/null
+++ b/cmds/am/proto/instrumentation_data.proto
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+syntax = "proto2";
+package android.am;
+
+option java_package = "com.android.commands.am";
+
+message ResultsBundleEntry {
+    optional string key = 1;
+
+    optional string value_string = 2;
+    optional sint32 value_int = 3;
+    optional float value_float = 4;
+    optional double value_double = 5;
+    optional sint64 value_long = 6;
+    optional ResultsBundle value_bundle = 7;
+}
+
+message ResultsBundle {
+    repeated ResultsBundleEntry entries = 1;
+}
+
+message TestStatus {
+    optional sint32 result_code = 3;
+    optional ResultsBundle results = 4;
+}
+
+enum SessionStatusCode {
+    /**
+     * The command ran successfully. This does not imply that the tests passed.
+     */
+    SESSION_FINISHED = 0;
+
+    /**
+     * There was an unrecoverable error running the tests.
+     */
+    SESSION_ABORTED = 1;
+}
+
+message SessionStatus {
+    optional SessionStatusCode status_code = 1;
+    optional string error_text = 2;
+    optional sint32 result_code = 3;
+    optional ResultsBundle results = 4;
+}
+
+message Session {
+    repeated TestStatus test_status = 1;
+    optional SessionStatus session_status = 2;
+}
+
+
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index e197bfc..91a4549 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -1,20 +1,18 @@
 /*
-**
-** Copyright 2007, 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.
-*/
-
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package com.android.commands.am;
 
@@ -235,6 +233,7 @@
                 "    -e <NAME> <VALUE>: set argument <NAME> to <VALUE>.  For test runners a\n" +
                 "        common form is [-e <testrunner_flag> <value>[,<value>...]].\n" +
                 "    -p <FILE>: write profiling data to <FILE>\n" +
+                "    -m: Write output as protobuf (machine readable)\n" +
                 "    -w: wait for instrumentation to finish before returning.  Required for\n" +
                 "        test runners.\n" +
                 "    --user <USER_ID> | current: Specify user instrumentation runs in;\n" +
@@ -543,208 +542,43 @@
         receiver.waitForFinish();
     }
 
-    private void runInstrument() throws Exception {
-        String profileFile = null;
-        boolean wait = false;
-        boolean rawMode = false;
-        boolean no_window_animation = false;
-        int userId = UserHandle.USER_CURRENT;
-        Bundle args = new Bundle();
-        String argKey = null, argValue = null;
-        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
-        String abi = null;
+    public void runInstrument() throws Exception {
+        Instrument instrument = new Instrument(mAm, mPm);
 
         String opt;
         while ((opt=nextOption()) != null) {
             if (opt.equals("-p")) {
-                profileFile = nextArgRequired();
+                instrument.profileFile = nextArgRequired();
             } else if (opt.equals("-w")) {
-                wait = true;
+                instrument.wait = true;
             } else if (opt.equals("-r")) {
-                rawMode = true;
+                instrument.rawMode = true;
+            } else if (opt.equals("-m")) {
+                instrument.proto = true;
             } else if (opt.equals("-e")) {
-                argKey = nextArgRequired();
-                argValue = nextArgRequired();
-                args.putString(argKey, argValue);
+                final String argKey = nextArgRequired();
+                final String argValue = nextArgRequired();
+                instrument.args.putString(argKey, argValue);
             } else if (opt.equals("--no_window_animation")
                     || opt.equals("--no-window-animation")) {
-                no_window_animation = true;
+                instrument.noWindowAnimation = true;
             } else if (opt.equals("--user")) {
-                userId = parseUserArg(nextArgRequired());
+                instrument.userId = parseUserArg(nextArgRequired());
             } else if (opt.equals("--abi")) {
-                abi = nextArgRequired();
+                instrument.abi = nextArgRequired();
             } else {
                 System.err.println("Error: Unknown option: " + opt);
                 return;
             }
         }
 
-        if (userId == UserHandle.USER_ALL) {
+        if (instrument.userId == UserHandle.USER_ALL) {
             System.err.println("Error: Can't start instrumentation with user 'all'");
             return;
         }
 
-        String cnArg = nextArgRequired();
+        instrument.componentNameArg = nextArgRequired();
 
-        ComponentName cn;
-        if (cnArg.contains("/")) {
-            cn = ComponentName.unflattenFromString(cnArg);
-            if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
-        } else {
-            List<InstrumentationInfo> infos = mPm.queryInstrumentation(null, 0).getList();
-
-            final int numInfos = infos == null ? 0: infos.size();
-            List<ComponentName> cns = new ArrayList<>();
-            for (int i = 0; i < numInfos; i++) {
-                InstrumentationInfo info = infos.get(i);
-
-                ComponentName c = new ComponentName(info.packageName, info.name);
-                if (cnArg.equals(info.packageName)) {
-                    cns.add(c);
-                }
-            }
-
-            if (cns.size() == 0) {
-                throw new IllegalArgumentException("No instrumentation found for: " + cnArg);
-            } else if (cns.size() == 1) {
-                cn = cns.get(0);
-            } else {
-                StringBuilder cnsStr = new StringBuilder();
-                final int numCns = cns.size();
-                for (int i = 0; i < numCns; i++) {
-                    cnsStr.append(cns.get(i).flattenToString());
-                    cnsStr.append(", ");
-                }
-
-                // Remove last ", "
-                cnsStr.setLength(cnsStr.length() - 2);
-
-                throw new IllegalArgumentException("Found multiple instrumentations: "
-                        + cnsStr.toString());
-            }
-        }
-
-        InstrumentationWatcher watcher = null;
-        UiAutomationConnection connection = null;
-        if (wait) {
-            watcher = new InstrumentationWatcher();
-            watcher.setRawOutput(rawMode);
-            connection = new UiAutomationConnection();
-        }
-
-        float[] oldAnims = null;
-        if (no_window_animation) {
-            oldAnims = wm.getAnimationScales();
-            wm.setAnimationScale(0, 0.0f);
-            wm.setAnimationScale(1, 0.0f);
-        }
-
-        if (abi != null) {
-            final String[] supportedAbis = Build.SUPPORTED_ABIS;
-            boolean matched = false;
-            for (String supportedAbi : supportedAbis) {
-                if (supportedAbi.equals(abi)) {
-                    matched = true;
-                    break;
-                }
-            }
-
-            if (!matched) {
-                throw new AndroidException(
-                        "INSTRUMENTATION_FAILED: Unsupported instruction set " + abi);
-            }
-        }
-
-        if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId, abi)) {
-            throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
-        }
-
-        if (watcher != null) {
-            if (!watcher.waitForFinish()) {
-                System.out.println("INSTRUMENTATION_ABORTED: System has crashed.");
-            }
-        }
-
-        if (oldAnims != null) {
-            wm.setAnimationScales(oldAnims);
-        }
-    }
-
-    private class InstrumentationWatcher extends IInstrumentationWatcher.Stub {
-        private boolean mFinished = false;
-        private boolean mRawMode = false;
-
-        /**
-         * Set or reset "raw mode".  In "raw mode", all bundles are dumped.  In "pretty mode",
-         * if a bundle includes Instrumentation.REPORT_KEY_STREAMRESULT, just print that.
-         * @param rawMode true for raw mode, false for pretty mode.
-         */
-        public void setRawOutput(boolean rawMode) {
-            mRawMode = rawMode;
-        }
-
-        @Override
-        public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
-            synchronized (this) {
-                // pretty printer mode?
-                String pretty = null;
-                if (!mRawMode && results != null) {
-                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
-                }
-                if (pretty != null) {
-                    System.out.print(pretty);
-                } else {
-                    if (results != null) {
-                        for (String key : results.keySet()) {
-                            System.out.println(
-                                    "INSTRUMENTATION_STATUS: " + key + "=" + results.get(key));
-                        }
-                    }
-                    System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode);
-                }
-                notifyAll();
-            }
-        }
-
-        @Override
-        public void instrumentationFinished(ComponentName name, int resultCode,
-                Bundle results) {
-            synchronized (this) {
-                // pretty printer mode?
-                String pretty = null;
-                if (!mRawMode && results != null) {
-                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
-                }
-                if (pretty != null) {
-                    System.out.println(pretty);
-                } else {
-                    if (results != null) {
-                        for (String key : results.keySet()) {
-                            System.out.println(
-                                    "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key));
-                        }
-                    }
-                    System.out.println("INSTRUMENTATION_CODE: " + resultCode);
-                }
-                mFinished = true;
-                notifyAll();
-            }
-        }
-
-        public boolean waitForFinish() {
-            synchronized (this) {
-                while (!mFinished) {
-                    try {
-                        if (!mAm.asBinder().pingBinder()) {
-                            return false;
-                        }
-                        wait(1000);
-                    } catch (InterruptedException e) {
-                        throw new IllegalStateException(e);
-                    }
-                }
-            }
-            return true;
-        }
+        instrument.run();
     }
 }
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
new file mode 100644
index 0000000..8eefd25
--- /dev/null
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.am;
+
+import android.app.IActivityManager;
+import android.app.IInstrumentationWatcher;
+import android.app.Instrumentation;
+import android.app.UiAutomationConnection;
+import android.content.ComponentName;
+import android.content.pm.IPackageManager;
+import android.content.pm.InstrumentationInfo;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.AndroidException;
+import android.util.proto.ProtoOutputStream;
+import android.view.IWindowManager;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Runs the am instrument command
+ */
+public class Instrument {
+    private final IActivityManager mAm;
+    private final IPackageManager mPm;
+    private final IWindowManager mWm;
+
+    // Command line arguments
+    public String profileFile = null;
+    public boolean wait = false;
+    public boolean rawMode = false;
+    public boolean proto = false;
+    public boolean noWindowAnimation = false;
+    public String abi = null;
+    public int userId = UserHandle.USER_CURRENT;
+    public Bundle args = new Bundle();
+    // Required
+    public String componentNameArg;
+
+    /**
+     * Construct the instrument command runner.
+     */
+    public Instrument(IActivityManager am, IPackageManager pm) {
+        mAm = am;
+        mPm = pm;
+        mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+    }
+
+    /**
+     * Base class for status reporting.
+     *
+     * All the methods on this interface are called within the synchronized block
+     * of the InstrumentationWatcher, so calls are in order.  However, that means
+     * you must be careful not to do blocking operations because you don't know
+     * exactly the locking dependencies.
+     */
+    private interface StatusReporter {
+        /**
+         * Status update for tests.
+         */
+        public void onInstrumentationStatusLocked(ComponentName name, int resultCode,
+                Bundle results);
+
+        /**
+         * The tests finished.
+         */
+        public void onInstrumentationFinishedLocked(ComponentName name, int resultCode,
+                Bundle results);
+
+        /**
+         * @param errorText a description of the error
+         * @param commandError True if the error is related to the commandline, as opposed
+         *      to a test failing.
+         */
+        public void onError(String errorText, boolean commandError);
+    }
+
+    /**
+     * Printer for the 'classic' text based status reporting.
+     */
+    private class TextStatusReporter implements StatusReporter {
+        private boolean mRawMode;
+
+        /**
+         * Human-ish readable output.
+         *
+         * @param rawMode   In "raw mode" (true), all bundles are dumped.
+         *                  In "pretty mode" (false), if a bundle includes
+         *                  Instrumentation.REPORT_KEY_STREAMRESULT, just print that.
+         */
+        public TextStatusReporter(boolean rawMode) {
+            mRawMode = rawMode;
+        }
+
+        @Override
+        public void onInstrumentationStatusLocked(ComponentName name, int resultCode,
+                Bundle results) {
+            // pretty printer mode?
+            String pretty = null;
+            if (!mRawMode && results != null) {
+                pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+            }
+            if (pretty != null) {
+                System.out.print(pretty);
+            } else {
+                if (results != null) {
+                    for (String key : results.keySet()) {
+                        System.out.println(
+                                "INSTRUMENTATION_STATUS: " + key + "=" + results.get(key));
+                    }
+                }
+                System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode);
+            }
+        }
+
+        @Override
+        public void onInstrumentationFinishedLocked(ComponentName name, int resultCode,
+                Bundle results) {
+            // pretty printer mode?
+            String pretty = null;
+            if (!mRawMode && results != null) {
+                pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
+            }
+            if (pretty != null) {
+                System.out.println(pretty);
+            } else {
+                if (results != null) {
+                    for (String key : results.keySet()) {
+                        System.out.println(
+                                "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key));
+                    }
+                }
+                System.out.println("INSTRUMENTATION_CODE: " + resultCode);
+            }
+        }
+
+        @Override
+        public void onError(String errorText, boolean commandError) {
+            // The regular BaseCommand error printing will print the commandErrors.
+            if (!commandError) {
+                System.out.println(errorText);
+            }
+        }
+    }
+
+    /**
+     * Printer for the protobuf based status reporting.
+     */
+    private class ProtoStatusReporter implements StatusReporter {
+        @Override
+        public void onInstrumentationStatusLocked(ComponentName name, int resultCode,
+                Bundle results) {
+            final ProtoOutputStream proto = new ProtoOutputStream();
+
+            final long token = proto.startRepeatedObject(InstrumentationData.Session.TEST_STATUS);
+
+            proto.writeSInt32(InstrumentationData.TestStatus.RESULT_CODE, resultCode);
+            writeBundle(proto, InstrumentationData.TestStatus.RESULTS, results);
+
+            proto.endRepeatedObject(token);
+            writeProtoToStdout(proto);
+        }
+
+        @Override
+        public void onInstrumentationFinishedLocked(ComponentName name, int resultCode,
+                Bundle results) {
+            final ProtoOutputStream proto = new ProtoOutputStream();
+
+            final long token = proto.startObject(InstrumentationData.Session.SESSION_STATUS);
+
+            proto.writeEnum(InstrumentationData.SessionStatus.STATUS_CODE,
+                    InstrumentationData.SESSION_FINISHED);
+            proto.writeSInt32(InstrumentationData.SessionStatus.RESULT_CODE, resultCode);
+            writeBundle(proto, InstrumentationData.SessionStatus.RESULTS, results);
+
+            proto.endObject(token);
+            writeProtoToStdout(proto);
+        }
+
+        @Override
+        public void onError(String errorText, boolean commandError) {
+            final ProtoOutputStream proto = new ProtoOutputStream();
+
+            final long token = proto.startObject(InstrumentationData.Session.SESSION_STATUS);
+
+            proto.writeEnum(InstrumentationData.SessionStatus.STATUS_CODE,
+                    InstrumentationData.SESSION_ABORTED);
+            proto.writeString(InstrumentationData.SessionStatus.ERROR_TEXT, errorText);
+
+            proto.endObject(token);
+            writeProtoToStdout(proto);
+        }
+
+        private void writeBundle(ProtoOutputStream proto, long fieldId, Bundle bundle) {
+            final long bundleToken = proto.startObject(fieldId);
+
+            for (final String key: bundle.keySet()) {
+                final long entryToken = proto.startRepeatedObject(
+                        InstrumentationData.ResultsBundle.ENTRIES);
+
+                proto.writeString(InstrumentationData.ResultsBundleEntry.KEY, key);
+
+                final Object val = bundle.get(key);
+                if (val instanceof String) {
+                    proto.writeString(InstrumentationData.ResultsBundleEntry.VALUE_STRING,
+                            (String)val);
+                } else if (val instanceof Byte) {
+                    proto.writeSInt32(InstrumentationData.ResultsBundleEntry.VALUE_INT,
+                            ((Byte)val).intValue());
+                } else if (val instanceof Double) {
+                    proto.writeDouble(InstrumentationData.ResultsBundleEntry.VALUE_DOUBLE,
+                            ((Double)val).doubleValue());
+                } else if (val instanceof Float) {
+                    proto.writeFloat(InstrumentationData.ResultsBundleEntry.VALUE_FLOAT,
+                            ((Float)val).floatValue());
+                } else if (val instanceof Integer) {
+                    proto.writeSInt32(InstrumentationData.ResultsBundleEntry.VALUE_INT,
+                            ((Integer)val).intValue());
+                } else if (val instanceof Long) {
+                    proto.writeSInt64(InstrumentationData.ResultsBundleEntry.VALUE_LONG,
+                            ((Long)val).longValue());
+                } else if (val instanceof Short) {
+                    proto.writeSInt32(InstrumentationData.ResultsBundleEntry.VALUE_INT,
+                            ((Short)val).intValue());
+                } else if (val instanceof Bundle) {
+                    writeBundle(proto, InstrumentationData.ResultsBundleEntry.VALUE_BUNDLE,
+                            (Bundle)val);
+                }
+
+                proto.endRepeatedObject(entryToken);
+            }
+
+            proto.endObject(bundleToken);
+        }
+
+        private void writeProtoToStdout(ProtoOutputStream proto) {
+            try {
+                System.out.write(proto.getBytes());
+                System.out.flush();
+            } catch (IOException ex) {
+                System.err.println("Error writing finished response: ");
+                ex.printStackTrace(System.err);
+            }
+        }
+    }
+
+
+    /**
+     * Callbacks from the remote instrumentation instance.
+     */
+    private class InstrumentationWatcher extends IInstrumentationWatcher.Stub {
+        private final StatusReporter mReporter;
+
+        private boolean mFinished = false;
+
+        public InstrumentationWatcher(StatusReporter reporter) {
+            mReporter = reporter;
+        }
+
+        @Override
+        public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
+            synchronized (this) {
+                mReporter.onInstrumentationStatusLocked(name, resultCode, results);
+                notifyAll();
+            }
+        }
+
+        @Override
+        public void instrumentationFinished(ComponentName name, int resultCode, Bundle results) {
+            synchronized (this) {
+                mReporter.onInstrumentationFinishedLocked(name, resultCode, results);
+                mFinished = true;
+                notifyAll();
+            }
+        }
+
+        public boolean waitForFinish() {
+            synchronized (this) {
+                while (!mFinished) {
+                    try {
+                        if (!mAm.asBinder().pingBinder()) {
+                            return false;
+                        }
+                        wait(1000);
+                    } catch (InterruptedException e) {
+                        throw new IllegalStateException(e);
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Figure out which component they really meant.
+     */
+    private ComponentName parseComponentName(String cnArg) throws Exception {
+        if (cnArg.contains("/")) {
+            ComponentName cn = ComponentName.unflattenFromString(cnArg);
+            if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
+            return cn;
+        } else {
+            List<InstrumentationInfo> infos = mPm.queryInstrumentation(null, 0).getList();
+
+            final int numInfos = infos == null ? 0: infos.size();
+            ArrayList<ComponentName> cns = new ArrayList<>();
+            for (int i = 0; i < numInfos; i++) {
+                InstrumentationInfo info = infos.get(i);
+
+                ComponentName c = new ComponentName(info.packageName, info.name);
+                if (cnArg.equals(info.packageName)) {
+                    cns.add(c);
+                }
+            }
+
+            if (cns.size() == 0) {
+                throw new IllegalArgumentException("No instrumentation found for: " + cnArg);
+            } else if (cns.size() == 1) {
+                return cns.get(0);
+            } else {
+                StringBuilder cnsStr = new StringBuilder();
+                final int numCns = cns.size();
+                for (int i = 0; i < numCns; i++) {
+                    cnsStr.append(cns.get(i).flattenToString());
+                    cnsStr.append(", ");
+                }
+
+                // Remove last ", "
+                cnsStr.setLength(cnsStr.length() - 2);
+
+                throw new IllegalArgumentException("Found multiple instrumentations: "
+                        + cnsStr.toString());
+            }
+        }
+    }
+
+    /**
+     * Run the instrumentation.
+     */
+    public void run() throws Exception {
+        StatusReporter reporter = null;
+        float[] oldAnims = null;
+
+        try {
+            // Choose which output we will do.
+            if (proto) {
+                reporter = new ProtoStatusReporter();
+            } else if (wait) {
+                reporter = new TextStatusReporter(rawMode);
+            }
+
+            // Choose whether we have to wait for the results.
+            InstrumentationWatcher watcher = null;
+            UiAutomationConnection connection = null;
+            if (reporter != null) {
+                watcher = new InstrumentationWatcher(reporter);
+                connection = new UiAutomationConnection();
+            }
+
+            // Set the window animation if necessary
+            if (noWindowAnimation) {
+                oldAnims = mWm.getAnimationScales();
+                mWm.setAnimationScale(0, 0.0f);
+                mWm.setAnimationScale(1, 0.0f);
+            }
+
+            // Figure out which component we are tring to do.
+            final ComponentName cn = parseComponentName(componentNameArg);
+
+            // Choose an ABI if necessary
+            if (abi != null) {
+                final String[] supportedAbis = Build.SUPPORTED_ABIS;
+                boolean matched = false;
+                for (String supportedAbi : supportedAbis) {
+                    if (supportedAbi.equals(abi)) {
+                        matched = true;
+                        break;
+                    }
+                }
+                if (!matched) {
+                    throw new AndroidException(
+                            "INSTRUMENTATION_FAILED: Unsupported instruction set " + abi);
+                }
+            }
+
+            // Start the instrumentation
+            if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId,
+                        abi)) {
+                throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
+            }
+
+            // If we have been requested to wait, do so until the instrumentation is finished.
+            if (watcher != null) {
+                if (!watcher.waitForFinish()) {
+                    reporter.onError("INSTRUMENTATION_ABORTED: System has crashed.", false);
+                    return;
+                }
+            }
+        } catch (Exception ex) {
+            // Report failures
+            if (reporter != null) {
+                reporter.onError(ex.getMessage(), true);
+            }
+
+            // And re-throw the exception
+            throw ex;
+        } finally {
+            // Clean up
+            if (oldAnims != null) {
+                mWm.setAnimationScales(oldAnims);
+            }
+        }
+    }
+}
+
