// Copyright (c) 2012 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 "power_manager/powerd/system/power_supply.h"

#include <cmath>

#include <base/bind.h>
#include <base/file_util.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>

#include "power_manager/common/clock.h"
#include "power_manager/common/power_constants.h"
#include "power_manager/common/prefs.h"
#include "power_manager/common/util.h"
#include "power_manager/powerd/system/udev.h"

namespace power_manager {
namespace system {

namespace {

// sysfs reports only integer values.  For non-integral values, it scales them
// up by 10^6.  This factor scales them back down accordingly.
const double kDoubleScaleFactor = 0.000001;

// Default time interval between polls, in milliseconds.
const int kDefaultPollMs = 30000;

// Default values for |battery_stabilized_after_*_delay_|, in milliseconds.
const int kDefaultBatteryStabilizedAfterStartupDelayMs = 5000;
const int kDefaultBatteryStabilizedAfterLinePowerConnectedDelayMs = 5000;
const int kDefaultBatteryStabilizedAfterLinePowerDisconnectedDelayMs = 5000;
const int kDefaultBatteryStabilizedAfterResumeDelayMs = 5000;

// Different power supply types reported by the kernel.
const char kBatteryType[] = "Battery";
const char kMainsType[] = "Mains";

// Battery states reported by the kernel. This is not the full set of
// possible states; see drivers/power/power_supply_sysfs.c.
const char kBatteryStatusCharging[] = "Charging";
const char kBatteryStatusFull[] = "Full";

// String value reported in the line power "model_name" file if an original
// spring AC charger is connected.
const char kOriginalSpringChargerModelName[] = "0x17";

// String value reported in the line power "model_name" file if the EC firmware
// is outdated and is incapable of reporting the model.
const char kOldFirmwareModelName[] = "0x00";

// Reads the contents of |filename| within |directory| into |out|, trimming
// trailing whitespace.  Returns true on success.
bool ReadAndTrimString(const base::FilePath& directory,
                       const std::string& filename,
                       std::string* out) {
  if (!base::ReadFileToString(directory.Append(filename), out))
    return false;

  base::TrimWhitespaceASCII(*out, base::TRIM_TRAILING, out);
  return true;
}

// Reads a 64-bit integer value from a file and returns true on success.
bool ReadInt64(const base::FilePath& directory,
               const std::string& filename,
               int64* out) {
  std::string buffer;
  if (!ReadAndTrimString(directory, filename, &buffer))
    return false;
  return base::StringToInt64(buffer, out);
}

// Reads an integer value and scales it to a double (see |kDoubleScaleFactor|.
// Returns 0.0 on failure.
double ReadScaledDouble(const base::FilePath& directory,
                        const std::string& filename) {
  int64 value = 0;
  return ReadInt64(directory, filename, &value) ?
      kDoubleScaleFactor * value : 0.0;
}

// Returns true if |type|, a power supply type read from a "type" file in
// sysfs, indicates USB.
bool IsUsbType(const std::string& type) {
  // These are defined in drivers/power/power_supply_sysfs.c in the kernel.
  return type == "USB" || type == "USB_DCP" || type == "USB_CDP" ||
      type == "USB_ACA";
}

// Returns true if |model_name|, a line power source's model, indicates that an
// original spring AC charger is connected. Also assumes that an original spring
// AC charger is connected if the firmware is outdated and doesn't report the
// model.
bool IsOriginalSpringCharger(const std::string& model_name) {
  return model_name == kOriginalSpringChargerModelName ||
      model_name == kOldFirmwareModelName;
}

}  // namespace

base::TimeTicks PowerSupply::TestApi::GetCurrentTime() const {
  return power_supply_->clock_->GetCurrentTime();
}

void PowerSupply::TestApi::SetCurrentTime(base::TimeTicks now) {
  power_supply_->clock_->set_current_time_for_testing(now);
}

void PowerSupply::TestApi::AdvanceTime(base::TimeDelta interval) {
  power_supply_->clock_->set_current_time_for_testing(
      GetCurrentTime() + interval);
}

bool PowerSupply::TestApi::TriggerPollTimeout() {
  if (!power_supply_->poll_timer_.IsRunning())
    return false;

  power_supply_->poll_timer_.Stop();
  power_supply_->HandlePollTimeout();
  return true;
}

const char PowerSupply::kUdevSubsystem[] = "power_supply";
const int PowerSupply::kMaxCurrentSamples = 5;
const int PowerSupply::kMaxChargeSamples = 5;
const int PowerSupply::kObservedBatteryChargeRateMinMs = kDefaultPollMs;
const int PowerSupply::kBatteryStabilizedSlackMs = 50;
const double PowerSupply::kLowBatteryShutdownSafetyPercent = 5.0;

PowerSupply::PowerSupply()
    : prefs_(NULL),
      udev_(NULL),
      clock_(new Clock),
      power_status_initialized_(false),
      low_battery_shutdown_percent_(0.0),
      is_suspended_(false),
      current_samples_(kMaxCurrentSamples),
      charge_samples_(kMaxChargeSamples),
      full_factor_(1.0) {
}

PowerSupply::~PowerSupply() {
  if (udev_)
    udev_->RemoveObserver(kUdevSubsystem, this);
}

void PowerSupply::Init(const base::FilePath& power_supply_path,
                       PrefsInterface* prefs,
                       UdevInterface* udev) {
  udev_ = udev;
  udev_->AddObserver(kUdevSubsystem, this);

  prefs_ = prefs;
  power_supply_path_ = power_supply_path;
  GetPowerSupplyPaths();

  poll_delay_ = GetMsPref(kBatteryPollIntervalPref, kDefaultPollMs);
  battery_stabilized_after_startup_delay_ = GetMsPref(
      kBatteryStabilizedAfterStartupMsPref,
      kDefaultBatteryStabilizedAfterStartupDelayMs);
  battery_stabilized_after_line_power_connected_delay_ = GetMsPref(
      kBatteryStabilizedAfterLinePowerConnectedMsPref,
      kDefaultBatteryStabilizedAfterLinePowerConnectedDelayMs);
  battery_stabilized_after_line_power_disconnected_delay_ = GetMsPref(
      kBatteryStabilizedAfterLinePowerDisconnectedMsPref,
      kDefaultBatteryStabilizedAfterLinePowerDisconnectedDelayMs);
  battery_stabilized_after_resume_delay_ = GetMsPref(
      kBatteryStabilizedAfterResumeMsPref,
      kDefaultBatteryStabilizedAfterResumeDelayMs);

  prefs_->GetDouble(kPowerSupplyFullFactorPref, &full_factor_);
  full_factor_ = std::min(std::max(kEpsilon, full_factor_), 1.0);

  int64 shutdown_time_sec = 0;
  if (prefs_->GetInt64(kLowBatteryShutdownTimePref, &shutdown_time_sec)) {
    low_battery_shutdown_time_ =
        base::TimeDelta::FromSeconds(shutdown_time_sec);
  }

  // The percentage-based threshold takes precedence over the time-based
  // threshold.
  if (prefs_->GetDouble(kLowBatteryShutdownPercentPref,
                        &low_battery_shutdown_percent_)) {
    low_battery_shutdown_time_ = base::TimeDelta();
  }

  // This log message is needed by the power_LoadTest autotest.
  LOG(INFO) << "Using low battery time threshold of "
            << low_battery_shutdown_time_.InSeconds()
            << " secs and using low battery percent threshold of "
            << low_battery_shutdown_percent_;

  // This defers the initial recording of samples until the current has
  // stabilized.
  ResetBatterySamples(battery_stabilized_after_startup_delay_);
  SchedulePoll();
}

void PowerSupply::AddObserver(PowerSupplyObserver* observer) {
  DCHECK(observer);
  observers_.AddObserver(observer);
}

void PowerSupply::RemoveObserver(PowerSupplyObserver* observer) {
  DCHECK(observer);
  observers_.RemoveObserver(observer);
}

bool PowerSupply::RefreshImmediately() {
  const bool success = UpdatePowerStatus();
  if (!is_suspended_)
    SchedulePoll();
  if (success) {
    notify_observers_task_.Reset(
        base::Bind(&PowerSupply::NotifyObservers, base::Unretained(this)));
    base::MessageLoop::current()->PostTask(
        FROM_HERE, notify_observers_task_.callback());
  }
  return success;
}

void PowerSupply::SetSuspended(bool suspended) {
  if (is_suspended_ == suspended)
    return;

  is_suspended_ = suspended;
  if (is_suspended_) {
    VLOG(1) << "Stopping polling due to suspend";
    poll_timer_.Stop();
    current_poll_delay_for_testing_ = base::TimeDelta();
  } else {
    ResetBatterySamples(battery_stabilized_after_resume_delay_);
    RefreshImmediately();
  }
}

void PowerSupply::OnUdevEvent(const std::string& subsystem,
                              const std::string& sysname,
                              UdevObserver::Action action) {
  VLOG(1) << "Heard about udev event";
  if (!is_suspended_)
    RefreshImmediately();
}

base::TimeDelta PowerSupply::GetMsPref(const std::string& pref_name,
                                       int64 default_duration_ms) const {
  prefs_->GetInt64(pref_name, &default_duration_ms);
  return base::TimeDelta::FromMilliseconds(default_duration_ms);
}

void PowerSupply::ResetBatterySamples(base::TimeDelta stabilized_delay) {
  current_samples_.Clear();
  charge_samples_.Clear();

  const base::TimeTicks now = clock_->GetCurrentTime();
  battery_stabilized_timestamp_ =
      std::max(battery_stabilized_timestamp_, now + stabilized_delay);
  VLOG(1) << "Waiting "
          << (battery_stabilized_timestamp_ - now).InMilliseconds()
          << " ms for battery current and charge to stabilize";
}

bool PowerSupply::UpdatePowerStatus() {
  VLOG(1) << "Updating power status";
  PowerStatus status;

  if (battery_path_.empty() || line_power_path_.empty())
    GetPowerSupplyPaths();

  status.line_power_path = line_power_path_.value();
  status.battery_path = battery_path_.value();

  std::string battery_status_string;
  if (base::PathExists(battery_path_)) {
    int64 present_value = 0;
    ReadInt64(battery_path_, "present", &present_value);
    status.battery_is_present = present_value != 0;
    if (status.battery_is_present)
      ReadAndTrimString(battery_path_, "status", &battery_status_string);
  } else {
    status.battery_is_present = false;
  }

  if (base::PathExists(line_power_path_)) {
    int64 online_value = 0;
    ReadInt64(line_power_path_, "online", &online_value);
    status.line_power_on = online_value != 0;
    ReadAndTrimString(line_power_path_, "type", &status.line_power_type);
    ReadAndTrimString(line_power_path_, "model_name",
                      &status.line_power_model_name);

    if (status.line_power_on) {
      status.external_power = IsUsbType(status.line_power_type) ?
          PowerSupplyProperties_ExternalPower_USB :
          (IsOriginalSpringCharger(status.line_power_model_name) ?
           PowerSupplyProperties_ExternalPower_ORIGINAL_SPRING_CHARGER :
           PowerSupplyProperties_ExternalPower_AC);
      status.line_power_voltage =
          ReadScaledDouble(line_power_path_, "voltage_now");
      status.line_power_current =
          ReadScaledDouble(line_power_path_, "current_now");
    } else {
      status.external_power = PowerSupplyProperties_ExternalPower_DISCONNECTED;
    }
  } else if (!status.battery_is_present) {
    // If there's no battery, assume that the system is on AC power.
    status.line_power_on = true;
    status.line_power_type = kMainsType;
    status.external_power = PowerSupplyProperties_ExternalPower_AC;
  } else {
    // Otherwise, infer the external power source from the kernel-reported
    // battery status.
    status.line_power_on =
        battery_status_string == kBatteryStatusCharging ||
        battery_status_string == kBatteryStatusFull;
    status.external_power = status.line_power_on ?
        PowerSupplyProperties_ExternalPower_AC :
        PowerSupplyProperties_ExternalPower_DISCONNECTED;
  }

  // The rest of the calculations all require a battery.
  if (!status.battery_is_present) {
    status.battery_state = PowerSupplyProperties_BatteryState_NOT_PRESENT;
    power_status_ = status;
    power_status_initialized_ = true;
    return true;
  }

  // POWER_SUPPLY_PROP_VENDOR does not seem to be a valid property
  // defined in <linux/power_supply.h>.
  if (base::PathExists(battery_path_.Append("manufacturer")))
    ReadAndTrimString(battery_path_, "manufacturer", &status.battery_vendor);
  else
    ReadAndTrimString(battery_path_, "vendor", &status.battery_vendor);
  ReadAndTrimString(battery_path_, "model_name", &status.battery_model_name);
  ReadAndTrimString(battery_path_, "serial_number", &status.battery_serial);
  ReadAndTrimString(battery_path_, "technology", &status.battery_technology);

  double battery_voltage = ReadScaledDouble(battery_path_, "voltage_now");
  status.battery_voltage = battery_voltage;

  // Attempt to determine nominal voltage for time remaining calculations.
  // The battery voltage used in calculating time remaining.  This may or may
  // not be the same as the instantaneous voltage |battery_voltage|, as voltage
  // levels vary over the time the battery is charged or discharged.
  double nominal_voltage = 0.0;
  if (base::PathExists(battery_path_.Append("voltage_min_design")))
    nominal_voltage = ReadScaledDouble(battery_path_, "voltage_min_design");
  else if (base::PathExists(battery_path_.Append("voltage_max_design")))
    nominal_voltage = ReadScaledDouble(battery_path_, "voltage_max_design");

  // Nominal voltage is not required to obtain charge level.  If it is missing,
  // just log a message, set to |battery_voltage| so time remaining
  // calculations will function, and proceed.
  if (nominal_voltage <= 0) {
    LOG(WARNING) << "Invalid voltage_min/max_design reading: "
                 << nominal_voltage << "V."
                 << " Time remaining calculations will not be available.";
    nominal_voltage = battery_voltage;
  }
  status.nominal_voltage = nominal_voltage;

  // ACPI has two different battery types: charge_battery and energy_battery.
  // The main difference is that charge_battery type exposes
  // 1. current_now in A
  // 2. charge_{now, full, full_design} in Ah
  // while energy_battery type exposes
  // 1. power_now W
  // 2. energy_{now, full, full_design} in Wh
  // Change all the energy readings to charge format.
  // If both energy and charge reading are present (some non-ACPI drivers
  // expose both readings), read only the charge format.
  double battery_charge_full = 0;
  double battery_charge_full_design = 0;
  double battery_charge = 0;

  if (base::PathExists(battery_path_.Append("charge_full"))) {
    battery_charge_full = ReadScaledDouble(battery_path_, "charge_full");
    battery_charge_full_design =
        ReadScaledDouble(battery_path_, "charge_full_design");
    battery_charge = ReadScaledDouble(battery_path_, "charge_now");
  } else if (base::PathExists(battery_path_.Append("energy_full"))) {
    // Valid |battery_voltage| is required to determine the charge so return
    // early if it is not present. In this case, we know nothing about
    // battery state or remaining percentage, so set proper status.
    if (battery_voltage <= 0) {
      LOG(WARNING) << "Invalid voltage_now reading for energy-to-charge"
                   << " conversion: " << battery_voltage;
      return false;
    }
    battery_charge_full =
        ReadScaledDouble(battery_path_, "energy_full") / battery_voltage;
    battery_charge_full_design =
        ReadScaledDouble(battery_path_, "energy_full_design") / battery_voltage;
    battery_charge =
        ReadScaledDouble(battery_path_, "energy_now") / battery_voltage;
  } else {
    LOG(WARNING) << "No charge/energy readings for battery";
    return false;
  }

  status.battery_charge_full = battery_charge_full;
  status.battery_charge_full_design = battery_charge_full_design;
  status.battery_charge = battery_charge;
  if (status.battery_charge_full <= 0.0) {
    LOG(WARNING) << "Got battery-full charge of " << status.battery_charge_full;
    return false;
  }

  // The current can be reported as negative on some systems but not on
  // others, so it can't be used to determine whether the battery is
  // charging or discharging.
  double battery_current = 0;
  if (base::PathExists(battery_path_.Append("power_now"))) {
    battery_current = fabs(ReadScaledDouble(battery_path_, "power_now")) /
        battery_voltage;
  } else {
    battery_current = fabs(ReadScaledDouble(battery_path_, "current_now"));
  }
  status.battery_current = battery_current;

  status.battery_energy = battery_charge * nominal_voltage;
  status.battery_energy_rate = battery_current * battery_voltage;

  status.battery_percentage = util::ClampPercent(
      100.0 * battery_charge / battery_charge_full);
  status.display_battery_percentage = util::ClampPercent(
      100.0 * (status.battery_percentage - low_battery_shutdown_percent_) /
      (100.0 * full_factor_ - low_battery_shutdown_percent_));

  const bool battery_is_full =
      battery_charge >= battery_charge_full * full_factor_;

  if (status.line_power_on) {
    if (battery_is_full) {
      status.battery_state = PowerSupplyProperties_BatteryState_FULL;
    } else if (battery_current > 0.0 &&
               (battery_status_string == kBatteryStatusCharging ||
                battery_status_string == kBatteryStatusFull)) {
      status.battery_state = PowerSupplyProperties_BatteryState_CHARGING;
    } else {
      status.battery_state = PowerSupplyProperties_BatteryState_DISCHARGING;
    }
  } else {
    status.battery_state = PowerSupplyProperties_BatteryState_DISCHARGING;
  }

  if (power_status_initialized_ &&
      status.line_power_on != power_status_.line_power_on) {
    ResetBatterySamples(status.line_power_on ?
        battery_stabilized_after_line_power_connected_delay_ :
        battery_stabilized_after_line_power_disconnected_delay_);
  }

  base::TimeTicks now = clock_->GetCurrentTime();
  if (now >= battery_stabilized_timestamp_) {
    charge_samples_.AddSample(battery_charge, now);
    if (battery_current > 0.0)
      current_samples_.AddSample(battery_current, now);
  }

  UpdateObservedBatteryChargeRate(&status);
  status.is_calculating_battery_time = !UpdateBatteryTimeEstimates(&status);
  status.battery_below_shutdown_threshold =
      IsBatteryBelowShutdownThreshold(status);

  power_status_ = status;
  power_status_initialized_ = true;
  return true;
}

void PowerSupply::GetPowerSupplyPaths() {
  // First check if both line power and battery paths have been found and still
  // exist.  If so, there is no need to do anything else.
  if (base::PathExists(battery_path_) && base::PathExists(line_power_path_))
    return;
  // Use a FileEnumerator to browse through all files/subdirectories in the
  // power supply sysfs directory.
  base::FileEnumerator file_enum(
      power_supply_path_, false, base::FileEnumerator::DIRECTORIES);
  // Read type info from all power sources, and try to identify battery and line
  // power sources.  Their paths are to be stored locally.
  for (base::FilePath path = file_enum.Next();
       !path.empty();
       path = file_enum.Next()) {
    // External devices have "scope" attributes containing the value "Device".
    // Skip them.
    base::FilePath scope_path = path.Append("scope");
    if (base::PathExists(scope_path)) {
      std::string buf;
      base::ReadFileToString(scope_path, &buf);
      base::TrimWhitespaceASCII(buf, base::TRIM_TRAILING, &buf);
      if (buf == "Device") {
        VLOG(1) << "Skipping Power supply " << path.value()
                << " with scope: " << buf;
        continue;
      }
    }
    std::string buf;
    if (base::ReadFileToString(path.Append("type"), &buf)) {
      base::TrimWhitespaceASCII(buf, base::TRIM_TRAILING, &buf);
      // Only look for battery / line power paths if they haven't been found
      // already.  This makes the assumption that they don't change (but battery
      // path can disappear if removed).  So this code should only be run once
      // for each power source.
      if (buf == kBatteryType && battery_path_.empty()) {
        VLOG(1) << "Battery path found: " << path.value();
        battery_path_ = path;
      } else if (buf != kBatteryType && line_power_path_.empty()) {
        VLOG(1) << "Line power path found: " << path.value();
        line_power_path_ = path;
      }
    }
  }
}

bool PowerSupply::UpdateBatteryTimeEstimates(PowerStatus* status) {
  DCHECK(status);
  status->battery_time_to_full = base::TimeDelta();
  status->battery_time_to_empty = base::TimeDelta();
  status->battery_time_to_shutdown = base::TimeDelta();

  if (clock_->GetCurrentTime() < battery_stabilized_timestamp_)
    return false;

  const double average_current = current_samples_.GetAverage();
  switch (status->battery_state) {
    case PowerSupplyProperties_BatteryState_CHARGING:
      if (average_current <= kEpsilon) {
        status->battery_time_to_full = base::TimeDelta::FromSeconds(-1);
      } else {
        const double charge_to_full = std::max(0.0,
            status->battery_charge_full * full_factor_ -
            status->battery_charge);
        status->battery_time_to_full = base::TimeDelta::FromSeconds(
            roundl(3600 * charge_to_full / average_current));
      }
      break;
    case PowerSupplyProperties_BatteryState_DISCHARGING:
      if (average_current <= kEpsilon) {
        status->battery_time_to_empty = base::TimeDelta::FromSeconds(-1);
        status->battery_time_to_shutdown = base::TimeDelta::FromSeconds(-1);
      } else {
        status->battery_time_to_empty = base::TimeDelta::FromSeconds(
            roundl(3600 * (status->battery_charge * status->nominal_voltage) /
                   (average_current * status->battery_voltage)));

        const double shutdown_charge =
            status->battery_charge_full * low_battery_shutdown_percent_ / 100.0;
        const double available_charge = std::max(0.0,
            status->battery_charge - shutdown_charge);
        status->battery_time_to_shutdown = base::TimeDelta::FromSeconds(
            roundl(3600 * (available_charge * status->nominal_voltage) /
                   (average_current * status->battery_voltage))) -
            low_battery_shutdown_time_;
        status->battery_time_to_shutdown =
            std::max(base::TimeDelta(), status->battery_time_to_shutdown);
      }
      break;
    case PowerSupplyProperties_BatteryState_FULL:
      break;
    default:
      NOTREACHED() << "Unhandled battery state " << status->battery_state;
  }

  return true;
}

void PowerSupply::UpdateObservedBatteryChargeRate(PowerStatus* status) const {
  DCHECK(status);
  const base::TimeDelta time_delta = charge_samples_.GetTimeDelta();
  status->observed_battery_charge_rate =
      (time_delta.InMilliseconds() < kObservedBatteryChargeRateMinMs) ? 0.0 :
      charge_samples_.GetValueDelta() / (time_delta.InSecondsF() / 3600);
}

bool PowerSupply::IsBatteryBelowShutdownThreshold(
    const PowerStatus& status) const {
  if (low_battery_shutdown_time_ == base::TimeDelta() &&
      low_battery_shutdown_percent_ <= kEpsilon)
    return false;

  // TODO(derat): Figure out what's causing http://crosbug.com/38912.
  if (status.battery_percentage <= kEpsilon) {
    LOG(WARNING) << "Ignoring probably-bogus zero battery percentage";
    return false;
  }

  const bool below_threshold =
      (status.battery_time_to_empty > base::TimeDelta() &&
       status.battery_time_to_empty <= low_battery_shutdown_time_ &&
       status.battery_percentage <= kLowBatteryShutdownSafetyPercent) ||
      status.battery_percentage <= low_battery_shutdown_percent_;

  // Most AC chargers can deliver enough current to prevent the battery from
  // discharging while the device is in use; other chargers (e.g. USB) may not
  // be able to, though. The observed charge rate is checked to verify whether
  // the battery's charge is increasing or decreasing.
  if (status.line_power_on)
    return below_threshold && status.observed_battery_charge_rate < 0.0;

  return below_threshold;
}

void PowerSupply::SchedulePoll() {
  base::TimeDelta delay = poll_delay_;
  base::TimeTicks now = clock_->GetCurrentTime();
  if (battery_stabilized_timestamp_ > now) {
    delay = std::min(delay,
        battery_stabilized_timestamp_ - now +
        base::TimeDelta::FromMilliseconds(kBatteryStabilizedSlackMs));
  }

  VLOG(1) << "Scheduling update in " << delay.InMilliseconds() << " ms";
  poll_timer_.Start(FROM_HERE, delay, this, &PowerSupply::HandlePollTimeout);
  current_poll_delay_for_testing_ = delay;
}

void PowerSupply::HandlePollTimeout() {
  current_poll_delay_for_testing_ = base::TimeDelta();
  const bool success = UpdatePowerStatus();
  SchedulePoll();
  if (success)
    NotifyObservers();
}

void PowerSupply::NotifyObservers() {
  FOR_EACH_OBSERVER(PowerSupplyObserver, observers_, OnPowerStatusUpdate());
}

}  // namespace system
}  // namespace power_manager
