// Copyright 2013 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/power_monitor/power_monitor.h" #include #include "base/logging.h" #include "base/no_destructor.h" #include "base/power_monitor/power_monitor_source.h" #include "base/trace_event/base_tracing.h" #include "build/build_config.h" namespace base { void PowerMonitor::Initialize(std::unique_ptr source) { DCHECK(!IsInitialized()); PowerMonitor* power_monitor = GetInstance(); power_monitor->source_ = std::move(source); // When a power source is associated with the power monitor, ensure the // initial state is propagated to observers, if needed. PowerMonitor::NotifyPowerStateChange( PowerMonitor::Source()->IsOnBatteryPower()); PowerMonitor::PowerMonitor::NotifyThermalStateChange( PowerMonitor::Source()->GetCurrentThermalState()); PowerMonitor::PowerMonitor::NotifySpeedLimitChange( PowerMonitor::Source()->GetInitialSpeedLimit()); } bool PowerMonitor::IsInitialized() { return GetInstance()->source_.get() != nullptr; } // static void PowerMonitor::AddPowerSuspendObserver(PowerSuspendObserver* obs) { GetInstance()->power_suspend_observers_->AddObserver(obs); } // static void PowerMonitor::RemovePowerSuspendObserver(PowerSuspendObserver* obs) { GetInstance()->power_suspend_observers_->RemoveObserver(obs); } // static void PowerMonitor::AddPowerStateObserver(PowerStateObserver* obs) { GetInstance()->power_state_observers_->AddObserver(obs); } // static void PowerMonitor::RemovePowerStateObserver(PowerStateObserver* obs) { GetInstance()->power_state_observers_->RemoveObserver(obs); } // static void PowerMonitor::AddPowerThermalObserver(PowerThermalObserver* obs) { GetInstance()->thermal_state_observers_->AddObserver(obs); } // static void PowerMonitor::RemovePowerThermalObserver(PowerThermalObserver* obs) { GetInstance()->thermal_state_observers_->RemoveObserver(obs); } // static bool PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState( PowerSuspendObserver* obs) { PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->is_system_suspended_lock_); power_monitor->power_suspend_observers_->AddObserver(obs); return power_monitor->is_system_suspended_; } // static bool PowerMonitor::AddPowerStateObserverAndReturnOnBatteryState( PowerStateObserver* obs) { PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->on_battery_power_lock_); power_monitor->power_state_observers_->AddObserver(obs); return power_monitor->on_battery_power_; } // static PowerThermalObserver::DeviceThermalState PowerMonitor::AddPowerStateObserverAndReturnPowerThermalState( PowerThermalObserver* obs) { PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->power_thermal_state_lock_); power_monitor->thermal_state_observers_->AddObserver(obs); return power_monitor->power_thermal_state_; } PowerMonitorSource* PowerMonitor::Source() { return GetInstance()->source_.get(); } bool PowerMonitor::IsOnBatteryPower() { DCHECK(IsInitialized()); PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->on_battery_power_lock_); return power_monitor->on_battery_power_; } TimeTicks PowerMonitor::GetLastSystemResumeTime() { PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->is_system_suspended_lock_); return power_monitor->last_system_resume_time_; } void PowerMonitor::ShutdownForTesting() { GetInstance()->source_ = nullptr; PowerMonitor* power_monitor = GetInstance(); { AutoLock auto_lock(power_monitor->is_system_suspended_lock_); power_monitor->is_system_suspended_ = false; power_monitor->last_system_resume_time_ = TimeTicks(); } { AutoLock auto_lock(power_monitor->on_battery_power_lock_); power_monitor->on_battery_power_ = false; } { AutoLock auto_lock(power_monitor->power_thermal_state_lock_); power_monitor->power_thermal_state_ = PowerThermalObserver::DeviceThermalState::kUnknown; } } // static PowerThermalObserver::DeviceThermalState PowerMonitor::GetCurrentThermalState() { DCHECK(IsInitialized()); return GetInstance()->source_->GetCurrentThermalState(); } // static void PowerMonitor::SetCurrentThermalState( PowerThermalObserver::DeviceThermalState state) { DCHECK(IsInitialized()); GetInstance()->source_->SetCurrentThermalState(state); } #if BUILDFLAG(IS_ANDROID) int PowerMonitor::GetRemainingBatteryCapacity() { DCHECK(IsInitialized()); return PowerMonitor::Source()->GetRemainingBatteryCapacity(); } #endif // BUILDFLAG(IS_ANDROID) void PowerMonitor::NotifyPowerStateChange(bool on_battery_power) { DCHECK(IsInitialized()); DVLOG(1) << "PowerStateChange: " << (on_battery_power ? "On" : "Off") << " battery"; PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->on_battery_power_lock_); if (power_monitor->on_battery_power_ != on_battery_power) { power_monitor->on_battery_power_ = on_battery_power; GetInstance()->power_state_observers_->Notify( FROM_HERE, &PowerStateObserver::OnPowerStateChange, on_battery_power); } } void PowerMonitor::NotifySuspend() { DCHECK(IsInitialized()); TRACE_EVENT_INSTANT0("base", "PowerMonitor::NotifySuspend", TRACE_EVENT_SCOPE_PROCESS); DVLOG(1) << "Power Suspending"; PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->is_system_suspended_lock_); if (!power_monitor->is_system_suspended_) { power_monitor->is_system_suspended_ = true; power_monitor->last_system_resume_time_ = TimeTicks::Max(); GetInstance()->power_suspend_observers_->Notify( FROM_HERE, &PowerSuspendObserver::OnSuspend); } } void PowerMonitor::NotifyResume() { DCHECK(IsInitialized()); TRACE_EVENT_INSTANT0("base", "PowerMonitor::NotifyResume", TRACE_EVENT_SCOPE_PROCESS); DVLOG(1) << "Power Resuming"; TimeTicks resume_time = TimeTicks::Now(); PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->is_system_suspended_lock_); if (power_monitor->is_system_suspended_) { power_monitor->is_system_suspended_ = false; power_monitor->last_system_resume_time_ = resume_time; GetInstance()->power_suspend_observers_->Notify( FROM_HERE, &PowerSuspendObserver::OnResume); } } void PowerMonitor::NotifyThermalStateChange( PowerThermalObserver::DeviceThermalState new_state) { DCHECK(IsInitialized()); DVLOG(1) << "ThermalStateChange: " << PowerMonitorSource::DeviceThermalStateToString(new_state); PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->power_thermal_state_lock_); if (power_monitor->power_thermal_state_ != new_state) { power_monitor->power_thermal_state_ = new_state; GetInstance()->thermal_state_observers_->Notify( FROM_HERE, &PowerThermalObserver::OnThermalStateChange, new_state); } } void PowerMonitor::NotifySpeedLimitChange(int speed_limit) { DCHECK(IsInitialized()); DVLOG(1) << "SpeedLimitChange: " << speed_limit; PowerMonitor* power_monitor = GetInstance(); AutoLock auto_lock(power_monitor->power_thermal_state_lock_); if (power_monitor->speed_limit_ != speed_limit) { power_monitor->speed_limit_ = speed_limit; GetInstance()->thermal_state_observers_->Notify( FROM_HERE, &PowerThermalObserver::OnSpeedLimitChange, speed_limit); } } PowerMonitor* PowerMonitor::GetInstance() { static base::NoDestructor power_monitor; return power_monitor.get(); } PowerMonitor::PowerMonitor() : power_state_observers_( base::MakeRefCounted>()), power_suspend_observers_( base::MakeRefCounted>()), thermal_state_observers_( base::MakeRefCounted< ObserverListThreadSafe>()) {} PowerMonitor::~PowerMonitor() = default; } // namespace base