diff options
Diffstat (limited to 'content/browser/gamepad/gamepad_provider.cc')
-rw-r--r-- | content/browser/gamepad/gamepad_provider.cc | 101 |
1 files changed, 69 insertions, 32 deletions
diff --git a/content/browser/gamepad/gamepad_provider.cc b/content/browser/gamepad/gamepad_provider.cc index 507c704..63a352f 100644 --- a/content/browser/gamepad/gamepad_provider.cc +++ b/content/browser/gamepad/gamepad_provider.cc @@ -9,42 +9,41 @@ #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 { +GamepadProvider::ClosureAndThread::ClosureAndThread( + const base::Closure& c, + const scoped_refptr<base::MessageLoopProxy>& m) + : closure(c), + message_loop(m) { +} + +GamepadProvider::ClosureAndThread::~ClosureAndThread() { +} + 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 +55,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 +90,46 @@ void GamepadProvider::Resume() { base::Bind(&GamepadProvider::ScheduleDoPoll, Unretained(this))); } +void GamepadProvider::RegisterForUserGesture(const base::Closure& closure) { + base::AutoLock lock(user_gesture_lock_); + user_gesture_observers_.push_back( + ClosureAndThread(closure, MessageLoop::current()->message_loop_proxy())); +} + 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)); + + polling_thread_->message_loop()->PostTask( + FROM_HERE, + base::Bind(&GamepadProvider::DoInitializePollingThread, + base::Unretained(this), + base::Passed(&fetcher))); +} - if (fetcher == NULL) - fetcher = new GamepadPlatformDataFetcher; +void GamepadProvider::DoInitializePollingThread( + scoped_ptr<GamepadDataFetcher> fetcher) { + DCHECK(MessageLoop::current() == polling_thread_->message_loop()); + DCHECK(!data_fetcher_.get()); // Should only initialize once. - // Pass ownership of fetcher to provider_. - data_fetcher_.reset(fetcher); + if (!fetcher.get()) + fetcher.reset(new GamepadPlatformDataFetcher); + data_fetcher_ = fetcher.Pass(); } void GamepadProvider::SendPauseHint(bool paused) { @@ -142,6 +163,8 @@ void GamepadProvider::DoPoll() { data_fetcher_->GetGamepadData(&hwbuf->buffer, changed); hwbuf->sequence.WriteEnd(); + CheckForUserGesture(); + // Schedule our next interval of polling. ScheduleDoPoll(); } @@ -170,4 +193,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 |