Bug 1424341 Round the Performance Timing APIs when privacy.reduceTimerPrecision is set
MozReview-Commit-ID: LrAmrIfKk39
--- a/dom/performance/Performance.cpp
+++ b/dom/performance/Performance.cpp
@@ -131,17 +131,18 @@ Performance::Now() const
DOMHighResTimeStamp
Performance::TimeOrigin()
{
if (!mPerformanceService) {
mPerformanceService = PerformanceService::GetOrCreate();
}
MOZ_ASSERT(mPerformanceService);
- return mPerformanceService->TimeOrigin(CreationTimeStamp());
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ mPerformanceService->TimeOrigin(CreationTimeStamp()));
}
JSObject*
Performance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return PerformanceBinding::Wrap(aCx, this, aGivenProto);
}
--- a/dom/performance/PerformanceNavigationTiming.h
+++ b/dom/performance/PerformanceNavigationTiming.h
@@ -5,16 +5,17 @@
* 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 "nsRFPService.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
@@ -34,17 +35,17 @@ public:
: 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();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(LoadEventEnd() - StartTime());
}
DOMHighResTimeStamp StartTime() const override
{
return 0;
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
--- a/dom/performance/PerformanceTiming.cpp
+++ b/dom/performance/PerformanceTiming.cpp
@@ -21,17 +21,17 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Per
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceTiming, Release)
PerformanceTiming::PerformanceTiming(Performance* aPerformance,
nsITimedChannel* aChannel,
nsIHttpChannel* aHttpChannel,
DOMHighResTimeStamp aZeroTime)
: mPerformance(aPerformance),
mFetchStart(0.0),
- mZeroTime(aZeroTime),
+ mZeroTime(nsRFPService::ReduceTimePrecisionAsMSecs(aZeroTime)),
mRedirectCount(0),
mTimingAllowed(true),
mAllRedirectsSameOrigin(true),
mInitialized(!!aChannel),
mReportCrossOriginRedirect(true)
{
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
@@ -164,17 +164,17 @@ PerformanceTiming::FetchStartHighRes()
if (!mAsyncOpen.IsNull()) {
if (!mWorkerRequestStart.IsNull() && mWorkerRequestStart > mAsyncOpen) {
mFetchStart = TimeStampToDOMHighRes(mWorkerRequestStart);
} else {
mFetchStart = TimeStampToDOMHighRes(mAsyncOpen);
}
}
}
- return mFetchStart;
+ return nsRFPService::ReduceTimePrecisionAsMSecs(mFetchStart);
}
DOMTimeMilliSec
PerformanceTiming::FetchStart()
{
return static_cast<int64_t>(FetchStartHighRes());
}
@@ -243,27 +243,27 @@ PerformanceTiming::ShouldReportCrossOrig
DOMHighResTimeStamp
PerformanceTiming::AsyncOpenHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting() || mAsyncOpen.IsNull()) {
return mZeroTime;
}
- return TimeStampToDOMHighRes(mAsyncOpen);
+ return nsRFPService::ReduceTimePrecisionAsMSecs(TimeStampToDOMHighRes(mAsyncOpen));
}
DOMHighResTimeStamp
PerformanceTiming::WorkerStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting() || mWorkerStart.IsNull()) {
return mZeroTime;
}
- return TimeStampToDOMHighRes(mWorkerStart);
+ return nsRFPService::ReduceTimePrecisionAsMSecs(TimeStampToDOMHighRes(mWorkerStart));
}
/**
* RedirectStartHighRes() is used by both the navigation timing and the
* resource timing. Since, navigation timing and resource timing check and
* interpret cross-domain redirects in a different manner,
* RedirectStartHighRes() will make no checks for cross-domain redirect.
* It's up to the consumers of this method (PerformanceTiming::RedirectStart()
@@ -273,17 +273,18 @@ PerformanceTiming::WorkerStartHighRes()
*/
DOMHighResTimeStamp
PerformanceTiming::RedirectStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting()) {
return mZeroTime;
}
- return TimeStampToDOMHighResOrFetchStart(mRedirectStart);
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighResOrFetchStart(mRedirectStart));
}
DOMTimeMilliSec
PerformanceTiming::RedirectStart()
{
if (!IsInitialized()) {
return 0;
}
@@ -307,17 +308,18 @@ PerformanceTiming::RedirectStart()
*/
DOMHighResTimeStamp
PerformanceTiming::RedirectEndHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting()) {
return mZeroTime;
}
- return TimeStampToDOMHighResOrFetchStart(mRedirectEnd);
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighResOrFetchStart(mRedirectEnd));
}
DOMTimeMilliSec
PerformanceTiming::RedirectEnd()
{
if (!IsInitialized()) {
return 0;
}
@@ -331,17 +333,18 @@ PerformanceTiming::RedirectEnd()
DOMHighResTimeStamp
PerformanceTiming::DomainLookupStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting()) {
return mZeroTime;
}
- return TimeStampToDOMHighResOrFetchStart(mDomainLookupStart);
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighResOrFetchStart(mDomainLookupStart));
}
DOMTimeMilliSec
PerformanceTiming::DomainLookupStart()
{
return static_cast<int64_t>(DomainLookupStartHighRes());
}
@@ -349,34 +352,36 @@ DOMHighResTimeStamp
PerformanceTiming::DomainLookupEndHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting()) {
return mZeroTime;
}
// Bug 1155008 - nsHttpTransaction is racy. Return DomainLookupStart when null
return mDomainLookupEnd.IsNull() ? DomainLookupStartHighRes()
- : TimeStampToDOMHighRes(mDomainLookupEnd);
+ : nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighRes(mDomainLookupEnd));
}
DOMTimeMilliSec
PerformanceTiming::DomainLookupEnd()
{
return static_cast<int64_t>(DomainLookupEndHighRes());
}
DOMHighResTimeStamp
PerformanceTiming::ConnectStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting()) {
return mZeroTime;
}
return mConnectStart.IsNull() ? DomainLookupEndHighRes()
- : TimeStampToDOMHighRes(mConnectStart);
+ : nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighRes(mConnectStart));
}
DOMTimeMilliSec
PerformanceTiming::ConnectStart()
{
return static_cast<int64_t>(ConnectStartHighRes());
}
@@ -386,17 +391,18 @@ PerformanceTiming::SecureConnectionStart
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting()) {
return mZeroTime;
}
return !mSecureConnection
? 0 // We use 0 here, because mZeroTime is sometimes set to the navigation
// start time.
: (mSecureConnectionStart.IsNull() ? mZeroTime
- : TimeStampToDOMHighRes(mSecureConnectionStart));
+ : nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighRes(mSecureConnectionStart)));
}
DOMTimeMilliSec
PerformanceTiming::SecureConnectionStart()
{
return static_cast<int64_t>(SecureConnectionStartHighRes());
}
@@ -404,17 +410,18 @@ DOMHighResTimeStamp
PerformanceTiming::ConnectEndHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
nsContentUtils::ShouldResistFingerprinting()) {
return mZeroTime;
}
// Bug 1155008 - nsHttpTransaction is racy. Return ConnectStart when null
return mConnectEnd.IsNull() ? ConnectStartHighRes()
- : TimeStampToDOMHighRes(mConnectEnd);
+ : nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighRes(mConnectEnd));
}
DOMTimeMilliSec
PerformanceTiming::ConnectEnd()
{
return static_cast<int64_t>(ConnectEndHighRes());
}
@@ -425,17 +432,18 @@ PerformanceTiming::RequestStartHighRes()
nsContentUtils::ShouldResistFingerprinting()) {
return mZeroTime;
}
if (mRequestStart.IsNull()) {
mRequestStart = mWorkerRequestStart;
}
- return TimeStampToDOMHighResOrFetchStart(mRequestStart);
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighResOrFetchStart(mRequestStart));
}
DOMTimeMilliSec
PerformanceTiming::RequestStart()
{
return static_cast<int64_t>(RequestStartHighRes());
}
@@ -450,17 +458,18 @@ PerformanceTiming::ResponseStartHighRes(
(!mCacheReadStart.IsNull() && mCacheReadStart < mResponseStart)) {
mResponseStart = mCacheReadStart;
}
if (mResponseStart.IsNull() ||
(!mRequestStart.IsNull() && mResponseStart < mRequestStart)) {
mResponseStart = mRequestStart;
}
- return TimeStampToDOMHighResOrFetchStart(mResponseStart);
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighResOrFetchStart(mResponseStart));
}
DOMTimeMilliSec
PerformanceTiming::ResponseStart()
{
return static_cast<int64_t>(ResponseStartHighRes());
}
@@ -475,17 +484,18 @@ PerformanceTiming::ResponseEndHighRes()
(!mCacheReadEnd.IsNull() && mCacheReadEnd < mResponseEnd)) {
mResponseEnd = mCacheReadEnd;
}
if (mResponseEnd.IsNull()) {
mResponseEnd = mWorkerResponseEnd;
}
// Bug 1155008 - nsHttpTransaction is racy. Return ResponseStart when null
return mResponseEnd.IsNull() ? ResponseStartHighRes()
- : TimeStampToDOMHighRes(mResponseEnd);
+ : nsRFPService::ReduceTimePrecisionAsMSecs(
+ TimeStampToDOMHighRes(mResponseEnd));
}
DOMTimeMilliSec
PerformanceTiming::ResponseEnd()
{
return static_cast<int64_t>(ResponseEndHighRes());
}
--- a/dom/performance/PerformanceTiming.h
+++ b/dom/performance/PerformanceTiming.h
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_PerformanceTiming_h
#define mozilla_dom_PerformanceTiming_h
#include "mozilla/Attributes.h"
#include "nsContentUtils.h"
#include "nsDOMNavigationTiming.h"
+#include "nsRFPService.h"
#include "nsWrapperCache.h"
#include "Performance.h"
class nsIHttpChannel;
class nsITimedChannel;
namespace mozilla {
namespace dom {
@@ -102,48 +103,52 @@ public:
* page
* - an absolute wall clock time since the unix epoch
*/
inline DOMHighResTimeStamp TimeStampToDOMHighRes(TimeStamp aStamp) const
{
MOZ_ASSERT(!aStamp.IsNull());
TimeDuration duration =
aStamp - GetDOMTiming()->GetNavigationStartTimeStamp();
- return duration.ToMilliseconds() + mZeroTime;
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ duration.ToMilliseconds() + mZeroTime);
}
virtual JSObject* WrapObject(JSContext *cx,
JS::Handle<JSObject*> aGivenProto) override;
// PerformanceNavigation WebIDL methods
DOMTimeMilliSec NavigationStart() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetNavigationStart();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetNavigationStart());
}
DOMTimeMilliSec UnloadEventStart()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetUnloadEventStart();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetUnloadEventStart());
}
DOMTimeMilliSec UnloadEventEnd()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetUnloadEventEnd();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetUnloadEventEnd());
}
uint8_t GetRedirectCount() const;
// Checks if the resource is either same origin as the page that started
// the load, or if the response contains the Timing-Allow-Origin header
// with a value of * or matching the domain of the loading Principal
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel, nsITimedChannel* aChannel);
@@ -189,80 +194,88 @@ public:
DOMTimeMilliSec ResponseEnd();
DOMTimeMilliSec DomLoading()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetDomLoading();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetDomLoading());
}
DOMTimeMilliSec DomInteractive() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetDomInteractive();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetDomInteractive());
}
DOMTimeMilliSec DomContentLoadedEventStart() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetDomContentLoadedEventStart();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetDomContentLoadedEventStart());
}
DOMTimeMilliSec DomContentLoadedEventEnd() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetDomContentLoadedEventEnd();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetDomContentLoadedEventEnd());
}
DOMTimeMilliSec DomComplete() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetDomComplete();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetDomComplete());
}
DOMTimeMilliSec LoadEventStart() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetLoadEventStart();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetLoadEventStart());
}
DOMTimeMilliSec LoadEventEnd() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetLoadEventEnd();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetLoadEventEnd());
}
DOMTimeMilliSec TimeToNonBlankPaint() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled() ||
nsContentUtils::ShouldResistFingerprinting()) {
return 0;
}
- return GetDOMTiming()->GetTimeToNonBlankPaint();
+ return nsRFPService::ReduceTimePrecisionAsMSecs(
+ GetDOMTiming()->GetTimeToNonBlankPaint());
}
private:
~PerformanceTiming();
bool IsInitialized() const;
void InitializeTimingInfo(nsITimedChannel* aChannel);