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