diff options
author | hongbo.min@intel.com <hongbo.min@intel.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-01 03:20:30 +0000 |
---|---|---|
committer | hongbo.min@intel.com <hongbo.min@intel.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-01 03:20:30 +0000 |
commit | 9cd7bf452a0098d938cae02de278b78e4efb3f75 (patch) | |
tree | be7f8b97faffca8356889101dd3c9379a7bbc588 | |
parent | cc12fbb00143737e4cb59b17fb8052f68891859a (diff) | |
download | chromium_src-9cd7bf452a0098d938cae02de278b78e4efb3f75.zip chromium_src-9cd7bf452a0098d938cae02de278b78e4efb3f75.tar.gz chromium_src-9cd7bf452a0098d938cae02de278b78e4efb3f75.tar.bz2 |
Move power event handling logic from ui/ layer to base/ on Windows
This fix is to create a new window for receiving and handling power broadcast message
in base/ instead of in each HWNDMessageHandler instance. It addressed the issue of layer
violation in power message handling and make base/ self-contained.
BUG=149059
Review URL: https://chromiumcodereview.appspot.com/11821050
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@185433 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/system_monitor/system_monitor.h | 34 | ||||
-rw-r--r-- | base/system_monitor/system_monitor_win.cc | 89 | ||||
-rw-r--r-- | ui/views/win/hwnd_message_handler.cc | 9 | ||||
-rw-r--r-- | ui/views/win/hwnd_message_handler.h | 2 |
4 files changed, 102 insertions, 32 deletions
diff --git a/base/system_monitor/system_monitor.h b/base/system_monitor/system_monitor.h index 6620d27..10f279f 100644 --- a/base/system_monitor/system_monitor.h +++ b/base/system_monitor/system_monitor.h @@ -134,13 +134,6 @@ class BASE_EXPORT SystemMonitor { // be copied. Any significant addition to this class is blocked on // refactoring to improve the state of affairs. See http://crbug.com/149059 -#if defined(OS_WIN) - // Windows-specific handling of a WM_POWERBROADCAST message. - // Embedders of this API should hook their top-level window - // message loop and forward WM_POWERBROADCAST through this call. - void ProcessWmPowerBroadcastMessage(int event_id); -#endif - // Cross-platform handling of a power event. void ProcessPowerMessage(PowerEvent event_id); @@ -148,6 +141,29 @@ class BASE_EXPORT SystemMonitor { void ProcessDevicesChanged(DeviceType device_type); private: +#if defined(OS_WIN) + // Represents a message-only window for power message handling on Windows. + // Only allow SystemMonitor to create it. + class 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 message-only window. + HWND message_hwnd_; + }; +#endif + #if defined(OS_MACOSX) void PlatformInit(); void PlatformDestroy(); @@ -183,6 +199,10 @@ class BASE_EXPORT SystemMonitor { std::vector<id> notification_observers_; #endif +#if defined(OS_WIN) + PowerMessageWindow power_message_window_; +#endif + DISALLOW_COPY_AND_ASSIGN(SystemMonitor); }; diff --git a/base/system_monitor/system_monitor_win.cc b/base/system_monitor/system_monitor_win.cc index 69ab85e..562b69b 100644 --- a/base/system_monitor/system_monitor_win.cc +++ b/base/system_monitor/system_monitor_win.cc @@ -4,23 +4,69 @@ #include "base/system_monitor/system_monitor.h" +#include "base/win/wrapped_window_proc.h" + namespace base { -void SystemMonitor::ProcessWmPowerBroadcastMessage(int event_id) { - PowerEvent power_event; +namespace { + +const wchar_t kWindowClassName[] = L"Base_PowerMessageWindow"; + +} // namespace + +// Function to query the system to see if it is currently running on +// battery power. Returns true if running on battery. +bool SystemMonitor::IsBatteryPower() { + SYSTEM_POWER_STATUS status; + if (!GetSystemPowerStatus(&status)) { + DLOG_GETLASTERROR(ERROR) << "GetSystemPowerStatus failed"; + return false; + } + return (status.ACLineStatus == 0); +} + +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_ = CreateWindowEx(WS_EX_NOACTIVATE, kWindowClassName, + NULL, WS_POPUP, 0, 0, 0, 0, NULL, NULL, instance_, NULL); + 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 = POWER_STATE_EVENT; + 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 = RESUME_EVENT; + power_event = SystemMonitor::RESUME_EVENT; break; case PBT_APMSUSPEND: // System has been suspended. - power_event = SUSPEND_EVENT; + power_event = SystemMonitor::SUSPEND_EVENT; break; default: return; @@ -33,18 +79,33 @@ void SystemMonitor::ProcessWmPowerBroadcastMessage(int event_id) { // PBT_APMRESUMECRITICAL - removed in Vista. // PBT_POWERSETTINGCHANGE - user changed the power settings. } - ProcessPowerMessage(power_event); + + SystemMonitor::Get()->ProcessPowerMessage(power_event); } -// Function to query the system to see if it is currently running on -// battery power. Returns true if running on battery. -bool SystemMonitor::IsBatteryPower() { - SYSTEM_POWER_STATUS status; - if (!GetSystemPowerStatus(&status)) { - DLOG_GETLASTERROR(ERROR) << "GetSystemPowerStatus failed"; - return false; +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 (status.ACLineStatus == 0); + return ::DefWindowProc(hwnd, message, wparam, lparam); +} + +// static +LRESULT CALLBACK SystemMonitor::PowerMessageWindow::WndProcThunk( + HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { + SystemMonitor::PowerMessageWindow* message_hwnd = + reinterpret_cast<SystemMonitor::PowerMessageWindow*>( + GetWindowLongPtr(hwnd, GWLP_USERDATA)); + if (message_hwnd) + return message_hwnd->WndProc(hwnd, message, wparam, lparam); + return ::DefWindowProc(hwnd, message, wparam, lparam); } } // namespace base diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index d1c8534..8c7fdbb 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/debug/trace_event.h" -#include "base/system_monitor/system_monitor.h" #include "base/win/windows_version.h" #include "ui/base/events/event.h" #include "ui/base/events/event_utils.h" @@ -1888,14 +1887,6 @@ void HWNDMessageHandler::OnPaint(HDC dc) { } } -LRESULT HWNDMessageHandler::OnPowerBroadcast(DWORD power_event, DWORD data) { - base::SystemMonitor* monitor = base::SystemMonitor::Get(); - if (monitor) - monitor->ProcessWmPowerBroadcastMessage(power_event); - SetMsgHandled(FALSE); - return 0; -} - LRESULT HWNDMessageHandler::OnReflectedMessage(UINT message, WPARAM w_param, LPARAM l_param) { diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h index f69979f..3654b93 100644 --- a/ui/views/win/hwnd_message_handler.h +++ b/ui/views/win/hwnd_message_handler.h @@ -296,7 +296,6 @@ class VIEWS_EXPORT HWNDMessageHandler : public ui::WindowImpl, MSG_WM_NCPAINT(OnNCPaint) MSG_WM_NOTIFY(OnNotify) MSG_WM_PAINT(OnPaint) - MSG_WM_POWERBROADCAST(OnPowerBroadcast) MSG_WM_SETFOCUS(OnSetFocus) MSG_WM_SETICON(OnSetIcon) MSG_WM_SETTEXT(OnSetText) @@ -346,7 +345,6 @@ class VIEWS_EXPORT HWNDMessageHandler : public ui::WindowImpl, LRESULT OnNCUAHDrawFrame(UINT message, WPARAM w_param, LPARAM l_param); LRESULT OnNotify(int w_param, NMHDR* l_param); void OnPaint(HDC dc); - LRESULT OnPowerBroadcast(DWORD power_event, DWORD data); LRESULT OnReflectedMessage(UINT message, WPARAM w_param, LPARAM l_param); LRESULT OnSetCursor(UINT message, WPARAM w_param, LPARAM l_param); void OnSetFocus(HWND last_focused_window); |