blob: cff81f7c5f5391caf46bca4108a767efcd1e9e17 [file] [log] [blame]
// Copyright 2021 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 "chrome/browser/metrics/power/battery_level_provider.h"
BatteryLevelProvider::BatteryState::BatteryState(
size_t interface_count,
size_t battery_count,
base::Optional<double> charge_level,
bool on_battery,
base::TimeTicks capture_time)
: interface_count(interface_count),
battery_count(battery_count),
charge_level(charge_level),
on_battery(on_battery),
capture_time(capture_time) {}
BatteryLevelProvider::BatteryState::BatteryState(const BatteryState&) = default;
BatteryLevelProvider::BatteryInterface::BatteryInterface(
bool battery_present_in)
: battery_present(battery_present_in) {}
BatteryLevelProvider::BatteryInterface::BatteryInterface(
const BatteryDetails& details_in)
: battery_present(true), details(details_in) {}
BatteryLevelProvider::BatteryInterface::BatteryInterface(
const BatteryInterface&) = default;
BatteryLevelProvider::BatteryState BatteryLevelProvider::MakeBatteryState(
const std::vector<BatteryInterface>& battery_interfaces) {
const base::TimeTicks capture_time = base::TimeTicks::Now();
uint64_t total_max_capacity = 0;
uint64_t total_current_capacity = 0;
bool on_battery = true;
bool any_capacity_invalid = false;
size_t battery_count = 0;
for (auto& interface : battery_interfaces) {
// The interface might have no battery.
if (!interface.battery_present)
continue;
// Counts the number of interfaces that has |battery_present == true|.
++battery_count;
// The state is considered on battery power only if all of the batteries
// are explicitly marked as not connected.
if (!interface.details.has_value() || interface.details->is_connected)
on_battery = false;
if (!interface.details.has_value()) {
any_capacity_invalid = true;
continue;
}
// Total capacity is averaged across all the batteries.
total_current_capacity += interface.details->current_capacity;
total_max_capacity += interface.details->full_charged_capacity;
}
base::Optional<double> charge_level;
// Avoid invalid division.
if (!any_capacity_invalid && total_max_capacity != 0) {
charge_level = static_cast<double>(total_current_capacity) /
static_cast<double>(total_max_capacity);
}
// If no battery was detected, we consider the system to be drawing power
// from an external power source, which is different from |on_battery|'s
// default value.
if (battery_count == 0)
on_battery = false;
return {battery_interfaces.size(), battery_count, charge_level, on_battery,
capture_time};
}