blob: e216d890ee838e413914ba06731a98e500377391 [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 "third_party/blink/renderer/modules/battery/battery_manager.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/battery/battery_dispatcher.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
BatteryManager* BatteryManager::Create(ExecutionContext* context) {
BatteryManager* battery_manager =
MakeGarbageCollected<BatteryManager>(context);
battery_manager->PauseIfNeeded();
return battery_manager;
}
BatteryManager::~BatteryManager() = default;
BatteryManager::BatteryManager(ExecutionContext* context)
: PausableObject(context), PlatformEventController(To<Document>(context)) {}
ScriptPromise BatteryManager::StartRequest(ScriptState* script_state) {
if (!battery_property_) {
battery_property_ = MakeGarbageCollected<BatteryProperty>(
ExecutionContext::From(script_state), this, BatteryProperty::kReady);
// If the context is in a stopped state already, do not start updating.
if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) {
battery_property_->Resolve(this);
} else {
has_event_listener_ = true;
StartUpdating();
}
}
return battery_property_->Promise(script_state->World());
}
bool BatteryManager::charging() {
return battery_status_.Charging();
}
double BatteryManager::chargingTime() {
return battery_status_.charging_time();
}
double BatteryManager::dischargingTime() {
return battery_status_.discharging_time();
}
double BatteryManager::level() {
return battery_status_.Level();
}
void BatteryManager::DidUpdateData() {
DCHECK(battery_property_);
BatteryStatus old_status = battery_status_;
battery_status_ = *BatteryDispatcher::Instance().LatestData();
if (battery_property_->GetState() == ScriptPromisePropertyBase::kPending) {
battery_property_->Resolve(this);
return;
}
Document* document = To<Document>(GetExecutionContext());
DCHECK(document);
if (document->IsContextPaused() || document->IsContextDestroyed())
return;
if (battery_status_.Charging() != old_status.Charging())
DispatchEvent(*Event::Create(event_type_names::kChargingchange));
if (battery_status_.charging_time() != old_status.charging_time())
DispatchEvent(*Event::Create(event_type_names::kChargingtimechange));
if (battery_status_.discharging_time() != old_status.discharging_time())
DispatchEvent(*Event::Create(event_type_names::kDischargingtimechange));
if (battery_status_.Level() != old_status.Level())
DispatchEvent(*Event::Create(event_type_names::kLevelchange));
}
void BatteryManager::RegisterWithDispatcher() {
BatteryDispatcher::Instance().AddController(this);
}
void BatteryManager::UnregisterWithDispatcher() {
BatteryDispatcher::Instance().RemoveController(this);
}
bool BatteryManager::HasLastData() {
return BatteryDispatcher::Instance().LatestData();
}
void BatteryManager::ContextPaused(PauseState) {
has_event_listener_ = false;
StopUpdating();
}
void BatteryManager::ContextUnpaused() {
has_event_listener_ = true;
StartUpdating();
}
void BatteryManager::ContextDestroyed(ExecutionContext*) {
has_event_listener_ = false;
battery_property_ = nullptr;
StopUpdating();
}
bool BatteryManager::HasPendingActivity() const {
// Prevent V8 from garbage collecting the wrapper object if there are
// event listeners or pending promises attached to it.
return HasEventListeners() ||
(battery_property_ &&
battery_property_->GetState() == ScriptPromisePropertyBase::kPending);
}
void BatteryManager::Trace(blink::Visitor* visitor) {
visitor->Trace(battery_property_);
PlatformEventController::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
PausableObject::Trace(visitor);
}
} // namespace blink