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 
     33 #include "core/inspector/WorkerInspectorController.h"
     34 
     35 #include "core/InspectorBackendDispatcher.h"
     36 #include "core/InspectorFrontend.h"
     37 #include "core/inspector/InjectedScriptHost.h"
     38 #include "core/inspector/InjectedScriptManager.h"
     39 #include "core/inspector/InspectorConsoleAgent.h"
     40 #include "core/inspector/InspectorFrontendChannel.h"
     41 #include "core/inspector/InspectorHeapProfilerAgent.h"
     42 #include "core/inspector/InspectorInstrumentation.h"
     43 #include "core/inspector/InspectorProfilerAgent.h"
     44 #include "core/inspector/InspectorState.h"
     45 #include "core/inspector/InspectorStateClient.h"
     46 #include "core/inspector/InspectorTimelineAgent.h"
     47 #include "core/inspector/InstrumentingAgents.h"
     48 #include "core/inspector/WorkerConsoleAgent.h"
     49 #include "core/inspector/WorkerDebuggerAgent.h"
     50 #include "core/inspector/WorkerRuntimeAgent.h"
     51 #include "core/workers/WorkerGlobalScope.h"
     52 #include "core/workers/WorkerReportingProxy.h"
     53 #include "core/workers/WorkerThread.h"
     54 #include "wtf/PassOwnPtr.h"
     55 
     56 namespace blink {
     57 
     58 namespace {
     59 
     60 class PageInspectorProxy FINAL : public InspectorFrontendChannel {
     61     WTF_MAKE_FAST_ALLOCATED;
     62 public:
     63     explicit PageInspectorProxy(WorkerGlobalScope* workerGlobalScope) : m_workerGlobalScope(workerGlobalScope) { }
     64     virtual ~PageInspectorProxy() { }
     65 private:
     66     virtual void sendMessageToFrontend(PassRefPtr<JSONObject> message) OVERRIDE
     67     {
     68         m_workerGlobalScope->thread()->workerReportingProxy().postMessageToPageInspector(message->toJSONString());
     69     }
     70     virtual void flush() OVERRIDE { }
     71     WorkerGlobalScope* m_workerGlobalScope;
     72 };
     73 
     74 class WorkerStateClient FINAL : public InspectorStateClient {
     75     WTF_MAKE_FAST_ALLOCATED;
     76 public:
     77     WorkerStateClient(WorkerGlobalScope* context) : m_workerGlobalScope(context) { }
     78     virtual ~WorkerStateClient() { }
     79 
     80 private:
     81     virtual void updateInspectorStateCookie(const String& cookie) OVERRIDE
     82     {
     83         m_workerGlobalScope->thread()->workerReportingProxy().updateInspectorStateCookie(cookie);
     84     }
     85 
     86     WorkerGlobalScope* m_workerGlobalScope;
     87 };
     88 
     89 }
     90 
     91 WorkerInspectorController::WorkerInspectorController(WorkerGlobalScope* workerGlobalScope)
     92     : m_workerGlobalScope(workerGlobalScope)
     93     , m_stateClient(adoptPtr(new WorkerStateClient(workerGlobalScope)))
     94     , m_state(adoptPtrWillBeNoop(new InspectorCompositeState(m_stateClient.get())))
     95     , m_instrumentingAgents(InstrumentingAgents::create())
     96     , m_injectedScriptManager(InjectedScriptManager::createForWorker())
     97     , m_debugServer(adoptPtr(new WorkerScriptDebugServer(workerGlobalScope)))
     98     , m_agents(m_instrumentingAgents.get(), m_state.get())
     99 {
    100     m_agents.append(WorkerRuntimeAgent::create(m_injectedScriptManager.get(), m_debugServer.get(), workerGlobalScope));
    101 
    102     OwnPtrWillBeRawPtr<InspectorTimelineAgent> timelineAgent = InspectorTimelineAgent::create(0, 0, 0, InspectorTimelineAgent::WorkerInspector, 0);
    103     OwnPtrWillBeRawPtr<WorkerDebuggerAgent> workerDebuggerAgent = WorkerDebuggerAgent::create(m_debugServer.get(), workerGlobalScope, m_injectedScriptManager.get());
    104     m_workerDebuggerAgent = workerDebuggerAgent.get();
    105     m_agents.append(workerDebuggerAgent.release());
    106 
    107     m_agents.append(InspectorProfilerAgent::create(m_injectedScriptManager.get(), 0));
    108     m_agents.append(InspectorHeapProfilerAgent::create(m_injectedScriptManager.get()));
    109     m_agents.append(WorkerConsoleAgent::create(timelineAgent.get(), m_injectedScriptManager.get(), workerGlobalScope));
    110     m_agents.append(timelineAgent.release());
    111 
    112     m_injectedScriptManager->injectedScriptHost()->init(m_instrumentingAgents.get(), m_debugServer.get());
    113 }
    114 
    115 WorkerInspectorController::~WorkerInspectorController()
    116 {
    117 }
    118 
    119 void WorkerInspectorController::connectFrontend()
    120 {
    121     ASSERT(!m_frontend);
    122     m_state->unmute();
    123     m_frontendChannel = adoptPtr(new PageInspectorProxy(m_workerGlobalScope));
    124     m_frontend = adoptPtr(new InspectorFrontend(m_frontendChannel.get()));
    125     m_backendDispatcher = InspectorBackendDispatcher::create(m_frontendChannel.get());
    126     m_agents.registerInDispatcher(m_backendDispatcher.get());
    127     m_agents.setFrontend(m_frontend.get());
    128     InspectorInstrumentation::frontendCreated();
    129 }
    130 
    131 void WorkerInspectorController::disconnectFrontend()
    132 {
    133     if (!m_frontend)
    134         return;
    135     m_backendDispatcher->clearFrontend();
    136     m_backendDispatcher.clear();
    137     // Destroying agents would change the state, but we don't want that.
    138     // Pre-disconnect state will be used to restore inspector agents.
    139     m_state->mute();
    140     m_agents.clearFrontend();
    141     m_frontend.clear();
    142     InspectorInstrumentation::frontendDeleted();
    143     m_frontendChannel.clear();
    144 }
    145 
    146 void WorkerInspectorController::restoreInspectorStateFromCookie(const String& inspectorCookie)
    147 {
    148     ASSERT(!m_frontend);
    149     connectFrontend();
    150     m_state->loadFromCookie(inspectorCookie);
    151 
    152     m_agents.restore();
    153 }
    154 
    155 void WorkerInspectorController::dispatchMessageFromFrontend(const String& message)
    156 {
    157     if (m_backendDispatcher)
    158         m_backendDispatcher->dispatch(message);
    159 }
    160 
    161 void WorkerInspectorController::resume()
    162 {
    163     if (WorkerRuntimeAgent* runtimeAgent = m_instrumentingAgents->workerRuntimeAgent()) {
    164         ErrorString unused;
    165         runtimeAgent->run(&unused);
    166     }
    167 }
    168 
    169 void WorkerInspectorController::dispose()
    170 {
    171     m_instrumentingAgents->reset();
    172     disconnectFrontend();
    173 }
    174 
    175 void WorkerInspectorController::interruptAndDispatchInspectorCommands()
    176 {
    177     m_workerDebuggerAgent->interruptAndDispatchInspectorCommands();
    178 }
    179 
    180 void WorkerInspectorController::trace(Visitor* visitor)
    181 {
    182     visitor->trace(m_workerGlobalScope);
    183     visitor->trace(m_state);
    184     visitor->trace(m_instrumentingAgents);
    185     visitor->trace(m_injectedScriptManager);
    186     visitor->trace(m_backendDispatcher);
    187     visitor->trace(m_agents);
    188     visitor->trace(m_workerDebuggerAgent);
    189 }
    190 
    191 }
    192