예제 #1
0
  private ChromiumTabInfo getChromiumTab(
      Process runtimeProcess,
      IBrowserTabChooser browserTabChooser,
      String host,
      int port,
      long maxStartupDelay,
      ListeningStream browserOutput)
      throws IOException, CoreException {
    // Give Chromium 20 seconds to start up.
    long endTime = System.currentTimeMillis() + Math.max(maxStartupDelay, 0L);
    while (true) {
      if (runtimeProcess != null && isProcessTerminated(runtimeProcess)) {
        throw new CoreException(
            new Status(
                IStatus.ERROR,
                SDBGDebugCorePlugin.PLUGIN_ID,
                "Could not launch browser - process terminated while trying to connect. "
                    + "Try closing any running Chrome instances."
                    + getProcessStreamMessage(browserOutput.toString())));
      }

      try {
        ChromiumTabInfo targetTab =
            (ChromiumTabInfo)
                findTargetTab(browserTabChooser, ChromiumConnector.getAvailableTabs(host, port));
        if (targetTab != null || System.currentTimeMillis() > endTime && runtimeProcess == null) {
          return targetTab;
        }
      } catch (IOException exception) {
        if (System.currentTimeMillis() > endTime) {
          throw exception;
        }
      }

      if (runtimeProcess != null && System.currentTimeMillis() > endTime) {
        throw new IOException("Timed out trying to connect to Chrome");
      }

      sleep(25);
    }
  }
예제 #2
0
  private ChromiumTabInfo getChromiumTab(
      Process runtimeProcess, int devToolsPortNumber, ListeningStream dartiumOutput)
      throws IOException, CoreException {
    // Give Chromium 20 seconds to start up.
    final int maxStartupDelay = 20 * 1000;

    long endTime = System.currentTimeMillis() + maxStartupDelay;

    while (true) {
      if (isProcessTerminated(runtimeProcess)) {
        throw new CoreException(
            new Status(
                IStatus.ERROR,
                DartDebugCorePlugin.PLUGIN_ID,
                "Could not launch browser - process terminated while trying to connect"
                    + getProcessStreamMessage(dartiumOutput.toString())));
      }

      try {
        List<ChromiumTabInfo> tabs = ChromiumConnector.getAvailableTabs(devToolsPortNumber);

        ChromiumTabInfo targetTab = findTargetTab(tabs);

        if (targetTab != null) {
          return targetTab;
        }
      } catch (IOException exception) {
        if (System.currentTimeMillis() > endTime) {
          throw exception;
        }
      }

      if (System.currentTimeMillis() > endTime) {
        throw new IOException("Timed out trying to connect to Dartium");
      }

      sleep(25);
    }
  }
예제 #3
0
  /** Launch browser and open file url. If debug mode also connect to browser. */
  void connectToChromiumDebug(
      File executable,
      String browserName,
      ILaunch launch,
      DartLaunchConfigWrapper launchConfig,
      String url,
      IProgressMonitor monitor,
      Process runtimeProcess,
      LogTimer timer,
      boolean enableBreakpoints,
      int devToolsPortNumber,
      ListeningStream dartiumOutput,
      String processDescription)
      throws CoreException {
    monitor.worked(1);

    try {
      // avg: 383ms
      timer.startTask("get chromium tabs");

      ChromiumTabInfo chromiumTab =
          getChromiumTab(runtimeProcess, devToolsPortNumber, dartiumOutput);

      monitor.worked(2);

      timer.stopTask();

      // avg: 46ms
      timer.startTask("open WIP connection");

      if (chromiumTab == null) {
        throw new DebugException(
            new Status(
                IStatus.ERROR, DartDebugCorePlugin.PLUGIN_ID, "Unable to connect to Dartium"));
      }

      if (chromiumTab == null || chromiumTab.getWebSocketDebuggerUrl() == null) {
        throw new DebugException(
            new Status(
                IStatus.ERROR, DartDebugCorePlugin.PLUGIN_ID, "Unable to connect to Chromium"));
      }

      WebkitConnection connection = new WebkitConnection(chromiumTab.getWebSocketDebuggerUrl());

      final DartiumDebugTarget debugTarget =
          new DartiumDebugTarget(
              executable,
              browserName,
              connection,
              launch,
              runtimeProcess,
              getResourceServer(),
              enableBreakpoints);

      monitor.worked(1);

      launch.setAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING, "UTF-8");
      launch.addDebugTarget(debugTarget);
      launch.addProcess(debugTarget.getProcess());
      debugTarget.getProcess().setAttribute(IProcess.ATTR_CMDLINE, processDescription);

      if (launchConfig.getShowLaunchOutput()) {
        dartiumOutput.setListener(
            new StreamListener() {
              @Override
              public void handleStreamData(String data) {
                debugTarget.writeToStdout(data);
              }
            });
      }

      debugTarget.openConnection(url);

      timer.stopTask();
    } catch (IOException e) {
      DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);

      IStatus status;

      // Clean up the error message on certain connection failures to Dartium.
      // http://code.google.com/p/dart/issues/detail?id=4435
      if (e.toString().indexOf("connection failed: unknown status code 500") != -1) {
        DartDebugCorePlugin.logError(e);

        status =
            new Status(
                IStatus.ERROR, DartDebugCorePlugin.PLUGIN_ID, "Unable to connect to Dartium");
      } else {
        status = new Status(IStatus.ERROR, DartDebugCorePlugin.PLUGIN_ID, e.toString(), e);
      }

      throw new CoreException(status);
    }

    if (firstLaunch) {
      firstLaunch = false;
    }

    monitor.worked(1);
  }
예제 #4
0
  protected void launchBrowser(
      ILaunch launch,
      DartLaunchConfigWrapper launchConfig,
      IFile file,
      String url,
      IProgressMonitor monitor,
      boolean enableDebugging)
      throws CoreException {

    // For now, we always start a debugging connection, even when we're not really debugging.
    boolean enableBreakpoints = enableDebugging;

    monitor.beginTask("Launching Dartium...", enableDebugging ? 7 : 2);

    File dartium = DartSdkManager.getManager().getSdk().getDartiumExecutable();

    if (dartium == null) {
      throw new CoreException(
          new Status(IStatus.ERROR, DartDebugCorePlugin.PLUGIN_ID, "Could not find Dartium"));
    }

    IPath browserLocation = new Path(dartium.getAbsolutePath());

    String browserName = dartium.getName();

    // avg: 0.434 sec (old: 0.597)
    LogTimer timer = new LogTimer("Dartium debug startup");

    // avg: 55ms
    timer.startTask(browserName + " startup");

    url = resolveLaunchUrl(file, url);

    // for now, check if browser is open, and connection is alive
    boolean restart =
        browserProcess == null
            || isProcessTerminated(browserProcess)
            || DartiumDebugTarget.getActiveTarget() == null
            || !DartiumDebugTarget.getActiveTarget().canTerminate();

    if (!restart) {
      DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);

      try {
        DartiumDebugTarget.getActiveTarget().navigateToUrl(url, enableBreakpoints);
      } catch (IOException e) {
        DartDebugCorePlugin.logError(e);
      }
    } else {
      terminateExistingBrowserProcess();

      StringBuilder processDescription = new StringBuilder();

      ListeningStream dartiumOutput =
          startNewBrowserProcess(
              launchConfig,
              url,
              monitor,
              enableDebugging,
              browserLocation,
              browserName,
              processDescription);

      sleep(100);

      monitor.worked(1);

      if (isProcessTerminated(browserProcess)) {
        DartDebugCorePlugin.logError("Dartium output: " + dartiumOutput.toString());

        throw new CoreException(
            new Status(
                IStatus.ERROR,
                DartDebugCorePlugin.PLUGIN_ID,
                "Could not launch browser - process terminated on startup"
                    + getProcessStreamMessage(dartiumOutput.toString())));
      }

      connectToChromiumDebug(
          dartium,
          browserName,
          launch,
          launchConfig,
          url,
          monitor,
          browserProcess,
          timer,
          enableBreakpoints,
          devToolsPortNumber,
          dartiumOutput,
          processDescription.toString());
    }

    DebugUIHelper.getHelper().activateApplication(dartium, "Chromium");

    timer.stopTask();
    timer.stopTimer();
    monitor.done();
  }
예제 #5
0
  private WebkitDebugTarget connectToChromiumDebug(
      String browserName,
      ILaunch launch,
      SDBGLaunchConfigWrapper launchConfig,
      String url,
      IProgressMonitor monitor,
      Process runtimeProcess,
      LogTimer timer,
      boolean enableBreakpoints,
      String host,
      int port,
      long maxStartupDelay,
      ListeningStream browserOutput,
      String processDescription,
      IResourceResolver resolver,
      IBrowserTabChooser browserTabChooser,
      boolean remote)
      throws CoreException {
    monitor.worked(1);

    // avg: 383ms
    timer.startTask("get chromium tabs");

    ChromiumTabInfo tab;

    try {
      tab =
          getChromiumTab(
              runtimeProcess, browserTabChooser, host, port, maxStartupDelay, browserOutput);
    } catch (IOException e) {
      SDBGDebugCorePlugin.logError(e);
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              SDBGDebugCorePlugin.PLUGIN_ID,
              "Unable to connect to Chrome at address "
                  + (host != null ? host : "")
                  + ":"
                  + port
                  + "; error: "
                  + e.getMessage(),
              e));
    }

    monitor.worked(2);

    timer.stopTask();

    // avg: 46ms
    timer.startTask("open WIP connection");

    if (tab == null) {
      throw new DebugException(
          new Status(
              IStatus.INFO,
              SDBGDebugCorePlugin.PLUGIN_ID,
              "No Chrome tab was chosen. Connection cancelled."));
    }

    if (tab.getWebSocketDebuggerUrl() == null) {
      throw new DebugException(
          new Status(
              IStatus.ERROR,
              SDBGDebugCorePlugin.PLUGIN_ID,
              "Unable to connect to Chrome"
                  + (remote
                      ? ".\n\nPossible reason: another debugger (e.g. Chrome DevTools) or another Eclipse debugging session is already attached to that particular Chrome tab."
                      : "")));
    }

    // Even when Chrome has reported all the debuggable tabs to us, the debug server
    // may not yet have started up. Delay a small fixed amount of time.
    sleep(100);

    if (resolver == null) {
      resolver = createResourceResolver(launch, launchConfig.getConfig(), tab);
    }

    try {
      WebkitConnection connection =
          new WebkitConnection(tab.getHost(), tab.getPort(), tab.getWebSocketDebuggerFile());

      final WebkitDebugTarget debugTarget =
          new WebkitDebugTarget(
              browserName,
              connection,
              launch,
              runtimeProcess,
              launchConfig.getProject(),
              resolver,
              adbManager,
              enableBreakpoints,
              remote);

      monitor.worked(1);

      registerProcess(launch, launchConfig, debugTarget.getProcess(), processDescription);
      launch.addDebugTarget(debugTarget);

      if (browserOutput != null && launchConfig.getShowLaunchOutput()) {
        browserOutput.setListener(
            new StreamListener() {
              @Override
              public void handleStreamData(String data) {
                debugTarget.writeToStdout(data);
              }
            });
      }

      if (browserOutput != null) {
        debugTarget.openConnection(url, true);
      } else {
        debugTarget.openConnection();
      }

      trace("Connected to WIP debug agent on host " + host + " and port " + port);

      timer.stopTask();

      monitor.worked(1);

      return debugTarget;
    } catch (IOException e) {
      SDBGDebugCorePlugin.logError(e);
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              SDBGDebugCorePlugin.PLUGIN_ID,
              "Unable to connect to Chrome tab at address "
                  + (tab.getHost() != null ? tab.getHost() : "")
                  + ":"
                  + tab.getPort()
                  + " ("
                  + tab.getWebSocketDebuggerFile()
                  + "): "
                  + e.getMessage(),
              e));
    }
  }
예제 #6
0
  public void launchBrowser(
      ILaunch launch,
      ILaunchConfiguration configuration,
      IResourceResolver resourceResolver,
      IBrowserTabChooser browserTabChooser,
      String url,
      IProgressMonitor monitor,
      boolean enableDebugging,
      List<String> extraCommandLineArgs)
      throws CoreException {
    try {
      if (launchSemaphore.tryAcquire()) {
        try {
          SDBGLaunchConfigWrapper launchConfig = new SDBGLaunchConfigWrapper(configuration);
          launchConfig.markAsLaunched();

          monitor.beginTask("Launching Chrome...", enableDebugging ? 7 : 2);

          // avg: 0.434 sec (old: 0.597)
          LogTimer timer = new LogTimer("Chrome debug startup");

          // avg: 55ms
          timer.startTask("Chrome startup");

          // for now, check if browser is open, and connection is alive
          boolean restart =
              browserProcess == null
                  || isProcessTerminated(browserProcess)
                  || WebkitDebugTarget.getActiveTarget() == null
                  || !WebkitDebugTarget.getActiveTarget().canTerminate();

          // we only re-cycle the debug connection if we're launching the same launch configuration
          if (!restart) {
            if (!WebkitDebugTarget.getActiveTarget()
                .getLaunch()
                .getLaunchConfiguration()
                .equals(launch.getLaunchConfiguration())) {
              restart = true;
            }
          }

          if (!restart) {
            if (enableDebugging != WebkitDebugTarget.getActiveTarget().getEnableBreakpoints()) {
              restart = true;
            }
          }

          CoreLaunchUtils.removeTerminatedLaunches();

          File browserExecutable = getBrowserExecutable();

          if (!restart && url != null && resourceResolver != null) {
            DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);

            try {
              WebkitDebugTarget.getActiveTarget()
                  .navigateToUrl(
                      launch.getLaunchConfiguration(),
                      url,
                      true /*enableBreakpoints*/,
                      resourceResolver);
            } catch (IOException e) {
              SDBGDebugCorePlugin.logError(e);
            }
          } else {
            terminateExistingBrowserProcess();

            StringBuilder processDescription = new StringBuilder();

            int[] devToolsPortNumberHolder = new int[1];
            ListeningStream browserOutput =
                startNewBrowserProcess(
                    launchConfig,
                    url,
                    monitor,
                    enableDebugging,
                    processDescription,
                    extraCommandLineArgs,
                    devToolsPortNumberHolder);

            sleep(100);

            monitor.worked(1);

            if (isProcessTerminated(browserProcess)) {
              SDBGDebugCorePlugin.logError("Browser output: " + browserOutput.toString());

              throw new CoreException(
                  new Status(
                      IStatus.ERROR,
                      SDBGDebugCorePlugin.PLUGIN_ID,
                      "Could not launch browser - process terminated on startup"
                          + getProcessStreamMessage(browserOutput.toString())));
            }

            if (enableDebugging) {
              connectToChromiumDebug(
                  browserExecutable.getName(),
                  launch,
                  launchConfig,
                  url,
                  monitor,
                  browserProcess,
                  timer,
                  true /*enableBreakpoints*/,
                  null,
                  devToolsPortNumberHolder[0],
                  20 * 1000L /*maxStartupDelay*/,
                  browserOutput,
                  processDescription.toString(),
                  resourceResolver,
                  browserTabChooser,
                  false /*remote*/);
            } else {
              registerProcess(
                  launch,
                  launchConfig,
                  DebugPlugin.newProcess(
                      launch,
                      browserProcess,
                      browserExecutable.getName()
                          + " - run only, debugging DISABLED ("
                          + new Date()
                          + ")"),
                  processDescription.toString());
            }
          }

          DebugUIHelper.getHelper().activateApplication(browserExecutable, "Chrome");

          timer.stopTask();
          timer.stopTimer();
          monitor.done();
        } finally {
          launchSemaphore.release();
        }
      }
    } catch (CoreException e) {
      DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);
      throw e;
    }
  }