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" | |
11 #include "base/logging.h" | 10 #include "base/logging.h" |
12 #include "base/single_thread_task_runner.h" | 11 #include "base/message_loop/message_loop.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" | |
15 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
16 #include "base/threading/thread_restrictions.h" | 15 #include "base/threading/thread_restrictions.h" |
17 #include "content/browser/gamepad/gamepad_data_fetcher.h" | 16 #include "content/browser/gamepad/gamepad_data_fetcher.h" |
18 #include "content/browser/gamepad/gamepad_platform_data_fetcher.h" | 17 #include "content/browser/gamepad/gamepad_platform_data_fetcher.h" |
19 #include "content/browser/gamepad/gamepad_provider.h" | 18 #include "content/browser/gamepad/gamepad_provider.h" |
20 #include "content/browser/gamepad/gamepad_service.h" | 19 #include "content/browser/gamepad/gamepad_service.h" |
21 #include "content/common/gamepad_hardware_buffer.h" | 20 #include "content/common/gamepad_hardware_buffer.h" |
22 #include "content/common/gamepad_messages.h" | 21 #include "content/common/gamepad_messages.h" |
23 #include "content/common/gamepad_user_gesture.h" | 22 #include "content/common/gamepad_user_gesture.h" |
24 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
25 | 24 |
26 using blink::WebGamepad; | 25 using blink::WebGamepad; |
27 using blink::WebGamepads; | 26 using blink::WebGamepads; |
28 | 27 |
29 namespace content { | 28 namespace content { |
30 | 29 |
31 GamepadProvider::ClosureAndThread::ClosureAndThread( | 30 GamepadProvider::ClosureAndThread::ClosureAndThread( |
32 const base::Closure& c, | 31 const base::Closure& c, |
33 const scoped_refptr<base::SingleThreadTaskRunner>& m) | 32 const scoped_refptr<base::MessageLoopProxy>& m) |
34 : closure(c), task_runner(m) { | 33 : closure(c), |
| 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->task_runner()->PostTask( | 86 polling_loop->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->task_runner()->PostTask( | 100 polling_loop->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->task_runner()->PostTask( | 103 polling_loop->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( | 110 user_gesture_observers_.push_back(ClosureAndThread( |
111 ClosureAndThread(closure, base::MessageLoop::current()->task_runner())); | 111 closure, base::MessageLoop::current()->message_loop_proxy())); |
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_->task_runner()->PostTask( | 147 polling_thread_->message_loop()->PostTask( |
148 FROM_HERE, base::Bind(&GamepadProvider::DoInitializePollingThread, | 148 FROM_HERE, |
149 base::Unretained(this), base::Passed(&fetcher))); | 149 base::Bind(&GamepadProvider::DoInitializePollingThread, |
| 150 base::Unretained(this), |
| 151 base::Passed(&fetcher))); |
150 } | 152 } |
151 | 153 |
152 void GamepadProvider::DoInitializePollingThread( | 154 void GamepadProvider::DoInitializePollingThread( |
153 scoped_ptr<GamepadDataFetcher> fetcher) { | 155 scoped_ptr<GamepadDataFetcher> fetcher) { |
154 DCHECK(base::MessageLoop::current() == polling_thread_->message_loop()); | 156 DCHECK(base::MessageLoop::current() == polling_thread_->message_loop()); |
155 DCHECK(!data_fetcher_.get()); // Should only initialize once. | 157 DCHECK(!data_fetcher_.get()); // Should only initialize once. |
156 | 158 |
157 if (!fetcher) | 159 if (!fetcher) |
158 fetcher.reset(new GamepadPlatformDataFetcher); | 160 fetcher.reset(new GamepadPlatformDataFetcher); |
159 data_fetcher_ = fetcher.Pass(); | 161 data_fetcher_ = fetcher.Pass(); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 DCHECK(base::MessageLoop::current() == polling_thread_->message_loop()); | 257 DCHECK(base::MessageLoop::current() == polling_thread_->message_loop()); |
256 if (have_scheduled_do_poll_) | 258 if (have_scheduled_do_poll_) |
257 return; | 259 return; |
258 | 260 |
259 { | 261 { |
260 base::AutoLock lock(is_paused_lock_); | 262 base::AutoLock lock(is_paused_lock_); |
261 if (is_paused_) | 263 if (is_paused_) |
262 return; | 264 return; |
263 } | 265 } |
264 | 266 |
265 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 267 base::MessageLoop::current()->PostDelayedTask( |
266 FROM_HERE, base::Bind(&GamepadProvider::DoPoll, Unretained(this)), | 268 FROM_HERE, |
| 269 base::Bind(&GamepadProvider::DoPoll, Unretained(this)), |
267 base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs)); | 270 base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs)); |
268 have_scheduled_do_poll_ = true; | 271 have_scheduled_do_poll_ = true; |
269 } | 272 } |
270 | 273 |
271 void GamepadProvider::OnGamepadConnectionChange( | 274 void GamepadProvider::OnGamepadConnectionChange( |
272 bool connected, int index, const WebGamepad& pad) { | 275 bool connected, int index, const WebGamepad& pad) { |
273 PadState& state = pad_states_.get()[index]; | 276 PadState& state = pad_states_.get()[index]; |
274 if (connected) | 277 if (connected) |
275 state.SetPad(pad); | 278 state.SetPad(pad); |
276 else | 279 else |
(...skipping 26 matching lines...) Expand all Loading... |
303 void GamepadProvider::CheckForUserGesture() { | 306 void GamepadProvider::CheckForUserGesture() { |
304 base::AutoLock lock(user_gesture_lock_); | 307 base::AutoLock lock(user_gesture_lock_); |
305 if (user_gesture_observers_.empty() && ever_had_user_gesture_) | 308 if (user_gesture_observers_.empty() && ever_had_user_gesture_) |
306 return; | 309 return; |
307 | 310 |
308 bool had_gesture_before = ever_had_user_gesture_; | 311 bool had_gesture_before = ever_had_user_gesture_; |
309 const WebGamepads& pads = SharedMemoryAsHardwareBuffer()->buffer; | 312 const WebGamepads& pads = SharedMemoryAsHardwareBuffer()->buffer; |
310 if (GamepadsHaveUserGesture(pads)) { | 313 if (GamepadsHaveUserGesture(pads)) { |
311 ever_had_user_gesture_ = true; | 314 ever_had_user_gesture_ = true; |
312 for (size_t i = 0; i < user_gesture_observers_.size(); i++) { | 315 for (size_t i = 0; i < user_gesture_observers_.size(); i++) { |
313 user_gesture_observers_[i].task_runner->PostTask( | 316 user_gesture_observers_[i].message_loop->PostTask(FROM_HERE, |
314 FROM_HERE, user_gesture_observers_[i].closure); | 317 user_gesture_observers_[i].closure); |
315 } | 318 } |
316 user_gesture_observers_.clear(); | 319 user_gesture_observers_.clear(); |
317 } | 320 } |
318 if (!had_gesture_before && ever_had_user_gesture_) { | 321 if (!had_gesture_before && ever_had_user_gesture_) { |
319 // Initialize pad_states_ for the first time. | 322 // Initialize pad_states_ for the first time. |
320 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { | 323 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { |
321 pad_states_.get()[i].SetPad(pads.items[i]); | 324 pad_states_.get()[i].SetPad(pads.items[i]); |
322 } | 325 } |
323 } | 326 } |
324 } | 327 } |
325 | 328 |
326 } // namespace content | 329 } // namespace content |
OLD | NEW |