1cbce55f8ed8cd4d49a009de2e0f07e57c7f59a0
[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 * Copyright (C) 2015 Apple Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *     * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *     * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 *     * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #ifndef InspectorTimelineAgent_h
34 #define InspectorTimelineAgent_h
35
36 #include "InspectorWebAgentBase.h"
37 #include "LayoutRect.h"
38 #include <inspector/InspectorBackendDispatchers.h>
39 #include <inspector/InspectorFrontendDispatchers.h>
40 #include <inspector/InspectorValues.h>
41 #include <inspector/ScriptDebugListener.h>
42 #include <wtf/Stopwatch.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 IntRect;
58 class URL;
59 class Page;
60 class PageScriptDebugServer;
61 class RenderObject;
62 class ResourceRequest;
63 class ResourceResponse;
64 class RunLoopObserver;
65
66 typedef String ErrorString;
67
68 enum class TimelineRecordType {
69     EventDispatch,
70     ScheduleStyleRecalculation,
71     RecalculateStyles,
72     InvalidateLayout,
73     Layout,
74     Paint,
75     Composite,
76     RenderingFrame,
77     ScrollLayer,
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     XHRReadyStateChange,
95     XHRLoad,
96
97     FunctionCall,
98     ProbeSample,
99     ConsoleProfile,
100
101     RequestAnimationFrame,
102     CancelAnimationFrame,
103     FireAnimationFrame,
104
105     WebSocketCreate,
106     WebSocketSendHandshakeRequest,
107     WebSocketReceiveHandshakeResponse,
108     WebSocketDestroy
109 };
110
111 class InspectorTimelineAgent final
112     : public InspectorAgentBase
113     , public Inspector::TimelineBackendDispatcherHandler
114     , public Inspector::ScriptDebugListener {
115     WTF_MAKE_NONCOPYABLE(InspectorTimelineAgent);
116     WTF_MAKE_FAST_ALLOCATED;
117 public:
118     enum InspectorType { PageInspector, WorkerInspector };
119
120     InspectorTimelineAgent(WebAgentContext&, InspectorPageAgent*, InspectorType, InspectorClient*);
121     virtual ~InspectorTimelineAgent();
122
123     virtual void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
124     virtual void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
125
126     virtual void start(ErrorString&, const int* maxCallStackDepth = nullptr) override;
127     virtual void stop(ErrorString&) override;
128
129     int id() const { return m_id; }
130
131     void setPageScriptDebugServer(PageScriptDebugServer*);
132
133     void didCommitLoad();
134
135     // Methods called from WebCore.
136     void startFromConsole(JSC::ExecState*, const String &title);
137     PassRefPtr<JSC::Profile> stopFromConsole(JSC::ExecState*, const String& title);
138
139     // InspectorInstrumentation callbacks.
140     void didInstallTimer(int timerId, int timeout, bool singleShot, Frame*);
141     void didRemoveTimer(int timerId, Frame*);
142     void willFireTimer(int timerId, Frame*);
143     void didFireTimer();
144     void willCallFunction(const String& scriptName, int scriptLine, Frame*);
145     void didCallFunction(Frame*);
146     void willDispatchXHRReadyStateChangeEvent(const String&, int, Frame*);
147     void didDispatchXHRReadyStateChangeEvent();
148     void willDispatchEvent(const Event&, Frame*);
149     void didDispatchEvent();
150     void willEvaluateScript(const String&, int, Frame&);
151     void didEvaluateScript(Frame&);
152     void didInvalidateLayout(Frame&);
153     void willLayout(Frame&);
154     void didLayout(RenderObject*);
155     void willScroll(Frame&);
156     void didScroll();
157     void willDispatchXHRLoadEvent(const String&, Frame*);
158     void didDispatchXHRLoadEvent();
159     void willComposite(Frame&);
160     void didComposite();
161     void willPaint(Frame&);
162     void didPaint(RenderObject*, const LayoutRect&);
163     void willRecalculateStyle(Frame*);
164     void didRecalculateStyle();
165     void didScheduleStyleRecalculation(Frame*);
166     void willWriteHTML(unsigned startLine, Frame*);
167     void didWriteHTML(unsigned endLine);
168     void didTimeStamp(Frame&, const String&);
169     void didMarkDOMContentEvent(Frame&);
170     void didMarkLoadEvent(Frame&);
171     void didRequestAnimationFrame(int callbackId, Frame*);
172     void didCancelAnimationFrame(int callbackId, Frame*);
173     void willFireAnimationFrame(int callbackId, Frame*);
174     void didFireAnimationFrame();
175     void time(Frame&, const String&);
176     void timeEnd(Frame&, const String&);
177 #if ENABLE(WEB_SOCKETS)
178     void didCreateWebSocket(unsigned long identifier, const URL&, const String& protocol, Frame*);
179     void willSendWebSocketHandshakeRequest(unsigned long identifier, Frame*);
180     void didReceiveWebSocketHandshakeResponse(unsigned long identifier, Frame*);
181     void didDestroyWebSocket(unsigned long identifier, Frame*);
182 #endif
183
184 protected:
185     // ScriptDebugListener
186     virtual void didParseSource(JSC::SourceID, const Script&) override { }
187     virtual void failedToParseSource(const String&, const String&, int, int, const String&) override { }
188     virtual void didPause(JSC::ExecState*, const Deprecated::ScriptValue&, const Deprecated::ScriptValue&) override { }
189     virtual void didContinue() override { }
190
191     virtual void breakpointActionLog(JSC::ExecState*, const String&) override { }
192     virtual void breakpointActionSound(int) override { }
193     virtual void breakpointActionProbe(JSC::ExecState*, const Inspector::ScriptBreakpointAction&, unsigned batchId, unsigned sampleId, const Deprecated::ScriptValue& result) override;
194
195 private:
196     friend class TimelineRecordStack;
197
198     struct TimelineRecordEntry {
199         TimelineRecordEntry()
200             : type(TimelineRecordType::EventDispatch) { }
201         TimelineRecordEntry(PassRefPtr<Inspector::InspectorObject> record, PassRefPtr<Inspector::InspectorObject> data, PassRefPtr<Inspector::InspectorArray> children, TimelineRecordType type)
202             : record(record), data(data), children(children), type(type)
203         {
204         }
205
206         RefPtr<Inspector::InspectorObject> record;
207         RefPtr<Inspector::InspectorObject> data;
208         RefPtr<Inspector::InspectorArray> children;
209         TimelineRecordType type;
210     };
211
212     void internalStart(const int* maxCallStackDepth = nullptr);
213     void internalStop();
214     double timestamp();
215
216     void sendEvent(RefPtr<Inspector::InspectorObject>&&);
217     void appendRecord(RefPtr<Inspector::InspectorObject>&& data, TimelineRecordType, bool captureCallStack, Frame*);
218     void pushCurrentRecord(RefPtr<Inspector::InspectorObject>&&, TimelineRecordType, bool captureCallStack, Frame*);
219     void pushCurrentRecord(const TimelineRecordEntry& record) { m_recordStack.append(record); }
220
221     TimelineRecordEntry createRecordEntry(RefPtr<Inspector::InspectorObject>&& data, TimelineRecordType, bool captureCallStack, Frame*);
222
223     void setFrameIdentifier(Inspector::InspectorObject* record, Frame*);
224
225     void didCompleteRecordEntry(const TimelineRecordEntry&);
226     void didCompleteCurrentRecord(TimelineRecordType);
227
228     void addRecordToTimeline(RefPtr<Inspector::InspectorObject>&&, TimelineRecordType);
229     void clearRecordStack();
230
231     void localToPageQuad(const RenderObject&, const LayoutRect&, FloatQuad*);
232
233     std::unique_ptr<Inspector::TimelineFrontendDispatcher> m_frontendDispatcher;
234     RefPtr<Inspector::TimelineBackendDispatcher> m_backendDispatcher;
235     InspectorPageAgent* m_pageAgent;
236
237     PageScriptDebugServer* m_scriptDebugServer { nullptr };
238     InspectorClient* m_client { nullptr };
239
240     Vector<TimelineRecordEntry> m_recordStack;
241     int m_id { 1 };
242     int m_callStackDepth { 0 };
243     int m_maxCallStackDepth { 5 };
244     InspectorType m_inspectorType;
245
246     Vector<TimelineRecordEntry> m_pendingConsoleProfileRecords;
247
248     bool m_enabled { false };
249     bool m_enabledFromFrontend { false };
250
251 #if PLATFORM(COCOA)
252     std::unique_ptr<WebCore::RunLoopObserver> m_frameStartObserver;
253     std::unique_ptr<WebCore::RunLoopObserver> m_frameStopObserver;
254 #endif
255     int m_runLoopNestingLevel { 0 };
256     bool m_startedComposite { false };
257 };
258
259 } // namespace WebCore
260
261 #endif // !defined(InspectorTimelineAgent_h)