dom/base/nsPerformance.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #ifndef nsPerformance_h___
     6 #define nsPerformance_h___
     8 #include "nsCOMPtr.h"
     9 #include "nsAutoPtr.h"
    10 #include "mozilla/Attributes.h"
    11 #include "nsWrapperCache.h"
    12 #include "nsDOMNavigationTiming.h"
    13 #include "nsContentUtils.h"
    14 #include "nsIDOMWindow.h"
    15 #include "js/TypeDecls.h"
    16 #include "mozilla/dom/BindingDeclarations.h"
    18 class nsITimedChannel;
    19 class nsPerformance;
    20 class nsIHttpChannel;
    22 namespace mozilla {
    23 namespace dom {
    24   class PerformanceEntry;
    25 }
    26 }
    28 // Script "performance.timing" object
    29 class nsPerformanceTiming MOZ_FINAL : public nsWrapperCache
    30 {
    31 public:
    32   typedef mozilla::TimeStamp TimeStamp;
    34 /**
    35  * @param   aPerformance
    36  *          The performance object (the JS parent).
    37  *          This will allow access to "window.performance.timing" attribute for
    38  *          the navigation timing (can't be null).
    39  * @param   aChannel
    40  *          An nsITimedChannel used to gather all the networking timings by both
    41  *          the navigation timing and the resource timing (can't be null).
    42  * @param   aHttpChannel
    43  *          An nsIHttpChannel (the resource's http channel).
    44  *          This will be used by the resource timing cross-domain check
    45  *          algorithm.
    46  *          Argument is null for the navigation timing (navigation timing uses
    47  *          another algorithm for the cross-domain redirects).
    48  * @param   aZeroTime
    49  *          The offset that will be added to the timestamp of each event. This
    50  *          argument should be equal to performance.navigationStart for
    51  *          navigation timing and "0" for the resource timing.
    52  */
    53   nsPerformanceTiming(nsPerformance* aPerformance,
    54                       nsITimedChannel* aChannel,
    55                       nsIHttpChannel* aHttpChannel,
    56                       DOMHighResTimeStamp aZeroTime);
    57   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsPerformanceTiming)
    58   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsPerformanceTiming)
    60   nsDOMNavigationTiming* GetDOMTiming() const;
    62   nsPerformance* GetParentObject() const
    63   {
    64     return mPerformance;
    65   }
    67   /**
    68    * @param   aStamp
    69    *          The TimeStamp recorded for a specific event. This TimeStamp can
    70    *          be null.
    71    * @return  the duration of an event with a given TimeStamp, relative to the
    72    *          navigationStart TimeStamp (the moment the user landed on the
    73    *          page), if the given TimeStamp is valid. Otherwise, it will return
    74    *          the FetchStart timing value.
    75    */
    76   inline DOMHighResTimeStamp TimeStampToDOMHighResOrFetchStart(TimeStamp aStamp)
    77   {
    78     return (!aStamp.IsNull())
    79         ? TimeStampToDOMHighRes(aStamp)
    80         : FetchStartHighRes();
    81   }
    83   /**
    84    * The nsITimedChannel records an absolute timestamp for each event.
    85    * The nsDOMNavigationTiming will record the moment when the user landed on
    86    * the page. This is a window.performance unique timestamp, so it can be used
    87    * for all the events (navigation timing and resource timing events).
    88    *
    89    * The algorithm operates in 2 steps:
    90    * 1. The first step is to subtract the two timestamps: the argument (the
    91    * envet's timesramp) and the navigation start timestamp. This will result in
    92    * a relative timestamp of the event (relative to the navigation start -
    93    * window.performance.timing.navigationStart).
    94    * 2. The second step is to add any required offset (the mZeroTime). For now,
    95    * this offset value is either 0 (for the resource timing), or equal to
    96    * "performance.navigationStart" (for navigation timing).
    97    * For the resource timing, mZeroTime is set to 0, causing the result to be a
    98    * relative time.
    99    * For the navigation timing, mZeroTime is set to "performance.navigationStart"
   100    * causing the result be an absolute time.
   101    *
   102    * @param   aStamp
   103    *          The TimeStamp recorded for a specific event. This TimeStamp can't
   104    *          be null.
   105    * @return  number of milliseconds value as one of:
   106    * - relative to the navigation start time, time the user has landed on the
   107    * page
   108    * - an absolute wall clock time since the unix epoch
   109    */
   110   inline DOMHighResTimeStamp TimeStampToDOMHighRes(TimeStamp aStamp) const
   111   {
   112     MOZ_ASSERT(!aStamp.IsNull());
   113     mozilla::TimeDuration duration =
   114         aStamp - GetDOMTiming()->GetNavigationStartTimeStamp();
   115     return duration.ToMilliseconds() + mZeroTime;
   116   }
   118   virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
   120   // PerformanceNavigation WebIDL methods
   121   DOMTimeMilliSec NavigationStart() const {
   122     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   123       return 0;
   124     }
   125     return GetDOMTiming()->GetNavigationStart();
   126   }
   127   DOMTimeMilliSec UnloadEventStart() {
   128     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   129       return 0;
   130     }
   131     return GetDOMTiming()->GetUnloadEventStart();
   132   }
   133   DOMTimeMilliSec UnloadEventEnd() {
   134     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   135       return 0;
   136     }
   137     return GetDOMTiming()->GetUnloadEventEnd();
   138   }
   140   uint16_t GetRedirectCount() const;
   141   bool IsSameOriginAsReferral() const;
   142   void CheckRedirectCrossOrigin(nsIHttpChannel* aResourceChannel);
   144   // High resolution (used by resource timing)
   145   DOMHighResTimeStamp FetchStartHighRes();
   146   DOMHighResTimeStamp RedirectStartHighRes();
   147   DOMHighResTimeStamp RedirectEndHighRes();
   148   DOMHighResTimeStamp DomainLookupStartHighRes();
   149   DOMHighResTimeStamp DomainLookupEndHighRes();
   150   DOMHighResTimeStamp ConnectStartHighRes();
   151   DOMHighResTimeStamp ConnectEndHighRes();
   152   DOMHighResTimeStamp RequestStartHighRes();
   153   DOMHighResTimeStamp ResponseStartHighRes();
   154   DOMHighResTimeStamp ResponseEndHighRes();
   156   // Low resolution (used by navigation timing)
   157   DOMTimeMilliSec FetchStart();
   158   DOMTimeMilliSec RedirectStart();
   159   DOMTimeMilliSec RedirectEnd();
   160   DOMTimeMilliSec DomainLookupStart();
   161   DOMTimeMilliSec DomainLookupEnd();
   162   DOMTimeMilliSec ConnectStart();
   163   DOMTimeMilliSec ConnectEnd();
   164   DOMTimeMilliSec RequestStart();
   165   DOMTimeMilliSec ResponseStart();
   166   DOMTimeMilliSec ResponseEnd();
   168   DOMTimeMilliSec DomLoading() {
   169     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   170       return 0;
   171     }
   172     return GetDOMTiming()->GetDomLoading();
   173   }
   174   DOMTimeMilliSec DomInteractive() const {
   175     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   176       return 0;
   177     }
   178     return GetDOMTiming()->GetDomInteractive();
   179   }
   180   DOMTimeMilliSec DomContentLoadedEventStart() const {
   181     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   182       return 0;
   183     }
   184     return GetDOMTiming()->GetDomContentLoadedEventStart();
   185   }
   186   DOMTimeMilliSec DomContentLoadedEventEnd() const {
   187     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   188       return 0;
   189     }
   190     return GetDOMTiming()->GetDomContentLoadedEventEnd();
   191   }
   192   DOMTimeMilliSec DomComplete() const {
   193     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   194       return 0;
   195     }
   196     return GetDOMTiming()->GetDomComplete();
   197   }
   198   DOMTimeMilliSec LoadEventStart() const {
   199     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   200       return 0;
   201     }
   202     return GetDOMTiming()->GetLoadEventStart();
   203   }
   204   DOMTimeMilliSec LoadEventEnd() const {
   205     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
   206       return 0;
   207     }
   208     return GetDOMTiming()->GetLoadEventEnd();
   209   }
   211 private:
   212   ~nsPerformanceTiming();
   213   bool IsInitialized() const;
   214   nsRefPtr<nsPerformance> mPerformance;
   215   nsCOMPtr<nsITimedChannel> mChannel;
   216   DOMHighResTimeStamp mFetchStart;
   217   // This is an offset that will be added to each timing ([ms] resolution).
   218   // There are only 2 possible values: (1) logicaly equal to navigationStart
   219   // TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results
   220   // are relative to the navigation start).
   221   DOMHighResTimeStamp mZeroTime;
   222   bool mReportCrossOriginResources;
   223 };
   225 // Script "performance.navigation" object
   226 class nsPerformanceNavigation MOZ_FINAL : public nsWrapperCache
   227 {
   228 public:
   229   explicit nsPerformanceNavigation(nsPerformance* aPerformance);
   230   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsPerformanceNavigation)
   231   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsPerformanceNavigation)
   233   nsDOMNavigationTiming* GetDOMTiming() const;
   234   nsPerformanceTiming* GetPerformanceTiming() const;
   236   nsPerformance* GetParentObject() const
   237   {
   238     return mPerformance;
   239   }
   241   virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
   243   // PerformanceNavigation WebIDL methods
   244   uint16_t Type() const {
   245     return GetDOMTiming()->GetType();
   246   }
   247   uint16_t RedirectCount() const {
   248     return GetPerformanceTiming()->GetRedirectCount();
   249   }
   251 private:
   252   ~nsPerformanceNavigation();
   253   nsRefPtr<nsPerformance> mPerformance;
   254 };
   256 // Script "performance" object
   257 class nsPerformance MOZ_FINAL : public nsISupports,
   258                                 public nsWrapperCache
   259 {
   260 public:
   261   typedef mozilla::dom::PerformanceEntry PerformanceEntry;
   262   nsPerformance(nsIDOMWindow* aWindow,
   263                 nsDOMNavigationTiming* aDOMTiming,
   264                 nsITimedChannel* aChannel,
   265                 nsPerformance* aParentPerformance);
   267   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   268   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsPerformance)
   270   nsDOMNavigationTiming* GetDOMTiming() const
   271   {
   272     return mDOMTiming;
   273   }
   275   nsITimedChannel* GetChannel() const
   276   {
   277     return mChannel;
   278   }
   280   nsPerformance* GetParentPerformance() const
   281   {
   282     return mParentPerformance;
   283   }
   285   nsIDOMWindow* GetParentObject() const
   286   {
   287     return mWindow.get();
   288   }
   290   virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
   292   // Performance WebIDL methods
   293   DOMHighResTimeStamp Now();
   294   nsPerformanceTiming* Timing();
   295   nsPerformanceNavigation* Navigation();
   297   void GetEntries(nsTArray<nsRefPtr<PerformanceEntry> >& retval);
   298   void GetEntriesByType(const nsAString& entryType,
   299                         nsTArray<nsRefPtr<PerformanceEntry> >& retval);
   300   void GetEntriesByName(const nsAString& name,
   301                         const mozilla::dom::Optional< nsAString >& entryType,
   302                         nsTArray<nsRefPtr<PerformanceEntry> >& retval);
   303   void AddEntry(nsIHttpChannel* channel,
   304                 nsITimedChannel* timedChannel);
   305   void ClearResourceTimings();
   306   void SetResourceTimingBufferSize(uint64_t maxSize);
   308 private:
   309   ~nsPerformance();
   311   nsCOMPtr<nsIDOMWindow> mWindow;
   312   nsRefPtr<nsDOMNavigationTiming> mDOMTiming;
   313   nsCOMPtr<nsITimedChannel> mChannel;
   314   nsRefPtr<nsPerformanceTiming> mTiming;
   315   nsRefPtr<nsPerformanceNavigation> mNavigation;
   316   nsTArray<nsRefPtr<PerformanceEntry> > mEntries;
   317   nsRefPtr<nsPerformance> mParentPerformance;
   318   uint64_t mBufferSizeSet;
   319   uint64_t mPrimaryBufferSize;
   321   static const uint64_t kDefaultBufferSize = 150;
   323   // Helper classes
   324   class PerformanceEntryComparator {
   325     public:
   326       bool Equals(const PerformanceEntry* aElem1,
   327                   const PerformanceEntry* aElem2) const;
   328       bool LessThan(const PerformanceEntry* aElem1,
   329                     const PerformanceEntry* aElem2) const;
   330   };
   331 };
   333 inline nsDOMNavigationTiming*
   334 nsPerformanceNavigation::GetDOMTiming() const
   335 {
   336   return mPerformance->GetDOMTiming();
   337 }
   339 inline nsPerformanceTiming*
   340 nsPerformanceNavigation::GetPerformanceTiming() const
   341 {
   342   return mPerformance->Timing();
   343 }
   345 inline nsDOMNavigationTiming*
   346 nsPerformanceTiming::GetDOMTiming() const
   347 {
   348   return mPerformance->GetDOMTiming();
   349 }
   351 #endif /* nsPerformance_h___ */

mercurial