blob: dda3d16216681dd78c6e2a0d61e57e152535d181 [file] [log] [blame]
// Copyright 2022 The Chromium OS 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 <base/bind.h>
#include <base/logging.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>
#include <string>
#include "federated/power_supply_training_condition.h"
#include "power_manager/proto_bindings/power_supply_properties.pb.h"
namespace federated {
namespace {
// TODO(alanlxl): use 90% for now.
constexpr double kMinimumAdequateBatteryLevel = 90.0;
void OnSignalConnected(const std::string& interface_name,
const std::string& signal_name,
bool success) {
if (!success) {
LOG(ERROR) << "Failed to connect to signal " << interface_name << ":"
<< signal_name << ".";
}
}
} // namespace
PowerSupplyTrainingCondition::PowerSupplyTrainingCondition(dbus::Bus* bus)
: powerd_dbus_proxy_(bus->GetObjectProxy(
power_manager::kPowerManagerServiceName,
dbus::ObjectPath(power_manager::kPowerManagerServicePath))),
enough_battery_(false),
weak_ptr_factory_(this) {
DCHECK_NE(powerd_dbus_proxy_, nullptr);
// Updates the battery status when receiving the kPowerSupplyPollSignal.
powerd_dbus_proxy_->ConnectToSignal(
power_manager::kPowerManagerInterface,
power_manager::kPowerSupplyPollSignal,
base::BindRepeating(&PowerSupplyTrainingCondition::OnPowerSupplyReceived,
weak_ptr_factory_.GetWeakPtr()),
base::BindOnce(&OnSignalConnected));
DVLOG(1) << "Construct PowerSupplyTrainingCondition";
}
bool PowerSupplyTrainingCondition::IsTrainingConditionSatisfied() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "PowerSupplyTrainingCondition::IsTrainingConditionSatisfied: "
<< enough_battery_;
return enough_battery_;
}
void PowerSupplyTrainingCondition::OnPowerSupplyReceived(
dbus::Signal* const signal) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (signal == nullptr) {
DVLOG(1) << "Received a null signal in OnPowerSupplyReceived.";
enough_battery_ = false;
return;
}
dbus::MessageReader reader(signal);
power_manager::PowerSupplyProperties power_supply_proto;
if (!reader.PopArrayOfBytesAsProto(&power_supply_proto)) {
DVLOG(1) << "Failed to read PowerSupplyProperties proto from dbus message.";
enough_battery_ = false;
return;
}
// When battery is enough, or the device is plugged-in.
enough_battery_ =
(power_supply_proto.has_battery_percent() &&
power_supply_proto.battery_percent() > kMinimumAdequateBatteryLevel) ||
(power_supply_proto.has_battery_state() &&
power_supply_proto.battery_state() !=
power_manager::PowerSupplyProperties::DISCHARGING);
}
} // namespace federated