Index: base/system_monitor/system_monitor.cc |
diff --git a/base/system_monitor/system_monitor.cc b/base/system_monitor/system_monitor.cc |
index 7c960cc09ff17bfec38301418de567790c6bd009..8d285efda011c22cc99506328fa57a43bcbf516d 100644 |
--- a/base/system_monitor/system_monitor.cc |
+++ b/base/system_monitor/system_monitor.cc |
@@ -10,6 +10,10 @@ |
#include "base/message_loop.h" |
#include "base/time.h" |
+#if defined(OS_WIN) |
+#include "base/win/wrapped_window_proc.h" |
+#endif |
+ |
namespace base { |
static SystemMonitor* g_system_monitor = NULL; |
@@ -20,6 +24,116 @@ static SystemMonitor* g_system_monitor = NULL; |
static int kDelayedBatteryCheckMs = 10 * 1000; |
#endif // defined(ENABLE_BATTERY_MONITORING) |
+#if defined(OS_WIN) |
+namespace { |
+ |
+const wchar_t kWindowClassName[] = L"Base_PowerMessageWindow"; |
+ |
+} // namespace |
+ |
+class SystemMonitor::PowerMessageWindow { |
+ public: |
+ PowerMessageWindow(); |
+ ~PowerMessageWindow(); |
+ |
+ private: |
+ void ProcessWmPowerBroadcastMessage(int event_id); |
+ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, |
+ WPARAM wparam, LPARAM lparam); |
+ static LRESULT CALLBACK WndProcThunk(HWND hwnd, |
+ UINT message, |
+ WPARAM wparam, |
+ LPARAM lparam); |
+ // Instance of the module containing the window procedure. |
+ HMODULE instance_; |
+ // A hidden window handle. |
+ HWND message_hwnd_; |
+}; |
+ |
+SystemMonitor::PowerMessageWindow::PowerMessageWindow() |
+ : instance_(NULL), message_hwnd_(NULL) { |
+ WNDCLASSEX window_class; |
+ base::win::InitializeWindowClass( |
+ kWindowClassName, |
+ &base::win::WrappedWindowProc< |
+ SystemMonitor::PowerMessageWindow::WndProcThunk>, |
+ 0, 0, 0, NULL, NULL, NULL, NULL, NULL, |
+ &window_class); |
+ instance_ = window_class.hInstance; |
+ ATOM clazz = RegisterClassEx(&window_class); |
+ DCHECK(clazz); |
+ |
+ message_hwnd_ = CreateWindow(kWindowClassName, |
+ NULL, 0, 0, 0, 0, 0, 0, 0, instance_, 0); |
+ SetWindowLongPtr(message_hwnd_, GWLP_USERDATA, |
+ reinterpret_cast<LONG_PTR>(this)); |
+} |
+ |
+SystemMonitor::PowerMessageWindow::~PowerMessageWindow() { |
+ if (message_hwnd_) { |
+ DestroyWindow(message_hwnd_); |
+ UnregisterClass(kWindowClassName, instance_); |
+ } |
+} |
+ |
+void SystemMonitor::PowerMessageWindow::ProcessWmPowerBroadcastMessage( |
+ int event_id) { |
+ SystemMonitor::PowerEvent power_event; |
+ switch (event_id) { |
+ case PBT_APMPOWERSTATUSCHANGE: // The power status changed. |
+ power_event = SystemMonitor::POWER_STATE_EVENT; |
+ break; |
+ case PBT_APMRESUMEAUTOMATIC: // Resume from suspend. |
+ //case PBT_APMRESUMESUSPEND: // User-initiated resume from suspend. |
+ // We don't notify for this latter event |
+ // because if it occurs it is always sent as a |
+ // second event after PBT_APMRESUMEAUTOMATIC. |
+ power_event = SystemMonitor::RESUME_EVENT; |
+ break; |
+ case PBT_APMSUSPEND: // System has been suspended. |
+ power_event = SystemMonitor::SUSPEND_EVENT; |
+ break; |
+ default: |
+ return; |
+ |
+ // Other Power Events: |
+ // PBT_APMBATTERYLOW - removed in Vista. |
+ // PBT_APMOEMEVENT - removed in Vista. |
+ // PBT_APMQUERYSUSPEND - removed in Vista. |
+ // PBT_APMQUERYSUSPENDFAILED - removed in Vista. |
+ // PBT_APMRESUMECRITICAL - removed in Vista. |
+ // PBT_POWERSETTINGCHANGE - user changed the power settings. |
+ } |
+ SystemMonitor::Get()->ProcessPowerMessage(power_event); |
+} |
+ |
+LRESULT CALLBACK SystemMonitor::PowerMessageWindow::WndProc( |
+ HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { |
+ switch (message) { |
+ case WM_POWERBROADCAST: { |
+ DWORD power_event = static_cast<DWORD>(message); |
+ ProcessWmPowerBroadcastMessage(power_event); |
+ return TRUE; |
+ } |
+ default: |
+ break; |
+ } |
+ return ::DefWindowProc(hwnd, message, wparam, lparam); |
+} |
+ |
+// static |
+LRESULT CALLBACK SystemMonitor::PowerMessageWindow::WndProcThunk( |
+ HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { |
+ PowerMessageWindow* message_hwnd = |
+ reinterpret_cast<PowerMessageWindow*>( |
+ GetWindowLongPtr(hwnd, GWLP_USERDATA)); |
+ if (message_hwnd) |
+ return message_hwnd->WndProc(hwnd, message, wparam, lparam); |
+ return ::DefWindowProc(hwnd, message, wparam, lparam); |
+} |
+#endif // OS_WIN |
+ |
+ |
SystemMonitor::SystemMonitor() |
: power_observer_list_(new ObserverListThreadSafe<PowerObserver>()), |
devices_changed_observer_list_( |
@@ -38,6 +152,9 @@ SystemMonitor::SystemMonitor() |
#if defined(OS_MACOSX) |
PlatformInit(); |
#endif |
+#if defined(OS_WIN) |
+ power_message_window_.reset(new PowerMessageWindow); |
+#endif |
} |
SystemMonitor::~SystemMonitor() { |