1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
// 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* executionContext,
PerformanceBase* performance,
PerformanceObserverCallback* callback) {
ASSERT(isMainThread());
return new PerformanceObserver(executionContext, performance, callback);
}
PerformanceObserver::PerformanceObserver(ExecutionContext* executionContext,
PerformanceBase* performance,
PerformanceObserverCallback* callback)
: m_executionContext(executionContext),
m_callback(this, callback),
m_performance(performance),
m_filterOptions(PerformanceEntry::Invalid),
m_isRegistered(false) {}
void PerformanceObserver::observe(const PerformanceObserverInit& observerInit,
ExceptionState& exceptionState) {
if (!m_performance) {
exceptionState.throwTypeError(
"Window may be destroyed? Performance target is invalid.");
return;
}
PerformanceEntryTypeMask entryTypes = PerformanceEntry::Invalid;
if (observerInit.hasEntryTypes() && observerInit.entryTypes().size()) {
const Vector<String>& sequence = observerInit.entryTypes();
for (const auto& entryTypeString : sequence)
entryTypes |= PerformanceEntry::toEntryTypeEnum(entryTypeString);
}
if (entryTypes == PerformanceEntry::Invalid) {
exceptionState.throwTypeError(
"A Performance Observer MUST have at least one valid entryType in its "
"entryTypes attribute.");
return;
}
m_filterOptions = entryTypes;
if (m_isRegistered)
m_performance->updatePerformanceObserverFilterOptions();
else
m_performance->registerPerformanceObserver(*this);
m_isRegistered = true;
}
void PerformanceObserver::disconnect() {
if (m_performance) {
m_performance->unregisterPerformanceObserver(*this);
}
m_performanceEntries.clear();
m_isRegistered = false;
}
void PerformanceObserver::enqueuePerformanceEntry(PerformanceEntry& entry) {
ASSERT(isMainThread());
m_performanceEntries.push_back(&entry);
if (m_performance)
m_performance->activateObserver(*this);
}
bool PerformanceObserver::shouldBeSuspended() const {
return m_executionContext->isContextSuspended();
}
void PerformanceObserver::deliver() {
ASSERT(!shouldBeSuspended());
if (m_performanceEntries.isEmpty())
return;
PerformanceEntryVector performanceEntries;
performanceEntries.swap(m_performanceEntries);
PerformanceObserverEntryList* entryList =
new PerformanceObserverEntryList(performanceEntries);
m_callback->call(this, entryList, this);
}
DEFINE_TRACE(PerformanceObserver) {
visitor->trace(m_executionContext);
visitor->trace(m_callback);
visitor->trace(m_performance);
visitor->trace(m_performanceEntries);
}
DEFINE_TRACE_WRAPPERS(PerformanceObserver) {
visitor->traceWrappers(m_callback);
}
} // namespace blink
|