chromium/chrome/browser/metrics/power/battery_discharge_reporter_unittest.cc

// Copyright 2021 The Chromium Authors
// 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_discharge_reporter.h"

#include <memory>

#include "base/power_monitor/battery_level_provider.h"
#include "base/power_monitor/battery_state_sampler.h"
#include "base/power_monitor/sampling_event_source.h"
#include "base/strings/strcat.h"
#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/metrics/power/power_metrics.h"
#include "chrome/browser/metrics/usage_scenario/usage_scenario_data_store.h"
#include "chrome/browser/performance_manager/public/user_tuning/battery_saver_mode_manager.h"
#include "chrome/browser/performance_manager/test_support/fake_child_process_tuning_delegate.h"
#include "chrome/browser/performance_manager/test_support/fake_frame_throttling_delegate.h"
#include "chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.h"
#include "components/performance_manager/public/user_tuning/prefs.h"
#include "components/prefs/testing_pref_service.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

constexpr const char* kBatteryDischargeModeHistogramName =;
constexpr const char* kBatteryDischargeModeTenMinutesHistogramName =;
constexpr const char* kBatteryDischargeRateMilliwattsHistogramName =;
constexpr const char* kBatteryDischargeRateMilliwattsTenMinutesHistogramName =;
constexpr const char* kBatteryDischargeRateRelativeHistogramName =;

constexpr base::TimeDelta kTolerableDrift =;
constexpr int kFullBatteryChargeLevel =;
constexpr int kHalfBatteryChargeLevel =;

std::optional<base::BatteryLevelProvider::BatteryState> MakeBatteryState(
    int current_capacity) {}

struct HistogramSampleExpectation {};

// For each histogram named after the combination of prefixes from
// `expectations` and suffixes from `suffixes`, verifies that there is a unique
// sample `expectation.sample`.
void ExpectHistogramSamples(
    base::HistogramTester* histogram_tester,
    const std::vector<const char*>& suffixes,
    const std::vector<HistogramSampleExpectation>& expectations) {}

class NoopSamplingEventSource : public base::SamplingEventSource {};

class NoopBatteryLevelProvider : public base::BatteryLevelProvider {};

class TestUsageScenarioDataStoreImpl : public UsageScenarioDataStoreImpl {};

}  // namespace

class BatteryDischargeReporterTest : public testing::Test {};

TEST_F(BatteryDischargeReporterTest, Simple_BatterySaverInactive) {}

TEST_F(BatteryDischargeReporterTest, Simple_BatterySaverActive) {}

TEST_F(BatteryDischargeReporterTest, BatteryDischargeCaptureIsTooLate) {}

TEST_F(BatteryDischargeReporterTest, BatteryDischargeCaptureIsLate) {}

TEST_F(BatteryDischargeReporterTest, BatteryDischargeCaptureIsTooEarly) {}

TEST_F(BatteryDischargeReporterTest, BatteryDischargeCaptureIsEarly) {}

TEST_F(BatteryDischargeReporterTest, FullChargedCapacityIncreased) {}

TEST_F(BatteryDischargeReporterTest, RetrievalError) {}

TEST_F(BatteryDischargeReporterTest, StateChanged_Battery) {}

TEST_F(BatteryDischargeReporterTest, StateChanged_PluggedIn) {}

TEST_F(BatteryDischargeReporterTest, NoBattery) {}

TEST_F(BatteryDischargeReporterTest, PluggedIn) {}

TEST_F(BatteryDischargeReporterTest, MultipleBatteries) {}

TEST_F(BatteryDischargeReporterTest, InsufficientResolution) {}

#if BUILDFLAG(IS_MAC)
TEST_F(BatteryDischargeReporterTest, MacFullyCharged) {
  TestBatteryDischargeMode(
      base::BatteryLevelProvider::BatteryState{
          .battery_count = 1,
          .is_external_power_connected = false,
          .current_capacity = 100,
          .full_charged_capacity = 100,
          .charge_unit = base::BatteryLevelProvider::BatteryLevelUnit::kMWh,
      },
      base::BatteryLevelProvider::BatteryState{
          .battery_count = 1,
          .is_external_power_connected = false,
          .current_capacity = 99,
          .full_charged_capacity = 100,
          .charge_unit = base::BatteryLevelProvider::BatteryLevelUnit::kMWh,
      },
      BatteryDischargeMode::kMacFullyCharged);
}
#endif  // BUILDFLAG(IS_MAC)

TEST_F(BatteryDischargeReporterTest, FullChargedCapacityIsZero) {}

TEST_F(BatteryDischargeReporterTest, BatteryLevelIncreased) {}

#if BUILDFLAG(IS_WIN)
TEST_F(BatteryDischargeReporterTest, BatteryDischargeGranularity) {
  TestUsageScenarioDataStoreImpl usage_scenario_data_store;

  BatteryDischargeReporter battery_discharge_reporter(
      environment_.battery_state_sampler(), &usage_scenario_data_store);

  const int64_t kGranularityMilliwattHours = 10;
  // Since the full charged capacity is 1000, a granularity of 10 is equal to
  // one percent, or 100 hundredths of a percent.
  const int64_t kGranularityRelative = 100;

  const auto kBatteryState = base::BatteryLevelProvider::BatteryState{
      .battery_count = 1,
      .is_external_power_connected = false,
      .current_capacity = 500,
      .full_charged_capacity = 1000,
      .charge_unit = base::BatteryLevelProvider::BatteryLevelUnit::kMWh,
      .battery_discharge_granularity = kGranularityMilliwattHours,
  };

  battery_discharge_reporter.OnBatteryStateSampled(kBatteryState);
  task_environment_.FastForwardBy(base::Minutes(1));
  battery_discharge_reporter.OnBatteryStateSampled(kBatteryState);

  histogram_tester_.ExpectUniqueSample(
      "Power.BatteryDischargeGranularityMilliwattHours2",
      kGranularityMilliwattHours, 1);
  histogram_tester_.ExpectUniqueSample(
      "Power.BatteryDischargeGranularityRelative2", kGranularityRelative, 1);
}

TEST_F(BatteryDischargeReporterTest, TenMinutesInterval) {
  TestUsageScenarioDataStoreImpl usage_scenario_data_store;

  BatteryDischargeReporter battery_discharge_reporter(
      environment_.battery_state_sampler(), &usage_scenario_data_store);

  {
    base::HistogramTester tester;

    // t = 0: No 10-minutes histograms emitted.
    battery_discharge_reporter.OnBatteryStateSampled(
        MakeBatteryState(kHalfBatteryChargeLevel));

    // t = 1 to 9 minutes: No 10-minutes histograms emitted.
    for (int i = 0; i < 9; ++i) {
      task_environment_.FastForwardBy(base::Minutes(1));
      battery_discharge_reporter.OnBatteryStateSampled(
          MakeBatteryState(kHalfBatteryChargeLevel - 2));
      tester.ExpectTotalCount(kBatteryDischargeModeTenMinutesHistogramName, 0);
      tester.ExpectTotalCount(
          kBatteryDischargeRateMilliwattsTenMinutesHistogramName, 0);
    }

    // t = 10 minutes: Expect 10-minutes histograms to be emitted.
    task_environment_.FastForwardBy(base::Minutes(1));
    battery_discharge_reporter.OnBatteryStateSampled(
        MakeBatteryState(kHalfBatteryChargeLevel - 100));
    // 100 mWh discharge over 10 minutes equals 600 mW.
    const int64_t kExpectedDischargeRate_mW = 600;
    tester.ExpectUniqueSample(kBatteryDischargeModeTenMinutesHistogramName,
                              BatteryDischargeMode::kDischarging, 1);
    tester.ExpectUniqueSample(
        kBatteryDischargeRateMilliwattsTenMinutesHistogramName,
        kExpectedDischargeRate_mW, 1);
  }

  {
    base::HistogramTester tester;

    // t = 20 minutes: Expect 10-minutes histograms to be emitted again.
    task_environment_.FastForwardBy(base::Minutes(10));
    battery_discharge_reporter.OnBatteryStateSampled(
        MakeBatteryState(kHalfBatteryChargeLevel - 300));
    // 200 mWh discharge over 10 minutes equals 1200 mW.
    const int64_t kExpectedDischargeRate_mW = 1200;
    tester.ExpectUniqueSample(kBatteryDischargeModeTenMinutesHistogramName,
                              BatteryDischargeMode::kDischarging, 1);
    tester.ExpectUniqueSample(
        kBatteryDischargeRateMilliwattsTenMinutesHistogramName,
        kExpectedDischargeRate_mW, 1);
  }

  {
    base::HistogramTester tester;

    // t = 31 minutes: The interval duration is invalid.
    task_environment_.FastForwardBy(base::Minutes(11));
    battery_discharge_reporter.OnBatteryStateSampled(
        MakeBatteryState(kHalfBatteryChargeLevel - 400));
    tester.ExpectUniqueSample(kBatteryDischargeModeTenMinutesHistogramName,
                              BatteryDischargeMode::kInvalidInterval, 1);
    tester.ExpectTotalCount(
        kBatteryDischargeRateMilliwattsTenMinutesHistogramName, 0);
  }
}
#endif  // BUILDFLAG(IS_WIN)