Bug 1263722 - Implement performance navigation timing r=baku

MozReview-Commit-ID: 9rJ3J6SqiDX
* * *
[mq]: test.patch

MozReview-Commit-ID: IYXp5G3iNSi

--HG--
extra : rebase_source : 5f2efdcf2cbd9f3b80752b59f083e32654a32e61
This commit is contained in:
Valentin Gosu 2016-04-17 22:03:28 +02:00
parent 9a17ff4441
commit d5c34da10e
24 changed files with 328 additions and 148 deletions

View File

@ -22,6 +22,7 @@
#include "mozilla/dom/PerformanceEntryEvent.h" #include "mozilla/dom/PerformanceEntryEvent.h"
#include "mozilla/dom/PerformanceNavigationBinding.h" #include "mozilla/dom/PerformanceNavigationBinding.h"
#include "mozilla/dom/PerformanceObserverBinding.h" #include "mozilla/dom/PerformanceObserverBinding.h"
#include "mozilla/dom/PerformanceNavigationTiming.h"
#include "mozilla/IntegerPrintfMacros.h" #include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "WorkerPrivate.h" #include "WorkerPrivate.h"

View File

@ -52,14 +52,14 @@ public:
JSObject* WrapObject(JSContext *cx, JSObject* WrapObject(JSContext *cx,
JS::Handle<JSObject*> aGivenProto) override; JS::Handle<JSObject*> aGivenProto) override;
void GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval); virtual void GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval);
void GetEntriesByType(const nsAString& aEntryType, virtual void GetEntriesByType(const nsAString& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval); nsTArray<RefPtr<PerformanceEntry>>& aRetval);
void GetEntriesByName(const nsAString& aName, virtual void GetEntriesByName(const nsAString& aName,
const Optional<nsAString>& aEntryType, const Optional<nsAString>& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval); nsTArray<RefPtr<PerformanceEntry>>& aRetval);
virtual void AddEntry(nsIHttpChannel* channel, virtual void AddEntry(nsIHttpChannel* channel,
nsITimedChannel* timedChannel) = 0; nsITimedChannel* timedChannel) = 0;
@ -154,7 +154,7 @@ protected:
nsTObserverArray<PerformanceObserver*> mObservers; nsTObserverArray<PerformanceObserver*> mObservers;
private: protected:
static const uint64_t kDefaultResourceTimingBufferSize = 150; static const uint64_t kDefaultResourceTimingBufferSize = 150;
// When kDefaultResourceTimingBufferSize is increased or removed, these should // When kDefaultResourceTimingBufferSize is increased or removed, these should

View File

@ -152,38 +152,7 @@ PerformanceMainThread::AddEntry(nsIHttpChannel* channel,
// The PerformanceResourceTiming object will use the PerformanceTiming // The PerformanceResourceTiming object will use the PerformanceTiming
// object to get all the required timings. // object to get all the required timings.
RefPtr<PerformanceResourceTiming> performanceEntry = RefPtr<PerformanceResourceTiming> performanceEntry =
new PerformanceResourceTiming(performanceTiming, this, entryName); new PerformanceResourceTiming(performanceTiming, this, entryName, channel);
nsAutoCString protocol;
// Can be an empty string.
Unused << channel->GetProtocolVersion(protocol);
// If this is a local fetch, nextHopProtocol should be set to empty string.
nsCOMPtr<nsICacheInfoChannel> cachedChannel = do_QueryInterface(channel);
if (cachedChannel) {
bool isFromCache;
if (NS_SUCCEEDED(cachedChannel->IsFromCache(&isFromCache))
&& isFromCache) {
protocol.Truncate();
}
}
performanceEntry->SetNextHopProtocol(NS_ConvertUTF8toUTF16(protocol));
uint64_t encodedBodySize = 0;
Unused << channel->GetEncodedBodySize(&encodedBodySize);
performanceEntry->SetEncodedBodySize(encodedBodySize);
uint64_t transferSize = 0;
Unused << channel->GetTransferSize(&transferSize);
performanceEntry->SetTransferSize(transferSize);
uint64_t decodedBodySize = 0;
Unused << channel->GetDecodedBodySize(&decodedBodySize);
if (decodedBodySize == 0) {
decodedBodySize = encodedBodySize;
}
performanceEntry->SetDecodedBodySize(decodedBodySize);
// If the initiator type had no valid value, then set it to the default // If the initiator type had no valid value, then set it to the default
// ("other") value. // ("other") value.
@ -338,5 +307,81 @@ PerformanceMainThread::CreationTime() const
return GetDOMTiming()->GetNavigationStart(); return GetDOMTiming()->GetNavigationStart();
} }
void
PerformanceMainThread::EnsureDocEntry()
{
if (!mDocEntry) {
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
mDocEntry = new PerformanceNavigationTiming(Timing(), this,
httpChannel);
}
}
void
PerformanceMainThread::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
// We return an empty list when 'privacy.resistFingerprinting' is on.
if (nsContentUtils::ShouldResistFingerprinting()) {
aRetval.Clear();
return;
}
aRetval = mResourceEntries;
aRetval.AppendElements(mUserEntries);
EnsureDocEntry();
if (mDocEntry) {
aRetval.AppendElement(mDocEntry);
}
aRetval.Sort(PerformanceEntryComparator());
}
void
PerformanceMainThread::GetEntriesByType(const nsAString& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
// We return an empty list when 'privacy.resistFingerprinting' is on.
if (nsContentUtils::ShouldResistFingerprinting()) {
aRetval.Clear();
return;
}
if (aEntryType.EqualsLiteral("navigation")) {
aRetval.Clear();
EnsureDocEntry();
if (mDocEntry) {
aRetval.AppendElement(mDocEntry);
}
return;
}
Performance::GetEntriesByType(aEntryType, aRetval);
}
void
PerformanceMainThread::GetEntriesByName(const nsAString& aName,
const Optional<nsAString>& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
// We return an empty list when 'privacy.resistFingerprinting' is on.
if (nsContentUtils::ShouldResistFingerprinting()) {
aRetval.Clear();
return;
}
if (aName.EqualsLiteral("document")) {
aRetval.Clear();
EnsureDocEntry();
if (mDocEntry) {
aRetval.AppendElement(mDocEntry);
}
return;
}
Performance::GetEntriesByName(aName, aEntryType, aRetval);
}
} // dom namespace } // dom namespace
} // mozilla namespace } // mozilla namespace

View File

@ -47,6 +47,15 @@ public:
return mChannel; return mChannel;
} }
// The GetEntries* methods need to be overriden in order to add the
// the document entry of type navigation.
virtual void GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval) override;
virtual void GetEntriesByType(const nsAString& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval) override;
virtual void GetEntriesByName(const nsAString& aName,
const Optional<nsAString>& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval) override;
protected: protected:
~PerformanceMainThread(); ~PerformanceMainThread();
@ -58,7 +67,9 @@ protected:
GetPerformanceTimingFromString(const nsAString& aTimingName) override; GetPerformanceTimingFromString(const nsAString& aTimingName) override;
void DispatchBufferFullEvent() override; void DispatchBufferFullEvent() override;
void EnsureDocEntry();
RefPtr<PerformanceEntry> mDocEntry;
RefPtr<nsDOMNavigationTiming> mDOMTiming; RefPtr<nsDOMNavigationTiming> mDOMTiming;
nsCOMPtr<nsITimedChannel> mChannel; nsCOMPtr<nsITimedChannel> mChannel;
RefPtr<PerformanceTiming> mTiming; RefPtr<PerformanceTiming> mTiming;

View File

@ -0,0 +1,95 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/PerformanceNavigationTiming.h"
#include "mozilla/dom/PerformanceNavigationTimingBinding.h"
using namespace mozilla::dom;
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PerformanceNavigationTiming)
NS_INTERFACE_MAP_END_INHERITING(PerformanceResourceTiming)
NS_IMPL_ADDREF_INHERITED(PerformanceNavigationTiming, PerformanceResourceTiming)
NS_IMPL_RELEASE_INHERITED(PerformanceNavigationTiming, PerformanceResourceTiming)
JSObject*
PerformanceNavigationTiming::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return PerformanceNavigationTimingBinding::Wrap(aCx, this, aGivenProto);
}
DOMHighResTimeStamp
PerformanceNavigationTiming::UnloadEventStart()
{
return mTiming->GetDOMTiming()->GetUnloadEventStart();
}
DOMHighResTimeStamp
PerformanceNavigationTiming::UnloadEventEnd()
{
return mTiming->GetDOMTiming()->GetUnloadEventEnd();
}
DOMHighResTimeStamp
PerformanceNavigationTiming::DomInteractive()
{
return mTiming->GetDOMTiming()->GetDomInteractive();
}
DOMHighResTimeStamp
PerformanceNavigationTiming::DomContentLoadedEventStart()
{
return mTiming->GetDOMTiming()->GetDomContentLoadedEventStart();
}
DOMHighResTimeStamp
PerformanceNavigationTiming::DomContentLoadedEventEnd()
{
return mTiming->GetDOMTiming()->GetDomContentLoadedEventEnd();
}
DOMHighResTimeStamp
PerformanceNavigationTiming::DomComplete()
{
return mTiming->GetDOMTiming()->GetDomComplete();
}
DOMHighResTimeStamp
PerformanceNavigationTiming::LoadEventStart()
{
return mTiming->GetDOMTiming()->GetLoadEventStart();
}
DOMHighResTimeStamp
PerformanceNavigationTiming::LoadEventEnd() const
{
return mTiming->GetDOMTiming()->GetLoadEventEnd();
}
NavigationType
PerformanceNavigationTiming::Type()
{
switch(mTiming->GetDOMTiming()->GetType()) {
case nsDOMNavigationTiming::TYPE_NAVIGATE:
return NavigationType::Navigate;
break;
case nsDOMNavigationTiming::TYPE_RELOAD:
return NavigationType::Reload;
break;
case nsDOMNavigationTiming::TYPE_BACK_FORWARD:
return NavigationType::Back_forward;
break;
default:
MOZ_CRASH(); // Should not happen
return NavigationType::Navigate;
}
}
uint16_t
PerformanceNavigationTiming::RedirectCount()
{
return mTiming->GetRedirectCount();
}

View File

@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_PerformanceNavigationTiming_h___
#define mozilla_dom_PerformanceNavigationTiming_h___
#include "nsCOMPtr.h"
#include "nsIChannel.h"
#include "nsITimedChannel.h"
#include "mozilla/dom/PerformanceResourceTiming.h"
#include "mozilla/dom/PerformanceNavigationTimingBinding.h"
#include "nsIHttpChannel.h"
namespace mozilla {
namespace dom {
// https://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming
class PerformanceNavigationTiming final
: public PerformanceResourceTiming
{
public:
NS_DECL_ISUPPORTS_INHERITED
explicit PerformanceNavigationTiming(PerformanceTiming* aPerformanceTiming,
Performance* aPerformance,
nsIHttpChannel* aChannel)
: PerformanceResourceTiming(aPerformanceTiming, aPerformance,
NS_LITERAL_STRING("document"), aChannel) {
SetEntryType(NS_LITERAL_STRING("navigation"));
SetInitiatorType(NS_LITERAL_STRING("navigation"));
}
DOMHighResTimeStamp Duration() const override
{
return LoadEventEnd() - StartTime();
}
DOMHighResTimeStamp StartTime() const override
{
return 0;
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
DOMHighResTimeStamp UnloadEventStart();
DOMHighResTimeStamp UnloadEventEnd();
DOMHighResTimeStamp DomInteractive();
DOMHighResTimeStamp DomContentLoadedEventStart();
DOMHighResTimeStamp DomContentLoadedEventEnd();
DOMHighResTimeStamp DomComplete();
DOMHighResTimeStamp LoadEventStart();
DOMHighResTimeStamp LoadEventEnd() const;
NavigationType Type();
uint16_t RedirectCount();
private:
~PerformanceNavigationTiming() {}
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PerformanceNavigationTiming_h___

View File

@ -25,7 +25,8 @@ NS_IMPL_RELEASE_INHERITED(PerformanceResourceTiming, PerformanceEntry)
PerformanceResourceTiming::PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming, PerformanceResourceTiming::PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
Performance* aPerformance, Performance* aPerformance,
const nsAString& aName) const nsAString& aName,
nsIHttpChannel* aChannel)
: PerformanceEntry(aPerformance->GetParentObject(), aName, NS_LITERAL_STRING("resource")), : PerformanceEntry(aPerformance->GetParentObject(), aName, NS_LITERAL_STRING("resource")),
mTiming(aPerformanceTiming), mTiming(aPerformanceTiming),
mEncodedBodySize(0), mEncodedBodySize(0),
@ -33,6 +34,34 @@ PerformanceResourceTiming::PerformanceResourceTiming(PerformanceTiming* aPerform
mDecodedBodySize(0) mDecodedBodySize(0)
{ {
MOZ_ASSERT(aPerformance, "Parent performance object should be provided"); MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
SetPropertiesFromChannel(aChannel);
}
void
PerformanceResourceTiming::SetPropertiesFromChannel(nsIHttpChannel* aChannel)
{
if (!aChannel) {
return;
}
nsAutoCString protocol;
Unused << aChannel->GetProtocolVersion(protocol);
SetNextHopProtocol(NS_ConvertUTF8toUTF16(protocol));
uint64_t encodedBodySize = 0;
Unused << aChannel->GetEncodedBodySize(&encodedBodySize);
SetEncodedBodySize(encodedBodySize);
uint64_t transferSize = 0;
Unused << aChannel->GetTransferSize(&transferSize);
SetTransferSize(transferSize);
uint64_t decodedBodySize = 0;
Unused << aChannel->GetDecodedBodySize(&decodedBodySize);
if (decodedBodySize == 0) {
decodedBodySize = encodedBodySize;
}
SetDecodedBodySize(decodedBodySize);
} }
PerformanceResourceTiming::~PerformanceResourceTiming() PerformanceResourceTiming::~PerformanceResourceTiming()

View File

@ -18,7 +18,7 @@ namespace mozilla {
namespace dom { namespace dom {
// http://www.w3.org/TR/resource-timing/#performanceresourcetiming // http://www.w3.org/TR/resource-timing/#performanceresourcetiming
class PerformanceResourceTiming final : public PerformanceEntry class PerformanceResourceTiming : public PerformanceEntry
{ {
public: public:
typedef mozilla::TimeStamp TimeStamp; typedef mozilla::TimeStamp TimeStamp;
@ -30,7 +30,8 @@ public:
PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming, PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
Performance* aPerformance, Performance* aPerformance,
const nsAString& aName); const nsAString& aName,
nsIHttpChannel* aChannel = nullptr);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
@ -173,6 +174,7 @@ public:
protected: protected:
virtual ~PerformanceResourceTiming(); virtual ~PerformanceResourceTiming();
void SetPropertiesFromChannel(nsIHttpChannel* aChannel);
size_t size_t
SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override; SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;

View File

@ -13,6 +13,7 @@ EXPORTS.mozilla.dom += [
'PerformanceMark.h', 'PerformanceMark.h',
'PerformanceMeasure.h', 'PerformanceMeasure.h',
'PerformanceNavigation.h', 'PerformanceNavigation.h',
'PerformanceNavigationTiming.h',
'PerformanceObserver.h', 'PerformanceObserver.h',
'PerformanceObserverEntryList.h', 'PerformanceObserverEntryList.h',
'PerformanceResourceTiming.h', 'PerformanceResourceTiming.h',
@ -27,6 +28,7 @@ UNIFIED_SOURCES += [
'PerformanceMark.cpp', 'PerformanceMark.cpp',
'PerformanceMeasure.cpp', 'PerformanceMeasure.cpp',
'PerformanceNavigation.cpp', 'PerformanceNavigation.cpp',
'PerformanceNavigationTiming.cpp',
'PerformanceObserver.cpp', 'PerformanceObserver.cpp',
'PerformanceObserverEntryList.cpp', 'PerformanceObserverEntryList.cpp',
'PerformanceResourceTiming.cpp', 'PerformanceResourceTiming.cpp',

View File

@ -0,0 +1,33 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* https://www.w3.org/TR/navigation-timing-2/#sec-PerformanceNavigationTiming
*
* Copyright © 2016 W3C® (MIT, ERCIM, Keio, Beihang).
* W3C liability, trademark and document use rules apply.
*/
enum NavigationType {
"navigate",
"reload",
"back_forward",
"prerender"
};
interface PerformanceNavigationTiming : PerformanceResourceTiming {
readonly attribute DOMHighResTimeStamp unloadEventStart;
readonly attribute DOMHighResTimeStamp unloadEventEnd;
readonly attribute DOMHighResTimeStamp domInteractive;
readonly attribute DOMHighResTimeStamp domContentLoadedEventStart;
readonly attribute DOMHighResTimeStamp domContentLoadedEventEnd;
readonly attribute DOMHighResTimeStamp domComplete;
readonly attribute DOMHighResTimeStamp loadEventStart;
readonly attribute DOMHighResTimeStamp loadEventEnd;
readonly attribute NavigationType type;
readonly attribute unsigned short redirectCount;
jsonifier;
};

View File

@ -739,6 +739,7 @@ WEBIDL_FILES = [
'PerformanceMark.webidl', 'PerformanceMark.webidl',
'PerformanceMeasure.webidl', 'PerformanceMeasure.webidl',
'PerformanceNavigation.webidl', 'PerformanceNavigation.webidl',
'PerformanceNavigationTiming.webidl',
'PerformanceObserver.webidl', 'PerformanceObserver.webidl',
'PerformanceObserverEntryList.webidl', 'PerformanceObserverEntryList.webidl',
'PerformanceResourceTiming.webidl', 'PerformanceResourceTiming.webidl',

View File

@ -1,50 +1,4 @@
[nav2_idlharness.html] [nav2_idlharness.html]
type: testharness type: testharness
[PerformanceNavigationTiming interface: existence and properties of interface object]
expected: FAIL
[PerformanceNavigationTiming interface object length]
expected: FAIL
[PerformanceNavigationTiming interface object name]
expected: FAIL
[PerformanceNavigationTiming interface: existence and properties of interface prototype object] [PerformanceNavigationTiming interface: existence and properties of interface prototype object]
expected: FAIL expected: FAIL
[PerformanceNavigationTiming interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[PerformanceNavigationTiming interface: attribute unloadEventStart]
expected: FAIL
[PerformanceNavigationTiming interface: attribute unloadEventEnd]
expected: FAIL
[PerformanceNavigationTiming interface: attribute domInteractive]
expected: FAIL
[PerformanceNavigationTiming interface: attribute domContentLoadedEventStart]
expected: FAIL
[PerformanceNavigationTiming interface: attribute domContentLoadedEventEnd]
expected: FAIL
[PerformanceNavigationTiming interface: attribute domComplete]
expected: FAIL
[PerformanceNavigationTiming interface: attribute loadEventStart]
expected: FAIL
[PerformanceNavigationTiming interface: attribute loadEventEnd]
expected: FAIL
[PerformanceNavigationTiming interface: attribute type]
expected: FAIL
[PerformanceNavigationTiming interface: attribute redirectCount]
expected: FAIL
[PerformanceNavigationTiming interface: operation toJSON()]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_document_open.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_document_replaced.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_frame_removed.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_instance_accessible_from_the_start.html]
type: testharness
[PerformanceNavigationTiming instance exists with reasonable values.]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_navigate_within_document.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_navigation_type_backforward.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_navigation_type_reload.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_redirect_server.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_redirect_xserver.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_unloadEvents_no_previous_document.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_unloadEvents_previous_document_cross_origin.sub.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL

View File

@ -1,5 +0,0 @@
[nav2_test_unloadEvents_with_previous_document.html]
type: testharness
[Navigation Timing 2 WPT]
expected: FAIL