Home | History | Annotate | Download | only in inspector
      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/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/Page.h"
     68 #include "core/rendering/RenderLayer.h"
     69 #include "platform/PlatformMouseEvent.h"
     70 
     71 namespace WebCore {
     72 
     73 InspectorController::InspectorController(Page* page, InspectorClient* inspectorClient)
     74     : m_instrumentingAgents(InstrumentingAgents::create())
     75     , m_injectedScriptManager(InjectedScriptManager::createForPage())
     76     , m_state(adoptPtr(new InspectorCompositeState(inspectorClient)))
     77     , m_overlay(InspectorOverlay::create(page, inspectorClient))
     78     , m_layerTreeAgent(0)
     79     , m_page(page)
     80     , m_inspectorClient(inspectorClient)
     81     , m_agents(m_instrumentingAgents.get(), m_state.get())
     82     , m_isUnderTest(false)
     83     , m_deferredAgentsInitialized(false)
     84 {
     85     InjectedScriptManager* injectedScriptManager = m_injectedScriptManager.get();
     86     InspectorOverlay* overlay = m_overlay.get();
     87 
     88     m_agents.append(InspectorInspectorAgent::create(m_page, injectedScriptManager));
     89 
     90     OwnPtr<InspectorPageAgent> pageAgentPtr(InspectorPageAgent::create(m_page, injectedScriptManager, inspectorClient, overlay));
     91     m_pageAgent = pageAgentPtr.get();
     92     m_agents.append(pageAgentPtr.release());
     93 
     94     OwnPtr<InspectorDOMAgent> domAgentPtr(InspectorDOMAgent::create(m_pageAgent, injectedScriptManager, overlay));
     95     m_domAgent = domAgentPtr.get();
     96     m_agents.append(domAgentPtr.release());
     97 
     98 
     99     OwnPtr<InspectorLayerTreeAgent> layerTreeAgentPtr(InspectorLayerTreeAgent::create(m_page));
    100     m_layerTreeAgent = layerTreeAgentPtr.get();
    101     m_agents.append(layerTreeAgentPtr.release());
    102 
    103     OwnPtr<InspectorTracingAgent> tracingAgentPtr = InspectorTracingAgent::create(inspectorClient);
    104     m_tracingAgent = tracingAgentPtr.get();
    105     m_agents.append(tracingAgentPtr.release());
    106 
    107     OwnPtr<InspectorTimelineAgent> timelineAgentPtr(InspectorTimelineAgent::create(m_pageAgent, m_layerTreeAgent,
    108         overlay, InspectorTimelineAgent::PageInspector, inspectorClient));
    109     m_timelineAgent = timelineAgentPtr.get();
    110     m_agents.append(timelineAgentPtr.release());
    111 
    112     PageScriptDebugServer* pageScriptDebugServer = &PageScriptDebugServer::shared();
    113 
    114     m_agents.append(PageRuntimeAgent::create(injectedScriptManager, pageScriptDebugServer, m_page, m_pageAgent));
    115 
    116     m_agents.append(PageConsoleAgent::create(injectedScriptManager, m_domAgent, m_timelineAgent));
    117 
    118     m_agents.append(InspectorWorkerAgent::create());
    119 
    120     ASSERT_ARG(inspectorClient, inspectorClient);
    121     m_injectedScriptManager->injectedScriptHost()->init(m_instrumentingAgents.get(), pageScriptDebugServer);
    122 }
    123 
    124 InspectorController::~InspectorController()
    125 {
    126 }
    127 
    128 PassOwnPtr<InspectorController> InspectorController::create(Page* page, InspectorClient* client)
    129 {
    130     return adoptPtr(new InspectorController(page, client));
    131 }
    132 
    133 void InspectorController::setTextAutosizingEnabled(bool enabled)
    134 {
    135     m_pageAgent->setTextAutosizingEnabled(enabled);
    136 }
    137 
    138 void InspectorController::setDeviceScaleAdjustment(float deviceScaleAdjustment)
    139 {
    140     m_pageAgent->setDeviceScaleAdjustment(deviceScaleAdjustment);
    141 }
    142 
    143 void InspectorController::initializeDeferredAgents()
    144 {
    145     if (m_deferredAgentsInitialized)
    146         return;
    147     m_deferredAgentsInitialized = true;
    148 
    149     InjectedScriptManager* injectedScriptManager = m_injectedScriptManager.get();
    150     InspectorOverlay* overlay = m_overlay.get();
    151 
    152     OwnPtr<InspectorResourceAgent> resourceAgentPtr(InspectorResourceAgent::create(m_pageAgent));
    153     m_resourceAgent = resourceAgentPtr.get();
    154     m_agents.append(resourceAgentPtr.release());
    155 
    156     m_agents.append(InspectorCSSAgent::create(m_domAgent, m_pageAgent, m_resourceAgent));
    157 
    158     m_agents.append(InspectorDOMStorageAgent::create(m_pageAgent));
    159 
    160     m_agents.append(InspectorMemoryAgent::create());
    161 
    162     m_agents.append(InspectorApplicationCacheAgent::create(m_pageAgent));
    163 
    164     PageScriptDebugServer* pageScriptDebugServer = &PageScriptDebugServer::shared();
    165 
    166     OwnPtr<InspectorDebuggerAgent> debuggerAgentPtr(PageDebuggerAgent::create(pageScriptDebugServer, m_pageAgent, injectedScriptManager, overlay));
    167     InspectorDebuggerAgent* debuggerAgent = debuggerAgentPtr.get();
    168     m_agents.append(debuggerAgentPtr.release());
    169 
    170     m_agents.append(InspectorDOMDebuggerAgent::create(m_domAgent, debuggerAgent));
    171 
    172     m_agents.append(InspectorProfilerAgent::create(injectedScriptManager, overlay));
    173 
    174     m_agents.append(InspectorHeapProfilerAgent::create(injectedScriptManager));
    175 
    176     m_agents.append(InspectorCanvasAgent::create(m_pageAgent, injectedScriptManager));
    177 
    178     m_agents.append(InspectorInputAgent::create(m_page, m_inspectorClient));
    179 }
    180 
    181 void InspectorController::willBeDestroyed()
    182 {
    183     disconnectFrontend();
    184     m_injectedScriptManager->disconnect();
    185     m_inspectorClient = 0;
    186     m_page = 0;
    187     m_instrumentingAgents->reset();
    188     m_agents.discardAgents();
    189 }
    190 
    191 void InspectorController::registerModuleAgent(PassOwnPtr<InspectorAgent> agent)
    192 {
    193     m_moduleAgents.append(agent.get());
    194     m_agents.append(agent);
    195 }
    196 
    197 void InspectorController::setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient> inspectorFrontendClient)
    198 {
    199     m_inspectorFrontendClient = inspectorFrontendClient;
    200 }
    201 
    202 void InspectorController::didClearDocumentOfWindowObject(LocalFrame* frame)
    203 {
    204     // If the page is supposed to serve as InspectorFrontend notify inspector frontend
    205     // client that it's cleared so that the client can expose inspector bindings.
    206     if (m_inspectorFrontendClient && frame == m_page->mainFrame())
    207         m_inspectorFrontendClient->windowObjectCleared();
    208 }
    209 
    210 void InspectorController::connectFrontend(const String& hostId, InspectorFrontendChannel* frontendChannel)
    211 {
    212     ASSERT(frontendChannel);
    213     m_hostId = hostId;
    214 
    215     initializeDeferredAgents();
    216     m_resourceAgent->setHostId(hostId);
    217 
    218     m_inspectorFrontend = adoptPtr(new InspectorFrontend(frontendChannel));
    219     // We can reconnect to existing front-end -> unmute state.
    220     m_state->unmute();
    221 
    222     m_agents.setFrontend(m_inspectorFrontend.get());
    223 
    224     InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get());
    225     InspectorInstrumentation::frontendCreated();
    226 
    227     ASSERT(m_inspectorClient);
    228     m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(frontendChannel);
    229 
    230     m_agents.registerInDispatcher(m_inspectorBackendDispatcher.get());
    231 }
    232 
    233 void InspectorController::disconnectFrontend()
    234 {
    235     if (!m_inspectorFrontend)
    236         return;
    237     m_inspectorBackendDispatcher->clearFrontend();
    238     m_inspectorBackendDispatcher.clear();
    239 
    240     // Destroying agents would change the state, but we don't want that.
    241     // Pre-disconnect state will be used to restore inspector agents.
    242     m_state->mute();
    243 
    244     m_agents.clearFrontend();
    245 
    246     m_inspectorFrontend.clear();
    247 
    248     // relese overlay page resources
    249     m_overlay->freePage();
    250     InspectorInstrumentation::frontendDeleted();
    251     InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
    252     m_hostId = "";
    253 }
    254 
    255 void InspectorController::reconnectFrontend()
    256 {
    257     if (!m_inspectorFrontend)
    258         return;
    259     InspectorFrontendChannel* frontendChannel = m_inspectorFrontend->channel();
    260     String hostId = m_hostId;
    261     disconnectFrontend();
    262     connectFrontend(hostId, frontendChannel);
    263 }
    264 
    265 void InspectorController::reuseFrontend(const String& hostId, InspectorFrontendChannel* frontendChannel, const String& inspectorStateCookie)
    266 {
    267     ASSERT(!m_inspectorFrontend);
    268     connectFrontend(hostId, frontendChannel);
    269     m_state->loadFromCookie(inspectorStateCookie);
    270     m_agents.restore();
    271 }
    272 
    273 void InspectorController::setProcessId(long processId)
    274 {
    275     IdentifiersFactory::setProcessId(processId);
    276 }
    277 
    278 void InspectorController::setLayerTreeId(int id)
    279 {
    280     m_timelineAgent->setLayerTreeId(id);
    281     m_tracingAgent->setLayerTreeId(id);
    282 }
    283 
    284 bool InspectorController::isUnderTest()
    285 {
    286     return m_isUnderTest;
    287 }
    288 
    289 void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
    290 {
    291     m_isUnderTest = true;
    292     if (InspectorInspectorAgent* inspectorAgent = m_instrumentingAgents->inspectorInspectorAgent())
    293         inspectorAgent->evaluateForTestInFrontend(callId, script);
    294 }
    295 
    296 void InspectorController::drawHighlight(GraphicsContext& context) const
    297 {
    298     m_overlay->paint(context);
    299 }
    300 
    301 void InspectorController::inspect(Node* node)
    302 {
    303     if (!node)
    304         return;
    305     Document* document = node->ownerDocument();
    306     if (!document)
    307         return;
    308     LocalFrame* frame = document->frame();
    309     if (!frame)
    310         return;
    311 
    312     if (!node->isElementNode() && !node->isDocumentNode())
    313         node = node->parentNode();
    314 
    315     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(ScriptState::forMainWorld(frame));
    316     if (injectedScript.isEmpty())
    317         return;
    318     injectedScript.inspectNode(node);
    319 }
    320 
    321 void InspectorController::setInjectedScriptForOrigin(const String& origin, const String& source)
    322 {
    323     if (InspectorInspectorAgent* inspectorAgent = m_instrumentingAgents->inspectorInspectorAgent())
    324         inspectorAgent->setInjectedScriptForOrigin(origin, source);
    325 }
    326 
    327 void InspectorController::dispatchMessageFromFrontend(const String& message)
    328 {
    329     if (m_inspectorBackendDispatcher)
    330         m_inspectorBackendDispatcher->dispatch(message);
    331 }
    332 
    333 bool InspectorController::handleGestureEvent(LocalFrame* frame, const PlatformGestureEvent& event)
    334 {
    335     // Overlay should not consume events.
    336     m_overlay->handleGestureEvent(event);
    337     if (InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent())
    338         return domAgent->handleGestureEvent(frame, event);
    339     return false;
    340 }
    341 
    342 bool InspectorController::handleMouseEvent(LocalFrame* frame, const PlatformMouseEvent& event)
    343 {
    344     // Overlay should not consume events.
    345     m_overlay->handleMouseEvent(event);
    346 
    347     if (event.type() == PlatformEvent::MouseMoved) {
    348         if (InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent())
    349             domAgent->handleMouseMove(frame, event);
    350         return false;
    351     }
    352     if (event.type() == PlatformEvent::MousePressed) {
    353         if (InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent())
    354             return domAgent->handleMousePress();
    355     }
    356     return false;
    357 }
    358 
    359 bool InspectorController::handleTouchEvent(LocalFrame* frame, const PlatformTouchEvent& event)
    360 {
    361     // Overlay should not consume events.
    362     m_overlay->handleTouchEvent(event);
    363     if (InspectorDOMAgent* domAgent = m_instrumentingAgents->inspectorDOMAgent())
    364         return domAgent->handleTouchEvent(frame, event);
    365     return false;
    366 }
    367 
    368 bool InspectorController::handleKeyboardEvent(LocalFrame* frame, const PlatformKeyboardEvent& event)
    369 {
    370     // Overlay should not consume events.
    371     m_overlay->handleKeyboardEvent(event);
    372     return false;
    373 }
    374 
    375 void InspectorController::requestPageScaleFactor(float scale, const IntPoint& origin)
    376 {
    377     m_inspectorClient->requestPageScaleFactor(scale, origin);
    378 }
    379 
    380 bool InspectorController::deviceEmulationEnabled()
    381 {
    382     if (InspectorPageAgent* pageAgent = m_instrumentingAgents->inspectorPageAgent())
    383         return pageAgent->deviceMetricsOverrideEnabled();
    384     return false;
    385 }
    386 
    387 void InspectorController::resume()
    388 {
    389     if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents->inspectorDebuggerAgent()) {
    390         ErrorString error;
    391         debuggerAgent->resume(&error);
    392     }
    393 }
    394 
    395 void InspectorController::setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize)
    396 {
    397     if (m_resourceAgent)
    398         m_resourceAgent->setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
    399 }
    400 
    401 void InspectorController::willProcessTask()
    402 {
    403     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
    404         timelineAgent->willProcessTask();
    405     if (InspectorProfilerAgent* profilerAgent = m_instrumentingAgents->inspectorProfilerAgent())
    406         profilerAgent->willProcessTask();
    407 }
    408 
    409 void InspectorController::didProcessTask()
    410 {
    411     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
    412         timelineAgent->didProcessTask();
    413     if (InspectorProfilerAgent* profilerAgent = m_instrumentingAgents->inspectorProfilerAgent())
    414         profilerAgent->didProcessTask();
    415     if (InspectorDOMDebuggerAgent* domDebuggerAgent = m_instrumentingAgents->inspectorDOMDebuggerAgent())
    416         domDebuggerAgent->didProcessTask();
    417 }
    418 
    419 void InspectorController::flushPendingFrontendMessages()
    420 {
    421     m_agents.flushPendingFrontendMessages();
    422 }
    423 
    424 void InspectorController::didCommitLoadForMainFrame()
    425 {
    426     Vector<InspectorAgent*> agents = m_moduleAgents;
    427     for (size_t i = 0; i < agents.size(); i++)
    428         agents[i]->didCommitLoadForMainFrame();
    429 }
    430 
    431 void InspectorController::didBeginFrame(int frameId)
    432 {
    433     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
    434         timelineAgent->didBeginFrame(frameId);
    435     if (InspectorCanvasAgent* canvasAgent = m_instrumentingAgents->inspectorCanvasAgent())
    436         canvasAgent->didBeginFrame();
    437 }
    438 
    439 void InspectorController::didCancelFrame()
    440 {
    441     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
    442         timelineAgent->didCancelFrame();
    443 }
    444 
    445 void InspectorController::willComposite()
    446 {
    447     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
    448         timelineAgent->willComposite();
    449 }
    450 
    451 void InspectorController::didComposite()
    452 {
    453     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
    454         timelineAgent->didComposite();
    455 }
    456 
    457 void InspectorController::processGPUEvent(double timestamp, int phase, bool foreign, uint64_t usedGPUMemoryBytes, uint64_t limitGPUMemoryBytes)
    458 {
    459     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
    460         timelineAgent->processGPUEvent(InspectorTimelineAgent::GPUEvent(timestamp, phase, foreign, usedGPUMemoryBytes, limitGPUMemoryBytes));
    461 }
    462 
    463 void InspectorController::scriptsEnabled(bool  enabled)
    464 {
    465     if (InspectorPageAgent* pageAgent = m_instrumentingAgents->inspectorPageAgent())
    466         pageAgent->scriptsEnabled(enabled);
    467 }
    468 
    469 void InspectorController::willAddPageOverlay(const GraphicsLayer* layer)
    470 {
    471     if (m_layerTreeAgent)
    472         m_layerTreeAgent->willAddPageOverlay(layer);
    473 }
    474 
    475 void InspectorController::didRemovePageOverlay(const GraphicsLayer* layer)
    476 {
    477     if (m_layerTreeAgent)
    478         m_layerTreeAgent->didRemovePageOverlay(layer);
    479 }
    480 
    481 } // namespace WebCore
    482