LCOV - code coverage report
Current view: top level - dom/performance - PerformanceTiming.h (source / functions) Hit Total Coverage
Test: output.info Lines: 12 69 17.4 %
Date: 2017-07-14 16:53:18 Functions: 6 21 28.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef mozilla_dom_PerformanceTiming_h
       8             : #define mozilla_dom_PerformanceTiming_h
       9             : 
      10             : #include "mozilla/Attributes.h"
      11             : #include "nsContentUtils.h"
      12             : #include "nsDOMNavigationTiming.h"
      13             : #include "nsWrapperCache.h"
      14             : #include "Performance.h"
      15             : 
      16             : class nsIHttpChannel;
      17             : class nsITimedChannel;
      18             : 
      19             : namespace mozilla {
      20             : namespace dom {
      21             : 
      22             : // Script "performance.timing" object
      23             : class PerformanceTiming final : public nsWrapperCache
      24             : {
      25             : public:
      26             : /**
      27             :  * @param   aPerformance
      28             :  *          The performance object (the JS parent).
      29             :  *          This will allow access to "window.performance.timing" attribute for
      30             :  *          the navigation timing (can't be null).
      31             :  * @param   aChannel
      32             :  *          An nsITimedChannel used to gather all the networking timings by both
      33             :  *          the navigation timing and the resource timing (can't be null).
      34             :  * @param   aHttpChannel
      35             :  *          An nsIHttpChannel (the resource's http channel).
      36             :  *          This will be used by the resource timing cross-domain check
      37             :  *          algorithm.
      38             :  *          Argument is null for the navigation timing (navigation timing uses
      39             :  *          another algorithm for the cross-domain redirects).
      40             :  * @param   aZeroTime
      41             :  *          The offset that will be added to the timestamp of each event. This
      42             :  *          argument should be equal to performance.navigationStart for
      43             :  *          navigation timing and "0" for the resource timing.
      44             :  */
      45             :   PerformanceTiming(Performance* aPerformance,
      46             :                     nsITimedChannel* aChannel,
      47             :                     nsIHttpChannel* aHttpChannel,
      48             :                     DOMHighResTimeStamp aZeroTime);
      49           6 :   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PerformanceTiming)
      50          13 :   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(PerformanceTiming)
      51             : 
      52           2 :   nsDOMNavigationTiming* GetDOMTiming() const
      53             :   {
      54           2 :     return mPerformance->GetDOMTiming();
      55             :   }
      56             : 
      57           0 :   Performance* GetParentObject() const
      58             :   {
      59           0 :     return mPerformance;
      60             :   }
      61             : 
      62             :   /**
      63             :    * @param   aStamp
      64             :    *          The TimeStamp recorded for a specific event. This TimeStamp can
      65             :    *          be null.
      66             :    * @return  the duration of an event with a given TimeStamp, relative to the
      67             :    *          navigationStart TimeStamp (the moment the user landed on the
      68             :    *          page), if the given TimeStamp is valid. Otherwise, it will return
      69             :    *          the FetchStart timing value.
      70             :    */
      71           2 :   inline DOMHighResTimeStamp TimeStampToDOMHighResOrFetchStart(TimeStamp aStamp)
      72             :   {
      73           2 :     return (!aStamp.IsNull())
      74           2 :         ? TimeStampToDOMHighRes(aStamp)
      75           2 :         : FetchStartHighRes();
      76             :   }
      77             : 
      78             :   /**
      79             :    * The nsITimedChannel records an absolute timestamp for each event.
      80             :    * The nsDOMNavigationTiming will record the moment when the user landed on
      81             :    * the page. This is a window.performance unique timestamp, so it can be used
      82             :    * for all the events (navigation timing and resource timing events).
      83             :    *
      84             :    * The algorithm operates in 2 steps:
      85             :    * 1. The first step is to subtract the two timestamps: the argument (the
      86             :    * envet's timesramp) and the navigation start timestamp. This will result in
      87             :    * a relative timestamp of the event (relative to the navigation start -
      88             :    * window.performance.timing.navigationStart).
      89             :    * 2. The second step is to add any required offset (the mZeroTime). For now,
      90             :    * this offset value is either 0 (for the resource timing), or equal to
      91             :    * "performance.navigationStart" (for navigation timing).
      92             :    * For the resource timing, mZeroTime is set to 0, causing the result to be a
      93             :    * relative time.
      94             :    * For the navigation timing, mZeroTime is set to "performance.navigationStart"
      95             :    * causing the result be an absolute time.
      96             :    *
      97             :    * @param   aStamp
      98             :    *          The TimeStamp recorded for a specific event. This TimeStamp can't
      99             :    *          be null.
     100             :    * @return  number of milliseconds value as one of:
     101             :    * - relative to the navigation start time, time the user has landed on the
     102             :    * page
     103             :    * - an absolute wall clock time since the unix epoch
     104             :    */
     105           2 :   inline DOMHighResTimeStamp TimeStampToDOMHighRes(TimeStamp aStamp) const
     106             :   {
     107           2 :     MOZ_ASSERT(!aStamp.IsNull());
     108             :     TimeDuration duration =
     109           2 :         aStamp - GetDOMTiming()->GetNavigationStartTimeStamp();
     110           2 :     return duration.ToMilliseconds() + mZeroTime;
     111             :   }
     112             : 
     113             :   virtual JSObject* WrapObject(JSContext *cx,
     114             :                                JS::Handle<JSObject*> aGivenProto) override;
     115             : 
     116             :   // PerformanceNavigation WebIDL methods
     117           0 :   DOMTimeMilliSec NavigationStart() const
     118             :   {
     119           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     120           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     121           0 :       return 0;
     122             :     }
     123           0 :     return GetDOMTiming()->GetNavigationStart();
     124             :   }
     125             : 
     126           0 :   DOMTimeMilliSec UnloadEventStart()
     127             :   {
     128           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     129           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     130           0 :       return 0;
     131             :     }
     132           0 :     return GetDOMTiming()->GetUnloadEventStart();
     133             :   }
     134             : 
     135           0 :   DOMTimeMilliSec UnloadEventEnd()
     136             :   {
     137           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     138           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     139           0 :       return 0;
     140             :     }
     141           0 :     return GetDOMTiming()->GetUnloadEventEnd();
     142             :   }
     143             : 
     144             :   uint16_t GetRedirectCount() const;
     145             : 
     146             :   // Checks if the resource is either same origin as the page that started
     147             :   // the load, or if the response contains the Timing-Allow-Origin header
     148             :   // with a value of * or matching the domain of the loading Principal
     149             :   bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel, nsITimedChannel* aChannel);
     150             : 
     151             :   // Cached result of CheckAllowedOrigin. If false, security sensitive
     152             :   // attributes of the resourceTiming object will be set to 0
     153             :   bool TimingAllowed() const;
     154             : 
     155             :   // If this is false the values of redirectStart/End will be 0
     156             :   // This is false if no redirects occured, or if any of the responses failed
     157             :   // the timing-allow-origin check in HttpBaseChannel::TimingAllowCheck
     158             :   bool ShouldReportCrossOriginRedirect() const;
     159             : 
     160             :   // High resolution (used by resource timing)
     161             :   DOMHighResTimeStamp FetchStartHighRes();
     162             :   DOMHighResTimeStamp RedirectStartHighRes();
     163             :   DOMHighResTimeStamp RedirectEndHighRes();
     164             :   DOMHighResTimeStamp DomainLookupStartHighRes();
     165             :   DOMHighResTimeStamp DomainLookupEndHighRes();
     166             :   DOMHighResTimeStamp ConnectStartHighRes();
     167             :   DOMHighResTimeStamp ConnectEndHighRes();
     168             :   DOMHighResTimeStamp RequestStartHighRes();
     169             :   DOMHighResTimeStamp ResponseStartHighRes();
     170             :   DOMHighResTimeStamp ResponseEndHighRes();
     171             : 
     172             :   // Low resolution (used by navigation timing)
     173             :   DOMTimeMilliSec FetchStart();
     174             :   DOMTimeMilliSec RedirectStart();
     175             :   DOMTimeMilliSec RedirectEnd();
     176             :   DOMTimeMilliSec DomainLookupStart();
     177             :   DOMTimeMilliSec DomainLookupEnd();
     178             :   DOMTimeMilliSec ConnectStart();
     179             :   DOMTimeMilliSec ConnectEnd();
     180             :   DOMTimeMilliSec RequestStart();
     181             :   DOMTimeMilliSec ResponseStart();
     182             :   DOMTimeMilliSec ResponseEnd();
     183             : 
     184           0 :   DOMTimeMilliSec DomLoading()
     185             :   {
     186           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     187           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     188           0 :       return 0;
     189             :     }
     190           0 :     return GetDOMTiming()->GetDomLoading();
     191             :   }
     192             : 
     193           0 :   DOMTimeMilliSec DomInteractive() const
     194             :   {
     195           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     196           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     197           0 :       return 0;
     198             :     }
     199           0 :     return GetDOMTiming()->GetDomInteractive();
     200             :   }
     201             : 
     202           0 :   DOMTimeMilliSec DomContentLoadedEventStart() const
     203             :   {
     204           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     205           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     206           0 :       return 0;
     207             :     }
     208           0 :     return GetDOMTiming()->GetDomContentLoadedEventStart();
     209             :   }
     210             : 
     211           0 :   DOMTimeMilliSec DomContentLoadedEventEnd() const
     212             :   {
     213           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     214           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     215           0 :       return 0;
     216             :     }
     217           0 :     return GetDOMTiming()->GetDomContentLoadedEventEnd();
     218             :   }
     219             : 
     220           0 :   DOMTimeMilliSec DomComplete() const
     221             :   {
     222           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     223           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     224           0 :       return 0;
     225             :     }
     226           0 :     return GetDOMTiming()->GetDomComplete();
     227             :   }
     228             : 
     229           0 :   DOMTimeMilliSec LoadEventStart() const
     230             :   {
     231           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     232           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     233           0 :       return 0;
     234             :     }
     235           0 :     return GetDOMTiming()->GetLoadEventStart();
     236             :   }
     237             : 
     238           0 :   DOMTimeMilliSec LoadEventEnd() const
     239             :   {
     240           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     241           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     242           0 :       return 0;
     243             :     }
     244           0 :     return GetDOMTiming()->GetLoadEventEnd();
     245             :   }
     246             : 
     247           0 :   DOMTimeMilliSec TimeToNonBlankPaint() const
     248             :   {
     249           0 :     if (!nsContentUtils::IsPerformanceTimingEnabled() ||
     250           0 :         nsContentUtils::ShouldResistFingerprinting()) {
     251           0 :       return 0;
     252             :     }
     253           0 :     return GetDOMTiming()->GetTimeToNonBlankPaint();
     254             :   }
     255             : 
     256             : private:
     257             :   ~PerformanceTiming();
     258             : 
     259             :   bool IsInitialized() const;
     260             :   void InitializeTimingInfo(nsITimedChannel* aChannel);
     261             : 
     262             :   bool IsTopLevelContentDocument() const;
     263             : 
     264             :   RefPtr<Performance> mPerformance;
     265             :   DOMHighResTimeStamp mFetchStart;
     266             : 
     267             :   // This is an offset that will be added to each timing ([ms] resolution).
     268             :   // There are only 2 possible values: (1) logicaly equal to navigationStart
     269             :   // TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results
     270             :   // are relative to the navigation start).
     271             :   DOMHighResTimeStamp mZeroTime;
     272             : 
     273             :   TimeStamp mAsyncOpen;
     274             :   TimeStamp mRedirectStart;
     275             :   TimeStamp mRedirectEnd;
     276             :   TimeStamp mDomainLookupStart;
     277             :   TimeStamp mDomainLookupEnd;
     278             :   TimeStamp mConnectStart;
     279             :   TimeStamp mConnectEnd;
     280             :   TimeStamp mRequestStart;
     281             :   TimeStamp mResponseStart;
     282             :   TimeStamp mCacheReadStart;
     283             :   TimeStamp mResponseEnd;
     284             :   TimeStamp mCacheReadEnd;
     285             :   uint16_t mRedirectCount;
     286             :   bool mTimingAllowed;
     287             :   bool mAllRedirectsSameOrigin;
     288             :   bool mInitialized;
     289             : 
     290             :   // If the resourceTiming object should have non-zero redirectStart and
     291             :   // redirectEnd attributes. It is false if there were no redirects, or if
     292             :   // any of the responses didn't pass the timing-allow-check
     293             :   bool mReportCrossOriginRedirect;
     294             : };
     295             : 
     296             : } // namespace dom
     297             : } // namespace mozilla
     298             : 
     299             : #endif // mozilla_dom_PerformanceTiming_h

Generated by: LCOV version 1.13