blob: ba81f131d808df3c2711a9028f04c5cd49a847d8 [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 "config.h"
#include "core/timing/PerformanceObserver.h"
#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "core/timing/PerformanceBase.h"
#include "core/timing/PerformanceEntry.h"
#include "core/timing/PerformanceObserverCallback.h"
#include "core/timing/PerformanceObserverEntryList.h"
#include "core/timing/PerformanceObserverInit.h"
#include "platform/Timer.h"
#include "wtf/MainThread.h"
#include <algorithm>
namespace blink {
PerformanceObserver* PerformanceObserver::create(PerformanceBase* performance, PerformanceObserverCallback* callback)
{
ASSERT(isMainThread());
return new PerformanceObserver(performance, callback);
}
PerformanceObserver::PerformanceObserver(PerformanceBase* performance, PerformanceObserverCallback* callback)
: m_callback(callback)
, m_performance(performance)
, m_filterOptions(PerformanceEntry::Invalid)
, m_isRegistered(false)
{
}
PerformanceObserver::~PerformanceObserver()
{
}
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 a non-empty entryTypes attribute.");
return;
}
m_filterOptions = entryTypes;
if (m_isRegistered)
m_performance->updatePerformanceObserverFilterOptions();
else
m_performance->registerPerformanceObserver(*this);
m_isRegistered = true;
}
void PerformanceObserver::disconnect()
{
m_performanceEntries.clear();
if (m_performance)
m_performance->unregisterPerformanceObserver(*this);
m_isRegistered = false;
}
void PerformanceObserver::enqueuePerformanceEntry(PerformanceEntry& entry)
{
ASSERT(isMainThread());
m_performanceEntries.append(&entry);
if (m_performance)
m_performance->activateObserver(*this);
}
bool PerformanceObserver::shouldBeSuspended() const
{
return m_callback->executionContext() && m_callback->executionContext()->activeDOMObjectsAreSuspended();
}
void PerformanceObserver::deliver()
{
ASSERT(!shouldBeSuspended());
if (m_performanceEntries.isEmpty())
return;
PerformanceEntryVector performanceEntries;
performanceEntries.swap(m_performanceEntries);
Member<PerformanceObserverEntryList> entryList(new PerformanceObserverEntryList(performanceEntries));
m_callback->handleEvent(entryList, this);
}
DEFINE_TRACE(PerformanceObserver)
{
visitor->trace(m_callback);
visitor->trace(m_performance);
visitor->trace(m_performanceEntries);
}
} // namespace blink