OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <cmath> | 5 #include <cmath> |
6 #include <set> | 6 #include <set> |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/location.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/message_loop/message_loop.h" | 12 #include "base/single_thread_task_runner.h" |
12 #include "base/message_loop/message_loop_proxy.h" | |
13 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 13 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 14 #include "base/thread_task_runner_handle.h" |
14 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
15 #include "base/threading/thread_restrictions.h" | 16 #include "base/threading/thread_restrictions.h" |
16 #include "content/browser/gamepad/gamepad_data_fetcher.h" | 17 #include "content/browser/gamepad/gamepad_data_fetcher.h" |
17 #include "content/browser/gamepad/gamepad_platform_data_fetcher.h" | 18 #include "content/browser/gamepad/gamepad_platform_data_fetcher.h" |
18 #include "content/browser/gamepad/gamepad_provider.h" | 19 #include "content/browser/gamepad/gamepad_provider.h" |
19 #include "content/browser/gamepad/gamepad_service.h" | 20 #include "content/browser/gamepad/gamepad_service.h" |
20 #include "content/common/gamepad_hardware_buffer.h" | 21 #include "content/common/gamepad_hardware_buffer.h" |
21 #include "content/common/gamepad_messages.h" | 22 #include "content/common/gamepad_messages.h" |
22 #include "content/common/gamepad_user_gesture.h" | 23 #include "content/common/gamepad_user_gesture.h" |
23 #include "content/public/browser/browser_thread.h" | 24 #include "content/public/browser/browser_thread.h" |
24 | 25 |
25 using blink::WebGamepad; | 26 using blink::WebGamepad; |
26 using blink::WebGamepads; | 27 using blink::WebGamepads; |
27 | 28 |
28 namespace content { | 29 namespace content { |
29 | 30 |
30 GamepadProvider::ClosureAndThread::ClosureAndThread( | 31 GamepadProvider::ClosureAndThread::ClosureAndThread( |
31 const base::Closure& c, | 32 const base::Closure& c, |
32 const scoped_refptr<base::MessageLoopProxy>& m) | 33 const scoped_refptr<base::SingleThreadTaskRunner>& m) |
33 : closure(c), | 34 : closure(c), task_runner(m) { |
34 message_loop(m) { | |
35 } | 35 } |
36 | 36 |
37 GamepadProvider::ClosureAndThread::~ClosureAndThread() { | 37 GamepadProvider::ClosureAndThread::~ClosureAndThread() { |
38 } | 38 } |
39 | 39 |
40 GamepadProvider::GamepadProvider() | 40 GamepadProvider::GamepadProvider() |
41 : is_paused_(true), | 41 : is_paused_(true), |
42 have_scheduled_do_poll_(false), | 42 have_scheduled_do_poll_(false), |
43 devices_changed_(true), | 43 devices_changed_(true), |
44 ever_had_user_gesture_(false) { | 44 ever_had_user_gesture_(false) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 base::AutoLock lock(shared_memory_lock_); | 76 base::AutoLock lock(shared_memory_lock_); |
77 *data = pads; | 77 *data = pads; |
78 } | 78 } |
79 | 79 |
80 void GamepadProvider::Pause() { | 80 void GamepadProvider::Pause() { |
81 { | 81 { |
82 base::AutoLock lock(is_paused_lock_); | 82 base::AutoLock lock(is_paused_lock_); |
83 is_paused_ = true; | 83 is_paused_ = true; |
84 } | 84 } |
85 base::MessageLoop* polling_loop = polling_thread_->message_loop(); | 85 base::MessageLoop* polling_loop = polling_thread_->message_loop(); |
86 polling_loop->PostTask( | 86 polling_loop->task_runner()->PostTask( |
87 FROM_HERE, | 87 FROM_HERE, |
88 base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), true)); | 88 base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), true)); |
89 } | 89 } |
90 | 90 |
91 void GamepadProvider::Resume() { | 91 void GamepadProvider::Resume() { |
92 { | 92 { |
93 base::AutoLock lock(is_paused_lock_); | 93 base::AutoLock lock(is_paused_lock_); |
94 if (!is_paused_) | 94 if (!is_paused_) |
95 return; | 95 return; |
96 is_paused_ = false; | 96 is_paused_ = false; |
97 } | 97 } |
98 | 98 |
99 base::MessageLoop* polling_loop = polling_thread_->message_loop(); | 99 base::MessageLoop* polling_loop = polling_thread_->message_loop(); |
100 polling_loop->PostTask( | 100 polling_loop->task_runner()->PostTask( |
101 FROM_HERE, | 101 FROM_HERE, |
102 base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), false)); | 102 base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), false)); |
103 polling_loop->PostTask( | 103 polling_loop->task_runner()->PostTask( |
104 FROM_HERE, | 104 FROM_HERE, |
105 base::Bind(&GamepadProvider::ScheduleDoPoll, Unretained(this))); | 105 base::Bind(&GamepadProvider::ScheduleDoPoll, Unretained(this))); |
106 } | 106 } |
107 | 107 |
108 void GamepadProvider::RegisterForUserGesture(const base::Closure& closure) { | 108 void GamepadProvider::RegisterForUserGesture(const base::Closure& closure) { |
109 base::AutoLock lock(user_gesture_lock_); | 109 base::AutoLock lock(user_gesture_lock_); |
110 user_gesture_observers_.push_back(ClosureAndThread( | 110 user_gesture_observers_.push_back( |
111 closure, base::MessageLoop::current()->message_loop_proxy())); | 111 ClosureAndThread(closure, base::MessageLoop::current()->task_runner())); |
112 } | 112 } |
113 | 113 |
114 void GamepadProvider::OnDevicesChanged(base::SystemMonitor::DeviceType type) { | 114 void GamepadProvider::OnDevicesChanged(base::SystemMonitor::DeviceType type) { |
115 base::AutoLock lock(devices_changed_lock_); | 115 base::AutoLock lock(devices_changed_lock_); |
116 devices_changed_ = true; | 116 devices_changed_ = true; |
117 } | 117 } |
118 | 118 |
119 void GamepadProvider::Initialize(scoped_ptr<GamepadDataFetcher> fetcher) { | 119 void GamepadProvider::Initialize(scoped_ptr<GamepadDataFetcher> fetcher) { |
120 size_t data_size = sizeof(GamepadHardwareBuffer); | 120 size_t data_size = sizeof(GamepadHardwareBuffer); |
121 base::SystemMonitor* monitor = base::SystemMonitor::Get(); | 121 base::SystemMonitor* monitor = base::SystemMonitor::Get(); |
(...skipping 15 matching lines...) Expand all Loading... |
137 const base::MessageLoop::Type kMessageLoopType = | 137 const base::MessageLoop::Type kMessageLoopType = |
138 base::MessageLoop::TYPE_DEFAULT; | 138 base::MessageLoop::TYPE_DEFAULT; |
139 #else | 139 #else |
140 // On Mac, the data fetcher uses IOKit which depends on CFRunLoop, so the | 140 // On Mac, the data fetcher uses IOKit which depends on CFRunLoop, so the |
141 // message loop needs to be a UI-type loop. On Windows it must be a UI loop | 141 // message loop needs to be a UI-type loop. On Windows it must be a UI loop |
142 // to properly pump the MessageWindow that captures device state. | 142 // to properly pump the MessageWindow that captures device state. |
143 const base::MessageLoop::Type kMessageLoopType = base::MessageLoop::TYPE_UI; | 143 const base::MessageLoop::Type kMessageLoopType = base::MessageLoop::TYPE_UI; |
144 #endif | 144 #endif |
145 polling_thread_->StartWithOptions(base::Thread::Options(kMessageLoopType, 0)); | 145 polling_thread_->StartWithOptions(base::Thread::Options(kMessageLoopType, 0)); |
146 | 146 |
147 polling_thread_->message_loop()->PostTask( | 147 polling_thread_->task_runner()->PostTask( |
148 FROM_HERE, | 148 FROM_HERE, base::Bind(&GamepadProvider::DoInitializePollingThread, |
149 base::Bind(&GamepadProvider::DoInitializePollingThread, | 149 base::Unretained(this), base::Passed(&fetcher))); |
150 base::Unretained(this), | |
151 base::Passed(&fetcher))); | |
152 } | 150 } |
153 | 151 |
154 void GamepadProvider::DoInitializePollingThread( | 152 void GamepadProvider::DoInitializePollingThread( |
155 scoped_ptr<GamepadDataFetcher> fetcher) { | 153 scoped_ptr<GamepadDataFetcher> fetcher) { |
156 DCHECK(base::MessageLoop::current() == polling_thread_->message_loop()); | 154 DCHECK(base::MessageLoop::current() == polling_thread_->message_loop()); |
157 DCHECK(!data_fetcher_.get()); // Should only initialize once. | 155 DCHECK(!data_fetcher_.get()); // Should only initialize once. |
158 | 156 |
159 if (!fetcher) | 157 if (!fetcher) |
160 fetcher.reset(new GamepadPlatformDataFetcher); | 158 fetcher.reset(new GamepadPlatformDataFetcher); |
161 data_fetcher_ = fetcher.Pass(); | 159 data_fetcher_ = fetcher.Pass(); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 DCHECK(base::MessageLoop::current() == polling_thread_->message_loop()); | 255 DCHECK(base::MessageLoop::current() == polling_thread_->message_loop()); |
258 if (have_scheduled_do_poll_) | 256 if (have_scheduled_do_poll_) |
259 return; | 257 return; |
260 | 258 |
261 { | 259 { |
262 base::AutoLock lock(is_paused_lock_); | 260 base::AutoLock lock(is_paused_lock_); |
263 if (is_paused_) | 261 if (is_paused_) |
264 return; | 262 return; |
265 } | 263 } |
266 | 264 |
267 base::MessageLoop::current()->PostDelayedTask( | 265 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
268 FROM_HERE, | 266 FROM_HERE, base::Bind(&GamepadProvider::DoPoll, Unretained(this)), |
269 base::Bind(&GamepadProvider::DoPoll, Unretained(this)), | |
270 base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs)); | 267 base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs)); |
271 have_scheduled_do_poll_ = true; | 268 have_scheduled_do_poll_ = true; |
272 } | 269 } |
273 | 270 |
274 void GamepadProvider::OnGamepadConnectionChange( | 271 void GamepadProvider::OnGamepadConnectionChange( |
275 bool connected, int index, const WebGamepad& pad) { | 272 bool connected, int index, const WebGamepad& pad) { |
276 PadState& state = pad_states_.get()[index]; | 273 PadState& state = pad_states_.get()[index]; |
277 if (connected) | 274 if (connected) |
278 state.SetPad(pad); | 275 state.SetPad(pad); |
279 else | 276 else |
(...skipping 26 matching lines...) Expand all Loading... |
306 void GamepadProvider::CheckForUserGesture() { | 303 void GamepadProvider::CheckForUserGesture() { |
307 base::AutoLock lock(user_gesture_lock_); | 304 base::AutoLock lock(user_gesture_lock_); |
308 if (user_gesture_observers_.empty() && ever_had_user_gesture_) | 305 if (user_gesture_observers_.empty() && ever_had_user_gesture_) |
309 return; | 306 return; |
310 | 307 |
311 bool had_gesture_before = ever_had_user_gesture_; | 308 bool had_gesture_before = ever_had_user_gesture_; |
312 const WebGamepads& pads = SharedMemoryAsHardwareBuffer()->buffer; | 309 const WebGamepads& pads = SharedMemoryAsHardwareBuffer()->buffer; |
313 if (GamepadsHaveUserGesture(pads)) { | 310 if (GamepadsHaveUserGesture(pads)) { |
314 ever_had_user_gesture_ = true; | 311 ever_had_user_gesture_ = true; |
315 for (size_t i = 0; i < user_gesture_observers_.size(); i++) { | 312 for (size_t i = 0; i < user_gesture_observers_.size(); i++) { |
316 user_gesture_observers_[i].message_loop->PostTask(FROM_HERE, | 313 user_gesture_observers_[i].task_runner->PostTask( |
317 user_gesture_observers_[i].closure); | 314 FROM_HERE, user_gesture_observers_[i].closure); |
318 } | 315 } |
319 user_gesture_observers_.clear(); | 316 user_gesture_observers_.clear(); |
320 } | 317 } |
321 if (!had_gesture_before && ever_had_user_gesture_) { | 318 if (!had_gesture_before && ever_had_user_gesture_) { |
322 // Initialize pad_states_ for the first time. | 319 // Initialize pad_states_ for the first time. |
323 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { | 320 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { |
324 pad_states_.get()[i].SetPad(pads.items[i]); | 321 pad_states_.get()[i].SetPad(pads.items[i]); |
325 } | 322 } |
326 } | 323 } |
327 } | 324 } |
328 | 325 |
329 } // namespace content | 326 } // namespace content |
OLD | NEW |