PerformanceEventTiming.h (5050B)
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_PerformanceEventTiming_h___ 8 #define mozilla_dom_PerformanceEventTiming_h___ 9 10 #include "Performance.h" 11 #include "mozilla/EventForwards.h" 12 #include "mozilla/dom/PerformanceEntry.h" 13 #include "nsINode.h" 14 #include "nsIWeakReferenceUtils.h" 15 #include "nsRFPService.h" 16 17 namespace mozilla { 18 class WidgetEvent; 19 namespace dom { 20 21 class PerformanceEventTiming final 22 : public PerformanceEntry, 23 public LinkedListElement<RefPtr<PerformanceEventTiming>> { 24 public: 25 NS_DECL_ISUPPORTS_INHERITED 26 27 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PerformanceEventTiming, 28 PerformanceEntry) 29 30 static already_AddRefed<PerformanceEventTiming> TryGenerateEventTiming( 31 const EventTarget* aTarget, const WidgetEvent* aEvent); 32 33 already_AddRefed<PerformanceEventTiming> Clone() { 34 RefPtr<PerformanceEventTiming> eventTiming = 35 new PerformanceEventTiming(*this); 36 return eventTiming.forget(); 37 } 38 39 JSObject* WrapObject(JSContext* cx, 40 JS::Handle<JSObject*> aGivenProto) override; 41 42 DOMHighResTimeStamp ProcessingStart() const { 43 if (mCachedProcessingStart.isNothing()) { 44 mCachedProcessingStart.emplace(nsRFPService::ReduceTimePrecisionAsMSecs( 45 mProcessingStart, mPerformance->GetRandomTimelineSeed(), 46 mPerformance->GetRTPCallerType())); 47 } 48 return mCachedProcessingStart.value(); 49 } 50 51 DOMHighResTimeStamp ProcessingEnd() const { 52 if (mCachedProcessingEnd.isNothing()) { 53 mCachedProcessingEnd.emplace(nsRFPService::ReduceTimePrecisionAsMSecs( 54 mProcessingEnd, mPerformance->GetRandomTimelineSeed(), 55 mPerformance->GetRTPCallerType())); 56 } 57 return mCachedProcessingEnd.value(); 58 } 59 60 bool Cancelable() const { return mCancelable; } 61 62 uint64_t InteractionId() const { return mInteractionId.valueOr(0); } 63 bool HasKnownInteractionId() const { return mInteractionId.isSome(); } 64 65 void SetInteractionId(Maybe<uint64_t> aInteractionId) { 66 mInteractionId = aInteractionId; 67 } 68 69 void SetInteractionId(uint64_t aInteractionId) { 70 mInteractionId = Some(aInteractionId); 71 } 72 73 nsINode* GetTarget() const; 74 75 void SetDuration(const DOMHighResTimeStamp aDuration) { 76 mDuration = Some(aDuration); 77 } 78 79 // nsRFPService::ReduceTimePrecisionAsMSecs might causes 80 // some memory overhead, using the raw timestamp internally 81 // to avoid calling in unnecessarily. 82 Maybe<DOMHighResTimeStamp> RawDuration() const { return mDuration; } 83 84 DOMHighResTimeStamp Duration() const override { 85 if (mCachedDuration.isNothing()) { 86 // Round the duration to the nearest 8ms. 87 // https://w3c.github.io/event-timing/#set-event-timing-entry-duration 88 DOMHighResTimeStamp roundedDuration = 89 std::round(mDuration.valueOr(0) / 8) * 8; 90 mCachedDuration.emplace(nsRFPService::ReduceTimePrecisionAsMSecs( 91 roundedDuration, mPerformance->GetRandomTimelineSeed(), 92 mPerformance->GetRTPCallerType())); 93 } 94 return mCachedDuration.value(); 95 } 96 97 // Similar as RawDuration; Used to avoid calling 98 // nsRFPService::ReduceTimePrecisionAsMSecs unnecessarily. 99 DOMHighResTimeStamp RawStartTime() const { return mStartTime; } 100 101 DOMHighResTimeStamp StartTime() const override { 102 if (mCachedStartTime.isNothing()) { 103 mCachedStartTime.emplace(nsRFPService::ReduceTimePrecisionAsMSecs( 104 mStartTime, mPerformance->GetRandomTimelineSeed(), 105 mPerformance->GetRTPCallerType())); 106 } 107 return mCachedStartTime.value(); 108 } 109 110 bool ShouldAddEntryToBuffer(double aDuration) const; 111 bool ShouldAddEntryToObserverBuffer(PerformanceObserverInit&) const override; 112 113 void BufferEntryIfNeeded() override; 114 115 void FinalizeEventTiming(const WidgetEvent* aEvent); 116 117 EventMessage GetMessage() const { return mMessage; } 118 119 private: 120 PerformanceEventTiming(Performance* aPerformance, const nsAString& aName, 121 const TimeStamp& aStartTime, bool aIsCancelable, 122 EventMessage aMessage); 123 124 PerformanceEventTiming(const PerformanceEventTiming& aEventTimingEntry); 125 126 ~PerformanceEventTiming() = default; 127 128 RefPtr<Performance> mPerformance; 129 130 DOMHighResTimeStamp mProcessingStart; 131 mutable Maybe<DOMHighResTimeStamp> mCachedProcessingStart; 132 133 DOMHighResTimeStamp mProcessingEnd; 134 mutable Maybe<DOMHighResTimeStamp> mCachedProcessingEnd; 135 136 nsWeakPtr mTarget; 137 138 DOMHighResTimeStamp mStartTime; 139 mutable Maybe<DOMHighResTimeStamp> mCachedStartTime; 140 141 Maybe<DOMHighResTimeStamp> mDuration; 142 mutable Maybe<DOMHighResTimeStamp> mCachedDuration; 143 144 bool mCancelable; 145 146 Maybe<uint64_t> mInteractionId; 147 148 EventMessage mMessage; 149 }; 150 } // namespace dom 151 } // namespace mozilla 152 153 #endif