001package Torello.Browser;
002
003import static Torello.Java.C.BYELLOW;
004import static Torello.Java.C.RESET;
005
006import Torello.Java.JSON.ReadJSON;
007import Torello.JavaDoc.LinkJavaSource;
008import Torello.Browser.WebSocketSender;
009import NeoVisionaries.WebSockets.WebSocketException;
010
011import java.io.IOException;
012import java.util.stream.Stream;
013import java.util.Objects;
014import java.util.function.Consumer;
015import java.util.Objects;
016import javax.json.JsonObject;
017
018
019/**
020 * A Connection to a Browser, rather than an individual Page within the Browser.
021 * <EMBED CLASS='external-html' DATA-FILE-ID=PAGE_CONN>
022 */
023@Torello.JavaDoc.CSSLinks(FileNames="BrowserAndPageConn.css")
024public class BrowserConn
025{
026    // ********************************************************************************************
027    // ********************************************************************************************
028    // PUBLIC FIELDS
029    // ********************************************************************************************
030    // ********************************************************************************************
031
032
033    /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_BROWSER> */
034    public final String browser;
035
036    /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_PROT_VER> */
037    public final String protocolVersion;
038
039    /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_USER_AGENT> */
040    public final String userAgent;
041
042    /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_V8_VERSION> */
043    public final String v8Version;
044
045    /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_WEBKIT_VER> */
046    public final String webkitVersion;
047
048    /** <EMBED CLASS='external-html' DATA-FILE-ID=BC_WS_DEBUG_URL> */
049    public final String webSocketDebuggerUrl;
050
051
052    // ********************************************************************************************
053    // ********************************************************************************************
054    // Constructors
055    // ********************************************************************************************
056    // ********************************************************************************************
057
058
059    public BrowserConn(
060            final String browser,
061            final String protocolVersion,
062            final String userAgent,
063            final String v8Version,
064            final String webkitVersion,
065            final String webSocketDebuggerUrl
066        )
067    {
068        Objects.requireNonNull(webSocketDebuggerUrl, "webSocketDebuggerUrl is null");
069
070        this.browser                = browser;
071        this.protocolVersion        = protocolVersion;
072        this.userAgent              = userAgent;
073        this.v8Version              = v8Version;
074        this.webkitVersion          = webkitVersion;
075        this.webSocketDebuggerUrl   = webSocketDebuggerUrl;
076    }
077
078    public BrowserConn(final JsonObject jo)
079    {
080        this.browser            = ReadJSON.getString(jo, "Browser",             false,  true);
081        this.protocolVersion    = ReadJSON.getString(jo, "Protocol-Version",    false,  true);
082        this.userAgent          = ReadJSON.getString(jo, "User-Agent",          false,  true);
083        this.v8Version          = ReadJSON.getString(jo, "V8-Version",          true,   false);
084        this.webkitVersion      = ReadJSON.getString(jo, "WebKit-Version",      true,   false);
085
086        this.webSocketDebuggerUrl =
087            ReadJSON.getString(jo, "webSocketDebuggerUrl", false,  true);
088    }
089
090
091    // ********************************************************************************************
092    // ********************************************************************************************
093    // Build Methods
094    // ********************************************************************************************
095    // ********************************************************************************************
096
097
098    /**
099     * Creates a {@link WebSocketSender} connected to the {@link #webSocketDebuggerUrl} for this
100     * tab.  This URL is the endpoint that speaks the Chrome DevTools Protocol (CDP).
101     * 
102     * @param eventHandler          <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_EVENT_H>
103     * @param rdpErrorHandler       <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_RDP_ERR_H>
104     * @param browserErrorHandler   <EMBED CLASS='external-html' DATA-FILE-ID=PCBC_BROWSER_ERR_H>
105     */
106    public WebSocketSender createSender(
107            final Consumer<BrowserEvent>    eventHandler,
108            final Consumer<RDPError>        rdpErrorHandler,
109            final Consumer<BrowserError>    browserErrorHandler
110        )
111        throws IOException, WebSocketException
112    {
113        return new WebSocketSender
114            (this.webSocketDebuggerUrl, eventHandler, rdpErrorHandler, browserErrorHandler);
115    }
116
117    /**
118     * Retrieves the WebSocketDebugger URL for the main browser instance.
119     * This queries {@code /json/version} and parses the result into an instance.
120     *
121     * @param port  The DevTools port Chrome is listening on (default is 9222 if {@code null}).
122     * @param quiet If {@code false}, debug output is printed to the console.
123     * @return A {@code BrowserConn} instance representing the browser-level connection.
124     */
125    @LinkJavaSource(handle="BCBuilder")
126    public static BrowserConn getBrowserConn(Integer port, boolean quiet)
127    { return BCBuilder.getBrowserConn(port, quiet); }
128
129
130    // ********************************************************************************************
131    // ********************************************************************************************
132    // java.lang.Object Methods
133    // ********************************************************************************************
134    // ********************************************************************************************
135
136
137    @LinkJavaSource(handle="BCHelper", name="toString")
138    public String toString() { return BCHelper.toString(this); }
139
140    @LinkJavaSource(handle="BCHelper", name="hashCode")
141    public int hashCode() { return BCHelper.hashCode(this); }
142
143    @LinkJavaSource(handle="BCHelper", name="equals")
144    public boolean equals(Object o) { return BCHelper.equals(this, o); }
145
146    @LinkJavaSource(handle="BCHelper", name="clone")
147    public BrowserConn clone() { return BCHelper.clone(this); }
148}