15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/timing/PerformanceTiming.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/DocumentTiming.h"
36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/DocumentLoadTiming.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/DocumentLoader.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/loader/FrameLoader.h"
40bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/ResourceLoadTiming.h"
41bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/network/ResourceResponse.h"
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static unsigned long long toIntegerMilliseconds(double seconds)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(seconds >= 0);
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return static_cast<unsigned long long>(seconds * 1000.0);
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PerformanceTiming::PerformanceTiming(LocalFrame* frame)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : DOMWindowProperty(frame)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::navigationStart() const
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoadTiming* timing = documentLoadTiming();
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->navigationStart());
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::unloadEventStart() const
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoadTiming* timing = documentLoadTiming();
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (timing->hasCrossOriginRedirect() || !timing->hasSameOriginAsPreviousDocument())
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->unloadEventStart());
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::unloadEventEnd() const
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoadTiming* timing = documentLoadTiming();
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (timing->hasCrossOriginRedirect() || !timing->hasSameOriginAsPreviousDocument())
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->unloadEventEnd());
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::redirectStart() const
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoadTiming* timing = documentLoadTiming();
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (timing->hasCrossOriginRedirect())
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->redirectStart());
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::redirectEnd() const
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoadTiming* timing = documentLoadTiming();
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (timing->hasCrossOriginRedirect())
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->redirectEnd());
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::fetchStart() const
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoadTiming* timing = documentLoadTiming();
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->fetchStart());
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::domainLookupStart() const
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResourceLoadTiming* timing = resourceLoadTiming();
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return fetchStart();
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // This will be zero when a DNS request is not performed.
12993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Rather than exposing a special value that indicates no DNS, we "backfill" with fetchStart.
13093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    double dnsStart = timing->dnsStart;
13193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (dnsStart == 0.0)
13293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return fetchStart();
13393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
13493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(dnsStart);
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::domainLookupEnd() const
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResourceLoadTiming* timing = resourceLoadTiming();
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return domainLookupStart();
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // This will be zero when a DNS request is not performed.
14493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Rather than exposing a special value that indicates no DNS, we "backfill" with domainLookupStart.
14593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    double dnsEnd = timing->dnsEnd;
14693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (dnsEnd == 0.0)
14793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return domainLookupStart();
14893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
14993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(dnsEnd);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::connectStart() const
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoader* loader = documentLoader();
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!loader)
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return domainLookupEnd();
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return domainLookupEnd();
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // connectStart will be zero when a network request is not made.
16393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Rather than exposing a special value that indicates no new connection, we "backfill" with domainLookupEnd.
16493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    double connectStart = timing->connectStart;
16593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (connectStart == 0.0 || loader->response().connectionReused())
16693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return domainLookupEnd();
16793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
16893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // ResourceLoadTiming's connect phase includes DNS, however Navigation Timing's
16993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // connect phase should not. So if there is DNS time, trim it from the start.
17093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (timing->dnsEnd > 0.0 && timing->dnsEnd > connectStart)
17193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        connectStart = timing->dnsEnd;
17293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
17393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(connectStart);
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::connectEnd() const
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoader* loader = documentLoader();
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!loader)
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return connectStart();
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return connectStart();
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // connectEnd will be zero when a network request is not made.
18793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Rather than exposing a special value that indicates no new connection, we "backfill" with connectStart.
18893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    double connectEnd = timing->connectEnd;
18993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (connectEnd == 0.0 || loader->response().connectionReused())
19093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return connectStart();
19193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
19293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(connectEnd);
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::secureConnectionStart() const
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoader* loader = documentLoader();
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!loader)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    double sslStart = timing->sslStart;
20693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (sslStart == 0.0)
20793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 0;
20893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
20993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(sslStart);
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::requestStart() const
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResourceLoadTiming* timing = resourceLoadTiming();
21593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
21693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!timing || timing->sendStart == 0.0)
21793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return connectEnd();
21893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
21993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->sendStart);
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::responseStart() const
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ResourceLoadTiming* timing = resourceLoadTiming();
22593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!timing || timing->receiveHeadersEnd == 0.0)
22693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return requestStart();
2275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Response start needs to be the time of the first received byte.
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // However, the ResourceLoadTiming API currently only supports the time
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the last header byte was received. For many responses with reasonable
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // sized cookies, the HTTP headers fit into a single packet so this time
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // is basically equivalent. But for some responses, particularly those with
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // headers larger than a single packet, this time will be too late.
23493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->receiveHeadersEnd);
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::responseEnd() const
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoadTiming* timing = documentLoadTiming();
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->responseEnd());
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::domLoading() const
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const DocumentTiming* timing = documentTiming();
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return fetchStart();
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->domLoading);
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::domInteractive() const
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const DocumentTiming* timing = documentTiming();
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->domInteractive);
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::domContentLoadedEventStart() const
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const DocumentTiming* timing = documentTiming();
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->domContentLoadedEventStart);
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::domContentLoadedEventEnd() const
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const DocumentTiming* timing = documentTiming();
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->domContentLoadedEventEnd);
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::domComplete() const
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const DocumentTiming* timing = documentTiming();
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->domComplete);
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::loadEventStart() const
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoadTiming* timing = documentLoadTiming();
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->loadEventStart());
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::loadEventEnd() const
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoadTiming* timing = documentLoadTiming();
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!timing)
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return monotonicTimeToIntegerMilliseconds(timing->loadEventEnd());
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DocumentLoader* PerformanceTiming::documentLoader() const
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_frame)
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
314f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    return m_frame->loader().documentLoader();
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const DocumentTiming* PerformanceTiming::documentTiming() const
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_frame)
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Document* document = m_frame->document();
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!document)
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
326d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return &document->timing();
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DocumentLoadTiming* PerformanceTiming::documentLoadTiming() const
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoader* loader = documentLoader();
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!loader)
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return loader->timing();
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ResourceLoadTiming* PerformanceTiming::resourceLoadTiming() const
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DocumentLoader* loader = documentLoader();
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!loader)
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return loader->response().resourceLoadTiming();
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned long long PerformanceTiming::monotonicTimeToIntegerMilliseconds(double monotonicSeconds) const
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(monotonicSeconds >= 0);
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const DocumentLoadTiming* timing = documentLoadTiming();
35109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!timing)
35209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return 0;
35309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return toIntegerMilliseconds(timing->monotonicTimeToPseudoWallTime(monotonicSeconds));
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid PerformanceTiming::trace(Visitor* visitor)
3587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
3597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DOMWindowProperty::trace(visitor);
3607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
3617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
362c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
363