[Resource Timing] Gather timing information with reliable responseEnd time
[WebKit-https.git] / Source / WebCore / inspector / InspectorInstrumentation.cpp
1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 *     * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *     * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *     * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "config.h"
33 #include "InspectorInstrumentation.h"
34
35 #include "DOMWindow.h"
36 #include "DOMWrapperWorld.h"
37 #include "Database.h"
38 #include "DocumentLoader.h"
39 #include "Event.h"
40 #include "EventDispatcher.h"
41 #include "InspectorApplicationCacheAgent.h"
42 #include "InspectorCSSAgent.h"
43 #include "InspectorDOMAgent.h"
44 #include "InspectorDOMDebuggerAgent.h"
45 #include "InspectorDOMStorageAgent.h"
46 #include "InspectorDatabaseAgent.h"
47 #include "InspectorLayerTreeAgent.h"
48 #include "InspectorMemoryAgent.h"
49 #include "InspectorNetworkAgent.h"
50 #include "InspectorPageAgent.h"
51 #include "InspectorTimelineAgent.h"
52 #include "InspectorWorkerAgent.h"
53 #include "InstrumentingAgents.h"
54 #include "MainFrame.h"
55 #include "PageDebuggerAgent.h"
56 #include "PageHeapAgent.h"
57 #include "PageRuntimeAgent.h"
58 #include "RenderObject.h"
59 #include "RenderView.h"
60 #include "ScriptController.h"
61 #include "WebConsoleAgent.h"
62 #include "WebSocketFrame.h"
63 #include <inspector/ConsoleMessage.h>
64 #include <inspector/ScriptArguments.h>
65 #include <inspector/ScriptCallStack.h>
66 #include <inspector/agents/InspectorDebuggerAgent.h>
67 #include <runtime/ConsoleTypes.h>
68 #include <wtf/StdLibExtras.h>
69
70 #if ENABLE(WEB_REPLAY)
71 #include "InspectorReplayAgent.h"
72 #include "ReplayController.h"
73 #endif
74
75 using namespace Inspector;
76
77 namespace WebCore {
78
79 static const char* const requestAnimationFrameEventName = "requestAnimationFrame";
80 static const char* const cancelAnimationFrameEventName = "cancelAnimationFrame";
81 static const char* const animationFrameFiredEventName = "animationFrameFired";
82 static const char* const setTimerEventName = "setTimer";
83 static const char* const clearTimerEventName = "clearTimer";
84 static const char* const timerFiredEventName = "timerFired";
85
86 enum AsyncCallType {
87     AsyncCallTypeRequestAnimationFrame,
88     AsyncCallTypeTimer,
89 };
90
91 namespace {
92 static HashSet<InstrumentingAgents*>* s_instrumentingAgentsSet = nullptr;
93 }
94
95 int InspectorInstrumentation::s_frontendCounter = 0;
96
97 static void didScheduleAsyncCall(InstrumentingAgents& instrumentingAgents, AsyncCallType type, int callbackId, ScriptExecutionContext& context, bool singleShot)
98 {
99     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) {
100         JSC::ExecState* scriptState = context.execState();
101         if (!scriptState)
102             return;
103
104         debuggerAgent->didScheduleAsyncCall(scriptState, type, callbackId, singleShot);
105     }
106 }
107
108 static Frame* frameForScriptExecutionContext(ScriptExecutionContext* context)
109 {
110     Frame* frame = nullptr;
111     if (is<Document>(*context))
112         frame = downcast<Document>(*context).frame();
113     return frame;
114 }
115
116 static Frame* frameForScriptExecutionContext(ScriptExecutionContext& context)
117 {
118     Frame* frame = nullptr;
119     if (is<Document>(context))
120         frame = downcast<Document>(context).frame();
121     return frame;
122 }
123
124 void InspectorInstrumentation::didClearWindowObjectInWorldImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, DOMWrapperWorld& world)
125 {
126     InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent();
127     if (pageAgent)
128         pageAgent->didClearWindowObjectInWorld(&frame, world);
129     if (PageDebuggerAgent* debuggerAgent = instrumentingAgents.pageDebuggerAgent()) {
130         if (pageAgent && &world == &mainThreadNormalWorld() && &frame == &pageAgent->mainFrame())
131             debuggerAgent->didClearMainFrameWindowObject();
132     }
133     if (PageRuntimeAgent* pageRuntimeAgent = instrumentingAgents.pageRuntimeAgent()) {
134         if (&world == &mainThreadNormalWorld())
135             pageRuntimeAgent->didCreateMainWorldContext(frame);
136     }
137 }
138
139 bool InspectorInstrumentation::isDebuggerPausedImpl(InstrumentingAgents& instrumentingAgents)
140 {
141     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent())
142         return debuggerAgent->isPaused();
143     return false;
144 }
145
146 void InspectorInstrumentation::willInsertDOMNodeImpl(InstrumentingAgents& instrumentingAgents, Node& parent)
147 {
148     if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent())
149         domDebuggerAgent->willInsertDOMNode(parent);
150 }
151
152 void InspectorInstrumentation::didInsertDOMNodeImpl(InstrumentingAgents& instrumentingAgents, Node& node)
153 {
154     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
155         domAgent->didInsertDOMNode(node);
156     if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent())
157         domDebuggerAgent->didInsertDOMNode(node);
158 }
159
160 void InspectorInstrumentation::willRemoveDOMNodeImpl(InstrumentingAgents& instrumentingAgents, Node& node)
161 {
162     if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent())
163         domDebuggerAgent->willRemoveDOMNode(node);
164 }
165
166 void InspectorInstrumentation::didRemoveDOMNodeImpl(InstrumentingAgents& instrumentingAgents, Node& node)
167 {
168     if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent())
169         domDebuggerAgent->didRemoveDOMNode(node);
170     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
171         domAgent->didRemoveDOMNode(node);
172 }
173
174 void InspectorInstrumentation::willModifyDOMAttrImpl(InstrumentingAgents& instrumentingAgents, Element& element, const AtomicString& oldValue, const AtomicString& newValue)
175 {
176     if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent())
177         domDebuggerAgent->willModifyDOMAttr(element);
178     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
179         domAgent->willModifyDOMAttr(element, oldValue, newValue);
180 }
181
182 void InspectorInstrumentation::didModifyDOMAttrImpl(InstrumentingAgents& instrumentingAgents, Element& element, const AtomicString& name, const AtomicString& value)
183 {
184     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
185         domAgent->didModifyDOMAttr(element, name, value);
186 }
187
188 void InspectorInstrumentation::didRemoveDOMAttrImpl(InstrumentingAgents& instrumentingAgents, Element& element, const AtomicString& name)
189 {
190     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
191         domAgent->didRemoveDOMAttr(element, name);
192 }
193
194 void InspectorInstrumentation::didInvalidateStyleAttrImpl(InstrumentingAgents& instrumentingAgents, Node& node)
195 {
196     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
197         domAgent->didInvalidateStyleAttr(node);
198     if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent())
199         domDebuggerAgent->didInvalidateStyleAttr(node);
200 }
201
202 void InspectorInstrumentation::documentDetachedImpl(InstrumentingAgents& instrumentingAgents, Document& document)
203 {
204     if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
205         cssAgent->documentDetached(document);
206 }
207
208 void InspectorInstrumentation::frameWindowDiscardedImpl(InstrumentingAgents& instrumentingAgents, DOMWindow* window)
209 {
210     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
211         consoleAgent->frameWindowDiscarded(window);
212 }
213
214 void InspectorInstrumentation::mediaQueryResultChangedImpl(InstrumentingAgents& instrumentingAgents)
215 {
216     if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
217         cssAgent->mediaQueryResultChanged();
218 }
219
220 void InspectorInstrumentation::activeStyleSheetsUpdatedImpl(InstrumentingAgents& instrumentingAgents, Document& document)
221 {
222     if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
223         cssAgent->activeStyleSheetsUpdated(document);
224 }
225
226 void InspectorInstrumentation::didPushShadowRootImpl(InstrumentingAgents& instrumentingAgents, Element& host, ShadowRoot& root)
227 {
228     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
229         domAgent->didPushShadowRoot(host, root);
230 }
231
232 void InspectorInstrumentation::willPopShadowRootImpl(InstrumentingAgents& instrumentingAgents, Element& host, ShadowRoot& root)
233 {
234     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
235         domAgent->willPopShadowRoot(host, root);
236 }
237
238 void InspectorInstrumentation::didChangeCustomElementStateImpl(InstrumentingAgents& instrumentingAgents, Element& element)
239 {
240     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
241         domAgent->didChangeCustomElementState(element);
242 }
243
244 void InspectorInstrumentation::pseudoElementCreatedImpl(InstrumentingAgents& instrumentingAgents, PseudoElement& pseudoElement)
245 {
246     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
247         domAgent->pseudoElementCreated(pseudoElement);
248 }
249
250 void InspectorInstrumentation::pseudoElementDestroyedImpl(InstrumentingAgents& instrumentingAgents, PseudoElement& pseudoElement)
251 {
252     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
253         domAgent->pseudoElementDestroyed(pseudoElement);
254     if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents.inspectorLayerTreeAgent())
255         layerTreeAgent->pseudoElementDestroyed(pseudoElement);
256 }
257
258 void InspectorInstrumentation::didCreateNamedFlowImpl(InstrumentingAgents& instrumentingAgents, Document* document, WebKitNamedFlow& namedFlow)
259 {
260     if (!document)
261         return;
262
263     if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
264         cssAgent->didCreateNamedFlow(*document, namedFlow);
265 }
266
267 void InspectorInstrumentation::willRemoveNamedFlowImpl(InstrumentingAgents& instrumentingAgents, Document* document, WebKitNamedFlow& namedFlow)
268 {
269     if (!document)
270         return;
271
272     if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
273         cssAgent->willRemoveNamedFlow(*document, namedFlow);
274 }
275
276 void InspectorInstrumentation::didChangeRegionOversetImpl(InstrumentingAgents& instrumentingAgents, Document& document, WebKitNamedFlow& namedFlow)
277 {
278     if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
279         cssAgent->didChangeRegionOverset(document, namedFlow);
280 }
281
282 void InspectorInstrumentation::didRegisterNamedFlowContentElementImpl(InstrumentingAgents& instrumentingAgents, Document& document, WebKitNamedFlow& namedFlow, Node& contentElement, Node* nextContentElement)
283 {
284     if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
285         cssAgent->didRegisterNamedFlowContentElement(document, namedFlow, contentElement, nextContentElement);
286 }
287
288 void InspectorInstrumentation::didUnregisterNamedFlowContentElementImpl(InstrumentingAgents& instrumentingAgents, Document& document, WebKitNamedFlow& namedFlow, Node& contentElement)
289 {
290     if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
291         cssAgent->didUnregisterNamedFlowContentElement(document, namedFlow, contentElement);
292 }
293
294 void InspectorInstrumentation::mouseDidMoveOverElementImpl(InstrumentingAgents& instrumentingAgents, const HitTestResult& result, unsigned modifierFlags)
295 {
296     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
297         domAgent->mouseDidMoveOverElement(result, modifierFlags);
298 }
299
300 void InspectorInstrumentation::didScrollImpl(InstrumentingAgents& instrumentingAgents)
301 {
302     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
303         pageAgent->didScroll();
304 }
305
306 bool InspectorInstrumentation::handleTouchEventImpl(InstrumentingAgents& instrumentingAgents, Node& node)
307 {
308     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
309         return domAgent->handleTouchEvent(node);
310     return false;
311 }
312
313 bool InspectorInstrumentation::handleMousePressImpl(InstrumentingAgents& instrumentingAgents)
314 {
315     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
316         return domAgent->handleMousePress();
317     return false;
318 }
319
320 bool InspectorInstrumentation::forcePseudoStateImpl(InstrumentingAgents& instrumentingAgents, const Element& element, CSSSelector::PseudoClassType pseudoState)
321 {
322     if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
323         return cssAgent->forcePseudoState(element, pseudoState);
324     return false;
325 }
326
327 void InspectorInstrumentation::characterDataModifiedImpl(InstrumentingAgents& instrumentingAgents, CharacterData& characterData)
328 {
329     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
330         domAgent->characterDataModified(characterData);
331 }
332
333 void InspectorInstrumentation::willSendXMLHttpRequestImpl(InstrumentingAgents& instrumentingAgents, const String& url)
334 {
335     if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent())
336         domDebuggerAgent->willSendXMLHttpRequest(url);
337 }
338
339 void InspectorInstrumentation::didInstallTimerImpl(InstrumentingAgents& instrumentingAgents, int timerId, std::chrono::milliseconds timeout, bool singleShot, ScriptExecutionContext& context)
340 {
341     pauseOnNativeEventIfNeeded(instrumentingAgents, false, setTimerEventName, true);
342     didScheduleAsyncCall(instrumentingAgents, AsyncCallTypeTimer, timerId, context, singleShot);
343
344     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
345         timelineAgent->didInstallTimer(timerId, timeout, singleShot, frameForScriptExecutionContext(context));
346 }
347
348 void InspectorInstrumentation::didRemoveTimerImpl(InstrumentingAgents& instrumentingAgents, int timerId, ScriptExecutionContext& context)
349 {
350     pauseOnNativeEventIfNeeded(instrumentingAgents, false, clearTimerEventName, true);
351
352     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent())
353         debuggerAgent->didCancelAsyncCall(AsyncCallTypeTimer, timerId);
354     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
355         timelineAgent->didRemoveTimer(timerId, frameForScriptExecutionContext(context));
356 }
357
358 InspectorInstrumentationCookie InspectorInstrumentation::willCallFunctionImpl(InstrumentingAgents& instrumentingAgents, const String& scriptName, int scriptLine, ScriptExecutionContext* context)
359 {
360     int timelineAgentId = 0;
361     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) {
362         timelineAgent->willCallFunction(scriptName, scriptLine, frameForScriptExecutionContext(context));
363         timelineAgentId = timelineAgent->id();
364     }
365     return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
366 }
367
368 void InspectorInstrumentation::didCallFunctionImpl(const InspectorInstrumentationCookie& cookie, ScriptExecutionContext* context)
369 {
370     if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
371         timelineAgent->didCallFunction(frameForScriptExecutionContext(context));
372 }
373
374 InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InstrumentingAgents& instrumentingAgents, Document& document, const Event& event, bool hasEventListeners)
375 {
376     int timelineAgentId = 0;
377     InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent();
378     if (timelineAgent && hasEventListeners) {
379         timelineAgent->willDispatchEvent(event, document.frame());
380         timelineAgentId = timelineAgent->id();
381     }
382 #if ENABLE(WEB_REPLAY)
383     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
384         replayAgent->willDispatchEvent(event, document.frame());
385 #endif
386     return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
387 }
388
389 void InspectorInstrumentation::willHandleEventImpl(InstrumentingAgents& instrumentingAgents, const Event& event)
390 {
391     pauseOnNativeEventIfNeeded(instrumentingAgents, true, event.type(), false);
392 }
393
394 void InspectorInstrumentation::didDispatchEventImpl(const InspectorInstrumentationCookie& cookie)
395 {
396     if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
397         timelineAgent->didDispatchEvent();
398 }
399
400 InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindowImpl(InstrumentingAgents& instrumentingAgents, const Event& event, DOMWindow& window)
401 {
402     int timelineAgentId = 0;
403     InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent();
404     if (timelineAgent && window.hasEventListeners(event.type())) {
405         timelineAgent->willDispatchEvent(event, window.frame());
406         timelineAgentId = timelineAgent->id();
407     }
408 #if ENABLE(WEB_REPLAY)
409     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
410         replayAgent->willDispatchEvent(event, window.frame());
411 #endif
412     return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
413 }
414
415 void InspectorInstrumentation::didDispatchEventOnWindowImpl(const InspectorInstrumentationCookie& cookie)
416 {
417     if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
418         timelineAgent->didDispatchEvent();
419 }
420
421 InspectorInstrumentationCookie InspectorInstrumentation::willEvaluateScriptImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, const String& url, int lineNumber)
422 {
423     int timelineAgentId = 0;
424     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) {
425         timelineAgent->willEvaluateScript(url, lineNumber, frame);
426         timelineAgentId = timelineAgent->id();
427     }
428     return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
429 }
430
431 void InspectorInstrumentation::didEvaluateScriptImpl(const InspectorInstrumentationCookie& cookie, Frame& frame)
432 {
433     if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
434         timelineAgent->didEvaluateScript(frame);
435 }
436
437 InspectorInstrumentationCookie InspectorInstrumentation::willFireTimerImpl(InstrumentingAgents& instrumentingAgents, int timerId, ScriptExecutionContext& context)
438 {
439     pauseOnNativeEventIfNeeded(instrumentingAgents, false, timerFiredEventName, false);
440
441     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent())
442         debuggerAgent->willDispatchAsyncCall(AsyncCallTypeTimer, timerId);
443
444     int timelineAgentId = 0;
445     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) {
446         timelineAgent->willFireTimer(timerId, frameForScriptExecutionContext(context));
447         timelineAgentId = timelineAgent->id();
448     }
449     return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
450 }
451
452 void InspectorInstrumentation::didFireTimerImpl(const InspectorInstrumentationCookie& cookie)
453 {
454     if (InspectorDebuggerAgent* debuggerAgent = cookie.instrumentingAgents()->inspectorDebuggerAgent())
455         debuggerAgent->didDispatchAsyncCall();
456     if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
457         timelineAgent->didFireTimer();
458 }
459
460 void InspectorInstrumentation::didInvalidateLayoutImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
461 {
462     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
463         timelineAgent->didInvalidateLayout(frame);
464 }
465
466 InspectorInstrumentationCookie InspectorInstrumentation::willLayoutImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
467 {
468     int timelineAgentId = 0;
469     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) {
470         timelineAgent->willLayout(frame);
471         timelineAgentId = timelineAgent->id();
472     }
473     return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
474 }
475
476 void InspectorInstrumentation::didLayoutImpl(const InspectorInstrumentationCookie& cookie, RenderObject& root)
477 {
478     if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
479         timelineAgent->didLayout(root);
480
481     if (InspectorPageAgent* pageAgent = cookie.instrumentingAgents()->inspectorPageAgent())
482         pageAgent->didLayout();
483 }
484
485 void InspectorInstrumentation::willCompositeImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
486 {
487     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
488         timelineAgent->willComposite(frame);
489 }
490
491 void InspectorInstrumentation::didCompositeImpl(InstrumentingAgents& instrumentingAgents)
492 {
493     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
494         timelineAgent->didComposite();
495 }
496
497 void InspectorInstrumentation::willPaintImpl(InstrumentingAgents& instrumentingAgents, RenderObject& renderer)
498 {
499     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
500         timelineAgent->willPaint(renderer.frame());
501 }
502
503 void InspectorInstrumentation::didPaintImpl(InstrumentingAgents& instrumentingAgents, RenderObject& renderer, const LayoutRect& rect)
504 {
505     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
506         timelineAgent->didPaint(renderer, rect);
507
508     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
509         pageAgent->didPaint(renderer, rect);
510 }
511
512 InspectorInstrumentationCookie InspectorInstrumentation::willRecalculateStyleImpl(InstrumentingAgents& instrumentingAgents, Document& document)
513 {
514     int timelineAgentId = 0;
515     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) {
516         timelineAgent->willRecalculateStyle(document.frame());
517         timelineAgentId = timelineAgent->id();
518     }
519     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
520         networkAgent->willRecalculateStyle();
521     return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
522 }
523
524 void InspectorInstrumentation::didRecalculateStyleImpl(const InspectorInstrumentationCookie& cookie)
525 {
526     if (!cookie.isValid())
527         return;
528     
529     InstrumentingAgents& instrumentingAgents = *cookie.instrumentingAgents();
530
531     if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
532         timelineAgent->didRecalculateStyle();
533     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
534         networkAgent->didRecalculateStyle();
535     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
536         pageAgent->didRecalculateStyle();
537 }
538
539 void InspectorInstrumentation::didScheduleStyleRecalculationImpl(InstrumentingAgents& instrumentingAgents, Document& document)
540 {
541     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
542         timelineAgent->didScheduleStyleRecalculation(document.frame());
543     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
544         networkAgent->didScheduleStyleRecalculation(document);
545 }
546
547 void InspectorInstrumentation::applyEmulatedMediaImpl(InstrumentingAgents& instrumentingAgents, String& media)
548 {
549     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
550         pageAgent->applyEmulatedMedia(media);
551 }
552
553 void InspectorInstrumentation::willSendRequestImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
554 {
555     if (!loader)
556         return;
557
558     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
559         networkAgent->willSendRequest(identifier, *loader, request, redirectResponse);
560 }
561
562 void InspectorInstrumentation::continueAfterPingLoaderImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& response)
563 {
564     willSendRequestImpl(instrumentingAgents, identifier, loader, request, response);
565 }
566
567 void InspectorInstrumentation::markResourceAsCachedImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier)
568 {
569     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
570         networkAgent->markResourceAsCached(identifier);
571 }
572
573 void InspectorInstrumentation::didLoadResourceFromMemoryCacheImpl(InstrumentingAgents& instrumentingAgents, DocumentLoader* loader, CachedResource* cachedResource)
574 {
575     if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled())
576         return;
577     
578     if (!loader || !cachedResource)
579         return;
580
581     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
582         networkAgent->didLoadResourceFromMemoryCache(*loader, *cachedResource);
583 }
584
585 void InspectorInstrumentation::didReceiveResourceResponseImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
586 {
587     if (!loader)
588         return;
589
590     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
591         networkAgent->didReceiveResponse(identifier, *loader, response, resourceLoader);
592     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
593         consoleAgent->didReceiveResponse(identifier, response); // This should come AFTER resource notification, front-end relies on this.
594 }
595
596 void InspectorInstrumentation::didReceiveThreadableLoaderResponseImpl(InstrumentingAgents& instrumentingAgents, DocumentThreadableLoader& documentThreadableLoader, unsigned long identifier)
597 {
598     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
599         networkAgent->didReceiveThreadableLoaderResponse(identifier, documentThreadableLoader);
600 }
601
602 void InspectorInstrumentation::didReceiveDataImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const char* data, int dataLength, int encodedDataLength)
603 {
604     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
605         networkAgent->didReceiveData(identifier, data, dataLength, encodedDataLength);
606 }
607
608 void InspectorInstrumentation::didFinishLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader)
609 {
610     if (!loader)
611         return;
612
613     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
614         networkAgent->didFinishLoading(identifier, *loader);
615 }
616
617 void InspectorInstrumentation::didFailLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, DocumentLoader* loader, const ResourceError& error)
618 {
619     if (!loader)
620         return;
621
622     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
623         networkAgent->didFailLoading(identifier, *loader, error);
624     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
625         consoleAgent->didFailLoading(identifier, error); // This should come AFTER resource notification, front-end relies on this.
626 }
627
628 void InspectorInstrumentation::didFinishXHRLoadingImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, std::optional<String> decodedText, const String& url, const String& sendURL, unsigned sendLineNumber, unsigned sendColumnNumber)
629 {
630     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
631         consoleAgent->didFinishXHRLoading(identifier, url, sendURL, sendLineNumber, sendColumnNumber);
632     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent()) {
633         if (decodedText)
634             networkAgent->didFinishXHRLoading(identifier, *decodedText);
635     }
636 }
637
638 void InspectorInstrumentation::willLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents)
639 {
640     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
641         networkAgent->willLoadXHRSynchronously();
642 }
643
644 void InspectorInstrumentation::didLoadXHRSynchronouslyImpl(InstrumentingAgents& instrumentingAgents)
645 {
646     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
647         networkAgent->didLoadXHRSynchronously();
648 }
649
650 void InspectorInstrumentation::scriptImportedImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const String& sourceString)
651 {
652     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
653         networkAgent->setInitialScriptContent(identifier, sourceString);
654 }
655
656 void InspectorInstrumentation::scriptExecutionBlockedByCSPImpl(InstrumentingAgents& instrumentingAgents, const String& directiveText)
657 {
658     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent())
659         debuggerAgent->scriptExecutionBlockedByCSP(directiveText);
660 }
661
662 void InspectorInstrumentation::didReceiveScriptResponseImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier)
663 {
664     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
665         networkAgent->didReceiveScriptResponse(identifier);
666 }
667
668 void InspectorInstrumentation::domContentLoadedEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
669 {
670     if (!frame.isMainFrame())
671         return;
672
673     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
674         domAgent->mainFrameDOMContentLoaded();
675
676     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
677         pageAgent->domContentEventFired();
678 }
679
680 void InspectorInstrumentation::loadEventFiredImpl(InstrumentingAgents& instrumentingAgents, Frame* frame)
681 {
682     if (!frame || !frame->isMainFrame())
683         return;
684
685     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
686         pageAgent->loadEventFired();
687 }
688
689 void InspectorInstrumentation::frameDetachedFromParentImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
690 {
691     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
692         pageAgent->frameDetached(frame);
693
694 #if ENABLE(WEB_REPLAY)
695     if (!frame.isMainFrame())
696         return;
697
698     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
699         replayAgent->frameDetached(frame);
700 #endif
701 }
702
703 void InspectorInstrumentation::didCommitLoadImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, DocumentLoader* loader)
704 {
705     if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled())
706         return;
707
708     if (!frame.page())
709         return;
710
711     if (!loader)
712         return;
713
714     ASSERT(loader->frame() == &frame);
715
716     if (frame.isMainFrame()) {
717         if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
718             consoleAgent->reset();
719
720         if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
721             networkAgent->mainFrameNavigated(*loader);
722
723         if (InspectorCSSAgent* cssAgent = instrumentingAgents.inspectorCSSAgent())
724             cssAgent->reset();
725
726         if (InspectorDatabaseAgent* databaseAgent = instrumentingAgents.inspectorDatabaseAgent())
727             databaseAgent->clearResources();
728
729         if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
730             domAgent->setDocument(frame.document());
731
732         if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents.inspectorLayerTreeAgent())
733             layerTreeAgent->reset();
734
735         if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent())
736             pageDebuggerAgent->mainFrameNavigated();
737
738         if (PageHeapAgent* pageHeapAgent = instrumentingAgents.pageHeapAgent())
739             pageHeapAgent->mainFrameNavigated();
740     }
741
742     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
743         domAgent->didCommitLoad(frame.document());
744
745     if (InspectorPageAgent* pageAgent = instrumentingAgents.inspectorPageAgent())
746         pageAgent->frameNavigated(frame);
747
748     if (frame.isMainFrame()) {
749         if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
750             timelineAgent->mainFrameNavigated();
751     }
752
753 #if ENABLE(WEB_REPLAY)
754     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
755         replayAgent->frameNavigated(frame);
756 #endif
757 }
758
759 void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
760 {
761     if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled())
762         return;
763     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
764         domAgent->frameDocumentUpdated(frame);
765 }
766
767 void InspectorInstrumentation::loaderDetachedFromFrameImpl(InstrumentingAgents& instrumentingAgents, DocumentLoader& loader)
768 {
769     if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent())
770         inspectorPageAgent->loaderDetachedFromFrame(loader);
771 }
772
773 void InspectorInstrumentation::frameStartedLoadingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
774 {
775     if (frame.isMainFrame()) {
776         if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent())
777             pageDebuggerAgent->mainFrameStartedLoading();
778         if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.persistentInspectorTimelineAgent())
779             timelineAgent->mainFrameStartedLoading();
780     }
781
782     if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent())
783         inspectorPageAgent->frameStartedLoading(frame);
784 }
785
786 void InspectorInstrumentation::frameStoppedLoadingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
787 {
788     if (frame.isMainFrame()) {
789         if (PageDebuggerAgent* pageDebuggerAgent = instrumentingAgents.pageDebuggerAgent())
790             pageDebuggerAgent->mainFrameStoppedLoading();
791     }
792
793     if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent())
794         inspectorPageAgent->frameStoppedLoading(frame);
795 }
796
797 void InspectorInstrumentation::frameScheduledNavigationImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, double delay)
798 {
799     if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent())
800         inspectorPageAgent->frameScheduledNavigation(frame, delay);
801 }
802
803 void InspectorInstrumentation::frameClearedScheduledNavigationImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
804 {
805     if (InspectorPageAgent* inspectorPageAgent = instrumentingAgents.inspectorPageAgent())
806         inspectorPageAgent->frameClearedScheduledNavigation(frame);
807 }
808
809 void InspectorInstrumentation::willDestroyCachedResourceImpl(CachedResource& cachedResource)
810 {
811     if (!s_instrumentingAgentsSet)
812         return;
813
814     for (auto* instrumentingAgent : *s_instrumentingAgentsSet) {
815         if (InspectorNetworkAgent* inspectorNetworkAgent = instrumentingAgent->inspectorNetworkAgent())
816             inspectorNetworkAgent->willDestroyCachedResource(cachedResource);
817     }
818 }
819
820 // JavaScriptCore InspectorDebuggerAgent should know Console MessageTypes.
821 static bool isConsoleAssertMessage(MessageSource source, MessageType type)
822 {
823     return source == MessageSource::ConsoleAPI && type == MessageType::Assert;
824 }
825
826 void InspectorInstrumentation::addMessageToConsoleImpl(InstrumentingAgents& instrumentingAgents, std::unique_ptr<ConsoleMessage> message)
827 {
828     MessageSource source = message->source();
829     MessageType type = message->type();
830     String messageText = message->message();
831
832     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
833         consoleAgent->addMessageToConsole(WTFMove(message));
834     // FIXME: This should just pass the message on to the debugger agent. JavaScriptCore InspectorDebuggerAgent should know Console MessageTypes.
835     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent()) {
836         if (isConsoleAssertMessage(source, type))
837             debuggerAgent->handleConsoleAssert(messageText);
838     }
839 }
840
841 void InspectorInstrumentation::consoleCountImpl(InstrumentingAgents& instrumentingAgents, JSC::ExecState* state, Ref<ScriptArguments>&& arguments)
842 {
843     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
844         consoleAgent->count(state, WTFMove(arguments));
845 }
846
847 void InspectorInstrumentation::takeHeapSnapshotImpl(InstrumentingAgents& instrumentingAgents, const String& title)
848 {
849     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
850         consoleAgent->takeHeapSnapshot(title);
851 }
852
853 void InspectorInstrumentation::startConsoleTimingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, const String& title)
854 {
855     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
856         timelineAgent->time(frame, title);
857     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
858         consoleAgent->startTiming(title);
859 }
860
861 void InspectorInstrumentation::startConsoleTimingImpl(InstrumentingAgents& instrumentingAgents, const String& title)
862 {
863     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
864         consoleAgent->startTiming(title);
865 }
866
867 void InspectorInstrumentation::stopConsoleTimingImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, const String& title, Ref<ScriptCallStack>&& stack)
868 {
869     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
870         consoleAgent->stopTiming(title, WTFMove(stack));
871     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
872         timelineAgent->timeEnd(frame, title);
873 }
874
875 void InspectorInstrumentation::stopConsoleTimingImpl(InstrumentingAgents& instrumentingAgents, const String& title, Ref<ScriptCallStack>&& stack)
876 {
877     if (WebConsoleAgent* consoleAgent = instrumentingAgents.webConsoleAgent())
878         consoleAgent->stopTiming(title, WTFMove(stack));
879 }
880
881 void InspectorInstrumentation::consoleTimeStampImpl(InstrumentingAgents& instrumentingAgents, Frame& frame, Ref<ScriptArguments>&& arguments)
882 {
883     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) {
884         String message;
885         arguments->getFirstArgumentAsString(message);
886         timelineAgent->didTimeStamp(frame, message);
887      }
888 }
889
890 void InspectorInstrumentation::startProfilingImpl(InstrumentingAgents& instrumentingAgents, JSC::ExecState* exec, const String& title)
891 {
892     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.persistentInspectorTimelineAgent())
893         timelineAgent->startFromConsole(exec, title);
894 }
895
896 void InspectorInstrumentation::stopProfilingImpl(InstrumentingAgents& instrumentingAgents, JSC::ExecState* exec, const String& title)
897 {
898     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.persistentInspectorTimelineAgent())
899         timelineAgent->stopFromConsole(exec, title);
900 }
901
902 void InspectorInstrumentation::didOpenDatabaseImpl(InstrumentingAgents& instrumentingAgents, RefPtr<Database>&& database, const String& domain, const String& name, const String& version)
903 {
904     if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled())
905         return;
906     if (InspectorDatabaseAgent* dbAgent = instrumentingAgents.inspectorDatabaseAgent())
907         dbAgent->didOpenDatabase(WTFMove(database), domain, name, version);
908 }
909
910 void InspectorInstrumentation::didDispatchDOMStorageEventImpl(InstrumentingAgents& instrumentingAgents, const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin)
911 {
912     if (InspectorDOMStorageAgent* domStorageAgent = instrumentingAgents.inspectorDOMStorageAgent())
913         domStorageAgent->didDispatchDOMStorageEvent(key, oldValue, newValue, storageType, securityOrigin);
914 }
915
916 bool InspectorInstrumentation::shouldWaitForDebuggerOnStartImpl(InstrumentingAgents& instrumentingAgents)
917 {
918     if (InspectorWorkerAgent* workerAgent = instrumentingAgents.inspectorWorkerAgent())
919         return workerAgent->shouldWaitForDebuggerOnStart();
920     return false;
921 }
922
923 void InspectorInstrumentation::workerStartedImpl(InstrumentingAgents& instrumentingAgents, WorkerInspectorProxy* proxy, const URL& url)
924 {
925     if (InspectorWorkerAgent* workerAgent = instrumentingAgents.inspectorWorkerAgent())
926         workerAgent->workerStarted(proxy, url);
927 }
928
929 void InspectorInstrumentation::workerTerminatedImpl(InstrumentingAgents& instrumentingAgents, WorkerInspectorProxy* proxy)
930 {
931     if (InspectorWorkerAgent* workerAgent = instrumentingAgents.inspectorWorkerAgent())
932         workerAgent->workerTerminated(proxy);
933 }
934
935 #if ENABLE(WEB_SOCKETS)
936 void InspectorInstrumentation::didCreateWebSocketImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const URL& requestURL)
937 {
938     if (!instrumentingAgents.inspectorEnvironment().developerExtrasEnabled())
939         return;
940
941     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
942         networkAgent->didCreateWebSocket(identifier, requestURL);
943 }
944
945 void InspectorInstrumentation::willSendWebSocketHandshakeRequestImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const ResourceRequest& request)
946 {
947     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
948         networkAgent->willSendWebSocketHandshakeRequest(identifier, request);
949 }
950
951 void InspectorInstrumentation::didReceiveWebSocketHandshakeResponseImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const ResourceResponse& response)
952 {
953     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
954         networkAgent->didReceiveWebSocketHandshakeResponse(identifier, response);
955 }
956
957 void InspectorInstrumentation::didCloseWebSocketImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier)
958 {
959     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
960         networkAgent->didCloseWebSocket(identifier);
961 }
962
963 void InspectorInstrumentation::didReceiveWebSocketFrameImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const WebSocketFrame& frame)
964 {
965     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
966         networkAgent->didReceiveWebSocketFrame(identifier, frame);
967 }
968
969 void InspectorInstrumentation::didReceiveWebSocketFrameErrorImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const String& errorMessage)
970 {
971     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
972         networkAgent->didReceiveWebSocketFrameError(identifier, errorMessage);
973 }
974
975 void InspectorInstrumentation::didSendWebSocketFrameImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const WebSocketFrame& frame)
976 {
977     if (InspectorNetworkAgent* networkAgent = instrumentingAgents.inspectorNetworkAgent())
978         networkAgent->didSendWebSocketFrame(identifier, frame);
979 }
980 #endif
981
982 #if ENABLE(WEB_REPLAY)
983 void InspectorInstrumentation::sessionCreatedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySession>&& session)
984 {
985     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
986         replayAgent->sessionCreated(WTFMove(session));
987 }
988
989 void InspectorInstrumentation::sessionLoadedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySession>&& session)
990 {
991     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
992         replayAgent->sessionLoaded(WTFMove(session));
993 }
994
995 void InspectorInstrumentation::sessionModifiedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySession>&& session)
996 {
997     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
998         replayAgent->sessionModified(WTFMove(session));
999 }
1000
1001 void InspectorInstrumentation::segmentCreatedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySessionSegment>&& segment)
1002 {
1003     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1004         replayAgent->segmentCreated(WTFMove(segment));
1005 }
1006
1007 void InspectorInstrumentation::segmentCompletedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySessionSegment>&& segment)
1008 {
1009     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1010         replayAgent->segmentCompleted(WTFMove(segment));
1011 }
1012
1013 void InspectorInstrumentation::segmentLoadedImpl(InstrumentingAgents& instrumentingAgents, RefPtr<ReplaySessionSegment>&& segment)
1014 {
1015     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1016         replayAgent->segmentLoaded(WTFMove(segment));
1017 }
1018
1019 void InspectorInstrumentation::segmentUnloadedImpl(InstrumentingAgents& instrumentingAgents)
1020 {
1021     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1022         replayAgent->segmentUnloaded();
1023 }
1024
1025 void InspectorInstrumentation::captureStartedImpl(InstrumentingAgents& instrumentingAgents)
1026 {
1027     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1028         replayAgent->captureStarted();
1029 }
1030
1031 void InspectorInstrumentation::captureStoppedImpl(InstrumentingAgents& instrumentingAgents)
1032 {
1033     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1034         replayAgent->captureStopped();
1035 }
1036
1037 void InspectorInstrumentation::playbackStartedImpl(InstrumentingAgents& instrumentingAgents)
1038 {
1039     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1040         replayAgent->playbackStarted();
1041 }
1042
1043 void InspectorInstrumentation::playbackPausedImpl(InstrumentingAgents& instrumentingAgents, const ReplayPosition& position)
1044 {
1045     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1046         replayAgent->playbackPaused(position);
1047 }
1048
1049 void InspectorInstrumentation::playbackHitPositionImpl(InstrumentingAgents& instrumentingAgents, const ReplayPosition& position)
1050 {
1051     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1052         replayAgent->playbackHitPosition(position);
1053 }
1054
1055 void InspectorInstrumentation::playbackFinishedImpl(InstrumentingAgents& instrumentingAgents)
1056 {
1057     if (InspectorReplayAgent* replayAgent = instrumentingAgents.inspectorReplayAgent())
1058         replayAgent->playbackFinished();
1059 }
1060 #endif
1061
1062 #if ENABLE(RESOURCE_USAGE)
1063 void InspectorInstrumentation::didHandleMemoryPressureImpl(InstrumentingAgents& instrumentingAgents, Critical critical)
1064 {
1065     if (InspectorMemoryAgent* memoryAgent = instrumentingAgents.inspectorMemoryAgent())
1066         memoryAgent->didHandleMemoryPressure(critical);
1067 }
1068 #endif
1069
1070 void InspectorInstrumentation::networkStateChangedImpl(InstrumentingAgents& instrumentingAgents)
1071 {
1072     if (InspectorApplicationCacheAgent* applicationCacheAgent = instrumentingAgents.inspectorApplicationCacheAgent())
1073         applicationCacheAgent->networkStateChanged();
1074 }
1075
1076 void InspectorInstrumentation::updateApplicationCacheStatusImpl(InstrumentingAgents& instrumentingAgents, Frame& frame)
1077 {
1078     if (auto* applicationCacheAgent = instrumentingAgents.inspectorApplicationCacheAgent())
1079         applicationCacheAgent->updateApplicationCacheStatus(&frame);
1080 }
1081
1082 bool InspectorInstrumentation::consoleAgentEnabled(ScriptExecutionContext* scriptExecutionContext)
1083 {
1084     InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(scriptExecutionContext);
1085     InspectorConsoleAgent* consoleAgent = instrumentingAgents ? instrumentingAgents->webConsoleAgent() : nullptr;
1086     return consoleAgent && consoleAgent->enabled();
1087 }
1088
1089 bool InspectorInstrumentation::timelineAgentEnabled(ScriptExecutionContext* scriptExecutionContext)
1090 {
1091     InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(scriptExecutionContext);
1092     return instrumentingAgents && instrumentingAgents->inspectorTimelineAgent();
1093 }
1094
1095 bool InspectorInstrumentation::replayAgentEnabled(ScriptExecutionContext* scriptExecutionContext)
1096 {
1097 #if ENABLE(WEB_REPLAY)
1098     InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(scriptExecutionContext);
1099     return instrumentingAgents && instrumentingAgents->inspectorReplayAgent();
1100 #else
1101     UNUSED_PARAM(scriptExecutionContext);
1102     return false;
1103 #endif
1104 }
1105
1106 void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InstrumentingAgents& instrumentingAgents, bool isDOMEvent, const String& eventName, bool synchronous)
1107 {
1108     if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents.inspectorDOMDebuggerAgent())
1109         domDebuggerAgent->pauseOnNativeEventIfNeeded(isDOMEvent, eventName, synchronous);
1110 }
1111
1112 void InspectorInstrumentation::didRequestAnimationFrameImpl(InstrumentingAgents& instrumentingAgents, int callbackId, Frame* frame)
1113 {
1114     pauseOnNativeEventIfNeeded(instrumentingAgents, false, requestAnimationFrameEventName, true);
1115     didScheduleAsyncCall(instrumentingAgents, AsyncCallTypeRequestAnimationFrame, callbackId, *frame->document(), true);
1116
1117     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
1118         timelineAgent->didRequestAnimationFrame(callbackId, frame);
1119 }
1120
1121 void InspectorInstrumentation::didCancelAnimationFrameImpl(InstrumentingAgents& instrumentingAgents, int callbackId, Frame* frame)
1122 {
1123     pauseOnNativeEventIfNeeded(instrumentingAgents, false, cancelAnimationFrameEventName, true);
1124
1125     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent())
1126         debuggerAgent->didCancelAsyncCall(AsyncCallTypeRequestAnimationFrame, callbackId);
1127     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent())
1128         timelineAgent->didCancelAnimationFrame(callbackId, frame);
1129 }
1130
1131 InspectorInstrumentationCookie InspectorInstrumentation::willFireAnimationFrameImpl(InstrumentingAgents& instrumentingAgents, int callbackId, Frame* frame)
1132 {
1133     pauseOnNativeEventIfNeeded(instrumentingAgents, false, animationFrameFiredEventName, false);
1134
1135     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents.inspectorDebuggerAgent())
1136         debuggerAgent->willDispatchAsyncCall(AsyncCallTypeRequestAnimationFrame, callbackId);
1137
1138     int timelineAgentId = 0;
1139     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents.inspectorTimelineAgent()) {
1140         timelineAgent->willFireAnimationFrame(callbackId, frame);
1141         timelineAgentId = timelineAgent->id();
1142     }
1143     return InspectorInstrumentationCookie(instrumentingAgents, timelineAgentId);
1144 }
1145
1146 void InspectorInstrumentation::didFireAnimationFrameImpl(const InspectorInstrumentationCookie& cookie)
1147 {
1148     if (InspectorDebuggerAgent* debuggerAgent = cookie.instrumentingAgents()->inspectorDebuggerAgent())
1149         debuggerAgent->didDispatchAsyncCall();
1150     if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
1151         timelineAgent->didFireAnimationFrame();
1152 }
1153
1154 void InspectorInstrumentation::registerInstrumentingAgents(InstrumentingAgents& instrumentingAgents)
1155 {
1156     if (!s_instrumentingAgentsSet)
1157         s_instrumentingAgentsSet = new HashSet<InstrumentingAgents*>();
1158
1159     s_instrumentingAgentsSet->add(&instrumentingAgents);
1160 }
1161
1162 void InspectorInstrumentation::unregisterInstrumentingAgents(InstrumentingAgents& instrumentingAgents)
1163 {
1164     if (!s_instrumentingAgentsSet)
1165         return;
1166
1167     s_instrumentingAgentsSet->remove(&instrumentingAgents);
1168     if (s_instrumentingAgentsSet->isEmpty()) {
1169         delete s_instrumentingAgentsSet;
1170         s_instrumentingAgentsSet = nullptr;
1171     }
1172 }
1173
1174 InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(const InspectorInstrumentationCookie& cookie)
1175 {
1176     if (!cookie.isValid())
1177         return nullptr;
1178
1179     InspectorTimelineAgent* timelineAgent = cookie.instrumentingAgents()->inspectorTimelineAgent();
1180     if (timelineAgent && cookie.hasMatchingTimelineAgentId(timelineAgent->id()))
1181         return timelineAgent;
1182     return nullptr;
1183 }
1184
1185 InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForRenderer(RenderObject& renderer)
1186 {
1187     return instrumentingAgentsForFrame(renderer.frame());
1188 }
1189
1190 void InspectorInstrumentation::layerTreeDidChangeImpl(InstrumentingAgents& instrumentingAgents)
1191 {
1192     if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents.inspectorLayerTreeAgent())
1193         layerTreeAgent->layerTreeDidChange();
1194 }
1195
1196 void InspectorInstrumentation::renderLayerDestroyedImpl(InstrumentingAgents& instrumentingAgents, const RenderLayer& renderLayer)
1197 {
1198     if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents.inspectorLayerTreeAgent())
1199         layerTreeAgent->renderLayerDestroyed(renderLayer);
1200 }
1201
1202 } // namespace WebCore