/** * Starts pub serve for a given launch configuration. Checks if the current pub serve is for the * same pubspec.yaml, if not then starts up pub serve. * * @param wrapper - the launch config wrapper * @return - true if pub serve starts */ public boolean startPubServe(DartLaunchConfigWrapper wrapper) { // TODO(keertip): output to process console console = DartCore.getConsole(); if (currentLaunch != null) { IResource resource = currentLaunch.getApplicationResource(); if (resource != null) { // check if previous launch and new launch share the same pubspec. If so, and pub serve is // running, then current pub serve can be used. IContainer appDir = DartCore.getApplicationDirectory(resource); if (appDir.equals(DartCore.getApplicationDirectory(wrapper.getApplicationResource()))) { // TODO(keertip): make this separate checks so that new connection can be started without // starting new process if (process != null && !isTerminated() && pubConnection != null && pubConnection.isConnected()) { console.printSeparator("Starting pub serve : " + resource.getProject().getName()); // make sure pub is serving the directory, send serve directory command boolean isServed = serveDirectory(wrapper.getApplicationResource()); if (isServed) { currentLaunch = wrapper; return true; } } } } } // terminate existing pub serve if any dispose(); return runPubServe(wrapper); }
private List<String> buildArgumentsList( DartLaunchConfigWrapper launchConfig, IPath browserLocation, String url, boolean enableDebugging, int devToolsPortNumber) { List<String> arguments = new ArrayList<String>(); arguments.add(browserLocation.toOSString()); // Enable remote debug over HTTP on the specified port. arguments.add("--remote-debugging-port=" + devToolsPortNumber); // In order to start up multiple Chrome processes, we need to specify a different user dir. arguments.add("--user-data-dir=" + getCreateUserDataDirectoryPath()); // Indicates that the browser is in "browse without sign-in" (Guest session) mode. Should // completely disable extensions, sync and bookmarks. // devoncarew: This only works under _CHROMEOS. // arguments.add("--bwsi"); // Several extensions in the wild have errors that prevent connecting the debugger to Dartium. // arguments.add("--disable-extensions"); // Disables syncing browser data to a Google Account. Do we want to do this? // arguments.add("--disable-sync"); if (launchConfig.getUseWebComponents()) { arguments.add("--enable-experimental-webkit-features"); arguments.add("--enable-devtools-experiments"); } // Whether or not it's actually the first run. arguments.add("--no-first-run"); // Disables the default browser check. arguments.add("--no-default-browser-check"); // Bypass the error dialog when the profile lock couldn't be attained. arguments.add("--no-process-singleton-dialog"); for (String arg : launchConfig.getArgumentsAsArray()) { arguments.add(arg); } // Causes the browser to launch directly into incognito mode. // We use this to prevent the previous session's tabs from re-opening. // arguments.add("--incognito"); if (enableDebugging) { // Start up with a blank page. arguments.add(INITIAL_PAGE); } else { arguments.add(url); } return arguments; }
private boolean runPubServe(DartLaunchConfigWrapper wrapper) { stdOut = new StringBuilder(); stdError = new StringBuilder(); IResource resource = wrapper.getApplicationResource(); console.printSeparator("Starting pub serve : " + resource.getProject().getName()); workingDir = DartCore.getApplicationDirectory(resource); List<String> args = buildPubServeCommand(); String dirName = getPubserveRootDir(workingDir, resource); if (dirName != null) { args.add(getPubserveRootDir(workingDir, resource)); } ProcessBuilder builder = new ProcessBuilder(); builder.command(args); builder.directory(workingDir.getLocation().toFile()); try { process = builder.start(); } catch (IOException e) { DartCore.logError(e); return false; } Thread stdoutThread = new Thread( new Runnable() { @Override public void run() { copyStream(process.getInputStream(), stdOut, true); } }); stdoutThread.start(); Thread stderrThread = new Thread( new Runnable() { @Override public void run() { copyStream(process.getErrorStream(), stdError, true); } }); stderrThread.start(); while (!isTerminated() && !stdOut.toString().contains(LOCAL_HOST_ADDR)) { try { Thread.sleep(200); } catch (Exception exception) { } } if (isTerminated()) { return false; } currentLaunch = wrapper; return true; }
private boolean sendGetUrlCommand(PubCallback<String> callback) { PubCommands command = pubConnection.getCommands(); try { command.pathToUrl(getPathFromWorkingDir(currentLaunch.getApplicationResource()), callback); } catch (IOException e) { DartDebugCorePlugin.logError(e); return false; } return true; }
/** * @param launchConfig * @param url * @param monitor * @param enableDebugging * @param browserLocation * @param browserName * @throws CoreException */ private ListeningStream startNewBrowserProcess( DartLaunchConfigWrapper launchConfig, String url, IProgressMonitor monitor, boolean enableDebugging, IPath browserLocation, String browserName, StringBuilder argDescription) throws CoreException { Process process = null; monitor.worked(1); ProcessBuilder builder = new ProcessBuilder(); Map<String, String> env = builder.environment(); // Due to differences in 32bit and 64 bit environments, dartium 32bit launch does not work on // linux with this property. env.remove("LD_LIBRARY_PATH"); // Add the environment variable DART_FLAGS="--enable-checked-mode" // to enable asserts and type checks if (launchConfig.getCheckedMode()) { env.put("DART_FLAGS", "--enable-checked-mode"); } // Pass in --package-root if the preference is set String packageRoot = DartCore.getPlugin().getPackageRootPref(); // TODO(keertip): if using default "packages" directory, do not set env variable // TODO(devoncarew): why are we only passing package root in when launching a file (not a url)? if (packageRoot != null && launchConfig.getShouldLaunchFile()) { try { String packageRootUri = getResourceServer().getUrlForFile(new Path(packageRoot).toFile()); // Strip a trailing slash off the uri if the user setting didn't have one. if (!packageRoot.endsWith("/") && packageRootUri.endsWith("/")) { packageRootUri = packageRootUri.substring(0, packageRootUri.length() - 1); } env.put("DART_PACKAGE_ROOT", packageRootUri); } catch (IOException e) { DartDebugCorePlugin.logError(e); } } // This flag allows us to retrieve the dart: core sources from Dartium. env.put("DART_DEBUG_LIBS", "true"); devToolsPortNumber = DEVTOOLS_PORT_NUMBER; if (enableDebugging) { devToolsPortNumber = NetUtils.findUnusedPort(DEVTOOLS_PORT_NUMBER); if (devToolsPortNumber == -1) { throw new CoreException( new Status( IStatus.ERROR, DartDebugCorePlugin.PLUGIN_ID, "Unable to locate an available port for the Dartium debugger")); } } List<String> arguments = buildArgumentsList(launchConfig, browserLocation, url, enableDebugging, devToolsPortNumber); builder.command(arguments); builder.directory(DartSdkManager.getManager().getSdk().getDartiumWorkingDirectory()); builder.redirectErrorStream(true); describe(arguments, argDescription); try { process = builder.start(); } catch (IOException e) { DartDebugCorePlugin.logError("Exception while starting Dartium", e); throw new CoreException( new Status( IStatus.ERROR, DartDebugCorePlugin.PLUGIN_ID, "Could not launch browser: " + e.toString())); } browserProcess = process; return readFromProcessPipes(browserName, browserProcess.getInputStream()); }
/** 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); }