blob: 98091ee107da8c198f2dc41ff00f041f29111f8f [file] [log] [blame]
// Copyright 2014 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 "modules/battery/BatteryManager.h"
#include "core/dom/Document.h"
#include "core/events/Event.h"
#include "modules/battery/BatteryDispatcher.h"
#include "modules/battery/BatteryStatus.h"
#include "platform/RuntimeEnabledFeatures.h"
namespace blink {
BatteryManager* BatteryManager::create(ExecutionContext* context)
{
BatteryManager* batteryManager = new BatteryManager(context);
batteryManager->suspendIfNeeded();
return batteryManager;
}
BatteryManager::~BatteryManager()
{
#if !ENABLE(OILPAN)
stopUpdating();
#endif
}
BatteryManager::BatteryManager(ExecutionContext* context)
: ActiveDOMObject(context)
, PlatformEventController(toDocument(context)->page())
, m_batteryStatus(BatteryStatus::create())
, m_state(NotStarted)
{
}
ScriptPromise BatteryManager::startRequest(ScriptState* scriptState)
{
if (m_state == Pending)
return m_resolver->promise();
m_resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = m_resolver->promise();
ASSERT(executionContext());
// If the context is in a stopped state already, do not start updating.
if (m_state == Resolved || executionContext()->activeDOMObjectsAreStopped()) {
// FIXME: Consider returning the same promise in this case. See crbug.com/385025.
m_state = Resolved;
m_resolver->resolve(this);
} else if (m_state == NotStarted) {
m_state = Pending;
m_hasEventListener = true;
startUpdating();
}
return promise;
}
bool BatteryManager::charging()
{
return m_batteryStatus->charging();
}
double BatteryManager::chargingTime()
{
return m_batteryStatus->chargingTime();
}
double BatteryManager::dischargingTime()
{
return m_batteryStatus->dischargingTime();
}
double BatteryManager::level()
{
return m_batteryStatus->level();
}
void BatteryManager::didUpdateData()
{
ASSERT(RuntimeEnabledFeatures::batteryStatusEnabled());
ASSERT(m_state != NotStarted);
BatteryStatus* oldStatus = m_batteryStatus;
m_batteryStatus = BatteryDispatcher::instance().latestData();
if (m_state == Pending) {
ASSERT(m_resolver);
m_state = Resolved;
m_resolver->resolve(this);
return;
}
Document* document = toDocument(executionContext());
ASSERT(document);
if (document->activeDOMObjectsAreSuspended() || document->activeDOMObjectsAreStopped())
return;
ASSERT(oldStatus);
if (m_batteryStatus->charging() != oldStatus->charging())
dispatchEvent(Event::create(EventTypeNames::chargingchange));
if (m_batteryStatus->chargingTime() != oldStatus->chargingTime())
dispatchEvent(Event::create(EventTypeNames::chargingtimechange));
if (m_batteryStatus->dischargingTime() != oldStatus->dischargingTime())
dispatchEvent(Event::create(EventTypeNames::dischargingtimechange));
if (m_batteryStatus->level() != oldStatus->level())
dispatchEvent(Event::create(EventTypeNames::levelchange));
}
void BatteryManager::registerWithDispatcher()
{
BatteryDispatcher::instance().addController(this);
}
void BatteryManager::unregisterWithDispatcher()
{
BatteryDispatcher::instance().removeController(this);
}
bool BatteryManager::hasLastData()
{
return BatteryDispatcher::instance().latestData();
}
void BatteryManager::suspend()
{
m_hasEventListener = false;
stopUpdating();
}
void BatteryManager::resume()
{
m_hasEventListener = true;
startUpdating();
}
void BatteryManager::stop()
{
m_hasEventListener = false;
m_state = NotStarted;
stopUpdating();
}
bool BatteryManager::hasPendingActivity() const
{
// Prevent V8 from garbage collecting the wrapper object if there are
// event listeners attached to it.
return m_state == Resolved && hasEventListeners();
}
void BatteryManager::trace(Visitor* visitor)
{
visitor->trace(m_batteryStatus);
PlatformEventController::trace(visitor);
EventTargetWithInlineData::trace(visitor);
}
} // namespace blink