blob: 35f4c461b96d7ac9df152e8143652941b019b4a9 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/timing/PerformanceObserver.h"
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/PerformanceObserverCallback.h"
#include "core/dom/ExecutionContext.h"
#include "core/timing/PerformanceBase.h"
#include "core/timing/PerformanceEntry.h"
#include "core/timing/PerformanceObserverEntryList.h"
#include "core/timing/PerformanceObserverInit.h"
#include "platform/Timer.h"
#include <algorithm>
namespace blink {
PerformanceObserver* PerformanceObserver::Create(
ExecutionContext* execution_context,
PerformanceBase* performance,
PerformanceObserverCallback* callback) {
DCHECK(IsMainThread());
return new PerformanceObserver(execution_context, performance, callback);
}
PerformanceObserver::PerformanceObserver(ExecutionContext* execution_context,
PerformanceBase* performance,
PerformanceObserverCallback* callback)
: execution_context_(execution_context),
callback_(this, callback),
performance_(performance),
filter_options_(PerformanceEntry::kInvalid),
is_registered_(false) {}
void PerformanceObserver::observe(const PerformanceObserverInit& observer_init,
ExceptionState& exception_state) {
if (!performance_) {
exception_state.ThrowTypeError(
"Window may be destroyed? Performance target is invalid.");
return;
}
PerformanceEntryTypeMask entry_types = PerformanceEntry::kInvalid;
if (observer_init.hasEntryTypes() && observer_init.entryTypes().size()) {
const Vector<String>& sequence = observer_init.entryTypes();
for (const auto& entry_type_string : sequence)
entry_types |= PerformanceEntry::ToEntryTypeEnum(entry_type_string);
}
if (entry_types == PerformanceEntry::kInvalid) {
exception_state.ThrowTypeError(
"A Performance Observer MUST have at least one valid entryType in its "
"entryTypes attribute.");
return;
}
filter_options_ = entry_types;
if (is_registered_)
performance_->UpdatePerformanceObserverFilterOptions();
else
performance_->RegisterPerformanceObserver(*this);
is_registered_ = true;
}
void PerformanceObserver::disconnect() {
if (performance_) {
performance_->UnregisterPerformanceObserver(*this);
}
performance_entries_.clear();
is_registered_ = false;
}
void PerformanceObserver::EnqueuePerformanceEntry(PerformanceEntry& entry) {
DCHECK(IsMainThread());
performance_entries_.push_back(&entry);
if (performance_)
performance_->ActivateObserver(*this);
}
bool PerformanceObserver::ShouldBeSuspended() const {
return execution_context_->IsContextSuspended();
}
void PerformanceObserver::Deliver() {
DCHECK(!ShouldBeSuspended());
if (performance_entries_.IsEmpty())
return;
PerformanceEntryVector performance_entries;
performance_entries.swap(performance_entries_);
PerformanceObserverEntryList* entry_list =
new PerformanceObserverEntryList(performance_entries);
callback_->call(this, entry_list, this);
}
DEFINE_TRACE(PerformanceObserver) {
visitor->Trace(execution_context_);
visitor->Trace(callback_);
visitor->Trace(performance_);
visitor->Trace(performance_entries_);
}
DEFINE_TRACE_WRAPPERS(PerformanceObserver) {
visitor->TraceWrappers(callback_);
}
} // namespace blink