![JAR search and dependency download from the Maven repository](/logo.png)
flash.tools.debugger.concrete.PlayerSessionManager Maven / Gradle / Ivy
The newest version!
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 flash.tools.debugger.concrete; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.BindException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import flash.localization.LocalizationManager; import flash.tools.debugger.AIRLaunchInfo; import flash.tools.debugger.DebuggerLocalizer; import flash.tools.debugger.DefaultDebuggerCallbacks; import flash.tools.debugger.IDebuggerCallbacks; import flash.tools.debugger.ILaunchNotification; import flash.tools.debugger.ILauncher; import flash.tools.debugger.IProgress; import flash.tools.debugger.Player; import flash.tools.debugger.Session; import flash.tools.debugger.SessionManager2; import flash.tools.debugger.VersionException; import flash.util.URLHelper; public class PlayerSessionManager implements SessionManager2 { private ServerSocket m_serverSocket; private HashMap
that also has an argument * indicating that the process we are waiting for has terminated. * * @param pl * Optional process listener. If non-null, this is used to detect * if a process that was launched has terminated unexpectedly. * For example, if launch() launches adl, but adl exits, then we * don't want to continue to wait for a socket connection. */ private Session accept(ProcessListener pl, IProgress waitReporter) throws IOException { // get timeout int timeout = getPreference(PREF_ACCEPT_TIMEOUT); int totalTimeout = timeout; int iterateOn = 100; PlayerSession session = null; try { m_serverSocket.setSoTimeout(iterateOn); // Wait 100ms per iteration. We have to do that so that we can report how long // we have been waiting. Socket s = null; while (s == null && !airAppTerminated(pl)) { try { s = m_serverSocket.accept(); } catch(IOException ste) { timeout -= iterateOn; if (timeout < 0 || m_serverSocket == null || m_serverSocket.isClosed()) throw ste; // we reached the timeout, or someome called stopListening() } // Tell the progress monitor we've waited a little while longer, // so that the Eclipse progress bar can keep chugging along if (waitReporter != null) waitReporter.setProgress(totalTimeout - timeout, totalTimeout); } if (s == null && airAppTerminated(pl)) { throw pl.createLaunchFailureException(); } /* create a new session around this socket */ session = PlayerSession.createFromSocketWithOptions(s, m_debuggerCallbacks, this); // transfer preferences session.setPreferences(m_prefs); } catch(NullPointerException npe) { throw new BindException(getLocalizationManager().getLocalizedTextString("serverSocketNotListening")); //$NON-NLS-1$ } return session; } /** * Returns true if the passed-in process listener is for an AIR application * that has terminated. This is used by accept() in order to detect that it * should give up listening on the socket. * * The reason we can't do this for Flash player-based apps is that unlike * AIR apps, the process that we launched sometimes acts as just sort of a * "launcher" process that terminates quickly, and the actual Flash player * is in some other process. For example, on Mac, we often invoke the "open" * program to open a web browser; and on Windows, if you launch firefox.exe * but it detects that there is already a running instance of firefox.exe, * the new instance will just pass a message to the old instance, and then * the new instance will terminate. * * @param pl * a process listener, orm_prefs; private IDebuggerCallbacks m_debuggerCallbacks; private static LocalizationManager m_localizationManager; private Socket m_connectSocket; private boolean m_cancelConnect; static { // set up for localizing messages m_localizationManager = new LocalizationManager(); m_localizationManager.addLocalizer( new DebuggerLocalizer("flash.tools.debugger.concrete.djapi.") ); //$NON-NLS-1$ } public PlayerSessionManager() { m_debuggerCallbacks = new DefaultDebuggerCallbacks(); m_serverSocket = null; m_connectSocket = null; m_cancelConnect = false; m_prefs = new HashMap (); // manager setPreference(PREF_ACCEPT_TIMEOUT, 120000); // 2 minutes setPreference(PREF_URI_MODIFICATION, 1); setPreference(PREF_CONNECT_TIMEOUT, 120000); // 2 minutes setPreference(PREF_CONNECT_WAIT_INTERVAL, 250); // 0.25 seconds setPreference(PREF_CONNECT_RETRY_ATTEMPTS, -1); // Retry till timeout // session // response to requests setPreference(PREF_SOCKET_TIMEOUT, -1); // no timeout by default setPreference(PREF_RESPONSE_TIMEOUT, 750); // 0.75s setPreference(PREF_CONTEXT_RESPONSE_TIMEOUT, 1000); // 1s setPreference(PREF_GETVAR_RESPONSE_TIMEOUT, 1500); // 1.5s setPreference(PREF_SETVAR_RESPONSE_TIMEOUT, 5000); // 5s setPreference(PREF_SWFSWD_LOAD_TIMEOUT, 5000); // 5s // wait for a suspend to occur after a halt setPreference(PREF_SUSPEND_WAIT, 7000); // invoke getters by default setPreference(PREF_INVOKE_GETTERS, 1); // hierarchical variables view setPreference(PREF_HIERARCHICAL_VARIABLES, 0); } /** * Set preference * If an invalid preference is passed, it will be silently ignored. */ public void setPreference(String pref, int value) { m_prefs.put(pref, Integer.valueOf(value)); } public void setPreference(String pref, String value){ m_prefs.put(pref, value); } public Set keySet() { return m_prefs.keySet(); } public Object getPreferenceAsObject(String pref) { return m_prefs.get(pref); } /* * @see flash.tools.debugger.SessionManager#getPreference(java.lang.String) */ public int getPreference(String pref) { int val = 0; Integer i = (Integer)m_prefs.get(pref); if (i == null) throw new NullPointerException(); val = i.intValue(); return val; } /* * @see flash.tools.debugger.SessionManager#startListening() */ public void startListening() throws IOException { if (m_serverSocket == null) m_serverSocket = new ServerSocket(DProtocol.DEBUG_PORT); } /* * @see flash.tools.debugger.SessionManager#stopListening() */ public void stopListening() throws IOException { if (m_serverSocket != null) { m_serverSocket.close(); m_serverSocket = null; } } /* * @see flash.tools.debugger.SessionManager#isListening() */ public boolean isListening() { return (m_serverSocket == null) ? false : true; } private class LaunchInfo { private String m_uri; public LaunchInfo(String uri) { m_uri = uri; } public boolean isAbout() { return m_uri.startsWith("about:"); //$NON-NLS-1$ } public boolean isHttpOrAbout() { return m_uri.startsWith("http:") || m_uri.startsWith("https:") || isAbout(); //$NON-NLS-1$ //$NON-NLS-2$ } public boolean isWebPage() { return isHttpOrAbout() || m_uri.endsWith(".htm") || m_uri.endsWith(".html"); //$NON-NLS-1$ //$NON-NLS-2$ } public boolean isWebBrowserNativeLaunch() { return isWebPage() && (m_debuggerCallbacks.getHttpExe() != null); } public boolean isPlayerNativeLaunch() { return m_uri.length() > 0 && !isWebPage() && (m_debuggerCallbacks.getPlayerExe() != null); } public boolean isAIRLaunch() { return m_uri.startsWith("file:") && (m_uri.endsWith("-app.xml") || m_uri.endsWith("application.xml")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } private enum OS { Mac, Windows, Unix } private OS getOS() { String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ if (osName.startsWith("mac os x")) //$NON-NLS-1$ { return OS.Mac; } else if (osName.startsWith("windows")) //$NON-NLS-1$ { return OS.Windows; } else { return OS.Unix; } } /* * @see flash.tools.debugger.SessionManager#launch(java.lang.String, flash.tools.debugger.AIRLaunchInfo, boolean, flash.tools.debugger.IProgress) */ public Session launch(String uri, AIRLaunchInfo airLaunchInfo, boolean forDebugging, IProgress waitReporter, ILaunchNotification launchNotification) throws IOException { String[] launchCommand = getLaunchCommand(uri, airLaunchInfo,forDebugging); // create the process and attach a thread to watch it during our accept phase Process proc = m_debuggerCallbacks.launchDebugTarget(launchCommand); ProcessListener processListener = startProcessListener(airLaunchInfo,forDebugging, launchNotification, launchCommand, proc,false); PlayerSession session = null; if (forDebugging) { session = waitForConnection(uri, airLaunchInfo, waitReporter, proc, processListener); } return session; } private PlayerSession waitForConnection(String uri, AIRLaunchInfo airLaunchInfo, IProgress waitReporter, Process proc, ProcessListener pl) throws IOException { /* now wait for a connection */ PlayerSession session = (PlayerSession)accept(pl, waitReporter); session.setProcess(proc); session.setLaunchUrl(uri); session.setAIRLaunchInfo(airLaunchInfo); return session; } /** * Tweaks the launch URI if necessary, e.g. may append "?debug=true" */ private String tweakNativeLaunchUri(String uri, boolean forDebugging, LaunchInfo launchInfo) throws IOException, FileNotFoundException { // first let's see if it's an HTTP URL or not if (launchInfo.isHttpOrAbout()) { boolean modify = (getPreference(PREF_URI_MODIFICATION) != 0); if (modify && forDebugging && !launchInfo.isAbout()) { // escape spaces if we have any uri = URLHelper.escapeSpace(uri); // be sure that ?debug=true is included in query string URLHelper urlHelper = new URLHelper(uri); Map params = urlHelper.getParameterMap(); params.put("debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$ urlHelper.setParameterMap(params); uri = urlHelper.getURL(); } } else { // ok, its not an http: type request therefore we should be able to see // it on the file system, right? If not then it's probably not valid File f = null; if (uri.startsWith("file:")) //$NON-NLS-1$ { try { f = new File(new URI(uri)); } catch (URISyntaxException e) { IOException ioe = new IOException(e.getMessage()); ioe.initCause(e); throw ioe; } } else { f = new File(uri); } if (f.exists()) { // Do not use getCanonicalPath() -- see FB-24595 uri = f.getAbsolutePath(); } else { throw new FileNotFoundException(uri); } } return uri; } /** * Gets the arguments needed for launching a swf that needs to run * in a web browser or the standalone player. */ private String[] getFlashLaunchArgs(String uri, LaunchInfo launchInfo) throws FileNotFoundException { String[] launchCommand; OS os = getOS(); /** * Various ways to launch this stupid thing. If we have the exe * values for the player, then we can launch it directly, monitor * it and kill it when we die; otherwise we launch it through * a command shell (cmd.exe, open, or bash) and our Process object * dies right away since it spawned another process to run the * Player within. */ if (os == OS.Mac) { if (launchInfo.isWebBrowserNativeLaunch()) { File httpExe = m_debuggerCallbacks.getHttpExe(); String[] customParams = m_debuggerCallbacks.getBrowserParameters(uri); if (customParams == null) { launchCommand = new String[] { "/usr/bin/open", "-a", httpExe.toString(), uri }; //$NON-NLS-1$ //$NON-NLS-2$ } else { final int prependLen = 4; launchCommand = new String[customParams.length + prependLen ]; launchCommand[0] = "/usr/bin/open"; //$NON-NLS-1$ launchCommand[1] = "-a"; //$NON-NLS-1$ launchCommand[2] = httpExe.toString(); launchCommand[3] = "--args"; //$NON-NLS-1$ for ( int i = 0; i < customParams.length; i++) { launchCommand[i + prependLen] = customParams[i]; } } } else if (launchInfo.isPlayerNativeLaunch()) { File playerExe = m_debuggerCallbacks.getPlayerExe(); launchCommand = new String[] { "/usr/bin/open", "-a", playerExe.toString(), uri }; //$NON-NLS-1$ //$NON-NLS-2$ } else { launchCommand = new String[] { "/usr/bin/open", uri }; //$NON-NLS-1$ } } else // Windows or *nix { if (launchInfo.isWebBrowserNativeLaunch()) { File httpExe = m_debuggerCallbacks.getHttpExe(); String[] customParams = m_debuggerCallbacks.getBrowserParameters(uri); if (customParams == null) { if (os == OS.Windows) launchCommand = getWindowsBrowserLaunchArgs(httpExe, uri); else launchCommand = new String[] { httpExe.toString(), uri }; } else { final int prependLen = 1; launchCommand = new String[customParams.length + prependLen]; launchCommand[0] = httpExe.toString(); for ( int i = 0; i < customParams.length; i++) { launchCommand[i + prependLen] = customParams[i]; } } } else if (launchInfo.isPlayerNativeLaunch()) { File playerExe = m_debuggerCallbacks.getPlayerExe(); launchCommand = new String[] { playerExe.toString(), uri }; } else { if (os == OS.Windows) { // We must quote all ampersands in the URL; if we don't, then // cmd.exe will interpret the ampersand as a command separator. uri = uri.replaceAll("&", "\"&\""); //$NON-NLS-1$ //$NON-NLS-2$ launchCommand = new String[] { "cmd", "/c", "start", uri }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else { String exeName; if (launchInfo.isWebPage()) exeName = m_debuggerCallbacks.getHttpExeName(); else exeName = m_debuggerCallbacks.getPlayerExeName(); throw new FileNotFoundException(exeName); } } } return launchCommand; } /** * Gets the arguments needed for launching a web browser on Windows. */ private String[] getWindowsBrowserLaunchArgs(File httpExe, String uri) { if (httpExe.getName().equalsIgnoreCase("chrome.exe")) //$NON-NLS-1$ { // FB-16779: Adding "--disable-hang-monitor" to prevent Chrome // from warning us that a plug-inappears to be hung; it does // that when the user hits a breakpoint. return new String[] { httpExe.toString(), "--disable-hang-monitor", uri }; //$NON-NLS-1$ } else if (httpExe.getName().equalsIgnoreCase("iexplore.exe")) //$NON-NLS-1$ { boolean isIE8 = false; try { int[] ieVersion = m_debuggerCallbacks.getAppVersion(httpExe); if (ieVersion != null) isIE8 = (ieVersion[0] >= 8); } catch (IOException e) { // ignore } if (isIE8) { // FB-22107: Tell IE to keep using the new process we are // launching, rather than merging the new process into the // old one. This allows us to terminate the new IE // debugging session. return new String[] { httpExe.toString(), "-noframemerging", uri }; //$NON-NLS-1$ } } return new String[] { httpExe.toString(), uri }; } /** * Gets the arguments needed for launching a swf that needs to run * in AIR. */ private String[] getAIRLaunchArgs(String uri, AIRLaunchInfo airLaunchInfo) throws IOException { List cmdList = new LinkedList (); cmdList.add(airLaunchInfo.airDebugLauncher.getPath()); if (airLaunchInfo.airRuntimeDir != null) { cmdList.add("-runtime"); //$NON-NLS-1$ cmdList.add(airLaunchInfo.airRuntimeDir.getPath()); } if (airLaunchInfo.airSecurityPolicy != null) { cmdList.add("-security-policy"); //$NON-NLS-1$ cmdList.add(airLaunchInfo.airSecurityPolicy.getPath()); } if (airLaunchInfo.airPublisherID != null && airLaunchInfo.airPublisherID.length() > 0) { cmdList.add("-pubid"); //$NON-NLS-1$ cmdList.add(airLaunchInfo.airPublisherID); } if (airLaunchInfo.profile != null && airLaunchInfo.profile.length() > 0) { cmdList.add("-profile"); //$NON-NLS-1$ cmdList.add(airLaunchInfo.profile); } if (airLaunchInfo.screenSize != null && airLaunchInfo.screenSize.length() > 0) { cmdList.add("-screensize"); //$NON-NLS-1$ cmdList.add(airLaunchInfo.screenSize); } if (airLaunchInfo.dpi > 0) { //TODO: this is apparently only going to be used in AIR 2.5. //Figure out permanent solution when AIR 3.0 comes along. cmdList.add("-XscreenDPI"); //$NON-NLS-1$ cmdList.add(String.valueOf(airLaunchInfo.dpi)); } if (airLaunchInfo.versionPlatform != null && airLaunchInfo.versionPlatform.length() > 0) { cmdList.add("-XversionPlatform"); //$NON-NLS-1$ cmdList.add(airLaunchInfo.versionPlatform); } if (airLaunchInfo.extDir != null && airLaunchInfo.extDir.length() > 0) { cmdList.add("-extdir"); //$NON-NLS-1$ cmdList.add(airLaunchInfo.extDir); } if (airLaunchInfo.deviceExtDir != null && airLaunchInfo.deviceExtDir.length() > 0) { cmdList.add("-XdeviceExtDir"); //$NON-NLS-1$ cmdList.add(airLaunchInfo.deviceExtDir); } // If it's a "file:" URL, then pass the actual filename; otherwise, use the URL // ok, its not an http: type request therefore we should be able to see // it on the file system, right? If not then it's probably not valid File f = null; if (uri.startsWith("file:")) //$NON-NLS-1$ { try { f = new File(new URI(uri)); cmdList.add(f.getPath()); } catch (URISyntaxException e) { IOException ioe = new IOException(e.getMessage()); ioe.initCause(e); throw ioe; } } else { cmdList.add(uri); } if (airLaunchInfo.applicationContentRootDir != null) { cmdList.add(airLaunchInfo.applicationContentRootDir.getAbsolutePath()); } List args = null; if (airLaunchInfo.applicationArgumentsArray != null) { args = Arrays.asList(airLaunchInfo.applicationArgumentsArray); } else if (airLaunchInfo.applicationArguments != null) { args = splitArgs(airLaunchInfo.applicationArguments); } if (args != null && args.size() > 0) { cmdList.add("--"); //$NON-NLS-1$ cmdList.addAll(args); } return cmdList.toArray(new String[cmdList.size()]); } /** * This is annoying: We must duplicate the operating system's behavior * with regard to splitting arguments. * * @param arguments A single string of arguments that are intended to * be passed to an AIR application. The tricky part is that some * of the arguments may be quoted, and if they are, then the quoting * will be in a way that is specific to the current platform. For * example, on Windows, strings are quoted with the double-quote character * ("); on Mac and Unix, strings can be quoted with either double-quote * or single-quote. * @return The equivalent */ private List splitArgs(String arguments) { List retval = new ArrayList (); arguments = arguments.trim(); // Windows quotes only with double-quote; Mac and Unix also allow single-quote. boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("win"); //$NON-NLS-1$ //$NON-NLS-2$ boolean isMacOrUnix = !isWindows; int i=0; while (i accept() null
* @return true if pl refers to an AIR app that has terminated. */ private boolean airAppTerminated(ProcessListener pl) { if (pl != null) { if (pl.isAIRApp()) { if (pl.isProcessDead()) { return true; } } } return false; } /* * @see flash.tools.debugger.SessionManager#getDebuggerCallbacks() */ public IDebuggerCallbacks getDebuggerCallbacks() { return m_debuggerCallbacks; } /* * @see flash.tools.debugger.SessionManager#setDebuggerCallbacks(flash.tools.debugger.IDebuggerCallbacks) */ public void setDebuggerCallbacks(IDebuggerCallbacks debuggerCallbacks) { m_debuggerCallbacks = debuggerCallbacks; } /** * A private variation onconnect()
that also has an argument * indicating that the process we are waiting for has terminated. * * @param pl * Optional process listener. If non-null, this is used to detect * if a process that was launched has terminated unexpectedly. * For example, if launch() launches adl, but adl exits, then we * don't want to continue to wait for a socket connection. */ public Session connect(int port, IProgress waitReporter) throws IOException { final int waitTime = getPreference(PREF_CONNECT_WAIT_INTERVAL); final int maxRetryAttempts = getPreference(PREF_CONNECT_RETRY_ATTEMPTS); final int totalTimeout = getPreference(PREF_CONNECT_TIMEOUT); final long timeForConnectStart = System.currentTimeMillis(); long elapsedTime = 0; int retryAttempts = -1; PlayerSession session = null; Socket s = null; m_cancelConnect = false; // Try to see if a connect happens till totalTimeout // If the connection was refused in between, retry // again after waitTime until totalTimeout is elapsed. // Retry mechanism is disabled if PREF_CONNECT_RETRY_ATTEMPTS // is 0. while (s == null) { try { InetSocketAddress localAddress = new InetSocketAddress(InetAddress.getByName(null), port); s = new Socket(); //save the socket for canceling connect m_connectSocket = s; //connect to loopback address at the specified port s.connect(localAddress, totalTimeout); } catch(IOException ste) { if (ste instanceof SocketTimeoutException) { //if we timed out, abort connect abortConnect(ste); } safeCloseSocket(s); s = null; retryAttempts++; //if we should not retry, checkConnectTimeout //throws an exception elapsedTime = checkConnectTimeout(waitTime, maxRetryAttempts, totalTimeout, retryAttempts, timeForConnectStart, ste); } // Tell the progress monitor we've waited a little while longer, // so that the Eclipse progress bar can keep chugging along if (waitReporter != null) waitReporter.setProgress((int)elapsedTime, totalTimeout); if (s != null) { /** If we connected, make sure that we get some response * back after sending the handshake. This is required because * of the way port forwarding works. A connect will be successful * if port forwarding is set up, but we won't get any response * unless the application is actually listening. */ /* create a new session around this socket */ session = PlayerSession.createFromSocketWithOptions(s, m_debuggerCallbacks, this); // transfer preferences session.setPreferences(m_prefs); try { session.bind(); } catch (VersionException ex) { session.unbind(); safeCloseSocket(s); s = null; retryAttempts++; /** The VersionException here is considered as an IOException * because we do not know if there was even a valid application * listening on the port. Once the port is forwarded, connect * succeeds and we get a VersionException even if player is not * listening on that port. */ elapsedTime = checkConnectTimeout(waitTime, maxRetryAttempts, totalTimeout, retryAttempts, timeForConnectStart, new IOException(ex.getLocalizedMessage())); } } } m_connectSocket = null; return session; } /** * @param waitTime * @param maxRetryAttempts * @param totalTimeout * @param retryAttempts * @param startTime * @param caughtException * @return * @throws IOException */ private long checkConnectTimeout(final int waitTime, final int maxRetryAttempts, final int totalTimeout, int retryAttempts, final long startTime, IOException caughtException) throws IOException { long elapsedTime; long endTime = System.currentTimeMillis(); elapsedTime = endTime - startTime; // check if we should retry boolean retryFinished = (maxRetryAttempts != -1 && retryAttempts >= maxRetryAttempts); // check if we timed out or somebody called stopConnecting() if (retryFinished || elapsedTime > totalTimeout || m_cancelConnect ) { abortConnect(caughtException); } //wait a bit before retrying try { Thread.sleep(waitTime); } catch (InterruptedException e) { abortConnect(caughtException); } //check cancel before resuming if (m_cancelConnect ) { abortConnect(caughtException); } return elapsedTime; } /** * @param ste * @throws IOException */ private void abortConnect(IOException ste) throws IOException { m_connectSocket = null; m_cancelConnect = false; throw ste; } /** * @param s */ private void safeCloseSocket(Socket s) { //clean up the socket if (s != null && !s.isClosed()) { try { s.close(); } catch (IOException closeException) { //ignore } } } /* * @see flash.tools.debugger.SessionManager#stopConnecting() */ public void stopConnecting() throws IOException { if (!m_cancelConnect) { m_cancelConnect = true; if (m_connectSocket != null) { m_connectSocket.close(); m_connectSocket = null; } } } /* * @see flash.tools.debugger.SessionManager#isConnecting() */ public boolean isConnecting() { return (m_connectSocket == null) ? false : true; } /** * Returns the localization manager. Use this for all localized strings. */ public static LocalizationManager getLocalizationManager() { return m_localizationManager; } @Override public Process launchForRun(String uri, AIRLaunchInfo airLaunchInfo, IProgress waitReporter, ILaunchNotification launchNotification) throws IOException { String[] launchCommand = getLaunchCommand(uri, airLaunchInfo, false); // create the process and attach a thread to watch it during our accept phase Process proc = m_debuggerCallbacks.launchDebugTarget(launchCommand); //forDebugging = false // If launching an AIR app, and forDebugging=false (meaning we are just running it, // not debugging it), start a background thread that will call the launchNotification // when the launch is complete. startProcessListener(airLaunchInfo, false,launchNotification, launchCommand, proc,true); return proc; } private ProcessListener startProcessListener(AIRLaunchInfo airLaunchInfo, boolean forDebugging, ILaunchNotification launchNotification, String[] launchCommand, Process proc, boolean isRunLaunch) { ProcessListener processListener = new ProcessListener(launchCommand, proc, launchNotification, forDebugging, airLaunchInfo != null); // BUG FB-9874: launchNotifier added processListener.setIsRunLaunch(isRunLaunch); // If launching an AIR app, and forDebugging=false (meaning we are just running it, // not debugging it), start a background thread that will call the launchNotification // when the launch is complete. if (!forDebugging && airLaunchInfo != null && launchNotification != null) processListener.startLaunchNotifier(); return processListener; } private String[] getLaunchCommand(String uri, AIRLaunchInfo airLaunchInfo, boolean forDebugging) throws IOException, FileNotFoundException { String[] launchCommand; uri = uri.trim(); if (airLaunchInfo == null) { LaunchInfo launchInfo = new LaunchInfo(uri); uri = tweakNativeLaunchUri(uri, forDebugging, launchInfo); launchCommand = getFlashLaunchArgs(uri, launchInfo); } else // else, AIR { launchCommand = getAIRLaunchArgs(uri, airLaunchInfo); } return launchCommand; } @Override public Process launchForRun(String uri, AIRLaunchInfo airLaunchInfo, IProgress waitReporter, ILaunchNotification launchNotification, ILauncher launcher) throws IOException { String[] launchCommand = getLaunchCommandForLauncher(uri, airLaunchInfo,false); // create the process and attach a thread to watch it during our accept phase Process proc = m_debuggerCallbacks.launchDebugTarget(launchCommand,launcher); //forDebugging = false // If launching an AIR app, and forDebugging=false (meaning we are just running it, // not debugging it), start a background thread that will call the launchNotification // when the launch is complete. startProcessListener(airLaunchInfo, false,launchNotification, launchCommand, proc, true);; return proc; } private String[] getLaunchCommandForLauncher(String uri, AIRLaunchInfo airLaunchInfo,boolean forDebugging) throws IOException, FileNotFoundException { String[] launchCommand; if (airLaunchInfo == null) { LaunchInfo launchInfo = new LaunchInfo(uri); uri = tweakNativeLaunchUri(uri, forDebugging, launchInfo); launchCommand = new String[]{uri}; } else // else, AIR { launchCommand = getAIRLaunchArgs(uri, airLaunchInfo); } return launchCommand; } @Override public Session launch(String uri, AIRLaunchInfo airLaunchInfo, boolean forDebugging, IProgress waitReporter, ILaunchNotification launchNotification, ILauncher launcher) throws IOException { String[] launchCommand = getLaunchCommandForLauncher(uri, airLaunchInfo,forDebugging); // create the process and attach a thread to watch it during our accept phase Process proc = m_debuggerCallbacks.launchDebugTarget(launchCommand, launcher); ProcessListener processListener = startProcessListener(airLaunchInfo,forDebugging, launchNotification, launchCommand, proc,false); PlayerSession session = null; if (forDebugging) { session = waitForConnection(uri, airLaunchInfo, waitReporter, proc, processListener); session.setLauncher(launcher); } return session; } }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy