#include "chrome/browser/performance_manager/public/user_tuning/battery_saver_mode_manager.h"
#include <optional>
#include <utility>
#include "base/check.h"
#include "base/check_deref.h"
#include "base/check_is_test.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/message_loop/message_pump.h"
#include "base/notreached.h"
#include "base/power_monitor/battery_state_sampler.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_observer.h"
#include "base/run_loop.h"
#include "base/scoped_multi_source_observation.h"
#include "base/values.h"
#include "components/performance_manager/freezing/freezing_policy.h"
#include "components/performance_manager/performance_manager_impl.h"
#include "components/performance_manager/public/features.h"
#include "components/performance_manager/public/user_tuning/prefs.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/frame_rate_throttling.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_process_host_creation_observer.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/common/content_features.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_features.h"
#include "chromeos/dbus/power/power_manager_client.h"
#endif
namespace performance_manager::user_tuning {
namespace {
BatterySaverModeManager* g_battery_saver_mode_manager = …;
constexpr base::TimeDelta kBatteryUsageWriteFrequency = …;
BatterySaverModeState;
#if BUILDFLAG(IS_CHROMEOS_ASH)
constexpr int kBatterySaverModeThresholdAdjustmentForDisplayLevel = 3;
#else
constexpr int kBatterySaverModeThresholdAdjustmentForDisplayLevel = …;
#endif
class FrameThrottlingDelegateImpl
: public performance_manager::user_tuning::BatterySaverModeManager::
FrameThrottlingDelegate { … };
class ChildProcessTuningDelegateImpl
: public BatterySaverModeManager::ChildProcessTuningDelegate,
public content::RenderProcessHostCreationObserver,
public content::BrowserChildProcessObserver,
public content::RenderProcessHostObserver { … };
class FreezingDelegateImpl : public BatterySaverModeManager::FreezingDelegate { … };
}
class DesktopBatterySaverProvider
: public BatterySaverModeManager::BatterySaverProvider,
public base::PowerStateObserver,
public base::BatteryStateSampler::Observer { … };
#if BUILDFLAG(IS_CHROMEOS_ASH)
class ChromeOSBatterySaverProvider
: public BatterySaverModeManager::BatterySaverProvider,
public chromeos::PowerManagerClient::Observer {
public:
explicit ChromeOSBatterySaverProvider(BatterySaverModeManager* manager)
: manager_(manager) {
CHECK(manager_);
chromeos::PowerManagerClient* client = chromeos::PowerManagerClient::Get();
if (client) {
power_manager_client_observer_.Observe(client);
client->GetBatterySaverModeState(base::BindOnce(
&ChromeOSBatterySaverProvider::OnInitialBatterySaverModeObtained,
weak_ptr_factory_.GetWeakPtr()));
} else {
CHECK_IS_TEST();
}
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(
BatterySaverModeManager::kForceDeviceHasBatterySwitch)) {
force_has_battery_ = true;
has_battery_ = true;
}
}
~ChromeOSBatterySaverProvider() override = default;
void OnInitialBatterySaverModeObtained(
std::optional<power_manager::BatterySaverModeState> state) {
if (state) {
BatterySaverModeStateChanged(*state);
}
}
void BatterySaverModeStateChanged(
const power_manager::BatterySaverModeState& state) override {
if (!state.has_enabled() || enabled_ == state.enabled()) {
return;
}
enabled_ = state.enabled();
manager_->NotifyOnBatterySaverActiveChanged(enabled_);
}
void PowerChanged(
const power_manager::PowerSupplyProperties& proto) override {
bool device_has_battery =
proto.battery_state() !=
power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT;
has_battery_ = force_has_battery_ || device_has_battery;
}
bool DeviceHasBattery() const override { return has_battery_; }
bool IsBatterySaverModeEnabled() override { return false; }
bool IsBatterySaverModeManaged() override { return false; }
bool IsBatterySaverActive() const override { return enabled_; }
bool IsUsingBatteryPower() const override { return false; }
base::Time GetLastBatteryUsageTimestamp() const override {
return base::Time();
}
int SampledBatteryPercentage() const override { return -1; }
void SetTemporaryBatterySaverDisabledForSession(bool disabled) override {
NOTREACHED_IN_MIGRATION();
}
bool IsBatterySaverModeDisabledForSession() const override { return false; }
private:
bool enabled_ = false;
bool has_battery_ = false;
bool force_has_battery_ = false;
base::ScopedObservation<chromeos::PowerManagerClient,
chromeos::PowerManagerClient::Observer>
power_manager_client_observer_{this};
raw_ptr<BatterySaverModeManager> manager_;
base::WeakPtrFactory<ChromeOSBatterySaverProvider> weak_ptr_factory_{this};
};
#endif
const uint64_t BatterySaverModeManager::kLowBatteryThresholdPercent = …;
const char BatterySaverModeManager::kForceDeviceHasBatterySwitch[] = …;
bool BatterySaverModeManager::HasInstance() { … }
BatterySaverModeManager* BatterySaverModeManager::GetInstance() { … }
BatterySaverModeManager::~BatterySaverModeManager() { … }
void BatterySaverModeManager::AddObserver(Observer* o) { … }
void BatterySaverModeManager::RemoveObserver(Observer* o) { … }
bool BatterySaverModeManager::DeviceHasBattery() const { … }
bool BatterySaverModeManager::IsBatterySaverModeEnabled() { … }
bool BatterySaverModeManager::IsBatterySaverModeManaged() const { … }
bool BatterySaverModeManager::IsBatterySaverActive() const { … }
bool BatterySaverModeManager::IsUsingBatteryPower() const { … }
base::Time BatterySaverModeManager::GetLastBatteryUsageTimestamp() const { … }
int BatterySaverModeManager::SampledBatteryPercentage() const { … }
void BatterySaverModeManager::SetTemporaryBatterySaverDisabledForSession(
bool disabled) { … }
bool BatterySaverModeManager::IsBatterySaverModeDisabledForSession() const { … }
BatterySaverModeManager::BatterySaverModeManager(
PrefService* local_state,
std::unique_ptr<FrameThrottlingDelegate> frame_throttling_delegate,
std::unique_ptr<ChildProcessTuningDelegate> child_process_tuning_delegate,
std::unique_ptr<FreezingDelegate> freezing_delegate)
: … { … }
void BatterySaverModeManager::Start() { … }
void BatterySaverModeManager::NotifyOnBatterySaverModeChanged(
bool battery_saver_mode_enabled) { … }
void BatterySaverModeManager::NotifyOnBatterySaverActiveChanged(
bool battery_saver_mode_active) { … }
void BatterySaverModeManager::NotifyOnExternalPowerConnectedChanged(
bool on_battery_power) { … }
void BatterySaverModeManager::NotifyOnDeviceHasBatteryChanged(
bool has_battery) { … }
void BatterySaverModeManager::NotifyOnBatteryThresholdReached() { … }
}