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