• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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