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

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

mercurial