| 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 |