Title: [189338] trunk
Revision
189338
Author
[email protected]
Date
2015-09-03 20:58:43 -0700 (Thu, 03 Sep 2015)

Log Message

Web Inspector: InspectorController should support multiple frontend channels
https://bugs.webkit.org/show_bug.cgi?id=148538

Reviewed by Joseph Pecoraro.

Source/_javascript_Core:

Instead of a singleton, it should be possible to have multiple channels open
at the same time and to individually close channels as frontends come and go.

The FrontendRouter class keeps a list of open FrontendChannels and sends messages
to the appropriate frontends based on whether the message is a response or event.
Each InspectorController owns a single FrontendRouter and BackendDispatcher instance.
Inspector backend code that sends messages to the frontend should switch over to
using the router rather than directly using a FrontendChannel.

* CMakeLists.txt:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj:
* _javascript_Core.xcodeproj/project.pbxproj:
* inspector/InspectorBackendDispatcher.cpp: Move constructors/destructors out of the header
to avoid including InspectorFrontendRouter everywhere. Use the router instead of a
specific frontend channel. Remove guards that are no longer necessary since the router
is guaranteed to outlive the backend dispatcher.

(Inspector::SupplementalBackendDispatcher::SupplementalBackendDispatcher):
(Inspector::SupplementalBackendDispatcher::~SupplementalBackendDispatcher):
(Inspector::BackendDispatcher::BackendDispatcher):
(Inspector::BackendDispatcher::create):
(Inspector::BackendDispatcher::isActive):
(Inspector::BackendDispatcher::registerDispatcherForDomain):
(Inspector::BackendDispatcher::sendResponse):
(Inspector::BackendDispatcher::sendPendingErrors):
* inspector/InspectorBackendDispatcher.h:
(Inspector::SupplementalBackendDispatcher::SupplementalBackendDispatcher): Deleted.
(Inspector::SupplementalBackendDispatcher::~SupplementalBackendDispatcher): Deleted.
(Inspector::BackendDispatcher::clearFrontend): Deleted, no longer necessary.
(Inspector::BackendDispatcher::isActive): Moved to implementation file.
(Inspector::BackendDispatcher::BackendDispatcher): Moved to implementation file.
* inspector/InspectorFrontendRouter.cpp: Added.
(Inspector::FrontendRouter::create):
(Inspector::FrontendRouter::connectFrontend):
(Inspector::FrontendRouter::disconnectFrontend):
(Inspector::FrontendRouter::disconnectAllFrontends):
(Inspector::FrontendRouter::leakChannel):
(Inspector::FrontendRouter::hasLocalFrontend):
(Inspector::FrontendRouter::hasRemoteFrontend):
(Inspector::FrontendRouter::sendEvent):
(Inspector::FrontendRouter::sendResponse):
* inspector/InspectorFrontendRouter.h: Added.
* inspector/JSGlobalObjectInspectorController.cpp: Remove guards that are no longer necessary.
The frontend router and backend dispatcher now have the same lifetime as the controller.
Explicitly connect/disconnect the frontend channel.

(Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
(Inspector::JSGlobalObjectInspectorController::globalObjectDestroyed):
(Inspector::JSGlobalObjectInspectorController::connectFrontend):
(Inspector::JSGlobalObjectInspectorController::disconnectFrontend):
(Inspector::JSGlobalObjectInspectorController::disconnectAllFrontends):
(Inspector::JSGlobalObjectInspectorController::dispatchMessageFromFrontend):
(Inspector::JSGlobalObjectInspectorController::appendExtraAgent):
(Inspector::JSGlobalObjectInspectorController::pause): Deleted.
* inspector/JSGlobalObjectInspectorController.h:
* inspector/agents/InspectorAgent.cpp:
* inspector/agents/InspectorConsoleAgent.cpp:
* inspector/agents/InspectorDebuggerAgent.cpp:
* inspector/agents/InspectorRuntimeAgent.cpp:
* inspector/augmentable/AugmentableInspectorController.h:
(Inspector::AugmentableInspectorController::connected):
* inspector/remote/RemoteInspectorDebuggable.h:
* inspector/remote/RemoteInspectorDebuggableConnection.mm:
(Inspector::RemoteInspectorDebuggableConnection::close):
* inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py:
(CppAlternateBackendDispatcherHeaderGenerator.generate_output):
* inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py:
(ObjCFrontendDispatcherImplementationGenerator._generate_event): Use the router.
* runtime/JSGlobalObjectDebuggable.cpp:
(JSC::JSGlobalObjectDebuggable::disconnect):
* runtime/JSGlobalObjectDebuggable.h:

Source/WebCore:

No new tests, no behavior change from this patch. Teardown scenarios are
covered by existing protocol and inspector tests running under DRT and WKTR.

* ForwardingHeaders/inspector/InspectorFrontendRouter.h: Added.
* WebCore.vcxproj/WebCore.vcxproj:
* inspector/InspectorClient.h: Stop using forwarded types.
* inspector/InspectorController.cpp:
(WebCore::InspectorController::InspectorController):
(WebCore::InspectorController::inspectedPageDestroyed):
(WebCore::InspectorController::hasLocalFrontend):
(WebCore::InspectorController::hasRemoteFrontend):
(WebCore::InspectorController::connectFrontend):
(WebCore::InspectorController::disconnectFrontend):
(WebCore::InspectorController::disconnectAllFrontends): Added. Disconnects all
frontends and signals DisconnectReason::InspectedTargetDestroyed.

(WebCore::InspectorController::show):
(WebCore::InspectorController::close):
(WebCore::InspectorController::dispatchMessageFromFrontend):
* inspector/InspectorController.h: Add default value for isAutomaticInspection.
* inspector/InspectorDatabaseAgent.cpp:
* inspector/InspectorIndexedDBAgent.cpp:
* inspector/InspectorResourceAgent.cpp:
* inspector/WorkerInspectorController.cpp: Use a router with a singleton channel
that forwards messages over to the main page.

(WebCore::WorkerInspectorController::WorkerInspectorController):
(WebCore::WorkerInspectorController::connectFrontend):
(WebCore::WorkerInspectorController::disconnectFrontend):
(WebCore::WorkerInspectorController::dispatchMessageFromFrontend):
* inspector/WorkerInspectorController.h:
* page/PageDebuggable.cpp:
(WebCore::PageDebuggable::disconnect):
* page/PageDebuggable.h:
* testing/Internals.cpp: Clear the frontend client before disconnecting frontend channel.
(WebCore::Internals::openDummyInspectorFrontend):
(WebCore::Internals::closeDummyInspectorFrontend):

Source/WebKit/mac:

Remove the notifyInspectorController flag from closeWindow. Since InspectorClients
must now manually disconnect their FrontendChannel(s), we should always
perform the teardown that was guarded by this flag.

* WebCoreSupport/WebInspectorClient.h:
* WebCoreSupport/WebInspectorClient.mm:
(WebInspectorClient::bringFrontendToFront): Add a missing assertion.
(WebInspectorFrontendClient::closeWindow):
(WebInspectorFrontendClient::disconnectFromBackend):
(-[WebInspectorWindowController windowShouldClose:]):
(-[WebInspectorWindowController destroyInspectorView]): Always clear the frontend client.
(-[WebInspectorWindowController destroyInspectorView:]): Renamed to above.

Source/WebKit/win:

Remove the notifyInspectorController flag from closeWindow. Since InspectorClients
must now manually disconnect their FrontendChannel(s), we should always
perform the teardown that was guarded by this flag.

* WebCoreSupport/WebInspectorClient.cpp:
(WebInspectorClient::closeInspectorFrontend):
(WebInspectorFrontendClient::~WebInspectorFrontendClient):
(WebInspectorFrontendClient::closeWindow):
(WebInspectorFrontendClient::destroyInspectorView):
* WebCoreSupport/WebInspectorClient.h:

Source/WebKit2:

Explicitly disconnect the frontend channel when closing the frontend.

Rename createInspectorPage/closeFrontend to the symmetric and unambiguous
{open,close}FrontendConnection in the WebInspector class.

* WebProcess/WebCoreSupport/WebInspectorClient.cpp:
(WebKit::WebInspectorClient::openInspectorFrontend):
(WebKit::WebInspectorClient::closeInspectorFrontend):
* WebProcess/WebCoreSupport/WebInspectorClient.h: Stop using a forwarded type.
* WebProcess/WebPage/WebInspector.cpp:
(WebKit::WebInspector::openFrontendConnection):
(WebKit::WebInspector::closeFrontendConnection):
(WebKit::WebInspector::remoteFrontendConnected):
(WebKit::WebInspector::remoteFrontendDisconnected):
(WebKit::WebInspector::createInspectorPage): Deleted.
(WebKit::WebInspector::closeFrontend): Deleted.
* WebProcess/WebPage/WebInspector.h:

Tools:

InspectorClients must explicitly disconnect their frontend channel(s) from the
inspected page's InspectorController.

To make this possible, DumpRenderTree should not destroy non-primary views until
it has tried to close any abandoned Web Inspector instances. Performing teardown
in the reverse order prevents disconnection of the frontend channel because that
prematurely destroys the inspector frontend client.

* DumpRenderTree/mac/DumpRenderTree.mm:
(runTest):
* DumpRenderTree/win/DumpRenderTree.cpp:
(runTest):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (189337 => 189338)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2015-09-04 03:58:43 UTC (rev 189338)
@@ -323,6 +323,7 @@
     inspector/InjectedScriptManager.cpp
     inspector/InjectedScriptModule.cpp
     inspector/InspectorAgentRegistry.cpp
+    inspector/InspectorFrontendRouter.cpp
     inspector/InspectorBackendDispatcher.cpp
     inspector/InspectorValues.cpp
     inspector/JSGlobalObjectConsoleClient.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (189337 => 189338)


--- trunk/Source/_javascript_Core/ChangeLog	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-09-04 03:58:43 UTC (rev 189338)
@@ -1,3 +1,82 @@
+2015-09-03  Brian Burg  <[email protected]>
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        Instead of a singleton, it should be possible to have multiple channels open
+        at the same time and to individually close channels as frontends come and go.
+
+        The FrontendRouter class keeps a list of open FrontendChannels and sends messages
+        to the appropriate frontends based on whether the message is a response or event.
+        Each InspectorController owns a single FrontendRouter and BackendDispatcher instance.
+        Inspector backend code that sends messages to the frontend should switch over to
+        using the router rather than directly using a FrontendChannel.
+
+        * CMakeLists.txt:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * inspector/InspectorBackendDispatcher.cpp: Move constructors/destructors out of the header
+        to avoid including InspectorFrontendRouter everywhere. Use the router instead of a
+        specific frontend channel. Remove guards that are no longer necessary since the router
+        is guaranteed to outlive the backend dispatcher.
+
+        (Inspector::SupplementalBackendDispatcher::SupplementalBackendDispatcher):
+        (Inspector::SupplementalBackendDispatcher::~SupplementalBackendDispatcher):
+        (Inspector::BackendDispatcher::BackendDispatcher):
+        (Inspector::BackendDispatcher::create):
+        (Inspector::BackendDispatcher::isActive):
+        (Inspector::BackendDispatcher::registerDispatcherForDomain):
+        (Inspector::BackendDispatcher::sendResponse):
+        (Inspector::BackendDispatcher::sendPendingErrors):
+        * inspector/InspectorBackendDispatcher.h:
+        (Inspector::SupplementalBackendDispatcher::SupplementalBackendDispatcher): Deleted.
+        (Inspector::SupplementalBackendDispatcher::~SupplementalBackendDispatcher): Deleted.
+        (Inspector::BackendDispatcher::clearFrontend): Deleted, no longer necessary.
+        (Inspector::BackendDispatcher::isActive): Moved to implementation file.
+        (Inspector::BackendDispatcher::BackendDispatcher): Moved to implementation file.
+        * inspector/InspectorFrontendRouter.cpp: Added.
+        (Inspector::FrontendRouter::create):
+        (Inspector::FrontendRouter::connectFrontend):
+        (Inspector::FrontendRouter::disconnectFrontend):
+        (Inspector::FrontendRouter::disconnectAllFrontends):
+        (Inspector::FrontendRouter::leakChannel):
+        (Inspector::FrontendRouter::hasLocalFrontend):
+        (Inspector::FrontendRouter::hasRemoteFrontend):
+        (Inspector::FrontendRouter::sendEvent):
+        (Inspector::FrontendRouter::sendResponse):
+        * inspector/InspectorFrontendRouter.h: Added.
+        * inspector/JSGlobalObjectInspectorController.cpp: Remove guards that are no longer necessary.
+        The frontend router and backend dispatcher now have the same lifetime as the controller.
+        Explicitly connect/disconnect the frontend channel.
+
+        (Inspector::JSGlobalObjectInspectorController::JSGlobalObjectInspectorController):
+        (Inspector::JSGlobalObjectInspectorController::globalObjectDestroyed):
+        (Inspector::JSGlobalObjectInspectorController::connectFrontend):
+        (Inspector::JSGlobalObjectInspectorController::disconnectFrontend):
+        (Inspector::JSGlobalObjectInspectorController::disconnectAllFrontends):
+        (Inspector::JSGlobalObjectInspectorController::dispatchMessageFromFrontend):
+        (Inspector::JSGlobalObjectInspectorController::appendExtraAgent):
+        (Inspector::JSGlobalObjectInspectorController::pause): Deleted.
+        * inspector/JSGlobalObjectInspectorController.h:
+        * inspector/agents/InspectorAgent.cpp:
+        * inspector/agents/InspectorConsoleAgent.cpp:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        * inspector/augmentable/AugmentableInspectorController.h:
+        (Inspector::AugmentableInspectorController::connected):
+        * inspector/remote/RemoteInspectorDebuggable.h:
+        * inspector/remote/RemoteInspectorDebuggableConnection.mm:
+        (Inspector::RemoteInspectorDebuggableConnection::close):
+        * inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py:
+        (CppAlternateBackendDispatcherHeaderGenerator.generate_output):
+        * inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py:
+        (ObjCFrontendDispatcherImplementationGenerator._generate_event): Use the router.
+        * runtime/JSGlobalObjectDebuggable.cpp:
+        (JSC::JSGlobalObjectDebuggable::disconnect):
+        * runtime/JSGlobalObjectDebuggable.h:
+
 2015-09-03  Basile Clement  <[email protected]>
 
         [ES6] Recognize calls in tail position

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (189337 => 189338)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-09-04 03:58:43 UTC (rev 189338)
@@ -595,6 +595,7 @@
     <ClCompile Include="..\inspector\InjectedScriptModule.cpp" />
     <ClCompile Include="..\inspector\InspectorAgentRegistry.cpp" />
     <ClCompile Include="..\inspector\InspectorBackendDispatcher.cpp" />
+    <ClCompile Include="..\inspector\InspectorFrontendRouter.cpp" />
     <ClCompile Include="..\inspector\InspectorValues.cpp" />
     <ClCompile Include="..\inspector\JSInjectedScriptHost.cpp" />
     <ClCompile Include="..\inspector\JSInjectedScriptHostPrototype.cpp" />
@@ -1384,6 +1385,7 @@
     <ClInclude Include="..\inspector\InspectorBackendDispatcher.h" />
     <ClInclude Include="..\inspector\InspectorEnvironment.h" />
     <ClInclude Include="..\inspector\InspectorFrontendChannel.h" />
+    <ClInclude Include="..\inspector\InspectorFrontendRouter.h" />
     <ClInclude Include="..\inspector\InspectorValues.h" />
     <ClInclude Include="..\inspector\JSInjectedScriptHost.h" />
     <ClInclude Include="..\inspector\JSInjectedScriptHostPrototype.h" />

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (189337 => 189338)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-09-04 03:58:43 UTC (rev 189338)
@@ -1195,6 +1195,8 @@
 		99E45A2618A1B2590026D88F /* EncodedValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2118A1B2590026D88F /* EncodedValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		99E45A2718A1B2590026D88F /* InputCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2218A1B2590026D88F /* InputCursor.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		99E45A2818A1B2590026D88F /* NondeterministicInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2318A1B2590026D88F /* NondeterministicInput.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		99F1A6FE1B8E6D9400463B26 /* InspectorFrontendRouter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99F1A6FC1B8E6D9400463B26 /* InspectorFrontendRouter.cpp */; };
+		99F1A7011B98FBEC00463B26 /* InspectorFrontendRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 99F1A7001B98FBEC00463B26 /* InspectorFrontendRouter.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		9E729407190F01A5001A91B5 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
 		9E729408190F021E001A91B5 /* InitializeLLVMPOSIX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAC51805E75500472CE4 /* InitializeLLVMPOSIX.cpp */; };
 		9E72940B190F0514001A91B5 /* BundlePath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E72940A190F0514001A91B5 /* BundlePath.h */; };
@@ -3061,6 +3063,8 @@
 		99E45A2118A1B2590026D88F /* EncodedValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncodedValue.h; sourceTree = "<group>"; };
 		99E45A2218A1B2590026D88F /* InputCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputCursor.h; sourceTree = "<group>"; };
 		99E45A2318A1B2590026D88F /* NondeterministicInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NondeterministicInput.h; sourceTree = "<group>"; };
+		99F1A6FC1B8E6D9400463B26 /* InspectorFrontendRouter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorFrontendRouter.cpp; sourceTree = "<group>"; };
+		99F1A7001B98FBEC00463B26 /* InspectorFrontendRouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorFrontendRouter.h; sourceTree = "<group>"; };
 		9B4954E81A6640DB002815A6 /* ParserFunctionInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParserFunctionInfo.h; sourceTree = "<group>"; };
 		9E729409190F0306001A91B5 /* BundlePath.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BundlePath.mm; sourceTree = "<group>"; };
 		9E72940A190F0514001A91B5 /* BundlePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BundlePath.h; sourceTree = "<group>"; };
@@ -5707,6 +5711,7 @@
 		A5BA15DF1823409200A82E69 /* inspector */ = {
 			isa = PBXGroup;
 			children = (
+				99F1A7001B98FBEC00463B26 /* InspectorFrontendRouter.h */,
 				A513E5CC185FB992007E95AD /* agents */,
 				A5EA70E319F5B0E20098F5EC /* augmentable */,
 				A532438D185696CA002ED692 /* protocol */,
@@ -5738,6 +5743,7 @@
 				A593CF7B1840360300BFCE27 /* InspectorBackendDispatcher.h */,
 				A5D0A1BA1862301B00C7B496 /* InspectorEnvironment.h */,
 				A5945594182479EB00CC3843 /* InspectorFrontendChannel.h */,
+				99F1A6FC1B8E6D9400463B26 /* InspectorFrontendRouter.cpp */,
 				A55D93AB18514F7900400DED /* InspectorProtocolTypes.h */,
 				A593CF801840377100BFCE27 /* InspectorValues.cpp */,
 				A593CF811840377100BFCE27 /* InspectorValues.h */,
@@ -5901,6 +5907,7 @@
 				A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
 				0F898F321B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h in Headers */,
 				86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
+				99F1A7011B98FBEC00463B26 /* InspectorFrontendRouter.h in Headers */,
 				7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */,
 				797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */,
 				0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */,
@@ -7933,6 +7940,7 @@
 				C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */,
 				9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
 				E3EF88741B66DF23003F26CB /* JSPropertyNameIterator.cpp in Sources */,
+				99F1A6FE1B8E6D9400463B26 /* InspectorFrontendRouter.cpp in Sources */,
 				0F8F2B9E17306C8D007DBDA5 /* SourceCode.cpp in Sources */,
 				0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */,
 				E33E8D1C1B9013C300346B52 /* JSNativeStdFunction.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/inspector/InspectorBackendDispatcher.cpp (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/InspectorBackendDispatcher.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/InspectorBackendDispatcher.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -28,6 +28,7 @@
 #include "InspectorBackendDispatcher.h"
 
 #include "InspectorFrontendChannel.h"
+#include "InspectorFrontendRouter.h"
 #include "InspectorValues.h"
 #include <wtf/TemporaryChange.h>
 #include <wtf/text/CString.h>
@@ -35,6 +36,15 @@
 
 namespace Inspector {
 
+SupplementalBackendDispatcher::SupplementalBackendDispatcher(BackendDispatcher& backendDispatcher)
+    : m_backendDispatcher(backendDispatcher)
+{
+}
+
+SupplementalBackendDispatcher::~SupplementalBackendDispatcher()
+{
+}
+
 BackendDispatcher::CallbackBase::CallbackBase(Ref<BackendDispatcher>&& backendDispatcher, long requestId)
     : m_backendDispatcher(WTF::move(backendDispatcher))
     , m_requestId(requestId)
@@ -69,15 +79,28 @@
     m_backendDispatcher->sendResponse(m_requestId, WTF::move(partialMessage));
 }
 
-Ref<BackendDispatcher> BackendDispatcher::create(FrontendChannel* frontendChannel)
+BackendDispatcher::BackendDispatcher(Ref<FrontendRouter>&& router)
+    : m_frontendRouter(WTF::move(router))
 {
-    return adoptRef(*new BackendDispatcher(frontendChannel));
 }
 
+Ref<BackendDispatcher> BackendDispatcher::create(Ref<FrontendRouter>&& router)
+{
+    return adoptRef(*new BackendDispatcher(WTF::move(router)));
+}
+
+bool BackendDispatcher::isActive() const
+{
+    return m_frontendRouter->hasFrontends();
+}
+
 void BackendDispatcher::registerDispatcherForDomain(const String& domain, SupplementalBackendDispatcher* dispatcher)
 {
-    auto result = m_dispatchers.add(domain, dispatcher);
-    ASSERT_UNUSED(result, result.isNewEntry);
+    ASSERT_ARG(dispatcher, dispatcher);
+
+    // FIXME: <https://webkit.org/b/148492> Agents should only register with the backend once,
+    // and we should re-add the assertion that only one dispatcher is registered per domain.
+    m_dispatchers.set(domain, dispatcher);
 }
 
 void BackendDispatcher::dispatch(const String& message)
@@ -165,9 +188,6 @@
 
 void BackendDispatcher::sendResponse(long requestId, RefPtr<InspectorObject>&& result)
 {
-    if (!m_frontendChannel)
-        return;
-
     ASSERT(!m_protocolErrors.size());
 
     // The JSON-RPC 2.0 specification requires that the "error" member have the value 'null'
@@ -175,7 +195,7 @@
     Ref<InspectorObject> responseMessage = InspectorObject::create();
     responseMessage->setObject(ASCIILiteral("result"), result);
     responseMessage->setInteger(ASCIILiteral("id"), requestId);
-    m_frontendChannel->sendMessageToFrontend(responseMessage->toJSONString());
+    m_frontendRouter->sendResponse(responseMessage->toJSONString());
 }
 
 void BackendDispatcher::sendPendingErrors()
@@ -190,9 +210,6 @@
         -32000, // ServerError
     };
 
-    if (!m_frontendChannel)
-        return;
-    
     // To construct the error object, only use the last error's code and message.
     // Per JSON-RPC 2.0, Section 5.1, the 'data' member may contain nested errors,
     // but only one top-level Error object should be sent per request.
@@ -227,7 +244,7 @@
         message->setValue(ASCIILiteral("id"), InspectorValue::null());
     }
 
-    m_frontendChannel->sendMessageToFrontend(message->toJSONString());
+    m_frontendRouter->sendResponse(message->toJSONString());
 
     m_protocolErrors.clear();
     m_currentRequestId = Nullopt;

Modified: trunk/Source/_javascript_Core/inspector/InspectorBackendDispatcher.h (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/InspectorBackendDispatcher.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/InspectorBackendDispatcher.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -35,15 +35,14 @@
 namespace Inspector {
 
 class BackendDispatcher;
-class FrontendChannel;
+class FrontendRouter;
 
 typedef String ErrorString;
 
 class SupplementalBackendDispatcher : public RefCounted<SupplementalBackendDispatcher> {
 public:
-    SupplementalBackendDispatcher(BackendDispatcher& backendDispatcher)
-        : m_backendDispatcher(backendDispatcher) { }
-    virtual ~SupplementalBackendDispatcher() { }
+    SupplementalBackendDispatcher(BackendDispatcher&);
+    virtual ~SupplementalBackendDispatcher();
     virtual void dispatch(long requestId, const String& method, Ref<InspectorObject>&& message) = 0;
 protected:
     Ref<BackendDispatcher> m_backendDispatcher;
@@ -51,7 +50,7 @@
 
 class BackendDispatcher : public RefCounted<BackendDispatcher> {
 public:
-    JS_EXPORT_PRIVATE static Ref<BackendDispatcher> create(FrontendChannel*);
+    JS_EXPORT_PRIVATE static Ref<BackendDispatcher> create(Ref<FrontendRouter>&&);
 
     class JS_EXPORT_PRIVATE CallbackBase : public RefCounted<CallbackBase> {
     public:
@@ -69,8 +68,7 @@
         bool m_alreadySent { false };
     };
 
-    void clearFrontend() { m_frontendChannel = nullptr; }
-    bool isActive() const { return !!m_frontendChannel; }
+    bool isActive() const;
 
     bool hasProtocolErrors() const { return m_protocolErrors.size() > 0; }
 
@@ -104,12 +102,9 @@
     RefPtr<InspectorArray> getArray(InspectorObject*, const String& name, bool* valueFound);
 
 private:
-    BackendDispatcher(FrontendChannel* channel)
-        : m_frontendChannel(channel)
-    {
-    }
+    BackendDispatcher(Ref<FrontendRouter>&&);
 
-    FrontendChannel* m_frontendChannel;
+    Ref<FrontendRouter> m_frontendRouter;
     HashMap<String, SupplementalBackendDispatcher*> m_dispatchers;
 
     // Protocol errors reported for the top-level request being processed.

Added: trunk/Source/_javascript_Core/inspector/InspectorFrontendRouter.cpp (0 => 189338)


--- trunk/Source/_javascript_Core/inspector/InspectorFrontendRouter.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/inspector/InspectorFrontendRouter.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorFrontendRouter.h"
+
+#include "InspectorFrontendChannel.h"
+#include <wtf/Assertions.h>
+
+namespace Inspector {
+
+Ref<FrontendRouter> FrontendRouter::create()
+{
+    return adoptRef(*new FrontendRouter);
+}
+
+void FrontendRouter::connectFrontend(FrontendChannel* connection)
+{
+    ASSERT_ARG(connection, connection);
+
+    if (m_connections.contains(connection)) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    m_connections.append(connection);
+}
+
+void FrontendRouter::disconnectFrontend(FrontendChannel* connection)
+{
+    ASSERT_ARG(connection, connection);
+
+    if (!m_connections.contains(connection)) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    m_connections.removeFirst(connection);
+}
+
+void FrontendRouter::disconnectAllFrontends()
+{
+    m_connections.clear();
+}
+
+// FIXME: <https://webkit.org/b/148492> remove this method once agents move to using FrontendRouter directly.
+FrontendChannel* FrontendRouter::leakChannel() const
+{
+    if (m_connections.size())
+        return m_connections.at(0);
+
+    return nullptr;
+}
+
+bool FrontendRouter::hasLocalFrontend() const
+{
+    for (auto* connection : m_connections) {
+        if (connection->connectionType() == FrontendChannel::ConnectionType::Local)
+            return true;
+    }
+
+    return false;
+}
+
+bool FrontendRouter::hasRemoteFrontend() const
+{
+    for (auto* connection : m_connections) {
+        if (connection->connectionType() == FrontendChannel::ConnectionType::Remote)
+            return true;
+    }
+
+    return false;
+}
+
+void FrontendRouter::sendEvent(const String& message) const
+{
+    for (auto* connection : m_connections)
+        connection->sendMessageToFrontend(message);
+}
+
+void FrontendRouter::sendResponse(const String& message) const
+{
+    // FIXME: send responses to the appropriate frontend.
+    for (auto* connection : m_connections)
+        connection->sendMessageToFrontend(message);
+}
+
+} // namespace Inspector

Added: trunk/Source/_javascript_Core/inspector/InspectorFrontendRouter.h (0 => 189338)


--- trunk/Source/_javascript_Core/inspector/InspectorFrontendRouter.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/inspector/InspectorFrontendRouter.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InspectorFrontendRouter_h
+#define InspectorFrontendRouter_h
+
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace Inspector {
+
+class FrontendChannel;
+
+class JS_EXPORT_PRIVATE FrontendRouter : public RefCounted<FrontendRouter> {
+public:
+    static Ref<FrontendRouter> create();
+
+    bool hasFrontends() const { return !m_connections.isEmpty(); }
+    bool hasLocalFrontend() const;
+    bool hasRemoteFrontend() const;
+
+    void connectFrontend(FrontendChannel*);
+    void disconnectFrontend(FrontendChannel*);
+    void disconnectAllFrontends();
+
+    // FIXME: <https://webkit.org/b/148492> remove this method once agents move to using FrontendRouter directly.
+    FrontendChannel* leakChannel() const;
+
+    void sendEvent(const String& message) const;
+    void sendResponse(const String& message) const;
+
+private:
+    Vector<FrontendChannel*, 2> m_connections;
+};
+
+} // namespace Inspector
+
+#endif // !defined(InspectorFrontendRouter_h)

Modified: trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.cpp (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -35,6 +35,7 @@
 #include "InspectorAgent.h"
 #include "InspectorBackendDispatcher.h"
 #include "InspectorFrontendChannel.h"
+#include "InspectorFrontendRouter.h"
 #include "JSGlobalObject.h"
 #include "JSGlobalObjectConsoleAgent.h"
 #include "JSGlobalObjectConsoleClient.h"
@@ -63,7 +64,8 @@
 JSGlobalObjectInspectorController::JSGlobalObjectInspectorController(JSGlobalObject& globalObject)
     : m_globalObject(globalObject)
     , m_injectedScriptManager(std::make_unique<InjectedScriptManager>(*this, InjectedScriptHost::create()))
-    , m_frontendChannel(nullptr)
+    , m_frontendRouter(FrontendRouter::create())
+    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
     , m_executionStopwatch(Stopwatch::create())
     , m_includeNativeCallStackWithExceptions(true)
     , m_isAutomaticInspection(false)
@@ -98,23 +100,25 @@
 
 void JSGlobalObjectInspectorController::globalObjectDestroyed()
 {
-    disconnectFrontend(DisconnectReason::InspectedTargetDestroyed);
+    disconnectAllFrontends();
 
     m_injectedScriptManager->disconnect();
 }
 
 void JSGlobalObjectInspectorController::connectFrontend(FrontendChannel* frontendChannel, bool isAutomaticInspection)
 {
-    ASSERT(!m_frontendChannel);
-    ASSERT(!m_backendDispatcher);
+    ASSERT_ARG(frontendChannel, frontendChannel);
 
     m_isAutomaticInspection = isAutomaticInspection;
 
-    m_frontendChannel = frontendChannel;
-    m_backendDispatcher = BackendDispatcher::create(frontendChannel);
+    bool connectedFirstFrontend = !m_frontendRouter->hasFrontends();
+    m_frontendRouter->connectFrontend(frontendChannel);
 
-    m_agents.didCreateFrontendAndBackend(frontendChannel, m_backendDispatcher.get());
+    if (!connectedFirstFrontend)
+        return;
 
+    m_agents.didCreateFrontendAndBackend(frontendChannel, &m_backendDispatcher.get());
+
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
     m_inspectorAgent->activateExtraDomains(m_agents.extraDomains());
 
@@ -123,17 +127,32 @@
 #endif
 }
 
-void JSGlobalObjectInspectorController::disconnectFrontend(DisconnectReason reason)
+void JSGlobalObjectInspectorController::disconnectFrontend(FrontendChannel* frontendChannel)
 {
-    if (!m_frontendChannel)
+    ASSERT_ARG(frontendChannel, frontendChannel);
+
+    m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
+
+    m_frontendRouter->disconnectFrontend(frontendChannel);
+
+    m_isAutomaticInspection = false;
+
+    bool disconnectedLastFrontend = !m_frontendRouter->hasFrontends();
+    if (!disconnectedLastFrontend)
         return;
 
-    m_agents.willDestroyFrontendAndBackend(reason);
+#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
+    if (m_augmentingClient)
+        m_augmentingClient->inspectorDisconnected();
+#endif
+}
 
-    m_backendDispatcher->clearFrontend();
-    m_backendDispatcher = nullptr;
-    m_frontendChannel = nullptr;
+void JSGlobalObjectInspectorController::disconnectAllFrontends()
+{
+    m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectedTargetDestroyed);
 
+    m_frontendRouter->disconnectAllFrontends();
+
     m_isAutomaticInspection = false;
 
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
@@ -144,15 +163,11 @@
 
 void JSGlobalObjectInspectorController::dispatchMessageFromFrontend(const String& message)
 {
-    if (m_backendDispatcher)
-        m_backendDispatcher->dispatch(message);
+    m_backendDispatcher->dispatch(message);
 }
 
 void JSGlobalObjectInspectorController::pause()
 {
-    if (!m_frontendChannel)
-        return;
-
     ErrorString dummyError;
     m_debuggerAgent->enable(dummyError);
     m_debuggerAgent->pause(dummyError);
@@ -262,13 +277,11 @@
 {
     String domainName = agent->domainName();
 
-    if (m_frontendChannel)
-        agent->didCreateFrontendAndBackend(m_frontendChannel, m_backendDispatcher.get());
+    agent->didCreateFrontendAndBackend(m_frontendRouter->leakChannel(), &m_backendDispatcher.get());
 
     m_agents.appendExtraAgent(WTF::move(agent));
 
-    if (m_frontendChannel)
-        m_inspectorAgent->activateExtraDomain(domainName);
+    m_inspectorAgent->activateExtraDomain(domainName);
 }
 #endif
 

Modified: trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.h (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/JSGlobalObjectInspectorController.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -53,6 +53,7 @@
 
 class BackendDispatcher;
 class FrontendChannel;
+class FrontendRouter;
 class InjectedScriptManager;
 class InspectorAgent;
 class InspectorConsoleAgent;
@@ -73,7 +74,9 @@
     ~JSGlobalObjectInspectorController();
 
     void connectFrontend(FrontendChannel*, bool isAutomaticInspection);
-    void disconnectFrontend(DisconnectReason);
+    void disconnectFrontend(FrontendChannel*);
+    void disconnectAllFrontends();
+
     void dispatchMessageFromFrontend(const String&);
 
     void globalObjectDestroyed();
@@ -99,7 +102,7 @@
     virtual AugmentableInspectorControllerClient* augmentableInspectorControllerClient() const override { return m_augmentingClient; } 
     virtual void setAugmentableInspectorControllerClient(AugmentableInspectorControllerClient* client) override { m_augmentingClient = client; }
 
-    virtual FrontendChannel* frontendChannel() const override { return m_frontendChannel; }
+    virtual const FrontendRouter& frontendRouter() const override { return m_frontendRouter.get(); }
     virtual void appendExtraAgent(std::unique_ptr<InspectorAgentBase>) override;
 #endif
 
@@ -113,8 +116,8 @@
     InspectorConsoleAgent* m_consoleAgent;
     InspectorDebuggerAgent* m_debuggerAgent;
     AgentRegistry m_agents;
-    FrontendChannel* m_frontendChannel;
-    RefPtr<BackendDispatcher> m_backendDispatcher;
+    Ref<FrontendRouter> m_frontendRouter;
+    Ref<BackendDispatcher> m_backendDispatcher;
     Ref<WTF::Stopwatch> m_executionStopwatch;
     bool m_includeNativeCallStackWithExceptions;
     bool m_isAutomaticInspection;

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorAgent.cpp (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorAgent.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorAgent.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -32,6 +32,7 @@
 #include "InspectorAgent.h"
 
 #include "InspectorEnvironment.h"
+#include "InspectorFrontendRouter.h"
 #include "InspectorValues.h"
 #include "ScriptValue.h"
 

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorConsoleAgent.cpp (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorConsoleAgent.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorConsoleAgent.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -28,6 +28,7 @@
 
 #include "ConsoleMessage.h"
 #include "InjectedScriptManager.h"
+#include "InspectorFrontendRouter.h"
 #include "ScriptArguments.h"
 #include "ScriptCallFrame.h"
 #include "ScriptCallStack.h"

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -33,6 +33,7 @@
 #include "ContentSearchUtilities.h"
 #include "InjectedScript.h"
 #include "InjectedScriptManager.h"
+#include "InspectorFrontendRouter.h"
 #include "InspectorValues.h"
 #include "RegularExpression.h"
 #include "ScriptDebugServer.h"

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.cpp (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -37,6 +37,7 @@
 #include "HeapIterationScope.h"
 #include "InjectedScript.h"
 #include "InjectedScriptManager.h"
+#include "InspectorFrontendRouter.h"
 #include "InspectorValues.h"
 #include "JSLock.h"
 #include "ParserError.h"

Modified: trunk/Source/_javascript_Core/inspector/augmentable/AugmentableInspectorController.h (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/augmentable/AugmentableInspectorController.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/augmentable/AugmentableInspectorController.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -29,7 +29,7 @@
 #if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
 
 #include <_javascript_Core/AugmentableInspectorControllerClient.h>
-#include <_javascript_Core/InspectorFrontendChannel.h>
+#include <_javascript_Core/InspectorFrontendRouter.h>
 
 namespace Inspector {
 
@@ -42,10 +42,10 @@
     virtual AugmentableInspectorControllerClient* augmentableInspectorControllerClient() const = 0;
     virtual void setAugmentableInspectorControllerClient(AugmentableInspectorControllerClient*) = 0;
 
-    virtual FrontendChannel* frontendChannel() const = 0;
+    virtual const FrontendRouter& frontendRouter() const = 0;
     virtual void appendExtraAgent(std::unique_ptr<InspectorAgentBase>) = 0;
 
-    bool connected() const { return !!frontendChannel(); }
+    bool connected() const { return frontendRouter().hasFrontends(); }
 };
 
 } // namespace Inspector

Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggable.h (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggable.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggable.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -64,7 +64,7 @@
     virtual bool hasLocalDebugger() const = 0;
 
     virtual void connect(FrontendChannel*, bool isAutomaticInspection) = 0;
-    virtual void disconnect() = 0;
+    virtual void disconnect(FrontendChannel*) = 0;
     virtual void dispatchMessageFromRemoteFrontend(const String& message) = 0;
     virtual void setIndicating(bool) { } // Default is to do nothing.
     virtual void pause() { };

Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggableConnection.mm (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggableConnection.mm	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspectorDebuggableConnection.mm	2015-09-04 03:58:43 UTC (rev 189338)
@@ -191,7 +191,7 @@
 
             if (m_debuggable) {
                 if (m_connected)
-                    m_debuggable->disconnect();
+                    m_debuggable->disconnect(this);
 
                 m_debuggable = nullptr;
             }

Modified: trunk/Source/_javascript_Core/inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/scripts/codegen/generate_cpp_alternate_backend_dispatcher_header.py	2015-09-04 03:58:43 UTC (rev 189338)
@@ -47,6 +47,7 @@
     def generate_output(self):
         headers = [
             '"InspectorProtocolTypes.h"',
+            '<inspector/InspectorFrontendRouter.h>',
             '<_javascript_Core/InspectorBackendDispatcher.h>',
         ]
 

Modified: trunk/Source/_javascript_Core/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/scripts/codegen/generate_cpp_backend_dispatcher_implementation.py	2015-09-04 03:58:43 UTC (rev 189338)
@@ -50,6 +50,7 @@
     def generate_output(self):
         secondary_headers = [
             '<inspector/InspectorFrontendChannel.h>',
+            '<inspector/InspectorFrontendRouter.h>',
             '<inspector/InspectorValues.h>',
             '<wtf/NeverDestroyed.h>',
             '<wtf/text/CString.h>']

Modified: trunk/Source/_javascript_Core/inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py (189337 => 189338)


--- trunk/Source/_javascript_Core/inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/inspector/scripts/codegen/generate_objc_frontend_dispatcher_implementation.py	2015-09-04 03:58:43 UTC (rev 189338)
@@ -98,9 +98,7 @@
         lines = []
         lines.append(self._generate_event_signature(domain, event))
         lines.append('{')
-        lines.append('    FrontendChannel* frontendChannel = _controller->frontendChannel();')
-        lines.append('    if (!frontendChannel)')
-        lines.append('        return;')
+        lines.append('    const FrontendRouter& router = _controller->frontendRouter();')
         lines.append('')
 
         required_pointer_parameters = filter(lambda parameter: not parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), event.event_parameters)
@@ -126,7 +124,7 @@
         lines.append('    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("%s.%s"));' % (domain.domain_name, event.event_name))
         if event.event_parameters:
             lines.extend(self._generate_event_out_parameters(domain, event))
-        lines.append('    frontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());')
+        lines.append('    router.sendEvent(jsonMessage->toJSONString());')
         lines.append('}')
         return '\n'.join(lines)
 

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.cpp (189337 => 189338)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -56,11 +56,11 @@
     m_globalObject.inspectorController().connectFrontend(frontendChannel, automaticInspection);
 }
 
-void JSGlobalObjectDebuggable::disconnect()
+void JSGlobalObjectDebuggable::disconnect(FrontendChannel* frontendChannel)
 {
     JSLockHolder locker(&m_globalObject.vm());
 
-    m_globalObject.inspectorController().disconnectFrontend(DisconnectReason::InspectorDestroyed);
+    m_globalObject.inspectorController().disconnectFrontend(frontendChannel);
 }
 
 void JSGlobalObjectDebuggable::pause()

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.h (189337 => 189338)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectDebuggable.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -54,7 +54,7 @@
     virtual bool hasLocalDebugger() const override { return false; }
 
     virtual void connect(Inspector::FrontendChannel*, bool automaticInspection) override;
-    virtual void disconnect() override;
+    virtual void disconnect(Inspector::FrontendChannel*) override;
     virtual void dispatchMessageFromRemoteFrontend(const String& message) override;
     virtual void pause() override;
 

Modified: trunk/Source/WebCore/ChangeLog (189337 => 189338)


--- trunk/Source/WebCore/ChangeLog	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/ChangeLog	2015-09-04 03:58:43 UTC (rev 189338)
@@ -1,3 +1,48 @@
+2015-09-03  Brian Burg  <[email protected]>
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        No new tests, no behavior change from this patch. Teardown scenarios are
+        covered by existing protocol and inspector tests running under DRT and WKTR.
+
+        * ForwardingHeaders/inspector/InspectorFrontendRouter.h: Added.
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * inspector/InspectorClient.h: Stop using forwarded types.
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        (WebCore::InspectorController::inspectedPageDestroyed):
+        (WebCore::InspectorController::hasLocalFrontend):
+        (WebCore::InspectorController::hasRemoteFrontend):
+        (WebCore::InspectorController::connectFrontend):
+        (WebCore::InspectorController::disconnectFrontend):
+        (WebCore::InspectorController::disconnectAllFrontends): Added. Disconnects all
+        frontends and signals DisconnectReason::InspectedTargetDestroyed.
+
+        (WebCore::InspectorController::show):
+        (WebCore::InspectorController::close):
+        (WebCore::InspectorController::dispatchMessageFromFrontend):
+        * inspector/InspectorController.h: Add default value for isAutomaticInspection.
+        * inspector/InspectorDatabaseAgent.cpp:
+        * inspector/InspectorIndexedDBAgent.cpp:
+        * inspector/InspectorResourceAgent.cpp:
+        * inspector/WorkerInspectorController.cpp: Use a router with a singleton channel
+        that forwards messages over to the main page.
+
+        (WebCore::WorkerInspectorController::WorkerInspectorController):
+        (WebCore::WorkerInspectorController::connectFrontend):
+        (WebCore::WorkerInspectorController::disconnectFrontend):
+        (WebCore::WorkerInspectorController::dispatchMessageFromFrontend):
+        * inspector/WorkerInspectorController.h:
+        * page/PageDebuggable.cpp:
+        (WebCore::PageDebuggable::disconnect):
+        * page/PageDebuggable.h:
+        * testing/Internals.cpp: Clear the frontend client before disconnecting frontend channel.
+        (WebCore::Internals::openDummyInspectorFrontend):
+        (WebCore::Internals::closeDummyInspectorFrontend):
+
 2015-09-03  Jinyoung Hur  <[email protected]>
 
         [Texmap] highp precision should be used conditionally for fragment shaders on OpenGL ES

Added: trunk/Source/WebCore/ForwardingHeaders/inspector/InspectorFrontendRouter.h (0 => 189338)


--- trunk/Source/WebCore/ForwardingHeaders/inspector/InspectorFrontendRouter.h	                        (rev 0)
+++ trunk/Source/WebCore/ForwardingHeaders/inspector/InspectorFrontendRouter.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_InspectorFrontendRouter_h
+#define WebCore_FWD_InspectorFrontendRouter_h
+#include <_javascript_Core/InspectorFrontendRouter.h>
+#endif

Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (189337 => 189338)


--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj	2015-09-04 03:58:43 UTC (rev 189338)
@@ -20336,6 +20336,7 @@
     <ClInclude Include="..\ForwardingHeaders\inspector\InspectorBackendDispatcher.h" />
     <ClInclude Include="..\ForwardingHeaders\inspector\InspectorEnvironment.h" />
     <ClInclude Include="..\ForwardingHeaders\inspector\InspectorFrontendChannel.h" />
+    <ClInclude Include="..\ForwardingHeaders\inspector\InspectorFrontendRouter.h" />
     <ClInclude Include="..\ForwardingHeaders\inspector\InspectorBackendDispatchers.h" />
     <ClInclude Include="..\ForwardingHeaders\inspector\InspectorFrontendDispatchers.h" />
     <ClInclude Include="..\ForwardingHeaders\inspector\InspectorProtocolObjects.h" />

Modified: trunk/Source/WebCore/inspector/InspectorClient.h (189337 => 189338)


--- trunk/Source/WebCore/inspector/InspectorClient.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorClient.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -27,11 +27,14 @@
 #ifndef InspectorClient_h
 #define InspectorClient_h
 
-#include "InspectorForwarding.h"
 #include <wtf/Forward.h>
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 
+namespace Inspector {
+class FrontendChannel;
+}
+
 namespace WebCore {
 
 class FloatRect;
@@ -45,7 +48,7 @@
 
     virtual void inspectorDestroyed() = 0;
 
-    virtual InspectorFrontendChannel* openInspectorFrontend(InspectorController*) = 0;
+    virtual Inspector::FrontendChannel* openInspectorFrontend(InspectorController*) = 0;
     virtual void closeInspectorFrontend() = 0;
     virtual void bringFrontendToFront() = 0;
     virtual void didResizeMainFrame(Frame*) { }

Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (189337 => 189338)


--- trunk/Source/WebCore/inspector/InspectorController.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -68,6 +68,7 @@
 #include <inspector/InspectorBackendDispatcher.h>
 #include <inspector/InspectorBackendDispatchers.h>
 #include <inspector/InspectorFrontendDispatchers.h>
+#include <inspector/InspectorFrontendRouter.h>
 #include <inspector/agents/InspectorAgent.h>
 #include <profiler/LegacyProfiler.h>
 #include <runtime/JSLock.h>
@@ -85,6 +86,8 @@
 InspectorController::InspectorController(Page& page, InspectorClient* inspectorClient)
     : m_instrumentingAgents(InstrumentingAgents::create(*this))
     , m_injectedScriptManager(std::make_unique<WebInjectedScriptManager>(*this, WebInjectedScriptHost::create()))
+    , m_frontendRouter(FrontendRouter::create())
+    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
     , m_overlay(std::make_unique<InspectorOverlay>(page, inspectorClient))
     , m_executionStopwatch(Stopwatch::create())
     , m_page(page)
@@ -177,7 +180,8 @@
 
 void InspectorController::inspectedPageDestroyed()
 {
-    disconnectFrontend(DisconnectReason::InspectedTargetDestroyed);
+    disconnectAllFrontends();
+
     m_injectedScriptManager->disconnect();
     m_inspectorClient->inspectorDestroyed();
     m_inspectorClient = nullptr;
@@ -190,12 +194,12 @@
 
 bool InspectorController::hasLocalFrontend() const
 {
-    return m_frontendChannel && m_frontendChannel->connectionType() == FrontendChannel::ConnectionType::Local;
+    return m_frontendRouter->hasLocalFrontend();
 }
 
 bool InspectorController::hasRemoteFrontend() const
 {
-    return m_frontendChannel && m_frontendChannel->connectionType() == FrontendChannel::ConnectionType::Remote;
+    return m_frontendRouter->hasRemoteFrontend();
 }
 
 bool InspectorController::hasInspectorFrontendClient() const
@@ -219,74 +223,96 @@
 
 void InspectorController::connectFrontend(Inspector::FrontendChannel* frontendChannel, bool isAutomaticInspection)
 {
-    ASSERT(frontendChannel);
+    ASSERT_ARG(frontendChannel, frontendChannel);
     ASSERT(m_inspectorClient);
-    ASSERT(!m_frontendChannel);
-    ASSERT(!m_backendDispatcher);
 
+    bool connectedFirstFrontend = !m_frontendRouter->hasFrontends();
     m_isAutomaticInspection = isAutomaticInspection;
 
-    m_frontendChannel = frontendChannel;
-    m_backendDispatcher = BackendDispatcher::create(frontendChannel);
+    m_frontendRouter->connectFrontend(frontendChannel);
 
-    m_agents.didCreateFrontendAndBackend(frontendChannel, m_backendDispatcher.get());
-
-    InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get());
     InspectorInstrumentation::frontendCreated();
 
+    if (connectedFirstFrontend) {
+        InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get());
+        m_agents.didCreateFrontendAndBackend(frontendChannel, &m_backendDispatcher.get());
+    }
+
 #if ENABLE(REMOTE_INSPECTOR)
-    if (!hasRemoteFrontend())
+    if (!m_frontendRouter->hasRemoteFrontend())
         m_page.remoteInspectorInformationDidChange();
 #endif
 }
 
-void InspectorController::disconnectFrontend(DisconnectReason reason)
+void InspectorController::disconnectFrontend(FrontendChannel* frontendChannel)
 {
-    if (!m_frontendChannel)
-        return;
+    // The local frontend client should be disconnected first so it stops sending messages.
+    ASSERT(!m_frontendRouter->hasLocalFrontend() || !m_inspectorFrontendClient);
 
+    m_frontendRouter->disconnectFrontend(frontendChannel);
+    m_isAutomaticInspection = false;
+
+    InspectorInstrumentation::frontendDeleted();
+
+    bool disconnectedLastFrontend = !m_frontendRouter->hasFrontends();
+    if (disconnectedLastFrontend) {
+        // Release overlay page resources.
+        m_overlay->freePage();
+        m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
+        InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
+    }
+
 #if ENABLE(REMOTE_INSPECTOR)
-    if (!hasRemoteFrontend())
+    if (!m_frontendRouter->hasFrontends())
         m_page.remoteInspectorInformationDidChange();
 #endif
+}
 
-    m_agents.willDestroyFrontendAndBackend(reason);
+void InspectorController::disconnectAllFrontends()
+{
+    // The local frontend client should be disconnected first so it stops sending messages.
+    ASSERT(!m_frontendRouter->hasLocalFrontend() || !m_inspectorFrontendClient);
 
-    m_backendDispatcher->clearFrontend();
-    m_backendDispatcher = nullptr;
-    m_frontendChannel = nullptr;
+    m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectedTargetDestroyed);
 
+    m_frontendRouter->disconnectAllFrontends();
     m_isAutomaticInspection = false;
 
     // Release overlay page resources.
     m_overlay->freePage();
-    InspectorInstrumentation::frontendDeleted();
+
+    while (InspectorInstrumentation::hasFrontends())
+        InspectorInstrumentation::frontendDeleted();
+
     InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
+    
+#if ENABLE(REMOTE_INSPECTOR)
+    m_page.remoteInspectorInformationDidChange();
+#endif
 }
 
 void InspectorController::show()
 {
-    ASSERT(!hasRemoteFrontend());
+    ASSERT(!m_frontendRouter->hasRemoteFrontend());
 
+    // The local frontend client should be disconnected if there's no local frontend.
+    ASSERT(m_frontendRouter->hasLocalFrontend() || !m_inspectorFrontendClient);
+
     if (!enabled())
         return;
 
-    if (m_frontendChannel)
+    if (m_frontendRouter->hasLocalFrontend())
         m_inspectorClient->bringFrontendToFront();
-    else {
-        if (Inspector::FrontendChannel* frontendChannel = m_inspectorClient->openInspectorFrontend(this)) {
-            bool isAutomaticInspection = false;
-            connectFrontend(frontendChannel, isAutomaticInspection);
-        }
-    }
+    else if (Inspector::FrontendChannel* frontendChannel = m_inspectorClient->openInspectorFrontend(this))
+        connectFrontend(frontendChannel);
 }
 
 void InspectorController::close()
 {
-    if (!m_frontendChannel)
-        return;
-    disconnectFrontend(DisconnectReason::InspectorDestroyed);
-    m_inspectorClient->closeInspectorFrontend();
+    if (m_frontendRouter->hasLocalFrontend())
+        m_inspectorClient->closeInspectorFrontend();
+
+    ASSERT(!m_frontendRouter->hasLocalFrontend());
 }
 
 void InspectorController::setProcessId(long processId)
@@ -337,8 +363,7 @@
 
 void InspectorController::dispatchMessageFromFrontend(const String& message)
 {
-    if (m_backendDispatcher)
-        m_backendDispatcher->dispatch(message);
+    m_backendDispatcher->dispatch(message);
 }
 
 void InspectorController::hideHighlight()

Modified: trunk/Source/WebCore/inspector/InspectorController.h (189337 => 189338)


--- trunk/Source/WebCore/inspector/InspectorController.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorController.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -45,6 +45,7 @@
 namespace Inspector {
 class BackendDispatcher;
 class FrontendChannel;
+class FrontendRouter;
 class InspectorAgent;
 class InspectorObject;
 
@@ -98,8 +99,9 @@
     bool hasLocalFrontend() const;
     bool hasRemoteFrontend() const;
 
-    WEBCORE_EXPORT void connectFrontend(Inspector::FrontendChannel*, bool isAutomaticInspection);
-    WEBCORE_EXPORT void disconnectFrontend(Inspector::DisconnectReason);
+    WEBCORE_EXPORT void connectFrontend(Inspector::FrontendChannel*, bool isAutomaticInspection = false);
+    WEBCORE_EXPORT void disconnectFrontend(Inspector::FrontendChannel*);
+    WEBCORE_EXPORT void disconnectAllFrontends();
     void setProcessId(long);
 
     void inspect(Node*);
@@ -140,8 +142,8 @@
 
     Ref<InstrumentingAgents> m_instrumentingAgents;
     std::unique_ptr<WebInjectedScriptManager> m_injectedScriptManager;
-    RefPtr<Inspector::BackendDispatcher> m_backendDispatcher;
-    Inspector::FrontendChannel* m_frontendChannel { nullptr };
+    Ref<Inspector::FrontendRouter> m_frontendRouter;
+    Ref<Inspector::BackendDispatcher> m_backendDispatcher;
     std::unique_ptr<InspectorOverlay> m_overlay;
     Ref<WTF::Stopwatch> m_executionStopwatch;
     Inspector::AgentRegistry m_agents;

Modified: trunk/Source/WebCore/inspector/InspectorDatabaseAgent.cpp (189337 => 189338)


--- trunk/Source/WebCore/inspector/InspectorDatabaseAgent.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorDatabaseAgent.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -44,6 +44,7 @@
 #include "SQLTransactionErrorCallback.h"
 #include "SQLValue.h"
 #include "VoidCallback.h"
+#include <inspector/InspectorFrontendRouter.h>
 #include <inspector/InspectorValues.h>
 #include <wtf/Vector.h>
 

Modified: trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp (189337 => 189338)


--- trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -64,6 +64,7 @@
 #include <inspector/InjectedScript.h>
 #include <inspector/InjectedScriptManager.h>
 #include <inspector/InspectorFrontendDispatchers.h>
+#include <inspector/InspectorFrontendRouter.h>
 #include <inspector/InspectorValues.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/Vector.h>

Modified: trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp (189337 => 189338)


--- trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/InspectorResourceAgent.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -62,6 +62,7 @@
 #include "URL.h"
 #include "WebSocketFrame.h"
 #include <inspector/IdentifiersFactory.h>
+#include <inspector/InspectorFrontendRouter.h>
 #include <inspector/InspectorValues.h>
 #include <inspector/ScriptCallStack.h>
 #include <inspector/ScriptCallStackFactory.h>

Modified: trunk/Source/WebCore/inspector/WorkerInspectorController.cpp (189337 => 189338)


--- trunk/Source/WebCore/inspector/WorkerInspectorController.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/WorkerInspectorController.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -48,6 +48,7 @@
 #include "WorkerThread.h"
 #include <inspector/InspectorBackendDispatcher.h>
 #include <inspector/InspectorFrontendDispatchers.h>
+#include <inspector/InspectorFrontendRouter.h>
 #include <wtf/Stopwatch.h>
 
 using namespace Inspector;
@@ -80,6 +81,8 @@
     , m_instrumentingAgents(InstrumentingAgents::create(*this))
     , m_injectedScriptManager(std::make_unique<WebInjectedScriptManager>(*this, WebInjectedScriptHost::create()))
     , m_executionStopwatch(Stopwatch::create())
+    , m_frontendRouter(FrontendRouter::create())
+    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
 {
     auto runtimeAgent = std::make_unique<WorkerRuntimeAgent>(*m_injectedScriptManager, &workerGlobalScope);
     m_runtimeAgent = runtimeAgent.get();
@@ -114,27 +117,27 @@
 
 void WorkerInspectorController::connectFrontend()
 {
-    ASSERT(!m_frontendChannel);
-    m_frontendChannel = std::make_unique<PageInspectorProxy>(m_workerGlobalScope);
-    m_backendDispatcher = BackendDispatcher::create(m_frontendChannel.get());
-    m_agents.didCreateFrontendAndBackend(m_frontendChannel.get(), m_backendDispatcher.get());
+    ASSERT(!m_frontendRouter->hasFrontends());
+    ASSERT(!m_forwardingChannel);
+
+    m_forwardingChannel = std::make_unique<PageInspectorProxy>(m_workerGlobalScope);
+    m_frontendRouter->connectFrontend(m_forwardingChannel.get());
+    m_agents.didCreateFrontendAndBackend(m_forwardingChannel.get(), &m_backendDispatcher.get());
 }
 
 void WorkerInspectorController::disconnectFrontend(Inspector::DisconnectReason reason)
 {
-    if (!m_frontendChannel)
-        return;
+    ASSERT(m_frontendRouter->hasFrontends());
+    ASSERT(m_forwardingChannel);
 
     m_agents.willDestroyFrontendAndBackend(reason);
-    m_backendDispatcher->clearFrontend();
-    m_backendDispatcher = nullptr;
-    m_frontendChannel = nullptr;
+    m_frontendRouter->disconnectFrontend(m_forwardingChannel.get());
+    m_forwardingChannel = nullptr;
 }
 
 void WorkerInspectorController::dispatchMessageFromFrontend(const String& message)
 {
-    if (m_backendDispatcher)
-        m_backendDispatcher->dispatch(message);
+    m_backendDispatcher->dispatch(message);
 }
 
 void WorkerInspectorController::resume()

Modified: trunk/Source/WebCore/inspector/WorkerInspectorController.h (189337 => 189338)


--- trunk/Source/WebCore/inspector/WorkerInspectorController.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/inspector/WorkerInspectorController.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -41,6 +41,10 @@
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
+namespace Inspector {
+class FrontendRouter;
+};
+
 namespace WebCore {
 
 class InspectorInstrumentation;
@@ -78,9 +82,10 @@
     std::unique_ptr<WebInjectedScriptManager> m_injectedScriptManager;
     WorkerRuntimeAgent* m_runtimeAgent { nullptr };
     Inspector::AgentRegistry m_agents;
-    std::unique_ptr<Inspector::FrontendChannel> m_frontendChannel;
+    std::unique_ptr<Inspector::FrontendChannel> m_forwardingChannel;
     Ref<WTF::Stopwatch> m_executionStopwatch;
-    RefPtr<Inspector::BackendDispatcher> m_backendDispatcher;
+    Ref<Inspector::FrontendRouter> m_frontendRouter;
+    Ref<Inspector::BackendDispatcher> m_backendDispatcher;
     Vector<InspectorInstrumentationCookie, 2> m_injectedScriptInstrumentationCookies;
 };
 

Modified: trunk/Source/WebCore/page/PageDebuggable.cpp (189337 => 189338)


--- trunk/Source/WebCore/page/PageDebuggable.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/page/PageDebuggable.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -80,10 +80,10 @@
     inspectorController.connectFrontend(channel, isAutomaticInspection);
 }
 
-void PageDebuggable::disconnect()
+void PageDebuggable::disconnect(Inspector::FrontendChannel* channel)
 {
     InspectorController& inspectorController = m_page.inspectorController();
-    inspectorController.disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
+    inspectorController.disconnectFrontend(channel);
 
     if (m_forcedDeveloperExtrasEnabled) {
         m_forcedDeveloperExtrasEnabled = false;

Modified: trunk/Source/WebCore/page/PageDebuggable.h (189337 => 189338)


--- trunk/Source/WebCore/page/PageDebuggable.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/page/PageDebuggable.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -49,7 +49,7 @@
     virtual bool hasLocalDebugger() const override;
 
     virtual void connect(Inspector::FrontendChannel*, bool isAutomaticInspection) override;
-    virtual void disconnect() override;
+    virtual void disconnect(Inspector::FrontendChannel*) override;
     virtual void dispatchMessageFromRemoteFrontend(const String& message) override;
     virtual void setIndicating(bool) override;
 

Modified: trunk/Source/WebCore/testing/Internals.cpp (189337 => 189338)


--- trunk/Source/WebCore/testing/Internals.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebCore/testing/Internals.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -1734,9 +1734,8 @@
     m_frontendClient = std::make_unique<InspectorFrontendClientDummy>(&page->inspectorController(), frontendPage);
     frontendPage->inspectorController().setInspectorFrontendClient(m_frontendClient.get());
 
-    bool isAutomaticInspection = false;
     m_frontendChannel = std::make_unique<InspectorFrontendChannelDummy>(frontendPage);
-    page->inspectorController().connectFrontend(m_frontendChannel.get(), isAutomaticInspection);
+    page->inspectorController().connectFrontend(m_frontendChannel.get());
 
     return m_frontendWindow;
 }
@@ -1747,9 +1746,13 @@
     ASSERT(page);
     ASSERT(m_frontendWindow);
 
-    page->inspectorController().disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
+    Page* frontendPage = m_frontendWindow->document()->page();
+    ASSERT(frontendPage);
 
+    frontendPage->inspectorController().setInspectorFrontendClient(nullptr);
     m_frontendClient = nullptr;
+
+    page->inspectorController().disconnectFrontend(m_frontendChannel.get());
     m_frontendChannel = nullptr;
 
     m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());

Modified: trunk/Source/WebKit/mac/ChangeLog (189337 => 189338)


--- trunk/Source/WebKit/mac/ChangeLog	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/mac/ChangeLog	2015-09-04 03:58:43 UTC (rev 189338)
@@ -1,3 +1,23 @@
+2015-09-03  Brian Burg  <[email protected]>
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        Remove the notifyInspectorController flag from closeWindow. Since InspectorClients
+        must now manually disconnect their FrontendChannel(s), we should always
+        perform the teardown that was guarded by this flag.
+
+        * WebCoreSupport/WebInspectorClient.h:
+        * WebCoreSupport/WebInspectorClient.mm:
+        (WebInspectorClient::bringFrontendToFront): Add a missing assertion.
+        (WebInspectorFrontendClient::closeWindow):
+        (WebInspectorFrontendClient::disconnectFromBackend):
+        (-[WebInspectorWindowController windowShouldClose:]):
+        (-[WebInspectorWindowController destroyInspectorView]): Always clear the frontend client.
+        (-[WebInspectorWindowController destroyInspectorView:]): Renamed to above.
+
 2015-08-26  Andy Estes  <[email protected]>
 
         [Content Filtering] Determine navigation and content policy before continuing to filter a load

Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h (189337 => 189338)


--- trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -124,7 +124,7 @@
 
     virtual void bringToFront() override;
     virtual void closeWindow() override;
-    virtual void disconnectFromBackend();
+    void disconnectFromBackend();
 
     virtual void attachWindow(DockSide) override;
     virtual void detachWindow() override;

Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm (189337 => 189338)


--- trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebInspectorClient.mm	2015-09-04 03:58:43 UTC (rev 189338)
@@ -87,7 +87,7 @@
 - (WebInspectorClient*)inspectorClient;
 - (void)setAttachedWindowHeight:(unsigned)height;
 - (void)setDockingUnavailable:(BOOL)unavailable;
-- (void)destroyInspectorView:(bool)notifyInspectorController;
+- (void)destroyInspectorView;
 @end
 
 
@@ -130,6 +130,7 @@
 
 void WebInspectorClient::bringFrontendToFront()
 {
+    ASSERT(m_frontendClient);
     m_frontendClient->bringToFront();
 }
 
@@ -252,12 +253,12 @@
 
 void WebInspectorFrontendClient::closeWindow()
 {
-    [m_windowController.get() destroyInspectorView:true];
+    [m_windowController.get() destroyInspectorView];
 }
 
 void WebInspectorFrontendClient::disconnectFromBackend()
 {
-    [m_windowController.get() destroyInspectorView:false];
+    [m_windowController.get() destroyInspectorView];
 }
 
 void WebInspectorFrontendClient::attachWindow(DockSide)
@@ -522,7 +523,7 @@
 
 - (BOOL)windowShouldClose:(id)sender
 {
-    [self destroyInspectorView:true];
+    [self destroyInspectorView];
 
     return YES;
 }
@@ -676,7 +677,7 @@
     // Do nothing.
 }
 
-- (void)destroyInspectorView:(bool)notifyInspectorController
+- (void)destroyInspectorView
 {
     RetainPtr<WebInspectorWindowController> protect(self);
 
@@ -692,9 +693,9 @@
 
     _visible = NO;
 
-    if (notifyInspectorController) {
-        if (Page* inspectedPage = [_inspectedWebView.get() page])
-            inspectedPage->inspectorController().disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
+    if (Page* inspectedPage = [_inspectedWebView.get() page]) {
+        inspectedPage->inspectorController().setInspectorFrontendClient(nullptr);
+        inspectedPage->inspectorController().disconnectFrontend(_inspectorClient);
     }
 
     [_webView close];

Modified: trunk/Source/WebKit/win/ChangeLog (189337 => 189338)


--- trunk/Source/WebKit/win/ChangeLog	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/win/ChangeLog	2015-09-04 03:58:43 UTC (rev 189338)
@@ -1,3 +1,21 @@
+2015-09-03  Brian Burg  <[email protected]>
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        Remove the notifyInspectorController flag from closeWindow. Since InspectorClients
+        must now manually disconnect their FrontendChannel(s), we should always
+        perform the teardown that was guarded by this flag.
+
+        * WebCoreSupport/WebInspectorClient.cpp:
+        (WebInspectorClient::closeInspectorFrontend):
+        (WebInspectorFrontendClient::~WebInspectorFrontendClient):
+        (WebInspectorFrontendClient::closeWindow):
+        (WebInspectorFrontendClient::destroyInspectorView):
+        * WebCoreSupport/WebInspectorClient.h:
+
 2015-09-02  Andreas Kling  <[email protected]>
 
         ScrollbarThemes should be returned by reference.

Modified: trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp (189337 => 189338)


--- trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -174,7 +174,7 @@
 void WebInspectorClient::closeInspectorFrontend()
 {
     if (m_frontendClient)
-        m_frontendClient->destroyInspectorView(false);
+        m_frontendClient->destroyInspectorView();
 }
 
 void WebInspectorClient::bringFrontendToFront()
@@ -237,7 +237,7 @@
 
 WebInspectorFrontendClient::~WebInspectorFrontendClient()
 {
-    destroyInspectorView(true);
+    destroyInspectorView();
 }
 
 void WebInspectorFrontendClient::frontendLoaded()
@@ -269,7 +269,7 @@
 
 void WebInspectorFrontendClient::closeWindow()
 {
-    destroyInspectorView(true);
+    destroyInspectorView();
 }
 
 void WebInspectorFrontendClient::attachWindow(DockSide)
@@ -421,7 +421,7 @@
     m_inspectorClient->updateHighlight();
 }
 
-void WebInspectorFrontendClient::destroyInspectorView(bool notifyInspectorController)
+void WebInspectorFrontendClient::destroyInspectorView()
 {
     m_inspectorClient->releaseFrontend();
 
@@ -431,10 +431,10 @@
 
     closeWindowWithoutNotifications();
 
-    if (notifyInspectorController) {
-        m_inspectedWebView->page()->inspectorController().disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
-        m_inspectorClient->updateHighlight();
-    }
+    m_inspectedWebView->page()->inspectorController().setInspectorFrontendClient(nullptr);
+    m_inspectedWebView->page()->inspectorController().disconnectFrontend(m_inspectorClient);
+    m_inspectorClient->updateHighlight();
+
     ::DestroyWindow(m_frontendHwnd);
 }
 

Modified: trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h (189337 => 189338)


--- trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit/win/WebCoreSupport/WebInspectorClient.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -113,7 +113,7 @@
 
     virtual void inspectedURLChanged(const WTF::String& newURL);
 
-    void destroyInspectorView(bool notifyInspectorController);
+    void destroyInspectorView();
 
 private:
     void closeWindowWithoutNotifications();

Modified: trunk/Source/WebKit2/ChangeLog (189337 => 189338)


--- trunk/Source/WebKit2/ChangeLog	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/ChangeLog	2015-09-04 03:58:43 UTC (rev 189338)
@@ -1,3 +1,28 @@
+2015-09-03  Brian Burg  <[email protected]>
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        Explicitly disconnect the frontend channel when closing the frontend.
+
+        Rename createInspectorPage/closeFrontend to the symmetric and unambiguous
+        {open,close}FrontendConnection in the WebInspector class.
+
+        * WebProcess/WebCoreSupport/WebInspectorClient.cpp:
+        (WebKit::WebInspectorClient::openInspectorFrontend):
+        (WebKit::WebInspectorClient::closeInspectorFrontend):
+        * WebProcess/WebCoreSupport/WebInspectorClient.h: Stop using a forwarded type.
+        * WebProcess/WebPage/WebInspector.cpp:
+        (WebKit::WebInspector::openFrontendConnection):
+        (WebKit::WebInspector::closeFrontendConnection):
+        (WebKit::WebInspector::remoteFrontendConnected):
+        (WebKit::WebInspector::remoteFrontendDisconnected):
+        (WebKit::WebInspector::createInspectorPage): Deleted.
+        (WebKit::WebInspector::closeFrontend): Deleted.
+        * WebProcess/WebPage/WebInspector.h:
+
 2015-09-03  Timothy Hatcher  <[email protected]>
 
         Web Inspector: Closing the Safari window when the Web Inspector is one of the other windows in split screen mode can cause the entire screen to go black

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp (189337 => 189338)


--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -82,17 +82,19 @@
     delete this;
 }
 
-WebCore::InspectorFrontendChannel* WebInspectorClient::openInspectorFrontend(InspectorController* controller)
+Inspector::FrontendChannel* WebInspectorClient::openInspectorFrontend(InspectorController* controller)
 {
-    m_page->inspector()->createInspectorPage(controller->isUnderTest());
+    m_page->inspector()->openFrontendConnection(controller->isUnderTest());
 
     return m_page->inspector();
 }
 
 void WebInspectorClient::closeInspectorFrontend()
 {
-    if (m_page->inspector())
-        m_page->inspector()->closeFrontend();
+    if (m_page->inspector()) {
+        m_page->corePage()->inspectorController().disconnectFrontend(m_page->inspector());
+        m_page->inspector()->closeFrontendConnection();
+    }
 }
 
 void WebInspectorClient::bringFrontendToFront()

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h (189337 => 189338)


--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -27,7 +27,6 @@
 #define WebInspectorClient_h
 
 #include <WebCore/InspectorClient.h>
-#include <WebCore/InspectorForwarding.h>
 #include <WebCore/PageOverlay.h>
 #include <wtf/HashSet.h>
 
@@ -53,7 +52,7 @@
     // WebCore::InspectorClient
     void inspectorDestroyed() override;
 
-    WebCore::InspectorFrontendChannel* openInspectorFrontend(WebCore::InspectorController*) override;
+    Inspector::FrontendChannel* openInspectorFrontend(WebCore::InspectorController*) override;
     void closeInspectorFrontend() override;
     void bringFrontendToFront() override;
     void didResizeMainFrame(WebCore::Frame*) override;

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp (189337 => 189338)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -70,7 +70,7 @@
 }
 
 // Called from WebInspectorClient
-void WebInspector::createInspectorPage(bool underTest)
+void WebInspector::openFrontendConnection(bool underTest)
 {
 #if OS(DARWIN)
     mach_port_t listeningPort;
@@ -93,7 +93,7 @@
     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::CreateInspectorPage(connectionClientPort, canAttachWindow(), underTest), m_page->pageID());
 }
 
-void WebInspector::closeFrontend()
+void WebInspector::closeFrontendConnection()
 {
     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorProxy::DidClose(), m_page->pageID());
 
@@ -262,8 +262,7 @@
 {
     if (m_page->corePage()) {
         m_remoteFrontendConnected = true;
-        bool isAutomaticInspection = false;
-        m_page->corePage()->inspectorController().connectFrontend(this, isAutomaticInspection);
+        m_page->corePage()->inspectorController().connectFrontend(this);
     }
 }
 
@@ -272,7 +271,7 @@
     m_remoteFrontendConnected = false;
 
     if (m_page->corePage())
-        m_page->corePage()->inspectorController().disconnectFrontend(Inspector::DisconnectReason::InspectorDestroyed);
+        m_page->corePage()->inspectorController().disconnectFrontend(this);
 }
 #endif
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.h (189337 => 189338)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.h	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebInspector.h	2015-09-04 03:58:43 UTC (rev 189338)
@@ -97,9 +97,9 @@
     bool canAttachWindow();
 
     // Called from WebInspectorClient
-    void createInspectorPage(bool underTest);
+    void openFrontendConnection(bool underTest);
+    void closeFrontendConnection();
 
-    void closeFrontend();
     void bringToFront();
 
     WebPage* m_page;

Modified: trunk/Tools/ChangeLog (189337 => 189338)


--- trunk/Tools/ChangeLog	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Tools/ChangeLog	2015-09-04 03:58:43 UTC (rev 189338)
@@ -1,3 +1,23 @@
+2015-09-03  Brian Burg  <[email protected]>
+
+        Web Inspector: InspectorController should support multiple frontend channels
+        https://bugs.webkit.org/show_bug.cgi?id=148538
+
+        Reviewed by Joseph Pecoraro.
+
+        InspectorClients must explicitly disconnect their frontend channel(s) from the
+        inspected page's InspectorController.
+
+        To make this possible, DumpRenderTree should not destroy non-primary views until
+        it has tried to close any abandoned Web Inspector instances. Performing teardown
+        in the reverse order prevents disconnection of the frontend channel because that
+        prematurely destroys the inspector frontend client.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (runTest):
+        * DumpRenderTree/win/DumpRenderTree.cpp:
+        (runTest):
+
 2015-09-03  Timothy Hatcher  <[email protected]>
 
         Update WebKit nightly icon to be more like Safari

Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (189337 => 189338)


--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2015-09-04 03:58:43 UTC (rev 189338)
@@ -2039,6 +2039,13 @@
 
     workQueue.clear();
 
+    // If the test page could have possibly opened the Web Inspector frontend,
+    // then try to close it in case it was accidentally left open.
+    if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
+        gTestRunner->closeWebInspector();
+        gTestRunner->setDeveloperExtrasEnabled(false);
+    }
+
     if (gTestRunner->closeRemainingWindowsWhenComplete()) {
         NSArray* array = [DumpRenderTreeWindow openWindows];
 
@@ -2062,12 +2069,6 @@
         }
     }
 
-    // If developer extras enabled Web Inspector may have been open by the test.
-    if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
-        gTestRunner->closeWebInspector();
-        gTestRunner->setDeveloperExtrasEnabled(false);
-    }
-
     resetWebViewToConsistentStateBeforeTesting();
 
     // Loading an empty request synchronously replaces the document with a blank one, which is necessary

Modified: trunk/Tools/DumpRenderTree/win/DumpRenderTree.cpp (189337 => 189338)


--- trunk/Tools/DumpRenderTree/win/DumpRenderTree.cpp	2015-09-04 03:43:06 UTC (rev 189337)
+++ trunk/Tools/DumpRenderTree/win/DumpRenderTree.cpp	2015-09-04 03:58:43 UTC (rev 189338)
@@ -1147,6 +1147,13 @@
     // EventSendingController clearSavedEvents
     workQueue.clear();
 
+    // If the test page could have possibly opened the Web Inspector frontend,
+    // then try to close it in case it was accidentally left open.
+    if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
+        ::gTestRunner->closeWebInspector();
+        ::gTestRunner->setDeveloperExtrasEnabled(false);
+    }
+
     if (::gTestRunner->closeRemainingWindowsWhenComplete()) {
         Vector<HWND> windows = openWindows();
         unsigned size = windows.size();
@@ -1161,11 +1168,6 @@
         }
     }
 
-    if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
-        ::gTestRunner->closeWebInspector();
-        ::gTestRunner->setDeveloperExtrasEnabled(false);
-    }
-
     resetWebViewToConsistentStateBeforeTesting();
 
     // Loading an empty request synchronously replaces the document with a blank one, which is necessary
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to