blob: e67e68b6257bdaee34926b15902dbecd69c978d0 [file] [log] [blame]
/*
* 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;
import java.io.IOException;
/**
* A SessionManager controls connection establishment and preferences
* for all debugging sessions with the Flash Player.
*
* To begin a new debugging session:
*
* <ol>
* <li> Get a <code>SessionManager</code> from <code>Bootstrap.sessionManager()</code> </li>
* <li> Call <code>SessionManager.startListening()</code> </li>
* <li> If you want to have the API launch the Flash Player for you, call
* <code>SessionManager.launch()</code>. If you want to launch the Flash Player
* and then have the API connect to it, then launch the Flash Player and then
* call <code>SessionManager.accept()</code>. <em>Note:</em> <code>launch()</code>
* and <code>accept()</code> are both blocking calls, so you probably don't want
* to call them from your main UI thread. </li>
* <li> Finally, call <code>SessionManager.stopListening()</code>.
* </ol>
*/
public interface SessionManager
{
/**
* The preferences are set using the setPreference() method, and
* take effect immediately thereafter.
*/
/**
* The value used for <code>$accepttimeout</code> controls how long (in
* milliseconds) <code>accept()</code> waits before timing out. The
* default value for this preference is 120000 (2 minutes).
*/
public static final String PREF_ACCEPT_TIMEOUT = "$accepttimeout"; //$NON-NLS-1$
/**
* Valid values for <code>$urimodification</code> are 0 (off) and 1 (on).
* The default value is 1 (on), which allows this API to modify the URI
* passed to <code>launch()</code> as necessary for creating a debuggable
* version of an MXML file.
*/
public static final String PREF_URI_MODIFICATION = "$urimodification"; //$NON-NLS-1$
/**
*-----------------------------------------------------------------
* The following are Session specific preferences. These can be
* modified in this class, resulting in all future sessions using
* the values or they can be modified at the session level via
* Session.setPreference().
*-----------------------------------------------------------------
*/
/**
* <code>$responsetimeout</code> is used to determine how long (in
* milliseconds) the session will wait, for a player response before giving
* up on the request and throwing an Exception.
*/
public static final String PREF_RESPONSE_TIMEOUT = "$responsetimeout"; //$NON-NLS-1$
/**
* <code>$sockettimeout</code> is used to determine how long (in
* milliseconds) the session will wait on a Socket recv call.
* On timeout, we do not immediately abort the session, instead we
* write a squelch message to player. If the write succeeds, we assume
* everything is normal.This helps identify broken connections that
* are relevant when performing WiFi debugging.
* This is -1 by default to indicate no timeout
* (for backward compatibility).
*/
public static final String PREF_SOCKET_TIMEOUT = "$sockettimeout"; //$NON-NLS-1$
/**
* <code>$contextresponsetimeout</code> is used to determine how long (in
* milliseconds) the session will wait for a player response from a request
* to get context, before giving up on the request and throwing an
* Exception.
*/
public static final String PREF_CONTEXT_RESPONSE_TIMEOUT = "$contextresponsetimeout"; //$NON-NLS-1$
/**
* <code>$getvarresponsetimeout</code> is used to determine how long (in
* milliseconds) the session will wait, for a player response to a get
* variable request before giving up on the request and throwing an
* Exception.
*/
public static final String PREF_GETVAR_RESPONSE_TIMEOUT = "$getvarresponsetimeout"; //$NON-NLS-1$
/**
* <code>$setvarresponsetimeout</code> is the amount of time (in
* milliseconds) that a setter in the user's code will be given to execute,
* before the player interrupts it with a ScriptTimeoutError. Default value
* is 5000 ms.
*/
public static final String PREF_SETVAR_RESPONSE_TIMEOUT = "$setvarresponsetimeout"; //$NON-NLS-1$
/**
* <code>$swfswdloadtimeout<code> is used to determine how long (in milliseconds)
* the session will wait, for a player response to a swf/swd load
* request before giving up on the request and throwing an Exception.
*/
public static final String PREF_SWFSWD_LOAD_TIMEOUT = "$swfswdloadtimeout"; //$NON-NLS-1$
/**
* <code>$suspendwait</code> is the amount of time (in milliseconds) that
* a Session will wait for the Player to suspend, after a call to
* <code>suspend()</code>.
*/
public static final String PREF_SUSPEND_WAIT = "$suspendwait"; //$NON-NLS-1$
/**
* <code>$invokegetters</code> is used to determine whether a getter
* property is invoked or not when requested via <code>getVariable()</code>
* The default value is for this to be enabled.
*/
public static final String PREF_INVOKE_GETTERS = "$invokegetters"; //$NON-NLS-1$
public static final String PLAYER_SUPPORTS_GET = "$playersupportsget"; //$NON-NLS-1$
/**
* <code>$hiervars</code> is used to determine whether the members of
* a variable are shown in a hierchical way.
*/
public static final String PREF_HIERARCHICAL_VARIABLES = "$hiervars"; //$NON-NLS-1$
/**
* The value used for <code>$connecttimeout</code> controls how long (in
* milliseconds) <code>connect()</code> waits before timing out. The
* default value for this preference is 120000 (2 minutes).
*/
public static final String PREF_CONNECT_TIMEOUT = "$connecttimeout"; //$NON-NLS-1$
/**
* The value used for <code>$connectwaitinterval</code> controls how long (in
* milliseconds) we wait between subsequent <code>connect()</code> calls. The
* default value for this preference is 250.
*/
public static final String PREF_CONNECT_WAIT_INTERVAL = "$connectwaitinterval"; //$NON-NLS-1$
/**
* The value used for <code>$connectretryattempts</code> controls how many times
* the debugger retries connecting to the application. This is time bound by
* <code>$connecttimeout</code>. The default value for this preference is -1 and
* indicates that the debugger should retry till the timeout period has elapsed.
* Setting this to zero will disable the retry mechanism.
*/
public static final String PREF_CONNECT_RETRY_ATTEMPTS = "$connectretryattempts"; //$NON-NLS-1$
/**
* Set preference for this manager and for subsequent Sessions
* that are initiated after this call.
*
* If an invalid preference is passed, it will be silently ignored.
* @param pref preference name, one of the strings listed above
* @param value value to set for preference
*/
public void setPreference(String pref, int value);
/**
* Set preference for this manager and for subsequent Sessions
* that are initiated after this call.
*
* If an invalid preference is passed, it will be silently ignored.
* @param pref preference name, one of the strings listed above
* @param value value to set for preference
*/
public void setPreference(String pref, String value);
/**
* Return the value of a particular preference item
*
* @param pref preference name, one of the strings listed above
* @throws NullPointerException if pref does not exist
*/
public int getPreference(String pref) throws NullPointerException;
/**
* Listens for Player attempts to open a debug session. This method must be
* called prior to <code>accept()</code> being invoked.
*
* @throws IOException
* if opening the server side socket fails
*/
public void startListening() throws IOException;
/**
* Stops listening for new Player attempts to open a debug session. The
* method DOES NOT terminate currently connected sessions, but will cause
* threads blocked in <code>accept</code> to throw SocketExceptions.
*/
public void stopListening() throws IOException;
/**
* Is this object currently listening for Debug Player connections
* @return TRUE currently listening
*/
public boolean isListening();
/**
* Launches a Player using the given string as a URI, as defined by RFC2396.
* It is expected that the operating system will be able to launch the
* appropriate player application given this URI.
* <p>
* For example "http://localhost:8100/flex/my.mxml" or for a local file on
* Windows, "file://c:/my.swf"
* <p>
* This call will block until a session with the newly launched player is
* created.
* <p>
* It is the caller's responsibility to ensure that no other thread is
* blocking in <code>accept()</code>, since that thread will gain control
* of this session.
* <p>
* Before calling <code>launch()</code>, you should first call
* <code>supportsLaunch()</code>. If <code>supportsLaunch()</code>
* returns false, then you will have to tell the user to manually launch the
* Flash player.
* <p>
* Also, before calling <code>launch()</code>, you must call
* <code>startListening()</code>.
*
* @param uri
* which will launch a Flash player under running OS. For
* Flash/Flex apps, this can point to either a SWF or an HTML
* file. For AIR apps, this must point to the application.xml
* file for the application.
* @param airLaunchInfo
* If trying to launch an AIR application, this argument must be
* specified; it gives more information about how to do the
* launch. If trying to launch a regular web-based Flash or Flex
* application, such as one that will be in a browser or in the
* standalone Flash Player, this argument should be
* <code>null</code>.
* @param forDebugging
* if <code>true</code>, then the launch is for the purposes
* of debugging. If <code>false</code>, then the launch is
* simply because the user wants to run the movie but not debug
* it; in that case, the return value of this function will be
* <code>null</code>.
* @param waitReporter
* a progress monitor to allow accept() to notify its parent how
* long it has been waiting for the Flash player to connect to
* it. May be <code>null</code> if the caller doesn't need to
* know how long it's been waiting.
* @param launchNotification
* a notifier to notify the caller about ADL Exit Code.
* Main usage is for ADL Exit Code 1 (Successful invocation of an
* already running AIR application. ADL exits immediately).
* May be <code>null</code> if no need to listen ADL.
* Will only be called if forDebugging is false. (If forDebugging
* is true, error conditions are handled by throwing an exception.)
* The callback will be called on a different thread.
* @return a Session to use for debugging, or null if forDebugging==false.
* The return value is not used to indicate an error -- exceptions
* are used for that. If this function returns without throwing an
* exception, then the return value will always be non-null if
* forDebugging==true, or null if forDebugging==false.
* @throws BindException
* if <code>isListening()</code> == false
* @throws FileNotFoundException
* if file cannot be located
* @throws CommandLineException
* if the program that was launched exited unexpectedly. This
* will be returned, for example, when launching an AIR
* application, if adl exits with an error code.
* CommandLineException includes functions to return any error
* text that may have been sent to stdout/stderr, and the exit
* code of the program.
* @throws IOException
* see Runtime.exec()
*/
public Session launch(String uri, AIRLaunchInfo airLaunchInfo,
boolean forDebugging, IProgress waitReporter, ILaunchNotification launchNotification) throws IOException;
/**
* Returns information about the Flash player which will be used to run the
* given URI.
*
* @param uri
* The URI which will be passed to <code>launch()</code> -- for
* example, <code>http://flexserver/mymovie.mxml</code> or
* <code>c:\mymovie.swf</code>. If launching an AIR app, this
* should point to the app's *-app.xml file.
* @param airLaunchInfo
* If launching an AIR app, this should, if possible, contain
* info about the version of AIR being launched, but it can be
* null if you don't have that information. If launching a
* web-based app, this should be null.
* @return a {@link Player} which can be used to determine information about
* the player -- for example, whether it is a debugger-enabled
* player. Returns <code>null</code> if the player cannot be
* determined. <em>Important:</em> There are valid situations in
* which this will return <code>null</code>
*/
public Player playerForUri(String uri, AIRLaunchInfo airLaunchInfo);
/**
* Returns whether this platform supports the <code>launch()</code>
* command; that is, whether the debugger can programmatically launch the
* Flash player. If this function returns false, then the debugger will have
* to tell the user to manually launch the Flash player.
*
* @return true if this platform supports the <code>launch()</code>
* command.
*/
public boolean supportsLaunch();
/**
* Blocks until the next available player debug session commences, or until
* <code>getPreference(PREF_ACCEPT_TIMEOUT)</code> milliseconds pass.
* <p>
* Before calling <code>launch()</code>, you must call
* <code>startListening()</code>.
* <p>
* Once a Session is obtained, Session.bind() must be called prior to any
* other Session method.
*
* @param waitReporter
* a progress monitor to allow accept() to notify its parent how
* long it has been waiting for the Flash player to connect to it.
* May be <code>null</code> if the caller doesn't need to know how
* long it's been waiting.
* @throws BindException
* if isListening() == false
* @throws IOException -
* see java.net.ServerSocket.accept()
*/
public Session accept(IProgress waitReporter) throws IOException;
/**
* Tells the session manager to use the specified IDebuggerCallbacks for
* performing certain operatios, such as finding the Flash Player and
* launching the debug target. If you do not call this, the session manager
* will use a <code>DefaultDebuggerCallbacks</code> object.
*/
public void setDebuggerCallbacks(IDebuggerCallbacks debugger);
/**
* Initiate a debug session by connecting to the specified port. Blocks
* until a connection is made, or until
* <code>getPreference(PREF_CONNECT_TIMEOUT)</code> milliseconds pass.
* <p>
* This work-flow is a reverse of <code>accept()</code> and suited for
* cases where the player is unable to initiate the connection. The
* player must be listening on the specified port for an incoming debug
* connection. In addition, this function calls bind() on the session
* to determine if the handshake was successful so that retry works
* correctly even across port-forwards.
* <p>
* Use <code>stopConnecting()</code> to cancel connect,
* <code>isConnecting()</code> to check if we are currently trying to
* connect.
*
* @param port - The port to connect to. See DProtocol.DEBUG_CONNECT_PORT.
* @param waitReporter
* @return A Session object on which bind() has already been called.
* @throws IOException - This may have a wrapped VersionException due to bind()
*/
public Session connect(int port, IProgress waitReporter) throws IOException;
/**
* Stops connecting to the Player for a debug session. The
* method DOES NOT terminate currently connected sessions, but will cause
* threads blocked in <code>connect</code> to throw SocketExceptions.
*/
public void stopConnecting() throws IOException;
/**
* Is this object currently connecting to the Debug Player
* @return TRUE currently connecting
*/
public boolean isConnecting();
}