Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Side by Side Diff: content/browser/battery_status/battery_status_manager_win.cc

Issue 480503002: [Win] Battery Status API: use SingletonHwnd for notifications. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added thread checker Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | ui/gfx/win/singleton_hwnd.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/battery_status/battery_status_manager_win.h" 5 #include "content/browser/battery_status/battery_status_manager_win.h"
6 6
7 #include "base/memory/ref_counted.h" 7 #include "base/memory/ref_counted.h"
8 #include "base/strings/string16.h"
9 #include "base/win/message_window.h"
10 #include "base/win/windows_version.h" 8 #include "base/win/windows_version.h"
11 #include "content/browser/battery_status/battery_status_manager.h" 9 #include "content/browser/battery_status/battery_status_manager.h"
12 #include "content/public/browser/browser_thread.h" 10 #include "content/public/browser/browser_thread.h"
11 #include "ui/gfx/win/singleton_hwnd.h"
13 12
14 namespace content { 13 namespace content {
15 14
16 namespace { 15 namespace {
17 16
18 typedef BatteryStatusService::BatteryUpdateCallback BatteryCallback; 17 typedef BatteryStatusService::BatteryUpdateCallback BatteryCallback;
19 18
20 const wchar_t kWindowClassName[] = L"BatteryStatusMessageWindow"; 19 // Listens to battery changes using a singleton message window.
21
22 // Message-only window for handling battery changes on Windows.
23 class BatteryStatusObserver 20 class BatteryStatusObserver
24 : public base::RefCountedThreadSafe<BatteryStatusObserver> { 21 : public gfx::SingletonHwnd::Observer,
22 public base::RefCountedThreadSafe<BatteryStatusObserver> {
25 public: 23 public:
26 explicit BatteryStatusObserver(const BatteryCallback& callback) 24 explicit BatteryStatusObserver(const BatteryCallback& callback)
27 : power_handle_(NULL), 25 : power_handle_(NULL),
28 battery_change_handle_(NULL), 26 battery_change_handle_(NULL),
29 callback_(callback) { 27 callback_(callback),
28 started_(false) {
30 } 29 }
31 30
32 virtual ~BatteryStatusObserver() { DCHECK(!window_); } 31 virtual ~BatteryStatusObserver() { DCHECK(!started_); }
33 32
34 void Start() { 33 void Start() {
35 // Need to start on the UI thread to receive battery status notifications. 34 // Need to start on the UI thread to receive battery status notifications.
36 BrowserThread::PostTask( 35 BrowserThread::PostTask(
37 BrowserThread::UI, 36 BrowserThread::UI,
38 FROM_HERE, 37 FROM_HERE,
39 base::Bind(&BatteryStatusObserver::StartOnUI, this)); 38 base::Bind(&BatteryStatusObserver::StartOnUI, this));
40 } 39 }
41 40
42 void Stop() { 41 void Stop() {
43 BrowserThread::PostTask( 42 BrowserThread::PostTask(
44 BrowserThread::UI, 43 BrowserThread::UI,
45 FROM_HERE, 44 FROM_HERE,
46 base::Bind(&BatteryStatusObserver::StopOnUI, this)); 45 base::Bind(&BatteryStatusObserver::StopOnUI, this));
47 } 46 }
48 47
49 private: 48 private:
50 void StartOnUI() { 49 void StartOnUI() {
51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
52 if (window_) 51 if (started_)
53 return; 52 return;
54 53
55 if (CreateMessageWindow()) { 54 gfx::SingletonHwnd* message_window = gfx::SingletonHwnd::GetInstance();
56 BatteryChanged(); 55 message_window->AddObserver(this);
57 // RegisterPowerSettingNotification function work from Windows Vista 56
58 // onwards. However even without them we will receive notifications, 57 // RegisterPowerSettingNotification function work from Windows Vista
59 // e.g. when a power source is connected. 58 // onwards. However even without them we will receive notifications,
60 // TODO(timvolodine) : consider polling for battery changes on windows 59 // e.g. when a power source is connected.
61 // versions prior to Vista, see crbug.com/402466. 60 // TODO(timvolodine) : consider polling for battery changes on windows
62 power_handle_ = 61 // versions prior to Vista, see crbug.com/402466.
63 RegisterNotification(&GUID_ACDC_POWER_SOURCE); 62 power_handle_ = RegisterNotification(&GUID_ACDC_POWER_SOURCE,
64 battery_change_handle_ = 63 message_window->hwnd());
65 RegisterNotification(&GUID_BATTERY_PERCENTAGE_REMAINING); 64 battery_change_handle_ =
66 } else { 65 RegisterNotification(&GUID_BATTERY_PERCENTAGE_REMAINING,
67 // Could not create a message window, execute callback with the default 66 message_window->hwnd());
68 // values. 67 BatteryChanged();
69 callback_.Run(blink::WebBatteryStatus()); 68 started_ = true;
70 }
71 } 69 }
72 70
73 void StopOnUI() { 71 void StopOnUI() {
74 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
75 if (!window_) 73 if (!started_)
76 return; 74 return;
77 75
78 if (power_handle_) 76 if (power_handle_)
79 UnregisterNotification(power_handle_); 77 UnregisterNotification(power_handle_);
80 if (battery_change_handle_) 78 if (battery_change_handle_)
81 UnregisterNotification(battery_change_handle_); 79 UnregisterNotification(battery_change_handle_);
82 window_.reset(); 80
81 gfx::SingletonHwnd::GetInstance()->RemoveObserver(this);
82 started_ = false;
83 } 83 }
84 84
85 void BatteryChanged() { 85 void BatteryChanged() {
86 SYSTEM_POWER_STATUS win_status; 86 SYSTEM_POWER_STATUS win_status;
87 if (GetSystemPowerStatus(&win_status)) 87 if (GetSystemPowerStatus(&win_status))
88 callback_.Run(ComputeWebBatteryStatus(win_status)); 88 callback_.Run(ComputeWebBatteryStatus(win_status));
89 else 89 else
90 callback_.Run(blink::WebBatteryStatus()); 90 callback_.Run(blink::WebBatteryStatus());
91 } 91 }
92 92
93 bool HandleMessage(UINT message, 93 // SingletonHwnd::Observer
94 WPARAM wparam, 94 void OnWndProc(HWND hwnd,
95 LPARAM lparam, 95 UINT message,
96 LRESULT* result) { 96 WPARAM wparam,
97 switch(message) { 97 LPARAM lparam) OVERRIDE {
98 case WM_POWERBROADCAST: 98 if (message != WM_POWERBROADCAST)
99 if (wparam == PBT_APMPOWERSTATUSCHANGE || 99 return;
100 wparam == PBT_POWERSETTINGCHANGE) { 100
101 BatteryChanged(); 101 if (wparam == PBT_APMPOWERSTATUSCHANGE ||
102 } 102 wparam == PBT_POWERSETTINGCHANGE) {
103 *result = NULL; 103 BatteryChanged();
104 return true;
105 default:
106 return false;
107 } 104 }
108 } 105 }
109 106
110 HPOWERNOTIFY RegisterNotification(LPCGUID power_setting) { 107 HPOWERNOTIFY RegisterNotification(LPCGUID power_setting, HWND hwnd) {
111 if (base::win::GetVersion() < base::win::VERSION_VISTA) 108 if (base::win::GetVersion() < base::win::VERSION_VISTA)
112 return NULL; 109 return NULL;
113 110
114 return RegisterPowerSettingNotification(window_->hwnd(), power_setting, 111 return RegisterPowerSettingNotification(hwnd,
115 DEVICE_NOTIFY_WINDOW_HANDLE); 112 power_setting,
113 DEVICE_NOTIFY_WINDOW_HANDLE);
116 } 114 }
117 115
118 BOOL UnregisterNotification(HPOWERNOTIFY handle) { 116 BOOL UnregisterNotification(HPOWERNOTIFY handle) {
119 if (base::win::GetVersion() < base::win::VERSION_VISTA) 117 if (base::win::GetVersion() < base::win::VERSION_VISTA)
120 return FALSE; 118 return FALSE;
121 119
122 return UnregisterPowerSettingNotification(handle); 120 return UnregisterPowerSettingNotification(handle);
123 } 121 }
124 122
125 bool CreateMessageWindow() {
126 // TODO(timvolodine): consider reusing the message window of PowerMonitor.
127 window_.reset(new base::win::MessageWindow());
128 if (!window_->CreateNamed(base::Bind(&BatteryStatusObserver::HandleMessage,
129 base::Unretained(this)),
130 base::string16(kWindowClassName))) {
131 LOG(ERROR) << "Failed to create message window: " << kWindowClassName;
132 window_.reset();
133 return false;
134 }
135 return true;
136 }
137
138 HPOWERNOTIFY power_handle_; 123 HPOWERNOTIFY power_handle_;
139 HPOWERNOTIFY battery_change_handle_; 124 HPOWERNOTIFY battery_change_handle_;
140 BatteryCallback callback_; 125 BatteryCallback callback_;
141 scoped_ptr<base::win::MessageWindow> window_; 126 bool started_;
142 127
143 DISALLOW_COPY_AND_ASSIGN(BatteryStatusObserver); 128 DISALLOW_COPY_AND_ASSIGN(BatteryStatusObserver);
144 }; 129 };
145 130
146 class BatteryStatusManagerWin : public BatteryStatusManager { 131 class BatteryStatusManagerWin : public BatteryStatusManager {
147 public: 132 public:
148 explicit BatteryStatusManagerWin(const BatteryCallback& callback) 133 explicit BatteryStatusManagerWin(const BatteryCallback& callback)
149 : battery_observer_(new BatteryStatusObserver(callback)) {} 134 : battery_observer_(new BatteryStatusObserver(callback)) {}
150 virtual ~BatteryStatusManagerWin() { battery_observer_->Stop(); } 135 virtual ~BatteryStatusManagerWin() { battery_observer_->Stop(); }
151 136
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 } 182 }
198 183
199 // static 184 // static
200 scoped_ptr<BatteryStatusManager> BatteryStatusManager::Create( 185 scoped_ptr<BatteryStatusManager> BatteryStatusManager::Create(
201 const BatteryStatusService::BatteryUpdateCallback& callback) { 186 const BatteryStatusService::BatteryUpdateCallback& callback) {
202 return scoped_ptr<BatteryStatusManager>( 187 return scoped_ptr<BatteryStatusManager>(
203 new BatteryStatusManagerWin(callback)); 188 new BatteryStatusManagerWin(callback));
204 } 189 }
205 190
206 } // namespace content 191 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | ui/gfx/win/singleton_hwnd.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698