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 |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5ef2855b13da55f5f665ec7ca6ebe12b9b56867a |
| --- /dev/null |
| +++ b/content/browser/gamepad/gamepad_provider.cc |
| @@ -0,0 +1,127 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <cmath> |
| +#include <set> |
| +#include <vector> |
| + |
| +#include "base/bind.h" |
| +#include "base/logging.h" |
| +#include "base/message_loop.h" |
| +#include "base/task.h" |
| +#include "base/threading/thread.h" |
| +#include "base/threading/thread_restrictions.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/browser/gamepad/gamepad_provider.h" |
| +#include "content/browser/gamepad/data_fetcher.h" |
| +#include "content/common/gamepad_messages.h" |
| + |
| +namespace gamepad { |
| + |
| +using namespace content; |
| + |
| +Provider::Provider(DataFetcher* fetcher) |
| + : creator_loop_(MessageLoop::current()), |
| + provided_fetcher_(fetcher), |
| + devices_changed_(true), |
| + ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| + const size_t DataSize = sizeof(GamepadHardwareBuffer); |
|
jam
2011/11/16 00:24:58
nit: data_size per style guide. also, from what I'
scottmg
2011/11/16 18:04:35
Done.
|
| + base::SystemMonitor* monitor = base::SystemMonitor::Get(); |
| + if (monitor) |
| + monitor->AddDevicesChangedObserver(this); |
| + gamepad_shared_memory_.CreateAndMapAnonymous(DataSize); |
| + GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer(); |
| + memset(hwbuf, 0, sizeof(GamepadHardwareBuffer)); |
| +} |
| + |
| +Provider::~Provider() { |
| + base::SystemMonitor* monitor = base::SystemMonitor::Get(); |
| + if (monitor) |
| + monitor->RemoveDevicesChangedObserver(this); |
| + Stop(); |
| +} |
| + |
| +base::SharedMemoryHandle Provider::GetRendererSharedMemoryHandle( |
| + base::ProcessHandle process) { |
| + base::SharedMemoryHandle renderer_handle; |
| + gamepad_shared_memory_.ShareToProcess(process, &renderer_handle); |
| + return renderer_handle; |
| +} |
| + |
| +void Provider::OnDevicesChanged() { |
| + devices_changed_ = true; |
| +} |
| + |
| +void Provider::Start() { |
| + DCHECK(MessageLoop::current() == creator_loop_); |
| + |
| + if (polling_thread_.get()) |
| + return; |
| + |
| + polling_thread_.reset(new base::Thread("Gamepad polling thread")); |
| + if (!polling_thread_->Start()) { |
| + LOG(ERROR) << "Failed to start gamepad polling thread"; |
| + polling_thread_.reset(); |
| + return; |
| + } |
| + |
| + MessageLoop* polling_loop = polling_thread_->message_loop(); |
| + polling_loop->PostTask(FROM_HERE, |
|
jam
2011/11/16 00:24:58
nit: this style of spacing isn't in the style guid
scottmg
2011/11/16 18:04:35
Done.
|
| + base::Bind(&Provider::DoInitializePollingThread, this)); |
| +} |
| + |
| +void Provider::Stop() { |
| + DCHECK(MessageLoop::current() == creator_loop_); |
| + |
| + polling_thread_.reset(); |
| + data_fetcher_.reset(); |
| +} |
| + |
| +void Provider::DoInitializePollingThread() { |
| + DCHECK(MessageLoop::current() == polling_thread_->message_loop()); |
| + |
| + if (!provided_fetcher_.get()) |
| + provided_fetcher_.reset(new PlatformDataFetcher); |
| + |
| + // Pass ownership of fetcher to provider_. |
| + data_fetcher_.swap(provided_fetcher_); |
| + |
| + // Start polling. |
| + ScheduleDoPoll(); |
| +} |
| + |
| +void Provider::DoPoll() { |
| + DCHECK(MessageLoop::current() == polling_thread_->message_loop()); |
| + |
| + GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer(); |
| + |
|
jam
2011/11/16 00:24:58
nit: i'm not sure why each line in this function i
scottmg
2011/11/16 18:04:35
Done.
|
| + base::subtle::Barrier_AtomicIncrement(&hwbuf->start_marker, 1); |
| + |
| + data_fetcher_->GetGamepadData(hwbuf->buffer, devices_changed_); |
| + |
| + base::subtle::Barrier_AtomicIncrement(&hwbuf->end_marker, 1); |
| + |
| + devices_changed_ = false; |
| + |
| + // Schedule our next interval of polling. |
| + ScheduleDoPoll(); |
| +} |
| + |
| +void Provider::ScheduleDoPoll() { |
| + DCHECK(MessageLoop::current() == polling_thread_->message_loop()); |
| + |
| + MessageLoop::current()->PostDelayedTask(FROM_HERE, |
|
jam
2011/11/16 00:24:58
nit: ditto for tabbing
scottmg
2011/11/16 18:04:35
Done.
|
| + base::Bind(&Provider::DoPoll, weak_factory_.GetWeakPtr()), |
| + kDesiredSamplingIntervalMs); |
| +} |
| + |
| +GamepadHardwareBuffer* Provider::SharedMemoryAsHardwareBuffer() { |
| + void* mem = gamepad_shared_memory_.memory(); |
| + DCHECK(mem); |
| + return static_cast<GamepadHardwareBuffer*>(mem); |
| +} |
| + |
| +Provider* Provider::instance_ = NULL; |
|
jam
2011/11/16 00:24:58
nit: statics get listed at the top of the file bef
scottmg
2011/11/16 18:04:35
Done.
|
| + |
| +} // namespace gamepad |