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