Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "media/base/user_input_monitor.h" | 5 #include "media/base/user_input_monitor.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 17 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 18 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
| 19 #include "base/win/message_window.h" | 19 #include "base/win/message_window.h" |
| 20 #include "media/base/keyboard_event_counter.h" | 20 #include "media/base/keyboard_event_counter.h" |
| 21 #include "third_party/skia/include/core/SkPoint.h" | 21 #include "third_party/skia/include/core/SkPoint.h" |
| 22 #include "ui/events/keycodes/keyboard_code_conversion_win.h" | 22 #include "ui/events/keycodes/keyboard_code_conversion_win.h" |
| 23 | 23 |
| 24 namespace media { | 24 namespace media { |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // From the HID Usage Tables specification. | 27 // From the HID Usage Tables specification. |
| 28 const USHORT kGenericDesktopPage = 1; | 28 const USHORT kGenericDesktopPage = 1; |
| 29 const USHORT kMouseUsage = 2; | |
| 30 const USHORT kKeyboardUsage = 6; | 29 const USHORT kKeyboardUsage = 6; |
| 31 | 30 |
| 32 // This is the actual implementation of event monitoring. It's separated from | 31 // This is the actual implementation of event monitoring. It's separated from |
| 33 // UserInputMonitorWin since it needs to be deleted on the UI thread. | 32 // UserInputMonitorWin since it needs to be deleted on the UI thread. |
| 34 class UserInputMonitorWinCore | 33 class UserInputMonitorWinCore |
| 35 : public base::SupportsWeakPtr<UserInputMonitorWinCore>, | 34 : public base::SupportsWeakPtr<UserInputMonitorWinCore>, |
| 36 public base::MessageLoop::DestructionObserver { | 35 public base::MessageLoop::DestructionObserver { |
| 37 public: | 36 public: |
| 38 enum EventBitMask { | 37 enum EventBitMask { |
| 39 MOUSE_EVENT_MASK = 1, | 38 MOUSE_EVENT_MASK = 1, |
| 40 KEYBOARD_EVENT_MASK = 2, | 39 KEYBOARD_EVENT_MASK = 2, |
| 41 }; | 40 }; |
| 42 | 41 |
| 43 explicit UserInputMonitorWinCore( | 42 explicit UserInputMonitorWinCore( |
| 44 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, | 43 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); |
| 45 const scoped_refptr<UserInputMonitor::MouseListenerList>& | |
| 46 mouse_listeners); | |
| 47 ~UserInputMonitorWinCore() override; | 44 ~UserInputMonitorWinCore() override; |
| 48 | 45 |
| 49 // DestructionObserver overrides. | 46 // DestructionObserver overrides. |
| 50 void WillDestroyCurrentMessageLoop() override; | 47 void WillDestroyCurrentMessageLoop() override; |
| 51 | 48 |
| 52 size_t GetKeyPressCount() const; | 49 size_t GetKeyPressCount() const; |
| 53 void StartMonitor(EventBitMask type); | 50 void StartMonitor(EventBitMask type); |
| 54 void StopMonitor(EventBitMask type); | 51 void StopMonitor(EventBitMask type); |
| 55 | 52 |
| 56 private: | 53 private: |
| 57 // Handles WM_INPUT messages. | 54 // Handles WM_INPUT messages. |
| 58 LRESULT OnInput(HRAWINPUT input_handle); | 55 LRESULT OnInput(HRAWINPUT input_handle); |
| 59 // Handles messages received by |window_|. | 56 // Handles messages received by |window_|. |
| 60 bool HandleMessage(UINT message, | 57 bool HandleMessage(UINT message, |
| 61 WPARAM wparam, | 58 WPARAM wparam, |
| 62 LPARAM lparam, | 59 LPARAM lparam, |
| 63 LRESULT* result); | 60 LRESULT* result); |
| 64 RAWINPUTDEVICE* GetRawInputDevices(EventBitMask event, DWORD flags); | 61 RAWINPUTDEVICE* GetRawInputDevices(EventBitMask event, DWORD flags); |
| 65 | 62 |
| 66 // Task runner on which |window_| is created. | 63 // Task runner on which |window_| is created. |
| 67 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; | 64 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
| 68 scoped_refptr<base::ObserverListThreadSafe< | |
| 69 UserInputMonitor::MouseEventListener>> mouse_listeners_; | |
| 70 | 65 |
| 71 // These members are only accessed on the UI thread. | 66 // These members are only accessed on the UI thread. |
| 72 std::unique_ptr<base::win::MessageWindow> window_; | 67 std::unique_ptr<base::win::MessageWindow> window_; |
| 73 uint8_t events_monitored_; | 68 uint8_t events_monitored_; |
| 74 KeyboardEventCounter counter_; | 69 KeyboardEventCounter counter_; |
| 75 | 70 |
| 76 DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWinCore); | 71 DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWinCore); |
| 77 }; | 72 }; |
| 78 | 73 |
| 79 class UserInputMonitorWin : public UserInputMonitor { | 74 class UserInputMonitorWin : public UserInputMonitor { |
| 80 public: | 75 public: |
| 81 explicit UserInputMonitorWin( | 76 explicit UserInputMonitorWin( |
| 82 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner); | 77 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner); |
| 83 ~UserInputMonitorWin() override; | 78 ~UserInputMonitorWin() override; |
| 84 | 79 |
| 85 // Public UserInputMonitor overrides. | 80 // Public UserInputMonitor overrides. |
| 86 size_t GetKeyPressCount() const override; | 81 size_t GetKeyPressCount() const override; |
| 87 | 82 |
| 88 private: | 83 private: |
| 89 // Private UserInputMonitor overrides. | 84 // Private UserInputMonitor overrides. |
| 90 void StartKeyboardMonitoring() override; | 85 void StartKeyboardMonitoring() override; |
| 91 void StopKeyboardMonitoring() override; | 86 void StopKeyboardMonitoring() override; |
| 92 void StartMouseMonitoring() override; | |
| 93 void StopMouseMonitoring() override; | |
| 94 | 87 |
| 95 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; | 88 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
| 96 UserInputMonitorWinCore* core_; | 89 UserInputMonitorWinCore* core_; |
| 97 | 90 |
| 98 DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWin); | 91 DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWin); |
| 99 }; | 92 }; |
| 100 | 93 |
| 101 UserInputMonitorWinCore::UserInputMonitorWinCore( | 94 UserInputMonitorWinCore::UserInputMonitorWinCore( |
| 102 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, | 95 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) |
| 103 const scoped_refptr<UserInputMonitor::MouseListenerList>& mouse_listeners) | 96 : ui_task_runner_(ui_task_runner), events_monitored_(0) {} |
| 104 : ui_task_runner_(ui_task_runner), | |
| 105 mouse_listeners_(mouse_listeners), | |
| 106 events_monitored_(0) {} | |
| 107 | 97 |
| 108 UserInputMonitorWinCore::~UserInputMonitorWinCore() { | 98 UserInputMonitorWinCore::~UserInputMonitorWinCore() { |
| 109 DCHECK(!window_); | 99 DCHECK(!window_); |
| 110 DCHECK(!events_monitored_); | 100 DCHECK(!events_monitored_); |
| 111 } | 101 } |
| 112 | 102 |
| 113 void UserInputMonitorWinCore::WillDestroyCurrentMessageLoop() { | 103 void UserInputMonitorWinCore::WillDestroyCurrentMessageLoop() { |
| 114 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 104 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 115 StopMonitor(MOUSE_EVENT_MASK); | 105 StopMonitor(MOUSE_EVENT_MASK); |
|
Wez
2017/01/03 23:59:40
No need for this any more.
CJ
2017/01/07 00:12:36
Done.
| |
| 116 StopMonitor(KEYBOARD_EVENT_MASK); | 106 StopMonitor(KEYBOARD_EVENT_MASK); |
| 117 } | 107 } |
| 118 | 108 |
| 119 size_t UserInputMonitorWinCore::GetKeyPressCount() const { | 109 size_t UserInputMonitorWinCore::GetKeyPressCount() const { |
| 120 return counter_.GetKeyPressCount(); | 110 return counter_.GetKeyPressCount(); |
| 121 } | 111 } |
| 122 | 112 |
| 123 void UserInputMonitorWinCore::StartMonitor(EventBitMask type) { | 113 void UserInputMonitorWinCore::StartMonitor(EventBitMask type) { |
| 124 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 114 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 125 | 115 |
| 126 if (events_monitored_ & type) | 116 if (events_monitored_ & type) |
|
Wez
2017/01/03 23:59:40
nit: You can replace events_monitored_ with a bool
CJ
2017/01/07 00:12:36
Done.
| |
| 127 return; | 117 return; |
| 128 | 118 |
| 129 if (type == KEYBOARD_EVENT_MASK) | 119 if (type == KEYBOARD_EVENT_MASK) |
| 130 counter_.Reset(); | 120 counter_.Reset(); |
| 131 | 121 |
| 132 if (!window_) { | 122 if (!window_) { |
| 133 window_.reset(new base::win::MessageWindow()); | 123 window_.reset(new base::win::MessageWindow()); |
| 134 if (!window_->Create(base::Bind(&UserInputMonitorWinCore::HandleMessage, | 124 if (!window_->Create(base::Bind(&UserInputMonitorWinCore::HandleMessage, |
| 135 base::Unretained(this)))) { | 125 base::Unretained(this)))) { |
| 136 PLOG(ERROR) << "Failed to create the raw input window"; | 126 PLOG(ERROR) << "Failed to create the raw input window"; |
| 137 window_.reset(); | 127 window_.reset(); |
| 138 return; | 128 return; |
| 139 } | 129 } |
| 140 } | 130 } |
| 141 | 131 |
| 142 // Register to receive raw mouse and/or keyboard input. | 132 // Register to receive raw keyboard input. |
| 143 std::unique_ptr<RAWINPUTDEVICE> device( | 133 std::unique_ptr<RAWINPUTDEVICE> device( |
| 144 GetRawInputDevices(type, RIDEV_INPUTSINK)); | 134 GetRawInputDevices(type, RIDEV_INPUTSINK)); |
|
Wez
2017/01/03 23:59:40
You're removing mouse event support so you can rep
CJ
2017/01/07 00:12:36
Left in function to make the keyboard RawInputDevi
Wez
2017/01/09 22:38:43
Acknowledged.
| |
| 145 if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) { | 135 if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) { |
| 146 PLOG(ERROR) << "RegisterRawInputDevices() failed for RIDEV_INPUTSINK"; | 136 PLOG(ERROR) << "RegisterRawInputDevices() failed for RIDEV_INPUTSINK"; |
| 147 window_.reset(); | 137 window_.reset(); |
| 148 return; | 138 return; |
| 149 } | 139 } |
| 150 | 140 |
| 151 // Start observing message loop destruction if we start monitoring the first | 141 // Start observing message loop destruction if we start monitoring the first |
| 152 // event. | 142 // event. |
| 153 if (!events_monitored_) | 143 if (!events_monitored_) |
| 154 base::MessageLoop::current()->AddDestructionObserver(this); | 144 base::MessageLoop::current()->AddDestructionObserver(this); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 RAWINPUT* input = reinterpret_cast<RAWINPUT*>(buffer.get()); | 188 RAWINPUT* input = reinterpret_cast<RAWINPUT*>(buffer.get()); |
| 199 result = GetRawInputData( | 189 result = GetRawInputData( |
| 200 input_handle, RID_INPUT, buffer.get(), &size, sizeof(RAWINPUTHEADER)); | 190 input_handle, RID_INPUT, buffer.get(), &size, sizeof(RAWINPUTHEADER)); |
| 201 if (result == static_cast<UINT>(-1)) { | 191 if (result == static_cast<UINT>(-1)) { |
| 202 PLOG(ERROR) << "GetRawInputData() failed"; | 192 PLOG(ERROR) << "GetRawInputData() failed"; |
| 203 return 0; | 193 return 0; |
| 204 } | 194 } |
| 205 DCHECK_EQ(size, result); | 195 DCHECK_EQ(size, result); |
| 206 | 196 |
| 207 // Notify the observer about events generated locally. | 197 // Notify the observer about events generated locally. |
| 208 if (input->header.dwType == RIM_TYPEMOUSE && input->header.hDevice != NULL) { | 198 if (input->header.dwType == RIM_TYPEMOUSE && input->header.hDevice != NULL) { |
|
Wez
2017/01/03 23:59:40
This entire case can go away since we never listen
CJ
2017/01/07 00:12:36
Done.
| |
| 209 POINT position; | 199 POINT position; |
| 210 if (!GetCursorPos(&position)) { | 200 if (!GetCursorPos(&position)) { |
| 211 position.x = 0; | 201 position.x = 0; |
| 212 position.y = 0; | 202 position.y = 0; |
| 213 } | 203 } |
| 214 mouse_listeners_->Notify( | |
| 215 FROM_HERE, &UserInputMonitor::MouseEventListener::OnMouseMoved, | |
| 216 SkIPoint::Make(position.x, position.y)); | |
| 217 } else if (input->header.dwType == RIM_TYPEKEYBOARD && | 204 } else if (input->header.dwType == RIM_TYPEKEYBOARD && |
| 218 input->header.hDevice != NULL) { | 205 input->header.hDevice != NULL) { |
| 219 ui::EventType event = (input->data.keyboard.Flags & RI_KEY_BREAK) | 206 ui::EventType event = (input->data.keyboard.Flags & RI_KEY_BREAK) |
| 220 ? ui::ET_KEY_RELEASED | 207 ? ui::ET_KEY_RELEASED |
| 221 : ui::ET_KEY_PRESSED; | 208 : ui::ET_KEY_PRESSED; |
| 222 ui::KeyboardCode key_code = | 209 ui::KeyboardCode key_code = |
| 223 ui::KeyboardCodeForWindowsKeyCode(input->data.keyboard.VKey); | 210 ui::KeyboardCodeForWindowsKeyCode(input->data.keyboard.VKey); |
| 224 counter_.OnKeyboardEvent(event, key_code); | 211 counter_.OnKeyboardEvent(event, key_code); |
| 225 } | 212 } |
| 226 | 213 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 244 } | 231 } |
| 245 | 232 |
| 246 RAWINPUTDEVICE* UserInputMonitorWinCore::GetRawInputDevices(EventBitMask event, | 233 RAWINPUTDEVICE* UserInputMonitorWinCore::GetRawInputDevices(EventBitMask event, |
| 247 DWORD flags) { | 234 DWORD flags) { |
| 248 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 235 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 249 | 236 |
| 250 std::unique_ptr<RAWINPUTDEVICE> device(new RAWINPUTDEVICE()); | 237 std::unique_ptr<RAWINPUTDEVICE> device(new RAWINPUTDEVICE()); |
| 251 if (event == MOUSE_EVENT_MASK) { | 238 if (event == MOUSE_EVENT_MASK) { |
| 252 device->dwFlags = flags; | 239 device->dwFlags = flags; |
| 253 device->usUsagePage = kGenericDesktopPage; | 240 device->usUsagePage = kGenericDesktopPage; |
| 254 device->usUsage = kMouseUsage; | |
| 255 device->hwndTarget = window_->hwnd(); | 241 device->hwndTarget = window_->hwnd(); |
| 256 } else { | 242 } else { |
| 257 DCHECK_EQ(KEYBOARD_EVENT_MASK, event); | 243 DCHECK_EQ(KEYBOARD_EVENT_MASK, event); |
| 258 device->dwFlags = flags; | 244 device->dwFlags = flags; |
| 259 device->usUsagePage = kGenericDesktopPage; | 245 device->usUsagePage = kGenericDesktopPage; |
| 260 device->usUsage = kKeyboardUsage; | 246 device->usUsage = kKeyboardUsage; |
| 261 device->hwndTarget = window_->hwnd(); | 247 device->hwndTarget = window_->hwnd(); |
| 262 } | 248 } |
| 263 return device.release(); | 249 return device.release(); |
| 264 } | 250 } |
| 265 | 251 |
| 266 // | 252 // |
| 267 // Implementation of UserInputMonitorWin. | 253 // Implementation of UserInputMonitorWin. |
| 268 // | 254 // |
| 269 | 255 |
| 270 UserInputMonitorWin::UserInputMonitorWin( | 256 UserInputMonitorWin::UserInputMonitorWin( |
| 271 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) | 257 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) |
| 272 : ui_task_runner_(ui_task_runner), | 258 : ui_task_runner_(ui_task_runner), |
| 273 core_(new UserInputMonitorWinCore(ui_task_runner, mouse_listeners())) {} | 259 core_(new UserInputMonitorWinCore(ui_task_runner)) {} |
| 274 | 260 |
| 275 UserInputMonitorWin::~UserInputMonitorWin() { | 261 UserInputMonitorWin::~UserInputMonitorWin() { |
| 276 if (!ui_task_runner_->DeleteSoon(FROM_HERE, core_)) | 262 if (!ui_task_runner_->DeleteSoon(FROM_HERE, core_)) |
| 277 delete core_; | 263 delete core_; |
| 278 } | 264 } |
| 279 | 265 |
| 280 size_t UserInputMonitorWin::GetKeyPressCount() const { | 266 size_t UserInputMonitorWin::GetKeyPressCount() const { |
| 281 return core_->GetKeyPressCount(); | 267 return core_->GetKeyPressCount(); |
| 282 } | 268 } |
| 283 | 269 |
| 284 void UserInputMonitorWin::StartKeyboardMonitoring() { | 270 void UserInputMonitorWin::StartKeyboardMonitoring() { |
| 285 ui_task_runner_->PostTask( | 271 ui_task_runner_->PostTask( |
| 286 FROM_HERE, | 272 FROM_HERE, |
| 287 base::Bind(&UserInputMonitorWinCore::StartMonitor, | 273 base::Bind(&UserInputMonitorWinCore::StartMonitor, |
| 288 core_->AsWeakPtr(), | 274 core_->AsWeakPtr(), |
| 289 UserInputMonitorWinCore::KEYBOARD_EVENT_MASK)); | 275 UserInputMonitorWinCore::KEYBOARD_EVENT_MASK)); |
| 290 } | 276 } |
| 291 | 277 |
| 292 void UserInputMonitorWin::StopKeyboardMonitoring() { | 278 void UserInputMonitorWin::StopKeyboardMonitoring() { |
| 293 ui_task_runner_->PostTask( | 279 ui_task_runner_->PostTask( |
| 294 FROM_HERE, | 280 FROM_HERE, |
| 295 base::Bind(&UserInputMonitorWinCore::StopMonitor, | 281 base::Bind(&UserInputMonitorWinCore::StopMonitor, |
| 296 core_->AsWeakPtr(), | 282 core_->AsWeakPtr(), |
| 297 UserInputMonitorWinCore::KEYBOARD_EVENT_MASK)); | 283 UserInputMonitorWinCore::KEYBOARD_EVENT_MASK)); |
| 298 } | 284 } |
| 299 | 285 |
| 300 void UserInputMonitorWin::StartMouseMonitoring() { | |
| 301 ui_task_runner_->PostTask( | |
| 302 FROM_HERE, | |
| 303 base::Bind(&UserInputMonitorWinCore::StartMonitor, | |
| 304 core_->AsWeakPtr(), | |
| 305 UserInputMonitorWinCore::MOUSE_EVENT_MASK)); | |
| 306 } | |
| 307 | |
| 308 void UserInputMonitorWin::StopMouseMonitoring() { | |
| 309 ui_task_runner_->PostTask( | |
| 310 FROM_HERE, | |
| 311 base::Bind(&UserInputMonitorWinCore::StopMonitor, | |
| 312 core_->AsWeakPtr(), | |
| 313 UserInputMonitorWinCore::MOUSE_EVENT_MASK)); | |
| 314 } | |
| 315 | |
| 316 } // namespace | 286 } // namespace |
| 317 | 287 |
| 318 std::unique_ptr<UserInputMonitor> UserInputMonitor::Create( | 288 std::unique_ptr<UserInputMonitor> UserInputMonitor::Create( |
| 319 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | 289 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |
| 320 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) { | 290 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) { |
| 321 return base::WrapUnique(new UserInputMonitorWin(ui_task_runner)); | 291 return base::WrapUnique(new UserInputMonitorWin(ui_task_runner)); |
| 322 } | 292 } |
| 323 | 293 |
| 324 } // namespace media | 294 } // namespace media |
| OLD | NEW |