blob: 65898ea8131c28292b4bfea0cfb6456d4dd75cf3 [file] [log] [blame]
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
* Copyright (C) 2012 Intel Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_H_
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_double.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/core/timing/performance_entry.h"
#include "third_party/blink/renderer/core/timing/performance_navigation_timing.h"
#include "third_party/blink/renderer/core/timing/performance_paint_timing.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace base {
class Clock;
class TickClock;
} // namespace base
namespace blink {
class PerformanceMarkOptions;
class EventCounts;
class ExceptionState;
class LargestContentfulPaint;
class LayoutShift;
class MemoryInfo;
class Node;
class PerformanceElementTiming;
class PerformanceEventTiming;
class PerformanceMark;
class PerformanceMeasure;
class PerformanceNavigation;
class PerformanceObserver;
class PerformanceTiming;
class ProfilerInitOptions;
class ResourceResponse;
class ResourceTimingInfo;
class ScriptPromise;
class ScriptState;
class ScriptValue;
class SecurityOrigin;
class StringOrPerformanceMeasureOptions;
class UserTiming;
class V8ObjectBuilder;
using PerformanceEntryVector = HeapVector<Member<PerformanceEntry>>;
using PerformanceEntryDeque = HeapDeque<Member<PerformanceEntry>>;
class CORE_EXPORT Performance : public EventTargetWithInlineData {
DEFINE_WRAPPERTYPEINFO();
public:
~Performance() override;
const AtomicString& InterfaceName() const override;
// Overriden by WindowPerformance but not by WorkerPerformance.
virtual PerformanceTiming* timing() const;
virtual PerformanceNavigation* navigation() const;
virtual MemoryInfo* memory() const;
virtual ScriptPromise measureUserAgentSpecificMemory(
ScriptState*,
ExceptionState& exception_state) const;
virtual EventCounts* eventCounts();
// Reduce the resolution to prevent timing attacks. See:
// http://www.w3.org/TR/hr-time-2/#privacy-security
static double ClampTimeResolution(double time_seconds);
static DOMHighResTimeStamp MonotonicTimeToDOMHighResTimeStamp(
base::TimeTicks time_origin,
base::TimeTicks monotonic_time,
bool allow_negative_value);
static base::TimeDelta MonotonicTimeToTimeDelta(
base::TimeTicks time_origin,
base::TimeTicks monotonic_time,
bool allow_negative_value);
// Translate given platform monotonic time in seconds into a high resolution
// DOMHighResTimeStamp in milliseconds. The result timestamp is relative to
// document's time origin and has a time resolution that is safe for
// exposing to web.
DOMHighResTimeStamp MonotonicTimeToDOMHighResTimeStamp(base::TimeTicks) const;
DOMHighResTimeStamp now() const;
// Translate given platform monotonic time in seconds into base::TimeDelta.
// The result timestamp is relative to document's time origin and is
// equivalent to the timestamp returned by the function
// MonotonicTimeToDOMHighResTimeStamp.
base::TimeDelta MonotonicTimeToTimeDelta(base::TimeTicks) const;
// High Resolution Time Level 3 timeOrigin.
// (https://www.w3.org/TR/hr-time-3/#dom-performance-timeorigin)
DOMHighResTimeStamp timeOrigin() const;
// Internal getter method for the time origin value.
double GetTimeOrigin() const {
return time_origin_.since_origin().InSecondsF();
}
PerformanceEntryVector getEntries();
// Get BufferedEntriesByType will return all entries in the buffer regardless
// of whether they are exposed in the Performance Timeline. getEntriesByType
// will only return all entries for existing types in
// PerformanceEntry.IsValidTimelineEntryType.
PerformanceEntryVector getBufferedEntriesByType(
const AtomicString& entry_type);
PerformanceEntryVector getEntriesByType(const AtomicString& entry_type);
PerformanceEntryVector getEntriesByName(
const AtomicString& name,
const AtomicString& entry_type = g_null_atom);
void clearResourceTimings();
void setResourceTimingBufferSize(unsigned);
DEFINE_ATTRIBUTE_EVENT_LISTENER(resourcetimingbufferfull,
kResourcetimingbufferfull)
void AddLongTaskTiming(base::TimeTicks start_time,
base::TimeTicks end_time,
const AtomicString& name,
const AtomicString& container_type,
const AtomicString& container_src,
const AtomicString& container_id,
const AtomicString& container_name);
// Generates and add a performance entry for the given ResourceTimingInfo.
// |overridden_initiator_type| allows the initiator type to be overridden to
// the frame element name for the main resource.
void GenerateAndAddResourceTiming(
const ResourceTimingInfo&,
const AtomicString& overridden_initiator_type = g_null_atom);
// Generates timing info suitable for appending to the performance entries of
// a context with |origin|. This should be rarely used; most callsites should
// prefer the convenience method |GenerateAndAddResourceTiming()|.
static mojom::blink::ResourceTimingInfoPtr GenerateResourceTiming(
const SecurityOrigin& destination_origin,
const ResourceTimingInfo&,
ExecutionContext& context_for_use_counter);
void AddResourceTiming(
mojom::blink::ResourceTimingInfoPtr,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver,
ExecutionContext* context);
void NotifyNavigationTimingToObservers();
void AddFirstPaintTiming(base::TimeTicks start_time);
void AddFirstContentfulPaintTiming(base::TimeTicks start_time);
bool IsElementTimingBufferFull() const;
void AddElementTimingBuffer(PerformanceElementTiming&);
bool IsEventTimingBufferFull() const;
void AddEventTimingBuffer(PerformanceEventTiming&);
void AddLayoutShiftBuffer(LayoutShift&);
void AddLargestContentfulPaint(LargestContentfulPaint*);
PerformanceMark* mark(ScriptState*,
const AtomicString& mark_name,
PerformanceMarkOptions* mark_options,
ExceptionState&);
void clearMarks(const AtomicString& mark_name);
void clearMarks() { return clearMarks(AtomicString()); }
// This enum is used to index different possible strings for for UMA enum
// histogram. New enum values can be added, but existing enums must never be
// renumbered or deleted and reused.
// This enum should be consistent with MeasureParameterType
// in tools/metrics/histograms/enums.xml.
enum class MeasureParameterType {
kObjectObject = 0,
// 1 to 8, 13 to 25 are navigation-timing types.
kUnloadEventStart = 1,
kUnloadEventEnd = 2,
kDomInteractive = 3,
kDomContentLoadedEventStart = 4,
kDomContentLoadedEventEnd = 5,
kDomComplete = 6,
kLoadEventStart = 7,
kLoadEventEnd = 8,
kOther = 9,
kUndefinedOrNull = 10,
// Intentionally leaves out kNumber = 11 since number has been casted to
// string when users pass number into the API.
kUnprovided = 12,
kNavigationStart = 13,
kRedirectStart = 14,
kRedirectEnd = 15,
kFetchStart = 16,
kDomainLookupStart = 17,
kDomainLookupEnd = 18,
kConnectStart = 19,
kConnectEnd = 20,
kSecureConnectionStart = 21,
kRequestStart = 22,
kResponseStart = 23,
kResponseEnd = 24,
kDomLoading = 25,
kMaxValue = kDomLoading
};
UserTiming& GetUserTiming();
PerformanceMeasure* measure(ScriptState*,
const AtomicString& measure_name,
ExceptionState&);
PerformanceMeasure* measure(
ScriptState*,
const AtomicString& measure_name,
const StringOrPerformanceMeasureOptions& start_or_options,
ExceptionState&);
PerformanceMeasure* measure(
ScriptState*,
const AtomicString& measure_name,
const StringOrPerformanceMeasureOptions& start_or_options,
const String& end,
ExceptionState&);
void clearMeasures(const AtomicString& measure_name);
void clearMeasures() { return clearMeasures(AtomicString()); }
ScriptPromise profile(ScriptState*,
const ProfilerInitOptions*,
ExceptionState&);
void UnregisterPerformanceObserver(PerformanceObserver&);
void RegisterPerformanceObserver(PerformanceObserver&);
void UpdatePerformanceObserverFilterOptions();
void ActivateObserver(PerformanceObserver&);
void SuspendObserver(PerformanceObserver&);
bool HasObserverFor(PerformanceEntry::EntryType) const;
// Checks whether the single ResourceResponse passes the Timing-Allow-Origin
// check. The first parameter is the ResourceResponse being checked. The
// second parameter is the next ResourceResponse in the redirect chain, or is
// equal to the first parameter if there is no such response. This parameter
// is only introduced temporarily to enable computing a UseCounter within this
// method. The first bool parameter is
// https://fetch.spec.whatwg.org/#concept-request-response-tainting, while the
// second bool is
// https://fetch.spec.whatwg.org/#concept-request-tainted-origin.
// The next ResourceResponse and tainted origin flag are currently only being
// used in a UseCounter.
static bool PassesTimingAllowCheck(const ResourceResponse& response,
const ResourceResponse& next_response,
const SecurityOrigin&,
ExecutionContext*,
bool* response_tainting_not_basic,
bool* tainted_origin_flag);
static bool AllowsTimingRedirect(const Vector<ResourceResponse>&,
const ResourceResponse&,
const SecurityOrigin&,
ExecutionContext*);
// Determine whether a given Node can be exposed via a Web Perf API.
static bool CanExposeNode(Node*);
ScriptValue toJSONForBinding(ScriptState*) const;
void Trace(Visitor*) const override;
// The caller owns the |clock|.
void SetClocksForTesting(const base::Clock* clock,
const base::TickClock* tick_clock);
void ResetTimeOriginForTesting(base::TimeTicks time_origin);
private:
void AddPaintTiming(PerformancePaintTiming::PaintType,
base::TimeTicks start_time);
PerformanceMeasure* MeasureInternal(
ScriptState*,
const AtomicString& measure_name,
const StringOrPerformanceMeasureOptions& start,
base::Optional<String> end_mark,
ExceptionState&);
PerformanceMeasure* MeasureWithDetail(
ScriptState*,
const AtomicString& measure_name,
const base::Optional<StringOrDouble>& start,
const base::Optional<double>& duration,
const base::Optional<StringOrDouble>& end,
const ScriptValue& detail,
ExceptionState&);
void CopySecondaryBuffer();
PerformanceEntryVector getEntriesByTypeInternal(
PerformanceEntry::EntryType type);
void MeasureMemoryExperimentTimerFired(TimerBase*);
protected:
Performance(base::TimeTicks time_origin,
scoped_refptr<base::SingleThreadTaskRunner>);
// Expect WindowPerformance to override this method,
// WorkerPerformance doesn't have to override this.
virtual PerformanceNavigationTiming* CreateNavigationTimingInstance() {
return nullptr;
}
bool CanAddResourceTimingEntry();
void FireResourceTimingBufferFull(TimerBase*);
void NotifyObserversOfEntry(PerformanceEntry&) const;
void DeliverObservationsTimerFired(TimerBase*);
virtual void BuildJSONValue(V8ObjectBuilder&) const;
PerformanceEntryVector resource_timing_buffer_;
// The secondary RT buffer, used to store incoming entries after the main
// buffer is full, until the resourcetimingbufferfull event fires.
PerformanceEntryDeque resource_timing_secondary_buffer_;
unsigned resource_timing_buffer_size_limit_;
// A flag indicating that the buffer became full, the appropriate event was
// queued, but haven't yet fired.
bool resource_timing_buffer_full_event_pending_ = false;
PerformanceEntryVector event_timing_buffer_;
unsigned event_timing_buffer_max_size_;
PerformanceEntryVector element_timing_buffer_;
unsigned element_timing_buffer_max_size_;
PerformanceEntryVector layout_shift_buffer_;
PerformanceEntryVector largest_contentful_paint_buffer_;
PerformanceEntryVector longtask_buffer_;
PerformanceEntryVector visibility_state_buffer_;
Member<PerformanceEntry> navigation_timing_;
Member<UserTiming> user_timing_;
Member<PerformanceEntry> first_paint_timing_;
Member<PerformanceEntry> first_contentful_paint_timing_;
Member<PerformanceEventTiming> first_input_timing_;
base::TimeTicks time_origin_;
DOMHighResTimeStamp unix_at_zero_monotonic_;
const base::TickClock* tick_clock_;
PerformanceEntryTypeMask observer_filter_options_;
HeapLinkedHashSet<Member<PerformanceObserver>> observers_;
HeapLinkedHashSet<Member<PerformanceObserver>> active_observers_;
HeapLinkedHashSet<Member<PerformanceObserver>> suspended_observers_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
HeapTaskRunnerTimer<Performance> deliver_observations_timer_;
HeapTaskRunnerTimer<Performance> resource_timing_buffer_full_timer_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_H_