Record the reference time when Performance is constructed.
[WebKit-https.git] / Source / WebCore / page / Performance.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  * Copyright (C) 2012 Intel 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 "Performance.h"
34
35 #include "Document.h"
36 #include "DocumentLoader.h"
37 #include "PerformanceEntry.h"
38 #include "PerformanceNavigation.h"
39 #include "PerformanceResourceTiming.h"
40 #include "PerformanceTiming.h"
41 #include "PerformanceUserTiming.h"
42 #include "ResourceResponse.h"
43 #include <wtf/CurrentTime.h>
44
45 #if ENABLE(WEB_TIMING)
46
47 #include "Frame.h"
48
49 namespace WebCore {
50
51 #if ENABLE(RESOURCE_TIMING)
52 static const size_t defaultResourceTimingBufferSize = 150;
53 #endif
54
55 Performance::Performance(Frame* frame)
56     : DOMWindowProperty(frame)
57 #if ENABLE(RESOURCE_TIMING)
58     , m_resourceTimingBufferSize(defaultResourceTimingBufferSize)
59 #endif // ENABLE(RESOURCE_TIMING)
60 #if ENABLE(USER_TIMING)
61     , m_userTiming(0)
62 #endif // ENABLE(USER_TIMING)
63     , m_referenceTime(frame->document()->loader()->timing().referenceMonotonicTime())
64 {
65     ASSERT(m_referenceTime);
66 }
67
68 Performance::~Performance()
69 {
70 }
71
72 ScriptExecutionContext* Performance::scriptExecutionContext() const
73 {
74     if (!frame())
75         return 0;
76     return frame()->document();
77 }
78
79 PerformanceNavigation* Performance::navigation() const
80 {
81     if (!m_navigation)
82         m_navigation = PerformanceNavigation::create(m_frame);
83
84     return m_navigation.get();
85 }
86
87 PerformanceTiming* Performance::timing() const
88 {
89     if (!m_timing)
90         m_timing = PerformanceTiming::create(m_frame);
91
92     return m_timing.get();
93 }
94
95 #if ENABLE(PERFORMANCE_TIMELINE)
96 PassRefPtr<PerformanceEntryList> Performance::webkitGetEntries() const
97 {
98     RefPtr<PerformanceEntryList> entries = PerformanceEntryList::create();
99
100 #if ENABLE(RESOURCE_TIMING)
101     entries->appendAll(m_resourceTimingBuffer);
102 #endif // ENABLE(RESOURCE_TIMING)
103
104 #if ENABLE(USER_TIMING)
105     if (m_userTiming) {
106         entries->appendAll(m_userTiming->getMarks());
107         entries->appendAll(m_userTiming->getMeasures());
108     }
109 #endif // ENABLE(USER_TIMING)
110
111     entries->sort();
112     return entries;
113 }
114
115 PassRefPtr<PerformanceEntryList> Performance::webkitGetEntriesByType(const String& entryType)
116 {
117     RefPtr<PerformanceEntryList> entries = PerformanceEntryList::create();
118
119 #if ENABLE(RESOURCE_TIMING)
120     if (equalIgnoringCase(entryType, "resource"))
121         for (Vector<RefPtr<PerformanceEntry>>::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
122             entries->append(*resource);
123 #endif // ENABLE(RESOURCE_TIMING)
124
125 #if ENABLE(USER_TIMING)
126     if (m_userTiming) {
127         if (equalIgnoringCase(entryType, "mark"))
128             entries->appendAll(m_userTiming->getMarks());
129         else if (equalIgnoringCase(entryType, "measure"))
130             entries->appendAll(m_userTiming->getMeasures());
131     }
132 #endif // ENABLE(USER_TIMING)
133
134     entries->sort();
135     return entries;
136 }
137
138 PassRefPtr<PerformanceEntryList> Performance::webkitGetEntriesByName(const String& name, const String& entryType)
139 {
140     RefPtr<PerformanceEntryList> entries = PerformanceEntryList::create();
141
142 #if ENABLE(RESOURCE_TIMING)
143     if (entryType.isNull() || equalIgnoringCase(entryType, "resource"))
144         for (Vector<RefPtr<PerformanceEntry>>::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
145             if ((*resource)->name() == name)
146                 entries->append(*resource);
147 #endif // ENABLE(RESOURCE_TIMING)
148
149 #if ENABLE(USER_TIMING)
150     if (m_userTiming) {
151         if (entryType.isNull() || equalIgnoringCase(entryType, "mark"))
152             entries->appendAll(m_userTiming->getMarks(name));
153         if (entryType.isNull() || equalIgnoringCase(entryType, "measure"))
154             entries->appendAll(m_userTiming->getMeasures(name));
155     }
156 #endif // ENABLE(USER_TIMING)
157
158     entries->sort();
159     return entries;
160 }
161
162 #endif // ENABLE(PERFORMANCE_TIMELINE)
163
164 #if ENABLE(RESOURCE_TIMING)
165
166 void Performance::webkitClearResourceTimings()
167 {
168     m_resourceTimingBuffer.clear();
169 }
170
171 void Performance::webkitSetResourceTimingBufferSize(unsigned size)
172 {
173     m_resourceTimingBufferSize = size;
174     if (isResourceTimingBufferFull())
175         dispatchEvent(Event::create(eventNames().webkitresourcetimingbufferfullEvent, false, false));
176 }
177
178 void Performance::addResourceTiming(const String& initiatorName, Document* initiatorDocument, const ResourceRequest& request, const ResourceResponse& response, double initiationTime, double finishTime)
179 {
180     if (isResourceTimingBufferFull())
181         return;
182
183     RefPtr<PerformanceEntry> entry = PerformanceResourceTiming::create(initiatorName, request, response, initiationTime, finishTime, initiatorDocument);
184
185     m_resourceTimingBuffer.append(entry);
186
187     if (isResourceTimingBufferFull())
188         dispatchEvent(Event::create(eventNames().webkitresourcetimingbufferfullEvent, false, false));
189 }
190
191 bool Performance::isResourceTimingBufferFull()
192 {
193     return m_resourceTimingBuffer.size() >= m_resourceTimingBufferSize;
194 }
195
196 #endif // ENABLE(RESOURCE_TIMING)
197
198 #if ENABLE(USER_TIMING)
199 void Performance::webkitMark(const String& markName, ExceptionCode& ec)
200 {
201     ec = 0;
202     if (!m_userTiming)
203         m_userTiming = UserTiming::create(this);
204     m_userTiming->mark(markName, ec);
205 }
206
207 void Performance::webkitClearMarks(const String& markName)
208 {
209     if (!m_userTiming)
210         m_userTiming = UserTiming::create(this);
211     m_userTiming->clearMarks(markName);
212 }
213
214 void Performance::webkitMeasure(const String& measureName, const String& startMark, const String& endMark, ExceptionCode& ec)
215 {
216     ec = 0;
217     if (!m_userTiming)
218         m_userTiming = UserTiming::create(this);
219     m_userTiming->measure(measureName, startMark, endMark, ec);
220 }
221
222 void Performance::webkitClearMeasures(const String& measureName)
223 {
224     if (!m_userTiming)
225         m_userTiming = UserTiming::create(this);
226     m_userTiming->clearMeasures(measureName);
227 }
228
229 #endif // ENABLE(USER_TIMING)
230
231 double Performance::now() const
232 {
233     return 1000.0 * (WTF::monotonicallyIncreasingTime() - m_referenceTime);
234 }
235
236 } // namespace WebCore
237
238 #endif // ENABLE(WEB_TIMING)