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/InspectorInstrumentation.h" 33 34 #include "core/events/EventTarget.h" 35 #include "core/fetch/FetchInitiatorInfo.h" 36 #include "core/inspector/InspectorCSSAgent.h" 37 #include "core/inspector/InspectorConsoleAgent.h" 38 #include "core/inspector/InspectorController.h" 39 #include "core/inspector/InspectorDebuggerAgent.h" 40 #include "core/inspector/InspectorInspectorAgent.h" 41 #include "core/inspector/InspectorProfilerAgent.h" 42 #include "core/inspector/InspectorResourceAgent.h" 43 #include "core/inspector/InspectorTimelineAgent.h" 44 #include "core/inspector/InstrumentingAgents.h" 45 #include "core/inspector/WorkerInspectorController.h" 46 #include "core/workers/WorkerGlobalScope.h" 47 48 namespace WebCore { 49 50 namespace { 51 static HashSet<InstrumentingAgents*>* instrumentingAgentsSet = 0; 52 } 53 54 namespace InspectorInstrumentation { 55 int FrontendCounter::s_frontendCounter = 0; 56 } 57 58 InspectorInstrumentationCookie::InspectorInstrumentationCookie() 59 : m_instrumentingAgents(nullptr) 60 , m_timelineAgentId(0) 61 { 62 } 63 64 InspectorInstrumentationCookie::InspectorInstrumentationCookie(InstrumentingAgents* agents, int timelineAgentId) 65 : m_instrumentingAgents(agents) 66 , m_timelineAgentId(timelineAgentId) 67 { 68 } 69 70 InspectorInstrumentationCookie::InspectorInstrumentationCookie(const InspectorInstrumentationCookie& other) 71 : m_instrumentingAgents(other.m_instrumentingAgents) 72 , m_timelineAgentId(other.m_timelineAgentId) 73 { 74 } 75 76 InspectorInstrumentationCookie& InspectorInstrumentationCookie::operator=(const InspectorInstrumentationCookie& other) 77 { 78 if (this != &other) { 79 m_instrumentingAgents = other.m_instrumentingAgents; 80 m_timelineAgentId = other.m_timelineAgentId; 81 } 82 return *this; 83 } 84 85 InspectorInstrumentationCookie::~InspectorInstrumentationCookie() 86 { 87 } 88 89 namespace InspectorInstrumentation { 90 91 bool isDebuggerPausedImpl(InstrumentingAgents* instrumentingAgents) 92 { 93 if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) 94 return debuggerAgent->isPaused(); 95 return false; 96 } 97 98 void didReceiveResourceResponseButCanceledImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) 99 { 100 didReceiveResourceResponse(frame, identifier, loader, r, 0); 101 } 102 103 void continueAfterXFrameOptionsDeniedImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) 104 { 105 didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r); 106 } 107 108 void continueWithPolicyDownloadImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) 109 { 110 didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r); 111 } 112 113 void continueWithPolicyIgnoreImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r) 114 { 115 didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r); 116 } 117 118 void willDestroyResourceImpl(Resource* cachedResource) 119 { 120 if (!instrumentingAgentsSet) 121 return; 122 HashSet<InstrumentingAgents*>::iterator end = instrumentingAgentsSet->end(); 123 for (HashSet<InstrumentingAgents*>::iterator it = instrumentingAgentsSet->begin(); it != end; ++it) { 124 InstrumentingAgents* instrumentingAgents = *it; 125 if (InspectorResourceAgent* inspectorResourceAgent = instrumentingAgents->inspectorResourceAgent()) 126 inspectorResourceAgent->willDestroyResource(cachedResource); 127 } 128 } 129 130 bool collectingHTMLParseErrorsImpl(InstrumentingAgents* instrumentingAgents) 131 { 132 if (InspectorInspectorAgent* inspectorAgent = instrumentingAgents->inspectorInspectorAgent()) 133 return inspectorAgent->hasFrontend(); 134 return false; 135 } 136 137 PassOwnPtr<ScriptSourceCode> preprocessImpl(InstrumentingAgents* instrumentingAgents, LocalFrame* frame, const ScriptSourceCode& sourceCode) 138 { 139 if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) 140 return debuggerAgent->preprocess(frame, sourceCode); 141 return PassOwnPtr<ScriptSourceCode>(); 142 } 143 144 String preprocessEventListenerImpl(InstrumentingAgents* instrumentingAgents, LocalFrame* frame, const String& source, const String& url, const String& functionName) 145 { 146 if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) 147 return debuggerAgent->preprocessEventListener(frame, source, url, functionName); 148 return source; 149 } 150 151 bool canvasAgentEnabled(ExecutionContext* executionContext) 152 { 153 InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(executionContext); 154 return instrumentingAgents && instrumentingAgents->inspectorCanvasAgent(); 155 } 156 157 bool consoleAgentEnabled(ExecutionContext* executionContext) 158 { 159 InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(executionContext); 160 InspectorConsoleAgent* consoleAgent = instrumentingAgents ? instrumentingAgents->inspectorConsoleAgent() : 0; 161 return consoleAgent && consoleAgent->enabled(); 162 } 163 164 bool timelineAgentEnabled(ExecutionContext* executionContext) 165 { 166 InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(executionContext); 167 return instrumentingAgents && instrumentingAgents->inspectorTimelineAgent(); 168 } 169 170 void registerInstrumentingAgents(InstrumentingAgents* instrumentingAgents) 171 { 172 if (!instrumentingAgentsSet) 173 instrumentingAgentsSet = new HashSet<InstrumentingAgents*>(); 174 instrumentingAgentsSet->add(instrumentingAgents); 175 } 176 177 void unregisterInstrumentingAgents(InstrumentingAgents* instrumentingAgents) 178 { 179 if (!instrumentingAgentsSet) 180 return; 181 instrumentingAgentsSet->remove(instrumentingAgents); 182 if (instrumentingAgentsSet->isEmpty()) { 183 delete instrumentingAgentsSet; 184 instrumentingAgentsSet = 0; 185 } 186 } 187 188 InspectorTimelineAgent* retrieveTimelineAgent(const InspectorInstrumentationCookie& cookie) 189 { 190 if (!cookie.instrumentingAgents()) 191 return 0; 192 InspectorTimelineAgent* timelineAgent = cookie.instrumentingAgents()->inspectorTimelineAgent(); 193 if (timelineAgent && cookie.hasMatchingTimelineAgentId(timelineAgent->id())) 194 return timelineAgent; 195 return 0; 196 } 197 198 InstrumentingAgents* instrumentingAgentsFor(Page* page) 199 { 200 if (!page) 201 return 0; 202 return instrumentationForPage(page); 203 } 204 205 InstrumentingAgents* instrumentingAgentsFor(EventTarget* eventTarget) 206 { 207 if (!eventTarget) 208 return 0; 209 return instrumentingAgentsFor(eventTarget->executionContext()); 210 } 211 212 InstrumentingAgents* instrumentingAgentsFor(RenderObject* renderer) 213 { 214 return instrumentingAgentsFor(renderer->frame()); 215 } 216 217 InstrumentingAgents* instrumentingAgentsFor(WorkerGlobalScope* workerGlobalScope) 218 { 219 if (!workerGlobalScope) 220 return 0; 221 return instrumentationForWorkerGlobalScope(workerGlobalScope); 222 } 223 224 InstrumentingAgents* instrumentingAgentsForNonDocumentContext(ExecutionContext* context) 225 { 226 if (context->isWorkerGlobalScope()) 227 return instrumentationForWorkerGlobalScope(toWorkerGlobalScope(context)); 228 return 0; 229 } 230 231 } // namespace InspectorInstrumentation 232 233 namespace InstrumentationEvents { 234 const char PaintSetup[] = "PaintSetup"; 235 const char RasterTask[] = "RasterTask"; 236 const char Paint[] = "Paint"; 237 const char Layer[] = "Layer"; 238 const char RequestMainThreadFrame[] = "RequestMainThreadFrame"; 239 const char BeginFrame[] = "BeginFrame"; 240 const char ActivateLayerTree[] = "ActivateLayerTree"; 241 const char DrawFrame[] = "DrawFrame"; 242 const char EmbedderCallback[] = "EmbedderCallback"; 243 }; 244 245 namespace InstrumentationEventArguments { 246 const char FrameId[] = "frameId"; 247 const char LayerId[] = "layerId"; 248 const char LayerTreeId[] = "layerTreeId"; 249 const char PageId[] = "pageId"; 250 const char CallbackName[] = "callbackName"; 251 }; 252 253 InstrumentingAgents* instrumentationForPage(Page* page) 254 { 255 ASSERT(isMainThread()); 256 return page->inspectorController().m_instrumentingAgents.get(); 257 } 258 259 InstrumentingAgents* instrumentationForWorkerGlobalScope(WorkerGlobalScope* workerGlobalScope) 260 { 261 if (WorkerInspectorController* controller = workerGlobalScope->workerInspectorController()) 262 return controller->m_instrumentingAgents.get(); 263 return 0; 264 } 265 266 } // namespace WebCore 267 268