Chromium Code Reviews| Index: content/browser/gamepad/gamepad_provider.cc |
| diff --git a/content/browser/gamepad/gamepad_provider.cc b/content/browser/gamepad/gamepad_provider.cc |
| index 507c704ae0269830b46b907f2191746e0c0cddc1..c65dda4a191e86719be024a200d0a92dab827900 100644 |
| --- a/content/browser/gamepad/gamepad_provider.cc |
| +++ b/content/browser/gamepad/gamepad_provider.cc |
| @@ -9,13 +9,15 @@ |
| #include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/message_loop.h" |
| +#include "base/message_loop_proxy.h" |
| #include "base/threading/thread.h" |
| #include "base/threading/thread_restrictions.h" |
| -#include "content/browser/gamepad/data_fetcher.h" |
| +#include "content/browser/gamepad/gamepad_data_fetcher.h" |
| #include "content/browser/gamepad/gamepad_provider.h" |
| -#include "content/browser/gamepad/platform_data_fetcher.h" |
| +#include "content/browser/gamepad/gamepad_platform_data_fetcher.h" |
| #include "content/common/gamepad_hardware_buffer.h" |
| #include "content/common/gamepad_messages.h" |
| +#include "content/common/gamepad_user_gesture.h" |
| #include "content/public/browser/browser_thread.h" |
| namespace content { |
| @@ -24,27 +26,14 @@ GamepadProvider::GamepadProvider() |
| : is_paused_(true), |
| have_scheduled_do_poll_(false), |
| devices_changed_(true) { |
| - size_t data_size = sizeof(GamepadHardwareBuffer); |
| - base::SystemMonitor* monitor = base::SystemMonitor::Get(); |
| - if (monitor) |
| - monitor->AddDevicesChangedObserver(this); |
| - bool res = gamepad_shared_memory_.CreateAndMapAnonymous(data_size); |
| - CHECK(res); |
| - GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer(); |
| - memset(hwbuf, 0, sizeof(GamepadHardwareBuffer)); |
| - |
| - polling_thread_.reset(new base::Thread("Gamepad polling thread")); |
| - polling_thread_->StartWithOptions( |
| - base::Thread::Options(MessageLoop::TYPE_IO, 0)); |
| + Initialize(scoped_ptr<GamepadDataFetcher>()); |
| } |
| -void GamepadProvider::SetDataFetcher(GamepadDataFetcher* fetcher) { |
| - MessageLoop* polling_loop = polling_thread_->message_loop(); |
| - polling_loop->PostTask( |
| - FROM_HERE, |
| - base::Bind(&GamepadProvider::DoInitializePollingThread, |
| - Unretained(this), |
| - fetcher)); |
| +GamepadProvider::GamepadProvider(scoped_ptr<GamepadDataFetcher> fetcher) |
| + : is_paused_(true), |
| + have_scheduled_do_poll_(false), |
| + devices_changed_(true) { |
| + Initialize(fetcher.Pass()); |
| } |
| GamepadProvider::~GamepadProvider() { |
| @@ -56,7 +45,7 @@ GamepadProvider::~GamepadProvider() { |
| data_fetcher_.reset(); |
| } |
| -base::SharedMemoryHandle GamepadProvider::GetRendererSharedMemoryHandle( |
| +base::SharedMemoryHandle GamepadProvider::GetSharedMemoryHandleForProcess( |
| base::ProcessHandle process) { |
| base::SharedMemoryHandle renderer_handle; |
| gamepad_shared_memory_.ShareToProcess(process, &renderer_handle); |
| @@ -91,24 +80,49 @@ void GamepadProvider::Resume() { |
| base::Bind(&GamepadProvider::ScheduleDoPoll, Unretained(this))); |
| } |
| +void GamepadProvider::RegisterForUserGesture(const base::Closure& closure) { |
|
raymes
2012/09/05 23:37:13
This must be called from the IO thread, right? Sho
raymes
2012/09/06 04:07:53
Nevermind I see this is protected and can be calle
|
| + base::AutoLock lock(user_gesture_lock_); |
| + ClosureAndThread closure_and_thread; |
| + closure_and_thread.closure = closure; |
| + closure_and_thread.message_loop = |
| + MessageLoop::current()->message_loop_proxy(); |
| + user_gesture_observers_.push_back(closure_and_thread); |
| +} |
| + |
| void GamepadProvider::OnDevicesChanged(base::SystemMonitor::DeviceType type) { |
| base::AutoLock lock(devices_changed_lock_); |
| devices_changed_ = true; |
| } |
| -void GamepadProvider::DoInitializePollingThread(GamepadDataFetcher* fetcher) { |
| - DCHECK(MessageLoop::current() == polling_thread_->message_loop()); |
| +void GamepadProvider::Initialize(scoped_ptr<GamepadDataFetcher> fetcher) { |
| + size_t data_size = sizeof(GamepadHardwareBuffer); |
| + base::SystemMonitor* monitor = base::SystemMonitor::Get(); |
| + if (monitor) |
| + monitor->AddDevicesChangedObserver(this); |
| + bool res = gamepad_shared_memory_.CreateAndMapAnonymous(data_size); |
| + CHECK(res); |
| + GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer(); |
| + memset(hwbuf, 0, sizeof(GamepadHardwareBuffer)); |
| - if (data_fetcher_ != NULL) { |
| - // Already initialized. |
| - return; |
| - } |
| + polling_thread_.reset(new base::Thread("Gamepad polling thread")); |
| + polling_thread_->StartWithOptions( |
| + base::Thread::Options(MessageLoop::TYPE_IO, 0)); |
| - if (fetcher == NULL) |
| - fetcher = new GamepadPlatformDataFetcher; |
| + polling_thread_->message_loop()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&GamepadProvider::DoInitializePollingThread, |
| + base::Unretained(this), |
| + base::Passed(&fetcher))); |
| +} |
| - // Pass ownership of fetcher to provider_. |
| - data_fetcher_.reset(fetcher); |
| +void GamepadProvider::DoInitializePollingThread( |
| + scoped_ptr<GamepadDataFetcher> fetcher) { |
| + DCHECK(MessageLoop::current() == polling_thread_->message_loop()); |
| + DCHECK(!data_fetcher_.get()); // Should only initialize once. |
| + |
| + if (!fetcher.get()) |
| + fetcher.reset(new GamepadPlatformDataFetcher); |
| + data_fetcher_ = fetcher.Pass(); |
| } |
| void GamepadProvider::SendPauseHint(bool paused) { |
| @@ -142,6 +156,8 @@ void GamepadProvider::DoPoll() { |
| data_fetcher_->GetGamepadData(&hwbuf->buffer, changed); |
| hwbuf->sequence.WriteEnd(); |
| + CheckForUserGesture(); |
| + |
| // Schedule our next interval of polling. |
| ScheduleDoPoll(); |
| } |
| @@ -170,4 +186,18 @@ GamepadHardwareBuffer* GamepadProvider::SharedMemoryAsHardwareBuffer() { |
| return static_cast<GamepadHardwareBuffer*>(mem); |
| } |
| +void GamepadProvider::CheckForUserGesture() { |
| + base::AutoLock lock(user_gesture_lock_); |
| + if (user_gesture_observers_.empty()) |
| + return; // Don't need to check if nobody is listening. |
| + |
| + if (GamepadsHaveUserGesture(SharedMemoryAsHardwareBuffer()->buffer)) { |
| + for (size_t i = 0; i < user_gesture_observers_.size(); i++) { |
| + user_gesture_observers_[i].message_loop->PostTask(FROM_HERE, |
| + user_gesture_observers_[i].closure); |
| + } |
| + user_gesture_observers_.clear(); |
| + } |
| +} |
| + |
| } // namespace content |