// 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/metrics_collector.h"

#include <stdint.h>

#include <cmath>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include <base/format_macros.h>
#include <base/logging.h>
#include <base/timer/timer.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>

#include "power_manager/common/fake_prefs.h"
#include "power_manager/common/metrics_constants.h"
#include "power_manager/common/metrics_sender.h"
#include "power_manager/common/power_constants.h"
#include "power_manager/powerd/policy/backlight_controller_stub.h"
#include "power_manager/powerd/policy/suspender.h"
#include "power_manager/powerd/system/power_supply.h"

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Mock;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::Test;

namespace power_manager {
namespace metrics {

class MetricsCollectorTest : public Test {
 public:
  MetricsCollectorTest()
      : metrics_lib_(new StrictMock<MetricsLibraryMock>),
        metrics_sender_(
            std::unique_ptr<MetricsLibraryInterface>(metrics_lib_)) {
    collector_.clock_.set_current_time_for_testing(
        base::TimeTicks::FromInternalValue(1000));
    collector_.clock_.set_current_wall_time_for_testing(
        base::Time::FromInternalValue(2000));

    power_status_.battery_percentage = 100.0;
    power_status_.battery_is_present = true;
    power_status_.line_power_type = "Mains";
  }

 protected:
  // Initializes |collector_|.
  void Init() {
    collector_.Init(&prefs_, &display_backlight_controller_,
                    &keyboard_backlight_controller_, power_status_);
  }

  // Advances both the monotonically-increasing time and wall time by
  // |interval|.
  void AdvanceTime(base::TimeDelta interval) {
    collector_.clock_.set_current_time_for_testing(
        collector_.clock_.GetCurrentTime() + interval);
    collector_.clock_.set_current_wall_time_for_testing(
        collector_.clock_.GetCurrentWallTime() + interval);
  }

  // Adds expectations to ignore all metrics sent by HandleSessionStateChange()
  // (except ones listed in |metrics_to_test_|).
  void IgnoreHandleSessionStateChangeMetrics() {
    IgnoreEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kBatteryRemainingAtStartOfSessionName, PowerSource::AC));
    IgnoreEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kBatteryRemainingAtStartOfSessionName, PowerSource::BATTERY));
    IgnoreEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kBatteryRemainingAtEndOfSessionName, PowerSource::AC));
    IgnoreEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kBatteryRemainingAtEndOfSessionName, PowerSource::BATTERY));
    IgnoreMetric(kLengthOfSessionName);
    IgnoreMetric(kNumberOfAlsAdjustmentsPerSessionName);
    IgnoreMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kUserBrightnessAdjustmentsPerSessionName, PowerSource::AC));
    IgnoreMetric(MetricsCollector::AppendPowerSourceToEnumName(
        kUserBrightnessAdjustmentsPerSessionName, PowerSource::BATTERY));
  }

  // Adds expectations to ignore all metrics sent by HandlePowerStatusUpdate()
  // (except ones listed in |metrics_to_test_|).
  void IgnoreHandlePowerStatusUpdateMetrics() {
    IgnoreMetric(kNumOfSessionsPerChargeName);
    IgnoreEnumMetric(kBatteryRemainingWhenChargeStartsName);
    IgnoreEnumMetric(kBatteryChargeHealthName);
    IgnoreMetric(kBatteryDischargeRateName);
    IgnoreMetric(kBatteryDischargeRateWhileSuspendedName);
    IgnoreEnumMetric(kBatteryInfoSampleName);
    IgnoreEnumMetric(kPowerSupplyTypeName);
    IgnoreEnumMetric(kPowerSupplyMaxVoltageName);
    IgnoreEnumMetric(kPowerSupplyMaxPowerName);
    IgnoreEnumMetric(kConnectedChargingPortsName);
  }

  // Updates |power_status_|'s |line_power_on| member and passes it to
  // HandlePowerStatusUpdate().
  void UpdatePowerStatusLinePower(bool line_power_on) {
    power_status_.line_power_on = line_power_on;
    collector_.HandlePowerStatusUpdate(power_status_);
  }

  // Adds a metrics library mock expectation that the specified metric
  // will be generated.
  void ExpectMetric(
      const std::string& name, int sample, int min, int max, int buckets) {
    EXPECT_CALL(*metrics_lib_, SendToUMA(name, sample, min, max, buckets))
        .Times(1)
        .WillOnce(Return(true))
        .RetiresOnSaturation();
  }

  // Adds a metrics library mock expectation that the specified enum
  // metric will be generated.
  void ExpectEnumMetric(const std::string& name, int sample, int max) {
    EXPECT_CALL(*metrics_lib_, SendEnumToUMA(name, sample, max))
        .Times(1)
        .WillOnce(Return(true))
        .RetiresOnSaturation();
  }

  // Ignores an arbitrary number of reports of |name|.
  void IgnoreMetric(const std::string& name) {
    if (metrics_to_test_.count(name))
      return;
    EXPECT_CALL(*metrics_lib_, SendToUMA(name, _, _, _, _))
        .Times(AnyNumber())
        .WillRepeatedly(Return(true));
  }

  // Ignores an arbitrary number of reports of |name|.
  void IgnoreEnumMetric(const std::string& name) {
    if (metrics_to_test_.count(name))
      return;
    EXPECT_CALL(*metrics_lib_, SendEnumToUMA(name, _, _))
        .Times(AnyNumber())
        .WillRepeatedly(Return(true));
  }

  void ExpectBatteryDischargeRateMetric(int sample) {
    ExpectMetric(kBatteryDischargeRateName, sample, kBatteryDischargeRateMin,
                 kBatteryDischargeRateMax, kDefaultBuckets);
  }

  void ExpectNumOfSessionsPerChargeMetric(int sample) {
    ExpectMetric(kNumOfSessionsPerChargeName, sample,
                 kNumOfSessionsPerChargeMin, kNumOfSessionsPerChargeMax,
                 kDefaultBuckets);
  }

  FakePrefs prefs_;
  policy::BacklightControllerStub display_backlight_controller_;
  policy::BacklightControllerStub keyboard_backlight_controller_;
  system::PowerStatus power_status_;

  // StrictMock turns all unexpected calls into hard failures.
  StrictMock<MetricsLibraryMock>* metrics_lib_;  // Weak pointer.
  MetricsSender metrics_sender_;

  MetricsCollector collector_;

  // Names of metrics that will not be ignored by calls to Ignore*(). Tests
  // should insert the metrics that they're testing into this set and then call
  // Ignore*Metrics() (and call it again whenever expectations are cleared).
  std::set<std::string> metrics_to_test_;
};

TEST_F(MetricsCollectorTest, BacklightLevel) {
  power_status_.line_power_on = false;
  Init();
  ASSERT_TRUE(collector_.generate_backlight_metrics_timer_.IsRunning());
  collector_.HandleScreenDimmedChange(true, base::TimeTicks::Now());
  collector_.GenerateBacklightLevelMetrics();
  Mock::VerifyAndClearExpectations(metrics_lib_);

  const int64_t kCurrentDisplayPercent = 57;
  display_backlight_controller_.set_percent(kCurrentDisplayPercent);
  const int64_t kCurrentKeyboardPercent = 43;
  keyboard_backlight_controller_.set_percent(kCurrentKeyboardPercent);

  collector_.HandleScreenDimmedChange(false, base::TimeTicks::Now());
  ExpectEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
                       kBacklightLevelName, PowerSource::BATTERY),
                   kCurrentDisplayPercent, kMaxPercent);
  ExpectEnumMetric(kKeyboardBacklightLevelName, kCurrentKeyboardPercent,
                   kMaxPercent);
  collector_.GenerateBacklightLevelMetrics();

  power_status_.line_power_on = true;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  ExpectEnumMetric(MetricsCollector::AppendPowerSourceToEnumName(
                       kBacklightLevelName, PowerSource::AC),
                   kCurrentDisplayPercent, kMaxPercent);
  ExpectEnumMetric(kKeyboardBacklightLevelName, kCurrentKeyboardPercent,
                   kMaxPercent);
  collector_.GenerateBacklightLevelMetrics();
}

TEST_F(MetricsCollectorTest, BatteryDischargeRate) {
  power_status_.line_power_on = false;
  Init();

  metrics_to_test_.insert(kBatteryDischargeRateName);
  IgnoreHandlePowerStatusUpdateMetrics();

  // This much time must elapse before the discharge rate will be reported
  // again.
  const base::TimeDelta interval =
      base::TimeDelta::FromSeconds(kBatteryDischargeRateIntervalSec);

  power_status_.battery_energy_rate = 5.0;
  ExpectBatteryDischargeRateMetric(5000);
  collector_.HandlePowerStatusUpdate(power_status_);

  power_status_.battery_energy_rate = 4.5;
  ExpectBatteryDischargeRateMetric(4500);
  AdvanceTime(interval);
  collector_.HandlePowerStatusUpdate(power_status_);

  power_status_.battery_energy_rate = 6.4;
  ExpectBatteryDischargeRateMetric(6400);
  AdvanceTime(interval);
  collector_.HandlePowerStatusUpdate(power_status_);

  Mock::VerifyAndClearExpectations(metrics_lib_);
  IgnoreHandlePowerStatusUpdateMetrics();

  // Another update before the full interval has elapsed shouldn't result in
  // another report.
  AdvanceTime(interval / 2);
  collector_.HandlePowerStatusUpdate(power_status_);

  // Neither should a call while the energy rate is negative.
  AdvanceTime(interval);
  power_status_.battery_energy_rate = -4.0;
  collector_.HandlePowerStatusUpdate(power_status_);

  // Ditto for a call while the system is on AC power.
  power_status_.line_power_on = true;
  power_status_.battery_energy_rate = 4.0;
  collector_.HandlePowerStatusUpdate(power_status_);
}

TEST_F(MetricsCollectorTest, BatteryInfoWhenChargeStarts) {
  const double kBatteryPercentages[] = {10.1, 10.7, 82.4, 82.5, 100.0};

  power_status_.line_power_on = false;
  power_status_.battery_charge_full_design = 100.0;
  Init();

  metrics_to_test_.insert(kBatteryRemainingWhenChargeStartsName);
  metrics_to_test_.insert(kBatteryChargeHealthName);

  for (size_t i = 0; i < arraysize(kBatteryPercentages); ++i) {
    IgnoreHandlePowerStatusUpdateMetrics();

    power_status_.line_power_on = false;
    power_status_.battery_charge_full = kBatteryPercentages[i];
    power_status_.battery_percentage = kBatteryPercentages[i];
    collector_.HandlePowerStatusUpdate(power_status_);

    power_status_.line_power_on = true;
    ExpectEnumMetric(kBatteryRemainingWhenChargeStartsName,
                     round(power_status_.battery_percentage), kMaxPercent);
    ExpectEnumMetric(kBatteryChargeHealthName,
                     round(100.0 * power_status_.battery_charge_full /
                           power_status_.battery_charge_full_design),
                     kBatteryChargeHealthMax);
    collector_.HandlePowerStatusUpdate(power_status_);

    Mock::VerifyAndClearExpectations(metrics_lib_);
  }
}

TEST_F(MetricsCollectorTest, SessionStartOrStop) {
  const uint kAlsAdjustments[] = {0, 100};
  const uint kUserAdjustments[] = {0, 200};
  const double kBatteryPercentages[] = {10.5, 23.0};
  const int kSessionSecs[] = {900, kLengthOfSessionMax + 10};
  ASSERT_EQ(arraysize(kAlsAdjustments), arraysize(kUserAdjustments));
  ASSERT_EQ(arraysize(kAlsAdjustments), arraysize(kBatteryPercentages));
  ASSERT_EQ(arraysize(kAlsAdjustments), arraysize(kSessionSecs));

  power_status_.line_power_on = false;
  Init();

  for (size_t i = 0; i < arraysize(kAlsAdjustments); ++i) {
    IgnoreHandlePowerStatusUpdateMetrics();
    power_status_.battery_percentage = kBatteryPercentages[i];
    ExpectEnumMetric(
        MetricsCollector::AppendPowerSourceToEnumName(
            kBatteryRemainingAtStartOfSessionName, PowerSource::BATTERY),
        round(kBatteryPercentages[i]), kMaxPercent);
    collector_.HandlePowerStatusUpdate(power_status_);
    collector_.HandleSessionStateChange(SessionState::STARTED);
    Mock::VerifyAndClearExpectations(metrics_lib_);

    ExpectEnumMetric(
        MetricsCollector::AppendPowerSourceToEnumName(
            kBatteryRemainingAtEndOfSessionName, PowerSource::BATTERY),
        round(kBatteryPercentages[i]), kMaxPercent);

    display_backlight_controller_.set_num_als_adjustments(kAlsAdjustments[i]);
    display_backlight_controller_.set_num_user_adjustments(kUserAdjustments[i]);
    ExpectMetric(kNumberOfAlsAdjustmentsPerSessionName, kAlsAdjustments[i],
                 kNumberOfAlsAdjustmentsPerSessionMin,
                 kNumberOfAlsAdjustmentsPerSessionMax, kDefaultBuckets);
    ExpectMetric(
        MetricsCollector::AppendPowerSourceToEnumName(
            kUserBrightnessAdjustmentsPerSessionName, PowerSource::BATTERY),
        kUserAdjustments[i], kUserBrightnessAdjustmentsPerSessionMin,
        kUserBrightnessAdjustmentsPerSessionMax, kDefaultBuckets);

    AdvanceTime(base::TimeDelta::FromSeconds(kSessionSecs[i]));
    ExpectMetric(kLengthOfSessionName, kSessionSecs[i], kLengthOfSessionMin,
                 kLengthOfSessionMax, kDefaultBuckets);

    collector_.HandleSessionStateChange(SessionState::STOPPED);
    Mock::VerifyAndClearExpectations(metrics_lib_);
  }
}

TEST_F(MetricsCollectorTest, GenerateNumOfSessionsPerChargeMetric) {
  metrics_to_test_.insert(kNumOfSessionsPerChargeName);
  power_status_.line_power_on = false;
  Init();

  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // If the session is already started when going off line power, it should be
  // counted. Additional power status updates that don't describe a power source
  // change shouldn't increment the count.
  IgnoreHandleSessionStateChangeMetrics();
  collector_.HandleSessionStateChange(SessionState::STARTED);
  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(false);
  UpdatePowerStatusLinePower(false);
  UpdatePowerStatusLinePower(false);
  ExpectNumOfSessionsPerChargeMetric(1);
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Sessions that start while on battery power should also be counted.
  IgnoreHandleSessionStateChangeMetrics();
  collector_.HandleSessionStateChange(SessionState::STOPPED);
  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(false);
  collector_.HandleSessionStateChange(SessionState::STARTED);
  collector_.HandleSessionStateChange(SessionState::STOPPED);
  collector_.HandleSessionStateChange(SessionState::STARTED);
  collector_.HandleSessionStateChange(SessionState::STOPPED);
  collector_.HandleSessionStateChange(SessionState::STARTED);
  ExpectNumOfSessionsPerChargeMetric(3);
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Check that the pref is used, so the count will persist across reboots.
  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(false);
  prefs_.SetInt64(kNumSessionsOnCurrentChargePref, 5);
  ExpectNumOfSessionsPerChargeMetric(5);
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Negative values in the pref should be ignored.
  prefs_.SetInt64(kNumSessionsOnCurrentChargePref, -2);
  IgnoreHandlePowerStatusUpdateMetrics();
  UpdatePowerStatusLinePower(false);
  ExpectNumOfSessionsPerChargeMetric(1);
  UpdatePowerStatusLinePower(true);
  Mock::VerifyAndClearExpectations(metrics_lib_);
}

TEST_F(MetricsCollectorTest, SendEnumMetric) {
  Init();
  ExpectEnumMetric("Dummy.EnumMetric", 50, 200);
  EXPECT_TRUE(SendEnumMetric("Dummy.EnumMetric", 50, 200));

  // Out-of-bounds values should be capped.
  ExpectEnumMetric("Dummy.EnumMetric2", 20, 20);
  EXPECT_TRUE(SendEnumMetric("Dummy.EnumMetric2", 21, 20));
}

TEST_F(MetricsCollectorTest, SendMetric) {
  Init();
  ExpectMetric("Dummy.Metric", 3, 1, 100, 50);
  EXPECT_TRUE(SendMetric("Dummy.Metric", 3, 1, 100, 50));

  // Out-of-bounds values should not be capped (so they can instead land in the
  // underflow or overflow bucket).
  ExpectMetric("Dummy.Metric2", -1, 0, 20, 4);
  EXPECT_TRUE(SendMetric("Dummy.Metric2", -1, 0, 20, 4));
  ExpectMetric("Dummy.Metric3", 30, 5, 25, 6);
  EXPECT_TRUE(SendMetric("Dummy.Metric3", 30, 5, 25, 6));
}

TEST_F(MetricsCollectorTest, SendMetricWithPowerSource) {
  power_status_.line_power_on = false;
  Init();
  ExpectMetric("Dummy.MetricOnBattery", 3, 1, 100, 50);
  EXPECT_TRUE(
      collector_.SendMetricWithPowerSource("Dummy.Metric", 3, 1, 100, 50));

  IgnoreHandlePowerStatusUpdateMetrics();
  power_status_.line_power_on = true;
  collector_.HandlePowerStatusUpdate(power_status_);
  ExpectMetric("Dummy.MetricOnAC", 6, 2, 200, 80);
  EXPECT_TRUE(
      collector_.SendMetricWithPowerSource("Dummy.Metric", 6, 2, 200, 80));
}

TEST_F(MetricsCollectorTest, PowerButtonDownMetric) {
  Init();

  // We should ignore a button release that wasn't preceded by a press.
  collector_.HandlePowerButtonEvent(ButtonState::UP);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Presses that are followed by additional presses should also be ignored.
  collector_.HandlePowerButtonEvent(ButtonState::DOWN);
  collector_.HandlePowerButtonEvent(ButtonState::DOWN);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Send a regular sequence of events and check that the duration is reported.
  collector_.HandlePowerButtonEvent(ButtonState::DOWN);
  const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(243);
  AdvanceTime(kDuration);
  ExpectMetric(kPowerButtonDownTimeName, kDuration.InMilliseconds(),
               kPowerButtonDownTimeMin, kPowerButtonDownTimeMax,
               kDefaultBuckets);
  collector_.HandlePowerButtonEvent(ButtonState::UP);
}

TEST_F(MetricsCollectorTest, GatherDarkResumeMetrics) {
  Init();

  std::vector<policy::Suspender::DarkResumeInfo> wake_durations;
  base::TimeDelta suspend_duration;
  base::TimeDelta kTimeDelta1 = base::TimeDelta::FromSeconds(2);
  base::TimeDelta kTimeDelta2 = base::TimeDelta::FromSeconds(6);
  base::TimeDelta kTimeDelta3 = base::TimeDelta::FromMilliseconds(573);
  base::TimeDelta kTimeDelta4 = base::TimeDelta::FromSeconds(7);
  std::string kWakeReason1 = "WiFi.Pattern";
  std::string kWakeReason2 = "WiFi.Disconnect";
  std::string kWakeReason3 = "WiFi.SSID";
  std::string kWakeReason4 = "Other";
  std::string kExpectedHistogramPrefix = "Power.DarkResumeWakeDurationMs.";
  std::string kExpectedHistogram1 = kExpectedHistogramPrefix + kWakeReason1;
  std::string kExpectedHistogram2 = kExpectedHistogramPrefix + kWakeReason2;
  std::string kExpectedHistogram3 = kExpectedHistogramPrefix + kWakeReason3;
  std::string kExpectedHistogram4 = kExpectedHistogramPrefix + kWakeReason4;

  // First test the basic case.
  wake_durations.push_back(std::make_pair(kWakeReason1, kTimeDelta1));
  wake_durations.push_back(std::make_pair(kWakeReason2, kTimeDelta2));
  wake_durations.push_back(std::make_pair(kWakeReason3, kTimeDelta3));
  wake_durations.push_back(std::make_pair(kWakeReason4, kTimeDelta4));

  suspend_duration = base::TimeDelta::FromHours(2);

  ExpectMetric(kDarkResumeWakeupsPerHourName,
               wake_durations.size() / suspend_duration.InHours(),
               kDarkResumeWakeupsPerHourMin, kDarkResumeWakeupsPerHourMax,
               kDefaultBuckets);
  for (const auto& pair : wake_durations) {
    const base::TimeDelta& duration = pair.second;
    ExpectMetric(kDarkResumeWakeDurationMsName, duration.InMilliseconds(),
                 kDarkResumeWakeDurationMsMin, kDarkResumeWakeDurationMsMax,
                 kDefaultBuckets);
  }
  ExpectMetric(kExpectedHistogram1, kTimeDelta1.InMilliseconds(),
               kDarkResumeWakeDurationMsMin, kDarkResumeWakeDurationMsMax,
               kDefaultBuckets);
  ExpectMetric(kExpectedHistogram2, kTimeDelta2.InMilliseconds(),
               kDarkResumeWakeDurationMsMin, kDarkResumeWakeDurationMsMax,
               kDefaultBuckets);
  ExpectMetric(kExpectedHistogram3, kTimeDelta3.InMilliseconds(),
               kDarkResumeWakeDurationMsMin, kDarkResumeWakeDurationMsMax,
               kDefaultBuckets);
  ExpectMetric(kExpectedHistogram4, kTimeDelta4.InMilliseconds(),
               kDarkResumeWakeDurationMsMin, kDarkResumeWakeDurationMsMax,
               kDefaultBuckets);

  collector_.GenerateDarkResumeMetrics(wake_durations, suspend_duration);

  // If the suspend lasts for less than an hour, the wakeups per hour should be
  // scaled up.
  Mock::VerifyAndClearExpectations(metrics_lib_);
  wake_durations.clear();

  wake_durations.push_back(
      std::make_pair(kWakeReason1, base::TimeDelta::FromMilliseconds(359)));
  suspend_duration = base::TimeDelta::FromMinutes(13);

  IgnoreMetric(kDarkResumeWakeDurationMsName);
  IgnoreMetric(kExpectedHistogram1);
  ExpectMetric(kDarkResumeWakeupsPerHourName, 4, kDarkResumeWakeupsPerHourMin,
               kDarkResumeWakeupsPerHourMax, kDefaultBuckets);

  collector_.GenerateDarkResumeMetrics(wake_durations, suspend_duration);
}

TEST_F(MetricsCollectorTest, BatteryDischargeRateWhileSuspended) {
  const double kEnergyBeforeSuspend = 60;
  const double kEnergyAfterResume = 50;
  const base::TimeDelta kSuspendDuration = base::TimeDelta::FromHours(1);

  metrics_to_test_.insert(kBatteryDischargeRateWhileSuspendedName);
  power_status_.line_power_on = false;
  power_status_.battery_energy = kEnergyAfterResume;
  Init();

  // We shouldn't send a sample if we haven't suspended.
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // Ditto if the system is on AC before suspending...
  power_status_.line_power_on = true;
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(kSuspendDuration);
  ExpectMetric(kSuspendAttemptsBeforeSuccessName, 1, kSuspendAttemptsMin,
               kSuspendAttemptsMax, kSuspendAttemptsBuckets);
  collector_.HandleResume(1);
  power_status_.line_power_on = false;
  power_status_.battery_energy = kEnergyAfterResume;
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // ... or after resuming...
  power_status_.line_power_on = false;
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(kSuspendDuration);
  ExpectMetric(kSuspendAttemptsBeforeSuccessName, 2, kSuspendAttemptsMin,
               kSuspendAttemptsMax, kSuspendAttemptsBuckets);
  collector_.HandleResume(2);
  power_status_.line_power_on = true;
  power_status_.battery_energy = kEnergyAfterResume;
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // ... or if the battery's energy increased while the system was
  // suspended (i.e. it was temporarily connected to AC while suspended).
  power_status_.line_power_on = false;
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(kSuspendDuration);
  ExpectMetric(kSuspendAttemptsBeforeSuccessName, 1, kSuspendAttemptsMin,
               kSuspendAttemptsMax, kSuspendAttemptsBuckets);
  collector_.HandleResume(1);
  power_status_.battery_energy = kEnergyBeforeSuspend + 5.0;
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // The sample also shouldn't be reported if the system wasn't suspended
  // for very long.
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(base::TimeDelta::FromSeconds(
      kBatteryDischargeRateWhileSuspendedMinSuspendSec - 1));
  ExpectMetric(kSuspendAttemptsBeforeSuccessName, 1, kSuspendAttemptsMin,
               kSuspendAttemptsMax, kSuspendAttemptsBuckets);
  collector_.HandleResume(1);
  power_status_.battery_energy = kEnergyAfterResume;
  collector_.HandlePowerStatusUpdate(power_status_);
  Mock::VerifyAndClearExpectations(metrics_lib_);

  // The sample should be reported if the energy decreased over a long
  // enough time.
  power_status_.battery_energy = kEnergyBeforeSuspend;
  IgnoreHandlePowerStatusUpdateMetrics();
  collector_.HandlePowerStatusUpdate(power_status_);
  collector_.PrepareForSuspend();
  AdvanceTime(kSuspendDuration);
  ExpectMetric(kSuspendAttemptsBeforeSuccessName, 1, kSuspendAttemptsMin,
               kSuspendAttemptsMax, kSuspendAttemptsBuckets);
  collector_.HandleResume(1);
  power_status_.battery_energy = kEnergyAfterResume;
  const int rate_mw = static_cast<int>(
      round(1000 * (kEnergyBeforeSuspend - kEnergyAfterResume) /
            (kSuspendDuration.InSecondsF() / 3600)));
  ExpectMetric(kBatteryDischargeRateWhileSuspendedName, rate_mw,
               kBatteryDischargeRateWhileSuspendedMin,
               kBatteryDischargeRateWhileSuspendedMax, kDefaultBuckets);
  collector_.HandlePowerStatusUpdate(power_status_);
}

TEST_F(MetricsCollectorTest, PowerSupplyMaxVoltageAndPower) {
  metrics_to_test_ = {
      kPowerSupplyMaxVoltageName, kPowerSupplyMaxPowerName,
  };
  IgnoreHandlePowerStatusUpdateMetrics();
  power_status_.line_power_on = false;
  Init();

  power_status_.line_power_on = true;
  power_status_.line_power_max_voltage = 4.2;
  power_status_.line_power_max_current = 12.7;
  ExpectEnumMetric(
      kPowerSupplyMaxVoltageName,
      static_cast<int>(round(power_status_.line_power_max_voltage)),
      kPowerSupplyMaxVoltageMax);
  ExpectEnumMetric(
      kPowerSupplyMaxPowerName,
      static_cast<int>(round(power_status_.line_power_max_voltage *
                             power_status_.line_power_max_current)),
      kPowerSupplyMaxPowerMax);
  collector_.HandlePowerStatusUpdate(power_status_);

  // Nothing should be reported when line power is off.
  power_status_.line_power_on = false;
  collector_.HandlePowerStatusUpdate(power_status_);
}

TEST_F(MetricsCollectorTest, PowerSupplyType) {
  metrics_to_test_ = {kPowerSupplyTypeName};
  IgnoreHandlePowerStatusUpdateMetrics();
  power_status_.line_power_on = false;
  Init();

  power_status_.line_power_on = true;
  power_status_.line_power_type = system::PowerSupply::kUsbPdType;
  ExpectEnumMetric(kPowerSupplyTypeName,
                   static_cast<int>(PowerSupplyType::USB_PD),
                   static_cast<int>(PowerSupplyType::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);

  power_status_.line_power_type = system::PowerSupply::kBrickIdType;
  ExpectEnumMetric(kPowerSupplyTypeName,
                   static_cast<int>(PowerSupplyType::BRICK_ID),
                   static_cast<int>(PowerSupplyType::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);

  power_status_.line_power_type = "BOGUS";
  ExpectEnumMetric(kPowerSupplyTypeName,
                   static_cast<int>(PowerSupplyType::OTHER),
                   static_cast<int>(PowerSupplyType::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);

  // Nothing should be reported when line power is off.
  power_status_.line_power_on = false;
  collector_.HandlePowerStatusUpdate(power_status_);
}

TEST_F(MetricsCollectorTest, ConnectedChargingPorts) {
  metrics_to_test_ = {kConnectedChargingPortsName};
  IgnoreHandlePowerStatusUpdateMetrics();
  Init();

  // Start out without any ports.
  ExpectEnumMetric(kConnectedChargingPortsName,
                   static_cast<int>(ConnectedChargingPorts::NONE),
                   static_cast<int>(ConnectedChargingPorts::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);

  // Add a single disconnected port.
  power_status_.ports.emplace_back();
  ExpectEnumMetric(kConnectedChargingPortsName,
                   static_cast<int>(ConnectedChargingPorts::NONE),
                   static_cast<int>(ConnectedChargingPorts::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);

  // Connect the port to a dedicated charger.
  power_status_.ports[0].role =
      system::PowerStatus::Port::Role::DEDICATED_SOURCE;
  ExpectEnumMetric(kConnectedChargingPortsName,
                   static_cast<int>(ConnectedChargingPorts::PORT1),
                   static_cast<int>(ConnectedChargingPorts::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);

  // Add a second disconnected port.
  power_status_.ports.emplace_back();
  ExpectEnumMetric(kConnectedChargingPortsName,
                   static_cast<int>(ConnectedChargingPorts::PORT1),
                   static_cast<int>(ConnectedChargingPorts::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);

  // Connect the second port to a dual-role device.
  power_status_.ports[1].role = system::PowerStatus::Port::Role::DUAL_ROLE;
  ExpectEnumMetric(kConnectedChargingPortsName,
                   static_cast<int>(ConnectedChargingPorts::PORT1_PORT2),
                   static_cast<int>(ConnectedChargingPorts::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);

  // Disconnect the first port.
  power_status_.ports[0].role = system::PowerStatus::Port::Role::NONE;
  ExpectEnumMetric(kConnectedChargingPortsName,
                   static_cast<int>(ConnectedChargingPorts::PORT2),
                   static_cast<int>(ConnectedChargingPorts::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);

  // Add a third port, which this code doesn't support.
  power_status_.ports.emplace_back();
  ExpectEnumMetric(kConnectedChargingPortsName,
                   static_cast<int>(ConnectedChargingPorts::TOO_MANY_PORTS),
                   static_cast<int>(ConnectedChargingPorts::MAX));
  collector_.HandlePowerStatusUpdate(power_status_);
}

}  // namespace metrics
}  // namespace power_manager
