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