Web Inspector: add 'Automation' protocol domain and generate its backend classes...
authorbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 22 Feb 2016 04:49:29 +0000 (04:49 +0000)
committerbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 22 Feb 2016 04:49:29 +0000 (04:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=154509
<rdar://problem/24759098>

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

Add a new 'WebKit' framework, which is used to generate protocol code
in WebKit2.

Add --backend and --frontend flags to the main generator script.
These allow a framework to trigger two different sets of generators
so they can be separately generated and compiled.

* inspector/scripts/codegen/models.py:
(Framework.fromString):
(Frameworks): Add new framework.

* inspector/scripts/generate-inspector-protocol-bindings.py:
If neither --backend or --frontend is specified, assume both are wanted.
This matches the behavior for JavaScriptCore and WebInspector frameworks.

(generate_from_specification):
Generate C++ files for the backend and Objective-C files for the frontend.

Source/WebKit2:

Add a new 'Automation' domain which presents an RPC interface
for sending automation commands to an active WebAutomationSession
in the UIProcess via RemoteInspector. This is similar to how the
Inspector backend communicates bidirectionally with a remote
Inspector frontend.

Add build system logic to generate JSON-RPC protocol bindings
for the 'Automation' domain using the inspector code generators.

Move automation-related files that are not API or SPI into their
own directory.

* Configurations/BaseTarget.xcconfig: Tell where JavaScriptCore's
private headers are, since that's where the code generators live.

* CMakeLists.txt: Look in UIProcess/Automation directory.
* PlatformMac.cmake:
* DerivedSources.make: Generate protocol bindings for a single domain.
The names of the generated files will be improved in a follow-up patch
so that they do not clash with generated files in JavaScriptCore.

* UIProcess/Automation/Automation.json: Added.
* UIProcess/Automation/WebAutomationSession.cpp: Renamed from Source/WebKit2/UIProcess/WebAutomationSession.cpp.
(WebKit::WebAutomationSession::WebAutomationSession):
(WebKit::WebAutomationSession::~WebAutomationSession):
Set up a backend dispatcher and frontend router. They will be used later.

(WebKit::WebAutomationSession::dispatchMessageFromRemote):
Forward messages from the remote to the backend dispatcher. When
an agent / command handler is registered, it will receive the message.

(WebKit::WebAutomationSession::connect):
(WebKit::WebAutomationSession::disconnect):
Connenct and disconnect the frontend router to the remote channel.

* UIProcess/Automation/WebAutomationSession.h: Renamed from Source/WebKit2/UIProcess/WebAutomationSession.h.
* WebKit2.xcodeproj/project.pbxproj: Add and move files.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196891 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/scripts/codegen/models.py
Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py
Source/WebKit2/CMakeLists.txt
Source/WebKit2/ChangeLog
Source/WebKit2/Configurations/BaseTarget.xcconfig
Source/WebKit2/DerivedSources.make
Source/WebKit2/PlatformMac.cmake
Source/WebKit2/UIProcess/Automation/Automation.json [new file with mode: 0644]
Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp [moved from Source/WebKit2/UIProcess/WebAutomationSession.cpp with 80% similarity]
Source/WebKit2/UIProcess/Automation/WebAutomationSession.h [moved from Source/WebKit2/UIProcess/WebAutomationSession.h with 93% similarity]
Source/WebKit2/WebKit2.xcodeproj/project.pbxproj

index 3d6dd1d..e45edc7 100644 (file)
@@ -1,3 +1,29 @@
+2016-02-21  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: add 'Automation' protocol domain and generate its backend classes separately in WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=154509
+        <rdar://problem/24759098>
+
+        Reviewed by Timothy Hatcher.
+
+        Add a new 'WebKit' framework, which is used to generate protocol code
+        in WebKit2.
+
+        Add --backend and --frontend flags to the main generator script.
+        These allow a framework to trigger two different sets of generators
+        so they can be separately generated and compiled.
+
+        * inspector/scripts/codegen/models.py:
+        (Framework.fromString):
+        (Frameworks): Add new framework.
+
+        * inspector/scripts/generate-inspector-protocol-bindings.py:
+        If neither --backend or --frontend is specified, assume both are wanted.
+        This matches the behavior for JavaScriptCore and WebInspector frameworks.
+
+        (generate_from_specification):
+        Generate C++ files for the backend and Objective-C files for the frontend.
+
 2016-02-21  Sukolsak Sakshuwong  <sukolsak@gmail.com>
 
         Improvements to Intl code
index f4fa448..f09b3cf 100755 (executable)
@@ -45,6 +45,8 @@ _FRAMEWORK_CONFIG_MAP = {
         "export_macro": "JS_EXPORT_PRIVATE",
         "alternate_dispatchers": True,
     },
+    "WebKit": {
+    },
     "WebInspector": {
     },
     # Used for code generator tests.
@@ -78,6 +80,9 @@ class Framework:
         if frameworkString == "JavaScriptCore":
             return Frameworks.JavaScriptCore
 
+        if frameworkString == "WebKit":
+            return Frameworks.WebKit
+
         if frameworkString == "WebInspector":
             return Frameworks.WebInspector
 
@@ -90,6 +95,7 @@ class Framework:
 class Frameworks:
     Global = Framework("Global")
     JavaScriptCore = Framework("JavaScriptCore")
+    WebKit = Framework("WebKit")
     WebInspector = Framework("WebInspector")
     Test = Framework("Test")
 
index ea13945..a528a9d 100755 (executable)
@@ -112,7 +112,9 @@ def generate_from_specification(primary_specification_filepath=None,
                                 concatenate_output=False,
                                 output_dirpath=None,
                                 force_output=False,
-                                framework_name=""):
+                                framework_name="",
+                                generate_frontend=True,
+                                generate_backend=True):
 
     def load_specification(protocol, filepath, isSupplemental=False):
         try:
@@ -148,6 +150,7 @@ def generate_from_specification(primary_specification_filepath=None,
         generators.append(ObjCHeaderGenerator(protocol, primary_specification_filepath))
         generators.append(ObjCInternalHeaderGenerator(protocol, primary_specification_filepath))
         generators.append(ObjCProtocolTypesImplementationGenerator(protocol, primary_specification_filepath))
+
     elif protocol.framework is Frameworks.JavaScriptCore:
         generators.append(JSBackendCommandsGenerator(protocol, primary_specification_filepath))
         generators.append(CppAlternateBackendDispatcherHeaderGenerator(protocol, primary_specification_filepath))
@@ -157,6 +160,19 @@ def generate_from_specification(primary_specification_filepath=None,
         generators.append(CppFrontendDispatcherImplementationGenerator(protocol, primary_specification_filepath))
         generators.append(CppProtocolTypesHeaderGenerator(protocol, primary_specification_filepath))
         generators.append(CppProtocolTypesImplementationGenerator(protocol, primary_specification_filepath))
+
+    elif protocol.framework is Frameworks.WebKit and generate_backend:
+        generators.append(CppBackendDispatcherHeaderGenerator(protocol, primary_specification_filepath))
+        generators.append(CppBackendDispatcherImplementationGenerator(protocol, primary_specification_filepath))
+        generators.append(CppProtocolTypesHeaderGenerator(protocol, primary_specification_filepath))
+        generators.append(CppProtocolTypesImplementationGenerator(protocol, primary_specification_filepath))
+
+    elif protocol.framework is Frameworks.WebKit and generate_frontend:
+        # FIXME <rdar://problem/23466925>: This list of generators for the frontend is a placeholder.
+        generators.append(ObjCConversionHelpersGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCFrontendDispatcherImplementationGenerator(protocol, primary_specification_filepath))
+        generators.append(ObjCProtocolTypesImplementationGenerator(protocol, primary_specification_filepath))
+
     elif protocol.framework is Frameworks.WebInspector:
         generators.append(ObjCBackendDispatcherHeaderGenerator(protocol, primary_specification_filepath))
         generators.append(ObjCBackendDispatcherImplementationGenerator(protocol, primary_specification_filepath))
@@ -190,14 +206,15 @@ def generate_from_specification(primary_specification_filepath=None,
 
 
 if __name__ == '__main__':
-    allowed_framework_names = ['JavaScriptCore', 'WebInspector', 'Test']
+    allowed_framework_names = ['JavaScriptCore', 'WebInspector', 'WebKit', 'Test']
     cli_parser = optparse.OptionParser(usage="usage: %prog [options] PrimaryProtocol.json [SupplementalProtocol.json ...]")
     cli_parser.add_option("-o", "--outputDir", help="Directory where generated files should be written.")
     cli_parser.add_option("--framework", type="choice", choices=allowed_framework_names, help="The framework that the primary specification belongs to.")
     cli_parser.add_option("--force", action="store_true", help="Force output of generated scripts, even if nothing changed.")
     cli_parser.add_option("-v", "--debug", action="store_true", help="Log extra output for debugging the generator itself.")
     cli_parser.add_option("-t", "--test", action="store_true", help="Enable test mode. Use unique output filenames created by prepending the input filename.")
-
+    cli_parser.add_option("--frontend", action="store_true", help="Generate code for the frontend-side of the protocol only.")
+    cli_parser.add_option("--backend", action="store_true", help="Generate code for the backend-side of the protocol only.")
     options = None
 
     arg_options, arg_values = cli_parser.parse_args()
@@ -210,13 +227,22 @@ if __name__ == '__main__':
     if arg_options.debug:
         log.setLevel(logging.DEBUG)
 
+    generate_backend = arg_options.backend;
+    generate_frontend = arg_options.frontend;
+    # Default to generating both the frontend and backend if neither is specified.
+    if not generate_backend and not generate_frontend:
+        generate_backend = True
+        generate_frontend = True
+
     options = {
         'primary_specification_filepath': arg_values[0],
         'supplemental_specification_filepaths': arg_values[1:],
         'output_dirpath': arg_options.outputDir,
         'concatenate_output': arg_options.test,
         'framework_name': arg_options.framework,
-        'force_output': arg_options.force
+        'force_output': arg_options.force,
+        'generate_backend': generate_backend,
+        'generate_frontend': generate_frontend,
     }
 
     try:
index ae8aaa5..4cd0682 100644 (file)
@@ -29,6 +29,7 @@ set(WebKit2_INCLUDE_DIRECTORIES
     "${WEBKIT2_DIR}/UIProcess/API/C"
     "${WEBKIT2_DIR}/UIProcess/API/cpp"
     "${WEBKIT2_DIR}/UIProcess/Authentication"
+    "${WEBKIT2_DIR}/UIProcess/Automation"
     "${WEBKIT2_DIR}/UIProcess/Databases"
     "${WEBKIT2_DIR}/UIProcess/Downloads"
     "${WEBKIT2_DIR}/UIProcess/InspectorServer"
index f3d1ed9..fc9cbd8 100644 (file)
@@ -1,3 +1,49 @@
+2016-02-21  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: add 'Automation' protocol domain and generate its backend classes separately in WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=154509
+        <rdar://problem/24759098>
+
+        Reviewed by Timothy Hatcher.
+
+        Add a new 'Automation' domain which presents an RPC interface
+        for sending automation commands to an active WebAutomationSession
+        in the UIProcess via RemoteInspector. This is similar to how the
+        Inspector backend communicates bidirectionally with a remote
+        Inspector frontend.
+
+        Add build system logic to generate JSON-RPC protocol bindings
+        for the 'Automation' domain using the inspector code generators.
+
+        Move automation-related files that are not API or SPI into their
+        own directory.
+
+        * Configurations/BaseTarget.xcconfig: Tell where JavaScriptCore's
+        private headers are, since that's where the code generators live.
+
+        * CMakeLists.txt: Look in UIProcess/Automation directory.
+        * PlatformMac.cmake:
+        * DerivedSources.make: Generate protocol bindings for a single domain.
+        The names of the generated files will be improved in a follow-up patch
+        so that they do not clash with generated files in JavaScriptCore.
+
+        * UIProcess/Automation/Automation.json: Added.
+        * UIProcess/Automation/WebAutomationSession.cpp: Renamed from Source/WebKit2/UIProcess/WebAutomationSession.cpp.
+        (WebKit::WebAutomationSession::WebAutomationSession):
+        (WebKit::WebAutomationSession::~WebAutomationSession):
+        Set up a backend dispatcher and frontend router. They will be used later.
+
+        (WebKit::WebAutomationSession::dispatchMessageFromRemote):
+        Forward messages from the remote to the backend dispatcher. When
+        an agent / command handler is registered, it will receive the message.
+
+        (WebKit::WebAutomationSession::connect):
+        (WebKit::WebAutomationSession::disconnect):
+        Connenct and disconnect the frontend router to the remote channel.
+
+        * UIProcess/Automation/WebAutomationSession.h: Renamed from Source/WebKit2/UIProcess/WebAutomationSession.h.
+        * WebKit2.xcodeproj/project.pbxproj: Add and move files.
+
 2016-02-20  Olivier Blin  <olivier.blin@softathome.com>
 
         [cmake] Use ICU include dirs in WebKit2 and WebKitTestRunner
index cc947b9..aee6921 100644 (file)
@@ -51,6 +51,7 @@ UMBRELLA_FRAMEWORKS_DIR_Production_macosx_USE_OVERRIDE_FRAMEWORKS_DIR_NO = $(NEX
 UMBRELLA_FRAMEWORKS_DIR_Production_macosx_USE_OVERRIDE_FRAMEWORKS_DIR_YES = $(WK_OVERRIDE_FRAMEWORKS_DIR);
 UMBRELLA_FRAMEWORKS_DIR_engineering = $(BUILT_PRODUCTS_DIR);
 
+JAVASCRIPTCORE_PRIVATE_HEADERS_DIR = $(UMBRELLA_FRAMEWORKS_DIR)/JavaScriptCore.framework/PrivateHeaders;
 WEBCORE_PRIVATE_HEADERS_DIR = $(UMBRELLA_FRAMEWORKS_DIR)/WebCore.framework/PrivateHeaders;
 WEBKIT_LEGACY_PRIVATE_HEADERS_DIR = $(UMBRELLA_FRAMEWORKS_DIR)/WebKitLegacy.framework/PrivateHeaders;
 
index 5c5791d..6f2a767 100644 (file)
@@ -56,6 +56,7 @@ VPATH = \
     $(WebKit2)/WebProcess/ios \
     $(WebKit2)/WebProcess \
     $(WebKit2)/UIProcess \
+    $(WebKit2)/UIProcess/Automation \
     $(WebKit2)/UIProcess/Cocoa \
     $(WebKit2)/UIProcess/Databases \
     $(WebKit2)/UIProcess/Downloads \
@@ -192,3 +193,31 @@ all: $(SANDBOX_PROFILES)
 %.sb : %.sb.in
        @echo Pre-processing $* sandbox profile...
        $(CC) $(SDK_FLAGS) $(TEXT_PREPROCESSOR_FLAGS) $(FRAMEWORK_FLAGS) $(HEADER_FLAGS) -include "wtf/Platform.h" $< > $@
+
+JSON_RPC_GENERATOR_SCRIPTS = \
+       $(JavaScriptCore_SCRIPTS_DIR)/cpp_generator_templates.py \
+       $(JavaScriptCore_SCRIPTS_DIR)/cpp_generator.py \
+       $(JavaScriptCore_SCRIPTS_DIR)/generate_cpp_backend_dispatcher_header.py \
+       $(JavaScriptCore_SCRIPTS_DIR)/generate_cpp_backend_dispatcher_implementation.py \
+       $(JavaScriptCore_SCRIPTS_DIR)/generate_cpp_protocol_types_header.py \
+       $(JavaScriptCore_SCRIPTS_DIR)/generate_cpp_protocol_types_implementation.py \
+       $(JavaScriptCore_SCRIPTS_DIR)/generator_templates.py \
+       $(JavaScriptCore_SCRIPTS_DIR)/generator.py \
+       $(JavaScriptCore_SCRIPTS_DIR)/models.py \
+       $(JavaScriptCore_SCRIPTS_DIR)/generate-inspector-protocol-bindings.py \
+#
+
+JSON_RPC_INPUT_FILES = \
+    $(WebKit2)/UIProcess/Automation/Automation.json \
+#
+
+JSON_RPC_OUTPUT_FILES = \
+    InspectorBackendDispatchers.h \
+    InspectorBackendDispatchers.cpp \
+#
+
+# JSON-RPC Backend Dispatchers, Type Builders
+$(JSON_RPC_OUTPUT_FILES) : $(JSON_RPC_INPUT_FILES) $(JSON_RPC_GENERATOR_SCRIPTS)
+       $(PYTHON) $(JavaScriptCore_SCRIPTS_DIR)/generate-inspector-protocol-bindings.py --framework WebKit --backend --outputDir . $(JSON_RPC_INPUT_FILES)
+
+all : $(JSON_RPC_OUTPUT_FILES)
index 92e3b90..e881000 100644 (file)
@@ -6,6 +6,8 @@ add_definitions(-iframework ${QUARTZ_LIBRARY}/Frameworks)
 add_definitions(-iframework ${CARBON_LIBRARY}/Frameworks)
 add_definitions(-DWK_XPC_SERVICE_SUFFIX=".Development")
 
+set(JavaScriptCore_SCRIPTS_DIR "${DERIVED_SOURCES_DIR}/ForwardingHeaders/JavaScriptCore/Scripts")
+
 list(APPEND WebKit2_LIBRARIES
     WebKit
 )
@@ -140,7 +142,8 @@ list(APPEND WebKit2_SOURCES
     Shared/mac/WebMemorySampler.mac.mm
 
     UIProcess/ViewGestureController.cpp
-    UIProcess/WebAutomationSession.cpp
+
+    UIProcess/Automation/WebAutomationSession.cpp
 
     UIProcess/API/APIUserScript.cpp
     UIProcess/API/APIUserStyleSheet.cpp
@@ -352,6 +355,7 @@ list(APPEND WebKit2_INCLUDE_DIRECTORIES
     "${WEBKIT2_DIR}/UIProcess/API/C/mac"
     "${WEBKIT2_DIR}/UIProcess/API/Cocoa"
     "${WEBKIT2_DIR}/UIProcess/API/mac"
+    "${WEBKIT2_DIR}/UIProcess/Automation"
     "${WEBKIT2_DIR}/UIProcess/Cocoa"
     "${WEBKIT2_DIR}/UIProcess/Launcher/mac"
     "${WEBKIT2_DIR}/UIProcess/Scrolling"
@@ -495,4 +499,38 @@ list(APPEND WebKit2_SOURCES
     ${DERIVED_SOURCES_WEBKIT2_DIR}/MessageRecorderProbes.h
 )
 
+set(WebKit2_JSON_RPC_GENERATOR_SCRIPTS
+    ${JavaScriptCore_SCRIPTS_DIR}/generate-inspector-protocol-bindings.py
+    ${JavaScriptCore_SCRIPTS_DIR}/codegen/cpp_generator.py
+    ${JavaScriptCore_SCRIPTS_DIR}/codegen/cpp_generator_templates.py
+    ${JavaScriptCore_SCRIPTS_DIR}/codegen/generate_cpp_backend_dispatcher_header.py
+    ${JavaScriptCore_SCRIPTS_DIR}/codegen/generate_cpp_backend_dispatcher_implementation.py
+    ${JavaScriptCore_SCRIPTS_DIR}/codegen/generate_cpp_protocol_types_header.py
+    ${JavaScriptCore_SCRIPTS_DIR}/codegen/generate_cpp_protocol_types_implementation.py
+    ${JavaScriptCore_SCRIPTS_DIR}/codegen/generator.py
+    ${JavaScriptCore_SCRIPTS_DIR}/codegen/generator_templates.py
+    ${JavaScriptCore_SCRIPTS_DIR}/codegen/models.py
+)
+
+set(WebKit2_JSON_RPC_GENERATOR_INPUTS
+    ${WEBKIT2_DIR}/UIProcess/Automation/Automation.json
+)
+
+add_custom_command(
+    OUTPUT ${DERIVED_SOURCES_WEBKIT2_DIR}/InspectorBackendDispatchers.h ${DERIVED_SOURCES_WEBKIT2_DIR}/InspectorBackendDispatchers.cpp ${DERIVED_SOURCES_WEBKIT2_DIR}/InspectorProtocolObjects.h ${DERIVED_SOURCES_WEBKIT2_DIR}/InspectorProtocolObjects.cpp
+    MAIN_DEPENDENCY ${WebKit2_JSON_RPC_GENERATOR_INPUTS}
+    DEPENDS ${WebKit2_JSON_RPC_GENERATOR_SCRIPTS}
+    COMMAND ${PYTHON_EXECUTABLE} ${JavaScriptCore_SCRIPTS_DIR}/generate-inspector-protocol-bindings.py --outputDir "${DERIVED_SOURCES_WEBKIT2_DIR}" --framework WebKit --backend ${WebKit2_JSON_RPC_GENERATOR_INPUTS}
+    VERBATIM)
+
+list(APPEND WebKit2_HEADERS
+    ${DERIVED_SOURCES_WEBKIT2_DIR}/InspectorBackendDispatchers.h
+    ${DERIVED_SOURCES_WEBKIT2_DIR}/InspectorProtocolObjects.h
+)
+
+list(APPEND WebKit2_SOURCES
+    ${DERIVED_SOURCES_WEBKIT2_DIR}/InspectorBackendDispatchers.cpp
+    ${DERIVED_SOURCES_WEBKIT2_DIR}/InspectorProtocolObjects.cpp
+)
+
 WEBKIT_CREATE_FORWARDING_HEADERS(WebKit FILES ${WebKit2_FORWARDING_HEADERS_FILES} DIRECTORIES ${WebKit2_FORWARDING_HEADERS_DIRECTORIES})
diff --git a/Source/WebKit2/UIProcess/Automation/Automation.json b/Source/WebKit2/UIProcess/Automation/Automation.json
new file mode 100644 (file)
index 0000000..345c70b
--- /dev/null
@@ -0,0 +1,40 @@
+{
+    "domain": "Automation",
+    "description": "Automation domain exposes commands for automating user interactions with the browser.",
+    "types": [
+        {
+            "id": "OpaqueWindowHandle",
+            "type": "string",
+            "description": "An opaque identifier for a window."
+        },
+        {
+            "id": "BrowsingWindow",
+            "type": "object",
+            "description": "A handle representing an open window or tab in the automation session.",
+            "properties": [
+                { "name": "handle", "$ref": "OpaqueWindowHandle", "description": "Opaque handle for the window. Used as a key for window-related commands." },
+                { "name": "active", "type": "boolean", "description": "Whether the window is active at the time the command is handled." }
+            ]
+        }
+    ],
+    "commands": [
+        {
+            "name": "getWindows",
+            "returns": [
+                { "name": "windows", "type": "array", "items": { "$ref": "BrowsingWindow"}, "description": "All known windows and tabs in the browsing session." }
+            ],
+            "description": "Gets information about all open windows and tabs in the automation session."
+        },
+        {
+            "name": "openWindow",
+            "description": "Opens a new automation window in the current browsing context."
+        },
+        {
+            "name": "closeWindow",
+            "parameters": [
+                { "name": "handle", "$ref": "OpaqueWindowHandle", "description": "The handle for the window that should be closed." }
+            ],
+            "description": "Closes the specified window."
+        }
+    ]
+}
 #include "WebAutomationSession.h"
 
 #include "APIAutomationSessionClient.h"
+#include <JavaScriptCore/InspectorBackendDispatcher.h>
+#include <JavaScriptCore/InspectorFrontendRouter.h>
+
+using namespace Inspector;
 
 namespace WebKit {
 
 WebAutomationSession::WebAutomationSession()
     : m_client(std::make_unique<API::AutomationSessionClient>())
+    , m_frontendRouter(FrontendRouter::create())
+    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
 {
+    // FIXME: to actually handle incoming commands, an agent needs to be created
+    // and registered with the backend dispatcher in the constructor.
 }
 
 WebAutomationSession::~WebAutomationSession()
@@ -52,9 +60,9 @@ void WebAutomationSession::setClient(std::unique_ptr<API::AutomationSessionClien
 
 // Inspector::RemoteAutomationTarget API
 
-void WebAutomationSession::dispatchMessageFromRemote(const String&)
+void WebAutomationSession::dispatchMessageFromRemote(const String& message)
 {
-    // FIXME: to be implemented.
+    m_backendDispatcher->dispatch(message);
 }
 
 void WebAutomationSession::connect(Inspector::FrontendChannel* channel, bool isAutomaticConnection)
@@ -62,14 +70,20 @@ void WebAutomationSession::connect(Inspector::FrontendChannel* channel, bool isA
     UNUSED_PARAM(isAutomaticConnection);
 
     m_remoteChannel = channel;
+    m_frontendRouter->connectFrontend(channel);
+
     setIsPaired(true);
 }
 
 void WebAutomationSession::disconnect(Inspector::FrontendChannel* channel)
 {
+    ASSERT(channel == m_remoteChannel);
+
     m_remoteChannel = nullptr;
+    m_frontendRouter->disconnectFrontend(channel);
+
     setIsPaired(false);
-    
+
     if (m_client)
         m_client->didDisconnectFromRemote(this);
 }
@@ -37,6 +37,11 @@ namespace API {
 class AutomationSessionClient;
 }
 
+namespace Inspector {
+class BackendDispatcher;
+class FrontendRouter;
+}
+
 namespace WebKit {
 
 class WebAutomationSessionClient;
@@ -66,6 +71,8 @@ public:
 private:
     std::unique_ptr<API::AutomationSessionClient> m_client;
     String m_sessionIdentifier { ASCIILiteral("Untitled Session") };
+    Ref<Inspector::FrontendRouter> m_frontendRouter;
+    Ref<Inspector::BackendDispatcher> m_backendDispatcher;
 
 #if ENABLE(REMOTE_INSPECTOR)
     Inspector::FrontendChannel* m_remoteChannel { nullptr };
index f659b71..dcb8129 100644 (file)
                990D28B21C65209400986977 /* _WKAutomationSession.mm in Sources */ = {isa = PBXBuildFile; fileRef = 990D28AD1C65190400986977 /* _WKAutomationSession.mm */; };
                990D28BB1C6539D300986977 /* AutomationSessionClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 990D28B71C6539A000986977 /* AutomationSessionClient.h */; };
                990D28BC1C6539DA00986977 /* AutomationSessionClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 990D28B81C6539A000986977 /* AutomationSessionClient.mm */; };
-               990D28BF1C654D3900986977 /* WebAutomationSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 990D28BD1C65490A00986977 /* WebAutomationSession.cpp */; };
                990D28C01C6553F100986977 /* APIAutomationSessionClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 990D28B31C6526D400986977 /* APIAutomationSessionClient.h */; };
-               990D28C11C65626500986977 /* WebAutomationSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 990D28B51C6526F500986977 /* WebAutomationSession.h */; };
+               9955A6EC1C7980C200EB6A93 /* WebAutomationSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 9955A6EB1C7980BB00EB6A93 /* WebAutomationSession.h */; };
+               9955A6ED1C7980CA00EB6A93 /* WebAutomationSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9955A6EA1C7980BB00EB6A93 /* WebAutomationSession.cpp */; };
+               9955A6EF1C79810800EB6A93 /* Automation.json in Headers */ = {isa = PBXBuildFile; fileRef = 9955A6E91C7980BB00EB6A93 /* Automation.json */; settings = {ATTRIBUTES = (Private, ); }; };
+               9955A6F41C7986DC00EB6A93 /* InspectorBackendDispatchers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9955A6F01C79866400EB6A93 /* InspectorBackendDispatchers.cpp */; };
+               9955A6F51C7986E000EB6A93 /* InspectorBackendDispatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = 9955A6F11C79866400EB6A93 /* InspectorBackendDispatchers.h */; };
+               9955A6F61C7986E300EB6A93 /* InspectorProtocolObjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9955A6F21C79866400EB6A93 /* InspectorProtocolObjects.cpp */; };
+               9955A6F71C7986E500EB6A93 /* InspectorProtocolObjects.h in Headers */ = {isa = PBXBuildFile; fileRef = 9955A6F31C79866400EB6A93 /* InspectorProtocolObjects.h */; };
                99C81D591C20E1E5005C4C82 /* AutomationClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 99C81D561C20DFBE005C4C82 /* AutomationClient.mm */; };
                99C81D5A1C20E7E2005C4C82 /* AutomationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 99C81D551C20DFBE005C4C82 /* AutomationClient.h */; };
                99C81D5D1C21F38B005C4C82 /* APIAutomationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 99C81D5B1C20E817005C4C82 /* APIAutomationClient.h */; };
                990D28AD1C65190400986977 /* _WKAutomationSession.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKAutomationSession.mm; sourceTree = "<group>"; };
                990D28AF1C65203900986977 /* _WKAutomationSessionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKAutomationSessionInternal.h; sourceTree = "<group>"; };
                990D28B31C6526D400986977 /* APIAutomationSessionClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIAutomationSessionClient.h; sourceTree = "<group>"; };
-               990D28B51C6526F500986977 /* WebAutomationSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAutomationSession.h; sourceTree = "<group>"; };
                990D28B71C6539A000986977 /* AutomationSessionClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutomationSessionClient.h; sourceTree = "<group>"; };
                990D28B81C6539A000986977 /* AutomationSessionClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutomationSessionClient.mm; sourceTree = "<group>"; };
-               990D28BD1C65490A00986977 /* WebAutomationSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebAutomationSession.cpp; sourceTree = "<group>"; };
+               9955A6E91C7980BB00EB6A93 /* Automation.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Automation.json; sourceTree = "<group>"; };
+               9955A6EA1C7980BB00EB6A93 /* WebAutomationSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebAutomationSession.cpp; sourceTree = "<group>"; };
+               9955A6EB1C7980BB00EB6A93 /* WebAutomationSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAutomationSession.h; sourceTree = "<group>"; };
+               9955A6F01C79866400EB6A93 /* InspectorBackendDispatchers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorBackendDispatchers.cpp; sourceTree = "<group>"; };
+               9955A6F11C79866400EB6A93 /* InspectorBackendDispatchers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorBackendDispatchers.h; sourceTree = "<group>"; };
+               9955A6F21C79866400EB6A93 /* InspectorProtocolObjects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorProtocolObjects.cpp; sourceTree = "<group>"; };
+               9955A6F31C79866400EB6A93 /* InspectorProtocolObjects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorProtocolObjects.h; sourceTree = "<group>"; };
                99C81D551C20DFBE005C4C82 /* AutomationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutomationClient.h; sourceTree = "<group>"; };
                99C81D561C20DFBE005C4C82 /* AutomationClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutomationClient.mm; sourceTree = "<group>"; };
                99C81D5B1C20E817005C4C82 /* APIAutomationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIAutomationClient.h; sourceTree = "<group>"; };
                        path = mac;
                        sourceTree = "<group>";
                };
+               9955A6E81C79809000EB6A93 /* Automation */ = {
+                       isa = PBXGroup;
+                       children = (
+                               9955A6E91C7980BB00EB6A93 /* Automation.json */,
+                               9955A6EA1C7980BB00EB6A93 /* WebAutomationSession.cpp */,
+                               9955A6EB1C7980BB00EB6A93 /* WebAutomationSession.h */,
+                       );
+                       path = Automation;
+                       sourceTree = "<group>";
+               };
                A182D5B11BE6BCF40087A7CC /* ios */ = {
                        isa = PBXGroup;
                        children = (
                        children = (
                                BC032DC410F4387C0058C15A /* API */,
                                512F588D12A8836F00629530 /* Authentication */,
+                               9955A6E81C79809000EB6A93 /* Automation */,
                                1ABC3DF21899E415004F0626 /* Cocoa */,
                                1AB7D4C71288AA9A00CFD08C /* Downloads */,
                                2DA944A81884E9AB00ED86DB /* ios */,
                                1A0F29E1120B44420053D1B9 /* VisitedLinkStore.cpp */,
                                1A0F29E2120B44420053D1B9 /* VisitedLinkStore.h */,
                                1A60224918C16B0800C3E8C9 /* VisitedLinkStore.messages.in */,
-                               990D28BD1C65490A00986977 /* WebAutomationSession.cpp */,
-                               990D28B51C6526F500986977 /* WebAutomationSession.h */,
                                BC72BA1B11E64907001EB4EA /* WebBackForwardList.cpp */,
                                BC72BA1C11E64907001EB4EA /* WebBackForwardList.h */,
                                F036978715F4BF0500C3A80E /* WebColorPicker.cpp */,
                                1A64230712DD09EB00CAAE2C /* DrawingAreaProxyMessages.h */,
                                1AA575FF1496B7C000A4EE06 /* EventDispatcherMessageReceiver.cpp */,
                                1AA576001496B7C000A4EE06 /* EventDispatcherMessages.h */,
+                               9955A6F01C79866400EB6A93 /* InspectorBackendDispatchers.cpp */,
+                               9955A6F11C79866400EB6A93 /* InspectorBackendDispatchers.h */,
+                               9955A6F21C79866400EB6A93 /* InspectorProtocolObjects.cpp */,
+                               9955A6F31C79866400EB6A93 /* InspectorProtocolObjects.h */,
                                51DD9F2616367DA2001578E9 /* NetworkConnectionToWebProcessMessageReceiver.cpp */,
                                51DD9F2716367DA2001578E9 /* NetworkConnectionToWebProcessMessages.h */,
                                517CF0E1163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp */,
                                93E6A4EE1BC5DD3900F8A0E7 /* _WKHitTestResult.h in Headers */,
                                93A88B3B1BC710D900ABA5C2 /* _WKHitTestResultInternal.h in Headers */,
                                37A64E5518F38E3C00EB30F1 /* _WKInputDelegate.h in Headers */,
+                               9955A6EF1C79810800EB6A93 /* Automation.json in Headers */,
                                2D790A9D1AD7050D00AB90B3 /* _WKLayoutMode.h in Headers */,
                                A118A9F31908B8EA00F7C92B /* _WKNSFileManagerExtras.h in Headers */,
                                9323611E1B015DA800FA9232 /* _WKOverlayScrollbarStyle.h in Headers */,
                                E1EE53E311F8CFC000CCBEE4 /* InjectedBundlePageEditorClient.h in Headers */,
                                BC14E10A120B905E00826C0C /* InjectedBundlePageFormClient.h in Headers */,
                                510523821C7541FF007993CB /* LegacyUniqueIDBDatabaseIdentifier.h in Headers */,
-                               990D28C11C65626500986977 /* WebAutomationSession.h in Headers */,
                                CD5C66A1134B9D38004FE2A8 /* InjectedBundlePageFullScreenClient.h in Headers */,
                                BCA8C6A911E3BA5F00812FB7 /* InjectedBundlePageLoaderClient.h in Headers */,
                                510523801C7541FF007993CB /* LegacyUniqueIDBDatabase.h in Headers */,
                                BC8147A912F64CDA007B2C32 /* InjectedBundlePagePolicyClient.h in Headers */,
                                BCA8C6B011E3C08700812FB7 /* InjectedBundlePageUIClient.h in Headers */,
+                               9955A6F71C7986E500EB6A93 /* InspectorProtocolObjects.h in Headers */,
                                BC33E0D112408E8600360F3F /* InjectedBundleRangeHandle.h in Headers */,
                                BC14DF77120B5B7900826C0C /* InjectedBundleScriptWorld.h in Headers */,
                                C58CDF2A1887548B00871536 /* InteractionInformationAtPosition.h in Headers */,
                                E14A954A16E016A40068DE82 /* NetworkProcessPlatformStrategies.h in Headers */,
                                5179556E162877B300FA43B6 /* NetworkProcessProxy.h in Headers */,
                                513A163D163088F6005D7D22 /* NetworkProcessProxyMessages.h in Headers */,
+                               9955A6F51C7986E000EB6A93 /* InspectorBackendDispatchers.h in Headers */,
                                51FD18B61651FBAD00DBE1CE /* NetworkResourceLoader.h in Headers */,
                                E152551B17011819003D7ADB /* NetworkResourceLoaderMessages.h in Headers */,
                                5C20CBA01BB1ECD800895BB1 /* NetworkSession.h in Headers */,
                                1A002D49196B345D00B9AD44 /* SessionStateCoding.h in Headers */,
                                753E3E0E1887398900188496 /* SessionTracker.h in Headers */,
                                99C81D5A1C20E7E2005C4C82 /* AutomationClient.h in Headers */,
+                               9955A6EC1C7980C200EB6A93 /* WebAutomationSession.h in Headers */,
                                1A6420E512DCE2FF00CAAE2C /* ShareableBitmap.h in Headers */,
                                51217461164C20E30037A5C1 /* ShareableResource.h in Headers */,
                                1A24BED5120894D100FBB059 /* SharedMemory.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        shellPath = /bin/sh;
-                       shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebKit2\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebKit2\"\n\nexport WebKit2=\"${SRCROOT}\"\n\nif [ ! $CC ]; then\n    export CC=\"`xcrun -find clang`\"\nfi\n\nMAKEFILE_INCLUDE_FLAGS=$(echo \"${WEBKITADDITIONS_HEADER_SEARCH_PATHS}\" | perl -e 'print \"-I\" . join(\" -I\", split(\" \", <>));')\n\nif [ \"${ACTION}\" = \"build\" -o \"${ACTION}\" = \"install\" -o \"${ACTION}\" = \"installhdrs\" ]; then\n    make --no-builtin-rules ${MAKEFILE_INCLUDE_FLAGS} -f \"${WebKit2}/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.activecpu` SDKROOT=${SDKROOT}\nfi\n";
+                       shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebKit2\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebKit2\"\n\nexport WebKit2=\"${SRCROOT}\"\n\n/bin/ln -sfh \"${JAVASCRIPTCORE_PRIVATE_HEADERS_DIR}\" JavaScriptCorePrivateHeaders\nexport JavaScriptCore_SCRIPTS_DIR=\"JavaScriptCorePrivateHeaders\"\n\nif [ ! $CC ]; then\n    export CC=\"`xcrun -find clang`\"\nfi\n\nMAKEFILE_INCLUDE_FLAGS=$(echo \"${WEBKITADDITIONS_HEADER_SEARCH_PATHS}\" | perl -e 'print \"-I\" . join(\" -I\", split(\" \", <>));')\n\nif [ \"${ACTION}\" = \"build\" -o \"${ACTION}\" = \"install\" -o \"${ACTION}\" = \"installhdrs\" ]; then\n    make --no-builtin-rules ${MAKEFILE_INCLUDE_FLAGS} -f \"${WebKit2}/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.activecpu` SDKROOT=${SDKROOT}\nfi\n";
                };
 /* End PBXShellScriptBuildPhase section */
 
                        files = (
                                37A5E01318BBF937000A081E /* _WKActivatedElementInfo.mm in Sources */,
                                1A5704F71BE01FF400874AF1 /* _WKContextMenuElementInfo.mm in Sources */,
+                               9955A6F41C7986DC00EB6A93 /* InspectorBackendDispatchers.cpp in Sources */,
                                A1A4FE5B18DCE9FA00B5EA8A /* _WKDownload.mm in Sources */,
                                379A873918BBFE0F00588AF2 /* _WKElementAction.mm in Sources */,
                                1A5704F11BE0173F00874AF1 /* _WKElementInfo.mm in Sources */,
                                1AC1336718565B5700F3EC05 /* UserData.cpp in Sources */,
                                15739BBC1B42040300D258C1 /* UserMediaPermissionRequestManager.cpp in Sources */,
                                4A3CC18A19B063E700D14AEF /* UserMediaPermissionRequestManagerProxy.cpp in Sources */,
+                               9955A6ED1C7980CA00EB6A93 /* WebAutomationSession.cpp in Sources */,
                                4A3CC18C19B0641500D14AEF /* UserMediaPermissionRequestProxy.cpp in Sources */,
                                E4E864921B16750100C82F40 /* VersionChecks.mm in Sources */,
                                2DAF4FFB1B636181006013D6 /* ViewGestureController.cpp in Sources */,
                                BC857FB612B830E600EDEB2E /* WebOpenPanelParameters.cpp in Sources */,
                                BC857F8612B82D0B00EDEB2E /* WebOpenPanelResultListener.cpp in Sources */,
                                BC857F7E12B82CEE00EDEB2E /* WebOpenPanelResultListenerProxy.cpp in Sources */,
+                               9955A6F61C7986E300EB6A93 /* InspectorProtocolObjects.cpp in Sources */,
                                BC963D6B113DD19200574BE2 /* WebPage.cpp in Sources */,
                                C06C6095124C144B0001682F /* WebPageCreationParameters.cpp in Sources */,
                                8372DB281A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp in Sources */,
                                C98C48A91B6FD5B500145103 /* WKMediaSessionFocusManager.cpp in Sources */,
                                C9CD439E1B4B025300239E33 /* WKMediaSessionMetadata.cpp in Sources */,
                                BC4075FD124FF0270068F20A /* WKMutableArray.cpp in Sources */,
-                               990D28BF1C654D3900986977 /* WebAutomationSession.cpp in Sources */,
                                BC4075FF124FF0270068F20A /* WKMutableDictionary.cpp in Sources */,
                                1A5B1C501898606F004FCF9B /* WKNavigation.mm in Sources */,
                                1A256E3718A1A788006FB922 /* WKNavigationAction.mm in Sources */,