// A convenient method to be called by another activity.
  private void runTestAndWaitUntilDone(TestShellActivity activity, String url, int timeout) {
    activity.setCallback(
        new TestShellCallback() {
          @Override
          public void finished() {
            synchronized (LoadTestsAutoTest.this) {
              mFinished = true;
              LoadTestsAutoTest.this.notifyAll();
            }
          }

          @Override
          public void timedOut(String url) {}

          @Override
          public void dumpResult(String webViewDump) {
            String lines[] = webViewDump.split("\\r?\\n");
            for (String line : lines) {
              line = line.trim();
              // parse for a line like this:
              // totals:   9620.00 11947.00    10099.75    380.38
              // and return the 3rd number, which is mean
              if (line.startsWith("totals:")) {
                line = line.substring(7).trim(); // strip "totals:"
                String[] numbers = line.split("\\s+");
                if (numbers.length == 4) {
                  Bundle b = new Bundle();
                  b.putString("mean", numbers[2]);
                  getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, b);
                }
              }
            }
          }
        });

    mFinished = false;
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setClass(activity, TestShellActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    intent.putExtra(TestShellActivity.TEST_URL, url);
    intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout);
    intent.putExtra(TestShellActivity.RESULT_FILE, LOAD_TEST_RESULT);
    activity.startActivity(intent);

    // Wait until done.
    synchronized (this) {
      while (!mFinished) {
        try {
          this.wait();
        } catch (InterruptedException e) {
        }
      }
    }
  }
  // Invokes running of layout tests
  // and waits till it has finished running.
  public void runPageCyclerTest() throws IOException {
    LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();

    if (runner.mPageCyclerSuite != null) {
      // start forwarder to use page cycler suites hosted on external web server
      if (runner.mPageCyclerForwardHost == null) {
        throw new RuntimeException("no forwarder information provided");
      }
      runner.mTestPath =
          setUpForwarding(
              runner.mPageCyclerForwardHost, runner.mPageCyclerSuite, runner.mPageCyclerIteration);
      Log.d(LOGTAG, "using path: " + runner.mTestPath);
    }

    if (runner.mTestPath == null) {
      throw new RuntimeException("No test specified");
    }

    final TestShellActivity activity = (TestShellActivity) getActivity();

    Log.v(LOGTAG, "About to run tests, calling gc first...");
    freeMem();

    // Run tests
    runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis);

    getInstrumentation()
        .runOnMainSync(
            new Runnable() {

              @Override
              public void run() {
                activity.clearCache();
              }
            });
    if (mForwardServer != null) {
      mForwardServer.stop();
      mForwardServer = null;
    }
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
    }
    dumpMemoryInfo();

    // Kill activity
    activity.finish();
  }