diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-10 07:06:39 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-10 07:06:39 +0000 |
commit | 00c0d0437c9f6f8896df580bcbeffd022d1cf878 (patch) | |
tree | 0177c166101ddd30916ee2eaf50d409d2e86ace2 /content/browser/gamepad/gamepad_provider.cc | |
parent | 7b64f86e2c50c086dba2d3aba2b1a0d22208f072 (diff) | |
download | chromium_src-00c0d0437c9f6f8896df580bcbeffd022d1cf878.zip chromium_src-00c0d0437c9f6f8896df580bcbeffd022d1cf878.tar.gz chromium_src-00c0d0437c9f6f8896df580bcbeffd022d1cf878.tar.bz2 |
Implement the gamepad API in the IPC proxy
This does some reworking of the gamepad system to make it possible to hook in (previously it assumed that it was only talking to renderers) and I did some cleanup. Gamepad files were renamed to match the classes, and I did a bunch of test infrastructure work.
IMPORTANT BEHAVIOR CHANGE: This changes the Web gamepad API to report all gamepad data as soon as any of them are interacted with. This is what we need to do for Pepper anyway (since it gets all or none of the share memory) and I think makes more sense for most consumers anyway.
I separated out the user gesture detection code into a place where it can be used in the browser process as well, and exposed functionality in the gamepad provider to be notified when a user gesture happens.
The existing gamepad test was disabled and had bitrotted. This fixes it.
Review URL: https://chromiumcodereview.appspot.com/10912062
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@155676 0039d316-1c4b-4281-b951-d872f2087c98
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 |