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