1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/power_monitor/power_monitor.h" 6#include "base/power_monitor/power_monitor_device_source.h" 7#include "base/power_monitor/power_monitor_source.h" 8#include "base/win/wrapped_window_proc.h" 9 10namespace base { 11 12void ProcessPowerEventHelper(PowerMonitorSource::PowerEvent event) { 13 PowerMonitorSource::ProcessPowerEvent(event); 14} 15 16namespace { 17 18const wchar_t kWindowClassName[] = L"Base_PowerMessageWindow"; 19 20void ProcessWmPowerBroadcastMessage(WPARAM event_id) { 21 PowerMonitorSource::PowerEvent power_event; 22 switch (event_id) { 23 case PBT_APMPOWERSTATUSCHANGE: // The power status changed. 24 power_event = PowerMonitorSource::POWER_STATE_EVENT; 25 break; 26 case PBT_APMRESUMEAUTOMATIC: // Resume from suspend. 27 //case PBT_APMRESUMESUSPEND: // User-initiated resume from suspend. 28 // We don't notify for this latter event 29 // because if it occurs it is always sent as a 30 // second event after PBT_APMRESUMEAUTOMATIC. 31 power_event = PowerMonitorSource::RESUME_EVENT; 32 break; 33 case PBT_APMSUSPEND: // System has been suspended. 34 power_event = PowerMonitorSource::SUSPEND_EVENT; 35 break; 36 default: 37 return; 38 39 // Other Power Events: 40 // PBT_APMBATTERYLOW - removed in Vista. 41 // PBT_APMOEMEVENT - removed in Vista. 42 // PBT_APMQUERYSUSPEND - removed in Vista. 43 // PBT_APMQUERYSUSPENDFAILED - removed in Vista. 44 // PBT_APMRESUMECRITICAL - removed in Vista. 45 // PBT_POWERSETTINGCHANGE - user changed the power settings. 46 } 47 48 ProcessPowerEventHelper(power_event); 49} 50 51} // namespace 52 53// Function to query the system to see if it is currently running on 54// battery power. Returns true if running on battery. 55bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() { 56 SYSTEM_POWER_STATUS status; 57 if (!GetSystemPowerStatus(&status)) { 58 DPLOG(ERROR) << "GetSystemPowerStatus failed"; 59 return false; 60 } 61 return (status.ACLineStatus == 0); 62} 63 64PowerMonitorDeviceSource::PowerMessageWindow::PowerMessageWindow() 65 : instance_(NULL), message_hwnd_(NULL) { 66 if (!MessageLoopForUI::IsCurrent()) { 67 // Creating this window in (e.g.) a renderer inhibits shutdown on Windows. 68 // See http://crbug.com/230122. TODO(vandebo): http://crbug.com/236031 69 DLOG(ERROR) 70 << "Cannot create windows on non-UI thread, power monitor disabled!"; 71 return; 72 } 73 WNDCLASSEX window_class; 74 base::win::InitializeWindowClass( 75 kWindowClassName, 76 &base::win::WrappedWindowProc< 77 PowerMonitorDeviceSource::PowerMessageWindow::WndProcThunk>, 78 0, 0, 0, NULL, NULL, NULL, NULL, NULL, 79 &window_class); 80 instance_ = window_class.hInstance; 81 ATOM clazz = RegisterClassEx(&window_class); 82 DCHECK(clazz); 83 84 message_hwnd_ = CreateWindowEx(WS_EX_NOACTIVATE, kWindowClassName, 85 NULL, WS_POPUP, 0, 0, 0, 0, NULL, NULL, instance_, NULL); 86} 87 88PowerMonitorDeviceSource::PowerMessageWindow::~PowerMessageWindow() { 89 if (message_hwnd_) { 90 DestroyWindow(message_hwnd_); 91 UnregisterClass(kWindowClassName, instance_); 92 } 93} 94 95// static 96LRESULT CALLBACK PowerMonitorDeviceSource::PowerMessageWindow::WndProcThunk( 97 HWND hwnd, 98 UINT message, 99 WPARAM wparam, 100 LPARAM lparam) { 101 switch (message) { 102 case WM_POWERBROADCAST: 103 ProcessWmPowerBroadcastMessage(wparam); 104 return TRUE; 105 default: 106 return ::DefWindowProc(hwnd, message, wparam, lparam); 107 } 108} 109 110} // namespace base 111