summaryrefslogtreecommitdiffstats
path: root/content/browser/gamepad/gamepad_provider.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/gamepad/gamepad_provider.cc')
-rw-r--r--content/browser/gamepad/gamepad_provider.cc101
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