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