1 // Copyright 2013 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_ 6 #define BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "base/base_export.h" 12 #include "base/power_monitor/power_monitor_source.h" 13 #include "base/power_monitor/power_observer.h" 14 #include "build/build_config.h" 15 #include "build/chromeos_buildflags.h" 16 17 #if BUILDFLAG(IS_WIN) 18 #include <windows.h> 19 20 #include "base/power_monitor/speed_limit_observer_win.h" 21 #include "base/threading/sequence_bound.h" 22 #endif // BUILDFLAG(IS_WIN) 23 24 #if BUILDFLAG(IS_MAC) 25 #include <IOKit/IOTypes.h> 26 27 #include "base/mac/scoped_cftyperef.h" 28 #include "base/mac/scoped_ionotificationportref.h" 29 #include "base/power_monitor/battery_level_provider.h" 30 #include "base/power_monitor/iopm_power_source_sampling_event_source.h" 31 #include "base/power_monitor/thermal_state_observer_mac.h" 32 #endif // BUILDFLAG(IS_MAC) 33 34 #if BUILDFLAG(IS_IOS) 35 #include <objc/runtime.h> 36 #endif // BUILDFLAG(IS_IOS) 37 38 namespace base { 39 40 // A class used to monitor the power state change and notify the observers about 41 // the change event. 42 class BASE_EXPORT PowerMonitorDeviceSource : public PowerMonitorSource { 43 public: 44 PowerMonitorDeviceSource(); 45 46 PowerMonitorDeviceSource(const PowerMonitorDeviceSource&) = delete; 47 PowerMonitorDeviceSource& operator=(const PowerMonitorDeviceSource&) = delete; 48 49 ~PowerMonitorDeviceSource() override; 50 51 #if BUILDFLAG(IS_CHROMEOS) 52 // On Chrome OS, Chrome receives power-related events from powerd, the system 53 // power daemon, via D-Bus signals received on the UI thread. base can't 54 // directly depend on that code, so this class instead exposes static methods 55 // so that events can be passed in. 56 static void SetPowerSource(bool on_battery); 57 static void HandleSystemSuspending(); 58 static void HandleSystemResumed(); 59 static void ThermalEventReceived( 60 PowerThermalObserver::DeviceThermalState state); 61 62 // These two methods is used for handling thermal state update requests, such 63 // as asking for initial state when starting lisitening to thermal change. 64 PowerThermalObserver::DeviceThermalState GetCurrentThermalState() override; 65 void SetCurrentThermalState( 66 PowerThermalObserver::DeviceThermalState state) override; 67 #endif 68 69 private: 70 friend class PowerMonitorDeviceSourceTest; 71 72 #if BUILDFLAG(IS_WIN) 73 // Represents a message-only window for power message handling on Windows. 74 // Only allow PowerMonitor to create it. 75 class PowerMessageWindow { 76 public: 77 PowerMessageWindow(); 78 ~PowerMessageWindow(); 79 80 private: 81 static LRESULT CALLBACK WndProcThunk(HWND hwnd, 82 UINT message, 83 WPARAM wparam, 84 LPARAM lparam); 85 86 // Instance of the module containing the window procedure. 87 HMODULE instance_ = nullptr; 88 // A hidden message-only window. 89 HWND message_hwnd_ = nullptr; 90 // A handle, returned when we register for power setting notification 91 HPOWERNOTIFY power_notify_handle_ = nullptr; 92 }; 93 #endif // BUILDFLAG(IS_WIN) 94 95 #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) 96 void PlatformInit(); 97 void PlatformDestroy(); 98 #endif // BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) 99 100 #if BUILDFLAG(IS_MAC) 101 // Callback from IORegisterForSystemPower(). |refcon| is the |this| pointer. 102 static void SystemPowerEventCallback(void* refcon, 103 io_service_t service, 104 natural_t message_type, 105 void* message_argument); 106 #endif // BUILDFLAG(IS_MAC) 107 108 // Platform-specific method to check whether the system is currently 109 // running on battery power. Returns true if running on batteries, 110 // false otherwise. 111 bool IsOnBatteryPower() override; 112 113 #if BUILDFLAG(IS_ANDROID) 114 PowerThermalObserver::DeviceThermalState GetCurrentThermalState() override; 115 int GetRemainingBatteryCapacity() override; 116 #endif // BUILDFLAG(IS_ANDROID) 117 118 #if BUILDFLAG(IS_WIN) 119 // PowerMonitorSource: 120 int GetInitialSpeedLimit() override; 121 #endif // BUILDFLAG(IS_WIN) 122 123 #if BUILDFLAG(IS_MAC) 124 // PowerMonitorSource: 125 PowerThermalObserver::DeviceThermalState GetCurrentThermalState() override; 126 int GetInitialSpeedLimit() override; 127 128 // Retrieves the current battery state to update `is_on_battery_`. 129 void GetBatteryState(); 130 void OnBatteryStateReceived( 131 const absl::optional<BatteryLevelProvider::BatteryState>& battery_state); 132 133 // Reference to the system IOPMrootDomain port. 134 io_connect_t power_manager_port_ = IO_OBJECT_NULL; 135 136 // Notification port that delivers power (sleep/wake) notifications. 137 mac::ScopedIONotificationPortRef notification_port_; 138 139 // Notifier reference for the |notification_port_|. 140 io_object_t notifier_ = IO_OBJECT_NULL; 141 142 // Generates power-source-change events. 143 IOPMPowerSourceSamplingEventSource power_source_event_source_; 144 145 std::unique_ptr<BatteryLevelProvider> battery_level_provider_; 146 147 // Observer of thermal state events: critical temperature etc. 148 std::unique_ptr<ThermalStateObserverMac> thermal_state_observer_; 149 150 bool is_on_battery_ = false; 151 #endif 152 153 #if BUILDFLAG(IS_IOS) 154 // Holds pointers to system event notification observers. 155 std::vector<id> notification_observers_; 156 #endif 157 158 #if BUILDFLAG(IS_WIN) 159 PowerMessageWindow power_message_window_; 160 // |speed_limit_observer_| is owned by the main/UI thread but the 161 // SpeedLimitObserverWin is bound to a different sequence. 162 std::unique_ptr<base::SequenceBound<SpeedLimitObserverWin>> 163 speed_limit_observer_; 164 #endif 165 166 #if BUILDFLAG(IS_CHROMEOS) 167 PowerThermalObserver::DeviceThermalState current_thermal_state_ = 168 PowerThermalObserver::DeviceThermalState::kUnknown; 169 #endif 170 }; 171 172 } // namespace base 173 174 #endif // BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_ 175