Home | History | Annotate | Download | only in timing
      1 /*
      2  * Copyright (C) 2012 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 "core/timing/PerformanceResourceTiming.h"
     34 
     35 #include "core/dom/Document.h"
     36 #include "core/loader/DocumentLoadTiming.h"
     37 #include "core/loader/DocumentLoader.h"
     38 #include "core/timing/ResourceTimingInfo.h"
     39 #include "platform/network/ResourceRequest.h"
     40 #include "platform/network/ResourceResponse.h"
     41 
     42 namespace blink {
     43 
     44 static double monotonicTimeToDocumentMilliseconds(Document* document, double seconds)
     45 {
     46     ASSERT(seconds >= 0.0);
     47     return document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(seconds) * 1000.0;
     48 }
     49 
     50 PerformanceResourceTiming::PerformanceResourceTiming(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, double lastRedirectEndTime, bool allowTimingDetails, bool allowRedirectDetails)
     51     : PerformanceEntry(info.initialRequest().url().string(), "resource", monotonicTimeToDocumentMilliseconds(requestingDocument, startTime), monotonicTimeToDocumentMilliseconds(requestingDocument, info.loadFinishTime()))
     52     , m_initiatorType(info.initiatorType())
     53     , m_timing(info.finalResponse().resourceLoadTiming())
     54     , m_lastRedirectEndTime(lastRedirectEndTime)
     55     , m_finishTime(info.loadFinishTime())
     56     , m_didReuseConnection(info.finalResponse().connectionReused())
     57     , m_allowTimingDetails(allowTimingDetails)
     58     , m_allowRedirectDetails(allowRedirectDetails)
     59     , m_requestingDocument(requestingDocument)
     60 {
     61 }
     62 
     63 PerformanceResourceTiming::~PerformanceResourceTiming()
     64 {
     65 }
     66 
     67 AtomicString PerformanceResourceTiming::initiatorType() const
     68 {
     69     return m_initiatorType;
     70 }
     71 
     72 double PerformanceResourceTiming::redirectStart() const
     73 {
     74     if (!m_lastRedirectEndTime || !m_allowRedirectDetails)
     75         return 0.0;
     76 
     77     return PerformanceEntry::startTime();
     78 }
     79 
     80 double PerformanceResourceTiming::redirectEnd() const
     81 {
     82     if (!m_lastRedirectEndTime || !m_allowRedirectDetails)
     83         return 0.0;
     84 
     85     return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_lastRedirectEndTime);
     86 }
     87 
     88 double PerformanceResourceTiming::fetchStart() const
     89 {
     90     if (m_lastRedirectEndTime) {
     91         // FIXME: ASSERT(m_timing) should be in constructor once timeticks of
     92         // AppCache is exposed from chrome network stack, crbug/251100
     93         ASSERT(m_timing);
     94         return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->requestTime);
     95     }
     96 
     97     return PerformanceEntry::startTime();
     98 }
     99 
    100 double PerformanceResourceTiming::domainLookupStart() const
    101 {
    102     if (!m_allowTimingDetails)
    103         return 0.0;
    104 
    105     if (!m_timing || m_timing->dnsStart == 0.0)
    106         return fetchStart();
    107 
    108     return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->dnsStart);
    109 }
    110 
    111 double PerformanceResourceTiming::domainLookupEnd() const
    112 {
    113     if (!m_allowTimingDetails)
    114         return 0.0;
    115 
    116     if (!m_timing || m_timing->dnsEnd == 0.0)
    117         return domainLookupStart();
    118 
    119     return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->dnsEnd);
    120 }
    121 
    122 double PerformanceResourceTiming::connectStart() const
    123 {
    124     if (!m_allowTimingDetails)
    125         return 0.0;
    126 
    127     // connectStart will be zero when a network request is not made.
    128     if (!m_timing || m_timing->connectStart == 0.0 || m_didReuseConnection)
    129         return domainLookupEnd();
    130 
    131     // connectStart includes any DNS time, so we may need to trim that off.
    132     double connectStart = m_timing->connectStart;
    133     if (m_timing->dnsEnd > 0.0)
    134         connectStart = m_timing->dnsEnd;
    135 
    136     return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), connectStart);
    137 }
    138 
    139 double PerformanceResourceTiming::connectEnd() const
    140 {
    141     if (!m_allowTimingDetails)
    142         return 0.0;
    143 
    144     // connectStart will be zero when a network request is not made.
    145     if (!m_timing || m_timing->connectEnd == 0.0 || m_didReuseConnection)
    146         return connectStart();
    147 
    148     return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->connectEnd);
    149 }
    150 
    151 double PerformanceResourceTiming::secureConnectionStart() const
    152 {
    153     if (!m_allowTimingDetails)
    154         return 0.0;
    155 
    156     if (!m_timing || m_timing->sslStart == 0.0) // Secure connection not negotiated.
    157         return 0.0;
    158 
    159     return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->sslStart);
    160 }
    161 
    162 double PerformanceResourceTiming::requestStart() const
    163 {
    164     if (!m_allowTimingDetails)
    165         return 0.0;
    166 
    167     if (!m_timing)
    168         return connectEnd();
    169 
    170     return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->sendStart);
    171 }
    172 
    173 double PerformanceResourceTiming::responseStart() const
    174 {
    175     if (!m_allowTimingDetails)
    176         return 0.0;
    177 
    178     if (!m_timing)
    179         return requestStart();
    180 
    181     // FIXME: This number isn't exactly correct. See the notes in PerformanceTiming::responseStart().
    182     return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_timing->receiveHeadersEnd);
    183 }
    184 
    185 double PerformanceResourceTiming::responseEnd() const
    186 {
    187     if (!m_finishTime)
    188         return responseStart();
    189 
    190     return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_finishTime);
    191 }
    192 
    193 void PerformanceResourceTiming::trace(Visitor* visitor)
    194 {
    195     visitor->trace(m_requestingDocument);
    196     PerformanceEntry::trace(visitor);
    197 }
    198 
    199 } // namespace blink
    200