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..cfe5a07f58b568ab83dc531aff6c9cef6e88fa27 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,47 @@ 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(std::make_pair( |
+ 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)); |
- 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 +154,8 @@ void GamepadProvider::DoPoll() { |
data_fetcher_->GetGamepadData(&hwbuf->buffer, changed); |
hwbuf->sequence.WriteEnd(); |
+ CheckForUserGesture(); |
+ |
// Schedule our next interval of polling. |
ScheduleDoPoll(); |
} |
@@ -170,4 +184,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].second->PostTask(FROM_HERE, |
+ user_gesture_observers_[i].first); |
+ } |
+ user_gesture_observers_.clear(); |
+ } |
+} |
+ |
} // namespace content |