blob: efa46f2593ae690f5cbf526d65f04344fd537cd0 [file] [log] [blame]
// Copyright 2014 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 "content/browser/power_usage_monitor_impl.h"
#include "content/public/browser/notification_types.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "device/battery/battery_monitor.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
// Dummy ID to identify a phantom RenderProcessHost in tests.
const int kDummyRenderProcessHostID = 1;
class SystemInterfaceForTest : public PowerUsageMonitor::SystemInterface {
public:
SystemInterfaceForTest()
: num_pending_histogram_reports_(0),
discharge_percent_per_hour_(0),
now_(base::Time::FromInternalValue(1000)) {}
~SystemInterfaceForTest() override {}
int num_pending_histogram_reports() const {
return num_pending_histogram_reports_;
}
int discharge_percent_per_hour() const {
return discharge_percent_per_hour_;
}
void AdvanceClockSeconds(int seconds) {
now_ += base::TimeDelta::FromSeconds(seconds);
}
void AdvanceClockMinutes(int minutes) {
now_ += base::TimeDelta::FromMinutes(minutes);
}
void ScheduleHistogramReport(base::TimeDelta delay) override {
num_pending_histogram_reports_++;
}
void CancelPendingHistogramReports() override {
num_pending_histogram_reports_ = 0;
}
void RecordDischargePercentPerHour(int percent_per_hour) override {
discharge_percent_per_hour_ = percent_per_hour;
}
base::Time Now() override { return now_; }
private:
int num_pending_histogram_reports_;
int discharge_percent_per_hour_;
base::Time now_;
};
class PowerUsageMonitorTest : public testing::Test {
protected:
void SetUp() override {
monitor_.reset(new PowerUsageMonitor);
// PowerUsageMonitor assumes ownership.
scoped_ptr<SystemInterfaceForTest> test_interface(
new SystemInterfaceForTest());
system_interface_ = test_interface.get();
monitor_->SetSystemInterfaceForTest(test_interface.Pass());
// Without live renderers, the monitor won't do anything.
monitor_->OnRenderProcessNotification(NOTIFICATION_RENDERER_PROCESS_CREATED,
kDummyRenderProcessHostID);
}
void UpdateBatteryStatus(bool charging, double battery_level) {
device::BatteryStatus battery_status;
battery_status.charging = charging;
battery_status.level = battery_level;
monitor_->OnBatteryStatusUpdate(battery_status);
}
void KillTestRenderer() {
monitor_->OnRenderProcessNotification(
NOTIFICATION_RENDERER_PROCESS_CLOSED, kDummyRenderProcessHostID);
}
scoped_ptr<PowerUsageMonitor> monitor_;
SystemInterfaceForTest* system_interface_;
TestBrowserThreadBundle thread_bundle_;
};
TEST_F(PowerUsageMonitorTest, StartStopQuickly) {
// Going on battery power.
UpdateBatteryStatus(false, 1.0);
int initial_num_histogram_reports =
system_interface_->num_pending_histogram_reports();
ASSERT_GT(initial_num_histogram_reports, 0);
// Battery level goes down a bit.
system_interface_->AdvanceClockSeconds(1);
UpdateBatteryStatus(false, 0.9);
ASSERT_EQ(initial_num_histogram_reports,
system_interface_->num_pending_histogram_reports());
ASSERT_EQ(0, system_interface_->discharge_percent_per_hour());
// Wall power connected.
system_interface_->AdvanceClockSeconds(30);
UpdateBatteryStatus(true, 0);
ASSERT_EQ(0, system_interface_->num_pending_histogram_reports());
ASSERT_EQ(0, system_interface_->discharge_percent_per_hour());
}
TEST_F(PowerUsageMonitorTest, DischargePercentReported) {
// Going on battery power.
UpdateBatteryStatus(false, 1.0);
int initial_num_histogram_reports =
system_interface_->num_pending_histogram_reports();
ASSERT_GT(initial_num_histogram_reports, 0);
// Battery level goes down a bit.
system_interface_->AdvanceClockSeconds(30);
UpdateBatteryStatus(false, 0.9);
ASSERT_EQ(initial_num_histogram_reports,
system_interface_->num_pending_histogram_reports());
ASSERT_EQ(0, system_interface_->discharge_percent_per_hour());
// Wall power connected.
system_interface_->AdvanceClockMinutes(31);
UpdateBatteryStatus(true, 0);
ASSERT_EQ(0, system_interface_->num_pending_histogram_reports());
ASSERT_GT(system_interface_->discharge_percent_per_hour(), 0);
}
TEST_F(PowerUsageMonitorTest, NoRenderersDisablesMonitoring) {
KillTestRenderer();
// Going on battery power.
UpdateBatteryStatus(false, 1.0);
ASSERT_EQ(0, system_interface_->num_pending_histogram_reports());
ASSERT_EQ(0, system_interface_->discharge_percent_per_hour());
// Wall power connected.
system_interface_->AdvanceClockSeconds(30);
UpdateBatteryStatus(true, 0.5);
ASSERT_EQ(0, system_interface_->num_pending_histogram_reports());
ASSERT_EQ(0, system_interface_->discharge_percent_per_hour());
}
TEST_F(PowerUsageMonitorTest, NoRenderersCancelsInProgressMonitoring) {
// Going on battery power.
UpdateBatteryStatus(false, 1.0);
ASSERT_GT(system_interface_->num_pending_histogram_reports(), 0);
ASSERT_EQ(0, system_interface_->discharge_percent_per_hour());
// All renderers killed.
KillTestRenderer();
ASSERT_EQ(0, system_interface_->num_pending_histogram_reports());
// Wall power connected.
system_interface_->AdvanceClockMinutes(31);
UpdateBatteryStatus(true, 0);
ASSERT_EQ(0, system_interface_->num_pending_histogram_reports());
ASSERT_EQ(0, system_interface_->discharge_percent_per_hour());
}
} // namespace content