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

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

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:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.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):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@189338 268f45cc-cd09-0410-ab3c-d52691b4dbfc
50 files changed