DO NOT MERGE: cherry-pick https://review.source.android.com/14536 into tools_r6.

Original commit message:
------------
Attempt to fix intermittent ADT test run failures.

Change the ADT test run steps to be more deterministic:
1) Start the JDT test run listener server side connection before the client
side (this is invokked via the launch.addProcess call)
2) Don't fork off a separate thread to run the tests. This was always
redundant and inefficient anyway, since the AndroidLaunchController already
forks off a thread to perform the launch

Bug 7976

Change-Id: Ie237e7d83e1f5a945a2061506b7c302c04aef8d0
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchAction.java
index 2bde545..b398a05 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchAction.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchAction.java
@@ -25,6 +25,7 @@
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.debug.core.ILaunch;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchManager;
@@ -33,6 +34,7 @@
 import org.eclipse.jdt.junit.launcher.JUnitLaunchConfigurationDelegate;
 import org.eclipse.jdt.launching.IVMRunner;
 import org.eclipse.jdt.launching.VMRunnerConfiguration;
+import org.eclipse.swt.widgets.Display;
 
 /**
  * A launch action that executes a instrumentation test run on an Android device.
@@ -53,6 +55,8 @@
     /**
      * Launch a instrumentation test run on given Android device. 
      * Reuses JDT JUnit launch delegate so results can be communicated back to JDT JUnit UI.
+     * <p/>
+     * Note: Must be executed on non-UI thread.
      * 
      * @see IAndroidLaunchAction#doLaunchAction(DelayedLaunchInfo, IDevice)
      */
@@ -137,7 +141,7 @@
     }
 
     /**
-     * Provides a VM runner implementation which starts a thread implementation of a launch process
+     * Provides a VM runner implementation which starts a inline implementation of a launch process
      */
     private static class VMTestRunner implements IVMRunner {
         
@@ -156,15 +160,15 @@
             
             TestRunnerProcess runnerProcess = 
                 new TestRunnerProcess(config, mJUnitInfo);
-            runnerProcess.start();
             launch.addProcess(runnerProcess);
+            runnerProcess.run();
         }
     }
 
     /**
      * Launch process that executes the tests.
      */
-    private static class TestRunnerProcess extends Thread implements IProcess  {
+    private static class TestRunnerProcess implements IProcess  {
 
         private final VMRunnerConfiguration mRunConfig;
         private final AndroidJUnitLaunchInfo mJUnitInfo;
@@ -239,7 +243,7 @@
          * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
          */
         public boolean isTerminated() {
-            return mIsTerminated || isInterrupted();
+            return mIsTerminated;
         }
 
         /**
@@ -254,10 +258,18 @@
         } 
 
         /**
-         * Launches a test runner that will communicate results back to JDT JUnit UI
+         * Launches a test runner that will communicate results back to JDT JUnit UI.
+         * <p/>
+         * Must be executed on a non-UI thread.
          */
-        @Override
         public void run() {
+            if (Display.getCurrent() != null) {
+                AdtPlugin.log(IStatus.ERROR, "Adt test runner executed on UI thread");
+                AdtPlugin.printErrorToConsole(mJUnitInfo.getProject(),
+                        "Test launch failed due to internal error: Running tests on UI thread");
+                terminate();
+                return;
+            }
             mTestRunner = new RemoteAdtTestRunner();
             mTestRunner.runTests(mRunConfig.getProgramArguments(), mJUnitInfo);
         }