Web Inspector: timelines should not count time elapsed while paused in the debugger
[WebKit-https.git] / Source / WebCore / inspector / InspectorTimelineAgent.h
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2014 University of Washington.
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 #ifndef InspectorTimelineAgent_h
33 #define InspectorTimelineAgent_h
34
35 #if ENABLE(INSPECTOR)
36
37 #include "InspectorWebAgentBase.h"
38 #include "InspectorWebBackendDispatchers.h"
39 #include "InspectorWebFrontendDispatchers.h"
40 #include "LayoutRect.h"
41 #include <inspector/InspectorValues.h>
42 #include <inspector/ScriptDebugListener.h>
43 #include <wtf/Stopwatch.h>
44 #include <wtf/Vector.h>
45 #include <wtf/WeakPtr.h>
46
47 namespace JSC {
48 class Profile;
49 }
50
51 namespace WebCore {
52
53 class Event;
54 class FloatQuad;
55 class Frame;
56 class InspectorClient;
57 class InspectorPageAgent;
58 class InstrumentingAgents;
59 class IntRect;
60 class URL;
61 class Page;
62 class PageScriptDebugServer;
63 class RenderObject;
64 class ResourceRequest;
65 class ResourceResponse;
66
67 typedef String ErrorString;
68
69 enum class TimelineRecordType {
70     EventDispatch,
71     ScheduleStyleRecalculation,
72     RecalculateStyles,
73     InvalidateLayout,
74     Layout,
75     Paint,
76     ScrollLayer,
77     ResizeImage,
78
79     ParseHTML,
80
81     TimerInstall,
82     TimerRemove,
83     TimerFire,
84
85     EvaluateScript,
86
87     MarkLoad,
88     MarkDOMContent,
89
90     TimeStamp,
91     Time,
92     TimeEnd,
93
94     ScheduleResourceRequest,
95     ResourceSendRequest,
96     ResourceReceiveResponse,
97     ResourceReceivedData,
98     ResourceFinish,
99
100     XHRReadyStateChange,
101     XHRLoad,
102
103     FunctionCall,
104     ProbeSample,
105     ConsoleProfile,
106
107     RequestAnimationFrame,
108     CancelAnimationFrame,
109     FireAnimationFrame,
110
111     WebSocketCreate,
112     WebSocketSendHandshakeRequest,
113     WebSocketReceiveHandshakeResponse,
114     WebSocketDestroy
115 };
116
117 class InspectorTimelineAgent
118     : public InspectorAgentBase
119     , public Inspector::InspectorTimelineBackendDispatcherHandler
120     , public Inspector::ScriptDebugListener {
121     WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent);
122     WTF_MAKE_FAST_ALLOCATED;
123 public:
124     enum InspectorType { PageInspector, WorkerInspector };
125
126     InspectorTimelineAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorType, InspectorClient*);
127     ~InspectorTimelineAgent();
128
129     virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override;
130     virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override;
131
132     virtual void start(ErrorString&, const int* maxCallStackDepth = nullptr) override;
133     virtual void stop(ErrorString&) override;
134
135     int id() const { return m_id; }
136
137     void setPageScriptDebugServer(PageScriptDebugServer*);
138
139     void didCommitLoad();
140
141     // Methods called from WebCore.
142     void startFromConsole(JSC::ExecState*, const String &title);
143     PassRefPtr<JSC::Profile> stopFromConsole(JSC::ExecState*, const String& title);
144
145     void willCallFunction(const String& scriptName, int scriptLine, Frame*);
146     void didCallFunction(Frame*);
147
148     void willDispatchEvent(const Event&, Frame*);
149     void didDispatchEvent();
150
151     void didInvalidateLayout(Frame*);
152     void willLayout(Frame*);
153     void didLayout(RenderObject*);
154
155     void didScheduleStyleRecalculation(Frame*);
156     void willRecalculateStyle(Frame*);
157     void didRecalculateStyle();
158
159     void willPaint(Frame*);
160     void didPaint(RenderObject*, const LayoutRect&);
161
162     void willScroll(Frame*);
163     void didScroll();
164
165     void willWriteHTML(unsigned startLine, Frame*);
166     void didWriteHTML(unsigned endLine);
167
168     void didInstallTimer(int timerId, int timeout, bool singleShot, Frame*);
169     void didRemoveTimer(int timerId, Frame*);
170     void willFireTimer(int timerId, Frame*);
171     void didFireTimer();
172
173     void willDispatchXHRReadyStateChangeEvent(const String&, int, Frame*);
174     void didDispatchXHRReadyStateChangeEvent();
175     void willDispatchXHRLoadEvent(const String&, Frame*);
176     void didDispatchXHRLoadEvent();
177
178     void willEvaluateScript(const String&, int, Frame*);
179     void didEvaluateScript(Frame*);
180
181     void didTimeStamp(Frame*, const String&);
182     void didMarkDOMContentEvent(Frame*);
183     void didMarkLoadEvent(Frame*);
184
185     void time(Frame*, const String&);
186     void timeEnd(Frame*, const String&);
187
188     void didScheduleResourceRequest(const String& url, Frame*);
189     void willSendResourceRequest(unsigned long, const ResourceRequest&, Frame*);
190     void willReceiveResourceResponse(unsigned long, const ResourceResponse&, Frame*);
191     void didReceiveResourceResponse();
192     void didFinishLoadingResource(unsigned long, bool didFail, double finishTime, Frame*);
193     void willReceiveResourceData(unsigned long identifier, Frame*, int length);
194     void didReceiveResourceData();
195
196     void didRequestAnimationFrame(int callbackId, Frame*);
197     void didCancelAnimationFrame(int callbackId, Frame*);
198     void willFireAnimationFrame(int callbackId, Frame*);
199     void didFireAnimationFrame();
200
201     // Returns the elapsed time from a monotonic stopwatch that starts with timeline recording and
202     // pauses when the debugger pauses or execution is otherwise suspended.
203     double timestamp();
204
205 #if ENABLE(WEB_SOCKETS)
206     void didCreateWebSocket(unsigned long identifier, const URL&, const String& protocol, Frame*);
207     void willSendWebSocketHandshakeRequest(unsigned long identifier, Frame*);
208     void didReceiveWebSocketHandshakeResponse(unsigned long identifier, Frame*);
209     void didDestroyWebSocket(unsigned long identifier, Frame*);
210 #endif
211
212 protected:
213     // ScriptDebugListener
214     virtual void didParseSource(JSC::SourceID, const Script&) override { }
215     virtual void failedToParseSource(const String&, const String&, int, int, const String&) override { }
216     virtual void didPause(JSC::ExecState*, const Deprecated::ScriptValue&, const Deprecated::ScriptValue&) override;
217     virtual void didContinue() override;
218
219     virtual void breakpointActionLog(JSC::ExecState*, const String&) override { }
220     virtual void breakpointActionSound(int) override { }
221     virtual void breakpointActionProbe(JSC::ExecState*, const Inspector::ScriptBreakpointAction&, int hitCount, const Deprecated::ScriptValue& result) override;
222
223 private:
224     friend class TimelineRecordStack;
225
226     struct TimelineRecordEntry {
227         TimelineRecordEntry()
228             : type(TimelineRecordType::EventDispatch) { }
229         TimelineRecordEntry(PassRefPtr<Inspector::InspectorObject> record, PassRefPtr<Inspector::InspectorObject> data, PassRefPtr<Inspector::InspectorArray> children, TimelineRecordType type)
230             : record(record), data(data), children(children), type(type)
231         {
232         }
233
234         RefPtr<Inspector::InspectorObject> record;
235         RefPtr<Inspector::InspectorObject> data;
236         RefPtr<Inspector::InspectorArray> children;
237         TimelineRecordType type;
238     };
239
240     void internalStart(const int* maxCallStackDepth = nullptr);
241     void internalStop();
242
243     void sendEvent(PassRefPtr<Inspector::InspectorObject>);
244     void appendRecord(PassRefPtr<Inspector::InspectorObject> data, TimelineRecordType, bool captureCallStack, Frame*);
245     void pushCurrentRecord(PassRefPtr<Inspector::InspectorObject>, TimelineRecordType, bool captureCallStack, Frame*);
246     void pushCurrentRecord(const TimelineRecordEntry& record) { m_recordStack.append(record); }
247
248     TimelineRecordEntry createRecordEntry(PassRefPtr<Inspector::InspectorObject> data, TimelineRecordType, bool captureCallStack, Frame*);
249
250     void setFrameIdentifier(Inspector::InspectorObject* record, Frame*);
251
252     void didCompleteRecordEntry(const TimelineRecordEntry&);
253     void didCompleteCurrentRecord(TimelineRecordType);
254
255     void addRecordToTimeline(PassRefPtr<Inspector::InspectorObject>, TimelineRecordType);
256     void clearRecordStack();
257
258     void localToPageQuad(const RenderObject&, const LayoutRect&, FloatQuad*);
259     Page* page();
260
261     InspectorPageAgent* m_pageAgent;
262     PageScriptDebugServer* m_scriptDebugServer;
263
264     RefPtr<Stopwatch> m_stopwatch;
265
266     std::unique_ptr<Inspector::InspectorTimelineFrontendDispatcher> m_frontendDispatcher;
267     RefPtr<Inspector::InspectorTimelineBackendDispatcher> m_backendDispatcher;
268
269     Vector<TimelineRecordEntry> m_recordStack;
270
271     int m_id;
272     int m_callStackDepth;
273     int m_maxCallStackDepth;
274     InspectorType m_inspectorType;
275     InspectorClient* m_client;
276
277     Vector<TimelineRecordEntry> m_pendingConsoleProfileRecords;
278
279     bool m_enabled;
280     bool m_enabledFromFrontend;
281 };
282
283 } // namespace WebCore
284
285 #endif // !ENABLE(INSPECTOR)
286 #endif // !defined(InspectorTimelineAgent_h)