| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // 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_device_source.h" |
| |
| #include "base/message_loop/message_loop.h" |
| #include "base/power_monitor/power_monitor.h" |
| #include "base/power_monitor/power_monitor_source.h" |
| #include "base/win/wrapped_window_proc.h" |
| |
| namespace base { |
| |
| void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) { |
| PowerMonitorSource::ProcessPowerEvent(event); |
| } |
| |
| namespace { |
| |
| const wchar_t kWindowClassName[] = L"Base_PowerMessageWindow"; |
| |
| void ProcessWmPowerBroadcastMessage(WPARAM event_id) { |
| PowerMonitorSource::PowerEvent power_event; |
| switch (event_id) { |
| case PBT_APMPOWERSTATUSCHANGE: // The power status changed. |
| power_event = PowerMonitorSource::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 = PowerMonitorSource::RESUME_EVENT; |
| break; |
| case PBT_APMSUSPEND: // System has been suspended. |
| power_event = PowerMonitorSource::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. |
| } |
| |
| ProcessPowerEventHelper(power_event); |
| } |
| |
| } // namespace |
| |
| // Function to query the system to see if it is currently running on |
| // battery power. Returns true if running on battery. |
| bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() { |
| SYSTEM_POWER_STATUS status; |
| if (!GetSystemPowerStatus(&status)) { |
| DPLOG(ERROR) << "GetSystemPowerStatus failed"; |
| return false; |
| } |
| return (status.ACLineStatus == 0); |
| } |
| |
| PowerMonitorDeviceSource::PowerMessageWindow::PowerMessageWindow() |
| : instance_(NULL), message_hwnd_(NULL) { |
| if (!MessageLoopForUI::IsCurrent()) { |
| // Creating this window in (e.g.) a renderer inhibits shutdown on Windows. |
| // See http://crbug.com/230122. TODO(vandebo): http://crbug.com/236031 |
| DLOG(ERROR) |
| << "Cannot create windows on non-UI thread, power monitor disabled!"; |
| return; |
| } |
| WNDCLASSEX window_class; |
| base::win::InitializeWindowClass( |
| kWindowClassName, |
| &base::win::WrappedWindowProc< |
| PowerMonitorDeviceSource::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); |
| } |
| |
| PowerMonitorDeviceSource::PowerMessageWindow::~PowerMessageWindow() { |
| if (message_hwnd_) { |
| DestroyWindow(message_hwnd_); |
| UnregisterClass(kWindowClassName, instance_); |
| } |
| } |
| |
| // static |
| LRESULT CALLBACK PowerMonitorDeviceSource::PowerMessageWindow::WndProcThunk( |
| HWND hwnd, |
| UINT message, |
| WPARAM wparam, |
| LPARAM lparam) { |
| switch (message) { |
| case WM_POWERBROADCAST: |
| ProcessWmPowerBroadcastMessage(wparam); |
| return TRUE; |
| default: |
| return ::DefWindowProc(hwnd, message, wparam, lparam); |
| } |
| } |
| |
| } // namespace base |