1 /* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "core/inspector/InspectorController.h" 33 34 #include "bindings/core/v8/DOMWrapperWorld.h" 35 #include "core/InspectorBackendDispatcher.h" 36 #include "core/InspectorFrontend.h" 37 #include "core/inspector/IdentifiersFactory.h" 38 #include "core/inspector/InjectedScriptHost.h" 39 #include "core/inspector/InjectedScriptManager.h" 40 #include "core/inspector/InspectorApplicationCacheAgent.h" 41 #include "core/inspector/InspectorCSSAgent.h" 42 #include "core/inspector/InspectorCanvasAgent.h" 43 #include "core/inspector/InspectorClient.h" 44 #include "core/inspector/InspectorDOMAgent.h" 45 #include "core/inspector/InspectorDOMDebuggerAgent.h" 46 #include "core/inspector/InspectorDOMStorageAgent.h" 47 #include "core/inspector/InspectorDebuggerAgent.h" 48 #include "core/inspector/InspectorFrontendClient.h" 49 #include "core/inspector/InspectorHeapProfilerAgent.h" 50 #include "core/inspector/InspectorInputAgent.h" 51 #include "core/inspector/InspectorInspectorAgent.h" 52 #include "core/inspector/InspectorInstrumentation.h" 53 #include "core/inspector/InspectorLayerTreeAgent.h" 54 #include "core/inspector/InspectorMemoryAgent.h" 55 #include "core/inspector/InspectorOverlay.h" 56 #include "core/inspector/InspectorPageAgent.h" 57 #include "core/inspector/InspectorProfilerAgent.h" 58 #include "core/inspector/InspectorResourceAgent.h" 59 #include "core/inspector/InspectorState.h" 60 #include "core/inspector/InspectorTimelineAgent.h" 61 #include "core/inspector/InspectorTracingAgent.h" 62 #include "core/inspector/InspectorWorkerAgent.h" 63 #include "core/inspector/InstrumentingAgents.h" 64 #include "core/inspector/PageConsoleAgent.h" 65 #include "core/inspector/PageDebuggerAgent.h" 66 #include "core/inspector/PageRuntimeAgent.h" 67 #include "core/page/ContextMenuProvider.h" 68 #include "core/page/Page.h" 69 #include "core/rendering/RenderLayer.h" 70 #include "platform/PlatformMouseEvent.h" 71 72 namespace blink { 73 74 InspectorController::InspectorController(Page* page, InspectorClient* inspectorClient) 75 : m_instrumentingAgents(InstrumentingAgents::create()) 76 , m_injectedScriptManager(InjectedScriptManager::createForPage()) 77 , m_state(adoptPtrWillBeNoop(new InspectorCompositeState(inspectorClient))) 78 , m_overlay(InspectorOverlay::create(page, inspectorClient)) 79 , m_cssAgent(nullptr) 80 , m_resourceAgent(nullptr) 81 , m_layerTreeAgent(nullptr) 82 , m_inspectorFrontendClient(nullptr) 83 , m_page(page) 84 , m_inspectorClient(inspectorClient) 85 , m_agents(m_instrumentingAgents.get(), m_state.get()) 86 , m_isUnderTest(false) 87 , m_deferredAgentsInitialized(false) 88 { 89 InjectedScriptManager* injectedScriptManager = m_injectedScriptManager.get(); 90 InspectorOverlay* overlay = m_overlay.get(); 91 92 m_agents.append(InspectorInspectorAgent::create(m_page, injectedScriptManager)); 93 94 OwnPtrWillBeRawPtr<InspectorPageAgent> pageAgentPtr(InspectorPageAgent::create(m_page, injectedScriptManager, inspectorClient, overlay)); 95 m_pageAgent = pageAgentPtr.get(); 96 m_agents.append(pageAgentPtr.release()); 97 98 OwnPtrWillBeRawPtr<InspectorDOMAgent> domAgentPtr(InspectorDOMAgent::create(m_pageAgent, injectedScriptManager, overlay)); 99 m_domAgent = domAgentPtr.get(); 100 m_agents.append(domAgentPtr.release()); 101 102 103 OwnPtrWillBeRawPtr<InspectorLayerTreeAgent> layerTreeAgentPtr(InspectorLayerTreeAgent::create(m_page)); 104 m_layerTreeAgent = layerTreeAgentPtr.get(); 105 m_agents.append(layerTreeAgentPtr.release()); 106 107 OwnPtrWillBeRawPtr<InspectorWorkerAgent> workerAgentPtr = InspectorWorkerAgent::create(); 108 109 OwnPtrWillBeRawPtr<InspectorTracingAgent> tracingAgentPtr = InspectorTracingAgent::create(inspectorClient, workerAgentPtr.get()); 110 m_tracingAgent = tracingAgentPtr.get(); 111 m_agents.append(tracingAgentPtr.release()); 112 113 m_agents.append(workerAgentPtr.release()); 114 115 OwnPtrWillBeRawPtr<InspectorTimelineAgent> timelineAgentPtr(InspectorTimelineAgent::create(m_pageAgent, m_layerTreeAgent, 116 overlay, InspectorTimelineAgent::PageInspector, inspectorClient)); 117 m_timelineAgent = timelineAgentPtr.get(); 118 m_agents.append(timelineAgentPtr.release()); 119 120 PageScriptDebugServer* pageScriptDebugServer = &PageScriptDebugServer::shared(); 121 122 m_agents.append(PageRuntimeAgent::create(injectedScriptManager, inspectorClient, pageScriptDebugServer, m_page, m_pageAgent)); 123 124 m_agents.append(PageConsoleAgent::create(injectedScriptManager, m_domAgent, m_timelineAgent, m_page)); 125 126 ASSERT_ARG(inspectorClient, inspectorClient); 127 m_injectedScriptManager->injectedScriptHost()->init(m_instrumentingAgents.get(), pageScriptDebugServer); 128 } 129 130 InspectorController::~InspectorController() 131 { 132 } 133 134 void InspectorController::trace(Visitor* visitor) 135 { 136 visitor->trace(m_instrumentingAgents); 137 visitor->trace(m_injectedScriptManager); 138 visitor->trace(m_state); 139 visitor->trace(m_domAgent); 140 visitor->trace(m_pageAgent); 141 visitor->trace(m_timelineAgent); 142 visitor->trace(m_cssAgent); 143 visitor->trace(m_resourceAgent); 144 visitor->trace(m_layerTreeAgent); 145 visitor->trace(m_tracingAgent); 146 visitor->trace(m_inspectorBackendDispatcher); 147 visitor->trace(m_page); 148 visitor->trace(m_agents); 149 } 150 151 PassOwnPtrWillBeRawPtr<InspectorController> InspectorController::create(Page* page, InspectorClient* client) 152 { 153 return adoptPtrWillBeNoop(new InspectorController(page, client)); 154 } 155 156 void InspectorController::setTextAutosizingEnabled(bool enabled) 157 { 158 m_pageAgent->setTextAutosizingEnabled(enabled); 159 } 160 161 void InspectorController::setDeviceScaleAdjustment(float deviceScaleAdjustment) 162 { 163 m_pageAgent->setDeviceScaleAdjustment(deviceScaleAdjustment); 164 } 165 166 void InspectorController::setPreferCompositingToLCDTextEnabled(bool enabled) 167 { 168 m_pageAgent->setPreferCompositingToLCDTextEnabled(enabled); 169 } 170 171 void InspectorController::initializeDeferredAgents() 172 { 173 if (m_deferredAgentsInitialized) 174 return; 175 m_deferredAgentsInitialized = true; 176 177 InjectedScriptManager* injectedScriptManager = m_injectedScriptManager.get(); 178 InspectorOverlay* overlay = m_overlay.get(); 179 180 OwnPtrWillBeRawPtr<InspectorResourceAgent> resourceAgentPtr(InspectorResourceAgent::create(m_pageAgent)); 181 m_resourceAgent = resourceAgentPtr.get(); 182 m_agents.append(resourceAgentPtr.release()); 183 184 OwnPtrWillBeRawPtr<InspectorCSSAgent> cssAgentPtr(InspectorCSSAgent::create(m_domAgent, m_pageAgent, m_resourceAgent)); 185 m_cssAgent = cssAgentPtr.get(); 186 m_agents.append(cssAgentPtr.release()); 187 188 m_agents.append(InspectorDOMStorageAgent::create(m_pageAgent)); 189 190 m_agents.append(InspectorMemoryAgent::create()); 191 192 m_agents.append(InspectorApplicationCacheAgent::create(m_pageAgent)); 193 194 PageScriptDebugServer* pageScriptDebugServer = &PageScriptDebugServer::shared(); 195 196 OwnPtrWillBeRawPtr<InspectorDebuggerAgent> debuggerAgentPtr(PageDebuggerAgent::create(pageScriptDebugServer, m_pageAgent, injectedScriptManager, overlay)); 197 InspectorDebuggerAgent* debuggerAgent = debuggerAgentPtr.get(); 198 m_agents.append(debuggerAgentPtr.release()); 199 200 m_agents.append(InspectorDOMDebuggerAgent::create(m_domAgent, debuggerAgent)); 201 202 m_agents.append(InspectorProfilerAgent::create(injectedScriptManager, overlay)); 203 204 m_agents.append(InspectorHeapProfilerAgent::create(injectedScriptManager)); 205 206 m_agents.append(InspectorCanvasAgent::create(m_pageAgent, injectedScriptManager)); 207 208 m_agents.append(InspectorInputAgent::create(m_page, m_inspectorClient)); 209 } 210 211 void InspectorController::willBeDestroyed() 212 { 213 #if ENABLE(ASSERT) 214 ASSERT(m_page->mainFrame()); 215 if (m_page->mainFrame()->isLocalFrame()) 216 ASSERT(m_page->deprecatedLocalMainFrame()->view()); 217 #endif 218 219 disconnectFrontend(); 220 m_injectedScriptManager->disconnect(); 221 m_inspectorClient = 0; 222 m_page = nullptr; 223 m_instrumentingAgents->reset(); 224 m_agents.discardAgents(); 225 if (m_inspectorFrontendClient) 226 m_inspectorFrontendClient->dispose(); 227 } 228 229 void InspectorController::registerModuleAgent(PassOwnPtrWillBeRawPtr<InspectorAgent> agent) 230 { 231 m_agents.append(agent); 232 } 233 234 void InspectorController::setInspectorFrontendClient(InspectorFrontendClient* inspectorFrontendClient) 235 { 236 m_inspectorFrontendClient = inspectorFrontendClient; 237 } 238 239 void InspectorController::didClearDocumentOfWindowObject(LocalFrame* frame) 240 { 241 // If the page is supposed to serve as InspectorFrontend notify inspector frontend 242 // client that it's cleared so that the client can expose inspector bindings. 243 if (m_inspectorFrontendClient && frame == m_page->mainFrame()) 244 m_inspectorFrontendClient->windowObjectCleared(); 245 } 246 247 void InspectorController::connectFrontend(const String& hostId, InspectorFrontendChannel* frontendChannel) 248 { 249 ASSERT(frontendChannel); 250 m_hostId = hostId; 251 252 initializeDeferredAgents(); 253 m_resourceAgent->setHostId(hostId); 254 255 m_inspectorFrontend = adoptPtr(new InspectorFrontend(frontendChannel)); 256 // We can reconnect to existing front-end -> unmute state. 257 m_state->unmute(); 258 259 m_agents.setFrontend(m_inspectorFrontend.get()); 260 261 InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get()); 262 InspectorInstrumentation::frontendCreated(); 263 264 ASSERT(m_inspectorClient); 265 m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(frontendChannel); 266 267 m_agents.registerInDispatcher(m_inspectorBackendDispatcher.get()); 268 } 269 270 void InspectorController::disconnectFrontend() 271 { 272 if (!m_inspectorFrontend) 273 return; 274 m_inspectorBackendDispatcher->clearFrontend(); 275 m_inspectorBackendDispatcher.clear(); 276 277 // Destroying agents would change the state, but we don't want that. 278 // Pre-disconnect state will be used to restore inspector agents. 279 m_state->mute(); 280 281 m_agents.clearFrontend(); 282 283 m_inspectorFrontend.clear(); 284 285 // relese overlay page resources 286 m_overlay->freePage(); 287 InspectorInstrumentation::frontendDeleted(); 288 InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get()); 289 m_hostId = ""; 290 } 291 292 void InspectorController::reconnectFrontend() 293 { 294 if (!m_inspectorFrontend) 295 return; 296 InspectorFrontendChannel* frontendChannel = m_inspectorFrontend->channel(); 297 String hostId = m_hostId; 298 disconnectFrontend(); 299 connectFrontend(hostId, frontendChannel); 300 } 301 302 void InspectorController::reuseFrontend(const String& hostId, InspectorFrontendChannel* frontendChannel, const String& inspectorStateCookie) 303 { 304 ASSERT(!m_inspectorFrontend); 305 connectFrontend(hostId, frontendChannel); 306 m_state->loadFromCookie(inspectorStateCookie); 307 m_agents.restore(); 308 } 309 310 void InspectorController::setProcessId(long processId) 311 { 312 IdentifiersFactory::setProcessId(processId); 313 } 314 315 void InspectorController::setLayerTreeId(int id) 316 { 317 m_timelineAgent->setLayerTreeId(id); 318 m_tracingAgent->setLayerTreeId(id); 319 } 320 321 bool InspectorController::isUnderTest() 322 { 323 return m_isUnderTest; 324 } 325 326 void InspectorController::evaluateForTestInFrontend(long callId, const String& script) 327 { 328 m_isUnderTest = true; 329 if (InspectorInspectorAgent* inspectorAgent = m_instrumentingAgents->inspectorInspectorAgent()) 330 inspectorAgent->evaluateForTestInFrontend(callId, script); 331 } 332 333 void InspectorController::drawHighlight(GraphicsContext& context) const 334 { 335 m_overlay->paint(context); 336 } 337 338 void InspectorController::inspect(Node* node) 339 { 340 if (!node) 341 return; 342 Document* document = node->ownerDocument(); 343 if (!document) 344 return; 345 LocalFrame* frame = document->frame(); 346 if (!frame) 347 return; 348 349 if (!node->isElementNode() && !node->isDocumentNode()) 350 node = node->parentNode(); 351 352 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(ScriptState::forMainWorld(frame)); 353 if (injectedScript.isEmpty()) 354 return; 355 injectedScript.inspectNode(node); 356 } 357 358 void InspectorController::setInjectedScriptForOrigin(const String& origin, const String& source) 359 { 360 if (InspectorInspectorAgent* inspectorAgent = m_instrumentingAgents->inspectorInspectorAgent()) 361 inspectorAgent->setInjectedScriptForOrigin(origin, source); 362 } 363 364 void InspectorController::showContextMenu(float x, float y, PassRefPtr<ContextMenuProvider> menuProvider) 365 { 366 if (!m_inspectorClient) 367 return; 368 m_inspectorClient->showContextMenu(x, y, menuProvider); 369 } 370 371 void InspectorController::dispatchMessageFromFrontend(const String& message) 372 { 373 if (m_inspectorBackendDispatcher) 374 m_inspectorBackendDispatcher->dispatch(message); 375 } 376 377 bool InspectorController::handleGestureEvent(LocalFrame* frame, const PlatformGestureEvent& event) 378 { 379 // Overlay should not consume events. 380 m_overlay->handleGestureEvent(event); 381 if (InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent()) 382 return domAgent->handleGestureEvent(frame, event); 383 return false; 384 } 385 386 bool InspectorController::handleMouseEvent(LocalFrame* frame, const PlatformMouseEvent& event) 387 { 388 // Overlay should not consume events. 389 m_overlay->handleMouseEvent(event); 390 391 if (event.type() == PlatformEvent::MouseMoved) { 392 if (InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent()) 393 return domAgent->handleMouseMove(frame, event); 394 return false; 395 } 396 if (event.type() == PlatformEvent::MousePressed) { 397 if (InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent()) 398 return domAgent->handleMousePress(); 399 } 400 return false; 401 } 402 403 bool InspectorController::handleTouchEvent(LocalFrame* frame, const PlatformTouchEvent& event) 404 { 405 // Overlay should not consume events. 406 m_overlay->handleTouchEvent(event); 407 if (InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent()) 408 return domAgent->handleTouchEvent(frame, event); 409 return false; 410 } 411 412 bool InspectorController::handleKeyboardEvent(LocalFrame* frame, const PlatformKeyboardEvent& event) 413 { 414 // Overlay should not consume events. 415 m_overlay->handleKeyboardEvent(event); 416 return false; 417 } 418 419 void InspectorController::deviceOrPageScaleFactorChanged() 420 { 421 m_pageAgent->deviceOrPageScaleFactorChanged(); 422 } 423 424 bool InspectorController::deviceEmulationEnabled() 425 { 426 return m_pageAgent->deviceMetricsOverrideEnabled(); 427 } 428 429 bool InspectorController::screencastEnabled() 430 { 431 return m_pageAgent->screencastEnabled(); 432 } 433 434 void InspectorController::resume() 435 { 436 if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents->inspectorDebuggerAgent()) { 437 ErrorString error; 438 debuggerAgent->resume(&error); 439 } 440 } 441 442 void InspectorController::setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize) 443 { 444 if (m_resourceAgent) 445 m_resourceAgent->setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize); 446 } 447 448 void InspectorController::willProcessTask() 449 { 450 if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) 451 timelineAgent->willProcessTask(); 452 if (InspectorProfilerAgent* profilerAgent = m_instrumentingAgents->inspectorProfilerAgent()) 453 profilerAgent->willProcessTask(); 454 } 455 456 void InspectorController::didProcessTask() 457 { 458 if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) 459 timelineAgent->didProcessTask(); 460 if (InspectorProfilerAgent* profilerAgent = m_instrumentingAgents->inspectorProfilerAgent()) 461 profilerAgent->didProcessTask(); 462 if (InspectorDOMDebuggerAgent* domDebuggerAgent = m_instrumentingAgents->inspectorDOMDebuggerAgent()) 463 domDebuggerAgent->didProcessTask(); 464 } 465 466 void InspectorController::flushPendingFrontendMessages() 467 { 468 m_agents.flushPendingFrontendMessages(); 469 } 470 471 void InspectorController::didCommitLoadForMainFrame() 472 { 473 m_agents.didCommitLoadForMainFrame(); 474 } 475 476 void InspectorController::didBeginFrame(int frameId) 477 { 478 if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) 479 timelineAgent->didBeginFrame(frameId); 480 if (InspectorCanvasAgent* canvasAgent = m_instrumentingAgents->inspectorCanvasAgent()) 481 canvasAgent->didBeginFrame(); 482 } 483 484 void InspectorController::didCancelFrame() 485 { 486 if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) 487 timelineAgent->didCancelFrame(); 488 } 489 490 void InspectorController::willComposite() 491 { 492 if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) 493 timelineAgent->willComposite(); 494 } 495 496 void InspectorController::didComposite() 497 { 498 if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) 499 timelineAgent->didComposite(); 500 } 501 502 void InspectorController::processGPUEvent(double timestamp, int phase, bool foreign, uint64_t usedGPUMemoryBytes, uint64_t limitGPUMemoryBytes) 503 { 504 if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent()) 505 timelineAgent->processGPUEvent(InspectorTimelineAgent::GPUEvent(timestamp, phase, foreign, usedGPUMemoryBytes, limitGPUMemoryBytes)); 506 } 507 508 void InspectorController::scriptsEnabled(bool enabled) 509 { 510 if (InspectorPageAgent* pageAgent = m_instrumentingAgents->inspectorPageAgent()) 511 pageAgent->scriptsEnabled(enabled); 512 } 513 514 void InspectorController::willAddPageOverlay(const GraphicsLayer* layer) 515 { 516 if (m_layerTreeAgent) 517 m_layerTreeAgent->willAddPageOverlay(layer); 518 } 519 520 void InspectorController::didRemovePageOverlay(const GraphicsLayer* layer) 521 { 522 if (m_layerTreeAgent) 523 m_layerTreeAgent->didRemovePageOverlay(layer); 524 } 525 526 } // namespace blink 527