| Index: content/browser/gamepad/gamepad_provider.cc
|
| diff --git a/content/browser/gamepad/gamepad_provider.cc b/content/browser/gamepad/gamepad_provider.cc
|
| deleted file mode 100644
|
| index 5f196b11ecafe656fd6ff0c154cafe72f3b85421..0000000000000000000000000000000000000000
|
| --- a/content/browser/gamepad/gamepad_provider.cc
|
| +++ /dev/null
|
| @@ -1,334 +0,0 @@
|
| -// Copyright (c) 2012 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 "content/browser/gamepad/gamepad_provider.h"
|
| -
|
| -#include <stddef.h>
|
| -#include <string.h>
|
| -#include <cmath>
|
| -#include <set>
|
| -#include <utility>
|
| -#include <vector>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/location.h"
|
| -#include "base/logging.h"
|
| -#include "base/single_thread_task_runner.h"
|
| -#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
|
| -#include "base/threading/thread.h"
|
| -#include "base/threading/thread_restrictions.h"
|
| -#include "base/threading/thread_task_runner_handle.h"
|
| -#include "build/build_config.h"
|
| -#include "content/browser/gamepad/gamepad_data_fetcher.h"
|
| -#include "content/browser/gamepad/gamepad_platform_data_fetcher.h"
|
| -#include "content/browser/gamepad/gamepad_service.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"
|
| -
|
| -using blink::WebGamepad;
|
| -using blink::WebGamepads;
|
| -
|
| -namespace content {
|
| -
|
| -GamepadProvider::ClosureAndThread::ClosureAndThread(
|
| - const base::Closure& c,
|
| - const scoped_refptr<base::SingleThreadTaskRunner>& m)
|
| - : closure(c), task_runner(m) {
|
| -}
|
| -
|
| -GamepadProvider::ClosureAndThread::ClosureAndThread(
|
| - const ClosureAndThread& other) = default;
|
| -
|
| -GamepadProvider::ClosureAndThread::~ClosureAndThread() {
|
| -}
|
| -
|
| -GamepadProvider::GamepadProvider()
|
| - : is_paused_(true),
|
| - have_scheduled_do_poll_(false),
|
| - devices_changed_(true),
|
| - ever_had_user_gesture_(false) {
|
| - Initialize(std::unique_ptr<GamepadDataFetcher>());
|
| -}
|
| -
|
| -GamepadProvider::GamepadProvider(std::unique_ptr<GamepadDataFetcher> fetcher)
|
| - : is_paused_(true),
|
| - have_scheduled_do_poll_(false),
|
| - devices_changed_(true),
|
| - ever_had_user_gesture_(false) {
|
| - Initialize(std::move(fetcher));
|
| -}
|
| -
|
| -GamepadProvider::~GamepadProvider() {
|
| - base::SystemMonitor* monitor = base::SystemMonitor::Get();
|
| - if (monitor)
|
| - monitor->RemoveDevicesChangedObserver(this);
|
| -
|
| - // Use Stop() to join the polling thread, as there may be pending callbacks
|
| - // which dereference |polling_thread_|.
|
| - polling_thread_->Stop();
|
| - data_fetcher_.reset();
|
| -}
|
| -
|
| -base::SharedMemoryHandle GamepadProvider::GetSharedMemoryHandleForProcess(
|
| - base::ProcessHandle process) {
|
| - base::SharedMemoryHandle renderer_handle;
|
| - gamepad_shared_memory_.ShareToProcess(process, &renderer_handle);
|
| - return renderer_handle;
|
| -}
|
| -
|
| -void GamepadProvider::GetCurrentGamepadData(WebGamepads* data) {
|
| - const WebGamepads& pads = SharedMemoryAsHardwareBuffer()->buffer;
|
| - base::AutoLock lock(shared_memory_lock_);
|
| - *data = pads;
|
| -}
|
| -
|
| -void GamepadProvider::Pause() {
|
| - {
|
| - base::AutoLock lock(is_paused_lock_);
|
| - is_paused_ = true;
|
| - }
|
| - base::MessageLoop* polling_loop = polling_thread_->message_loop();
|
| - polling_loop->task_runner()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), true));
|
| -}
|
| -
|
| -void GamepadProvider::Resume() {
|
| - {
|
| - base::AutoLock lock(is_paused_lock_);
|
| - if (!is_paused_)
|
| - return;
|
| - is_paused_ = false;
|
| - }
|
| -
|
| - base::MessageLoop* polling_loop = polling_thread_->message_loop();
|
| - polling_loop->task_runner()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&GamepadProvider::SendPauseHint, Unretained(this), false));
|
| - polling_loop->task_runner()->PostTask(
|
| - FROM_HERE,
|
| - 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, base::ThreadTaskRunnerHandle::Get()));
|
| -}
|
| -
|
| -void GamepadProvider::OnDevicesChanged(base::SystemMonitor::DeviceType type) {
|
| - base::AutoLock lock(devices_changed_lock_);
|
| - devices_changed_ = true;
|
| -}
|
| -
|
| -void GamepadProvider::Initialize(std::unique_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));
|
| - pad_states_.reset(new PadState[WebGamepads::itemsLengthCap]);
|
| -
|
| - polling_thread_.reset(new base::Thread("Gamepad polling thread"));
|
| -#if defined(OS_LINUX)
|
| - // On Linux, the data fetcher needs to watch file descriptors, so the message
|
| - // loop needs to be a libevent loop.
|
| - const base::MessageLoop::Type kMessageLoopType = base::MessageLoop::TYPE_IO;
|
| -#elif defined(OS_ANDROID)
|
| - // On Android, keeping a message loop of default type.
|
| - const base::MessageLoop::Type kMessageLoopType =
|
| - base::MessageLoop::TYPE_DEFAULT;
|
| -#else
|
| - // On Mac, the data fetcher uses IOKit which depends on CFRunLoop, so the
|
| - // message loop needs to be a UI-type loop. On Windows it must be a UI loop
|
| - // to properly pump the MessageWindow that captures device state.
|
| - const base::MessageLoop::Type kMessageLoopType = base::MessageLoop::TYPE_UI;
|
| -#endif
|
| - polling_thread_->StartWithOptions(base::Thread::Options(kMessageLoopType, 0));
|
| -
|
| - polling_thread_->task_runner()->PostTask(
|
| - FROM_HERE, base::Bind(&GamepadProvider::DoInitializePollingThread,
|
| - base::Unretained(this), base::Passed(&fetcher)));
|
| -}
|
| -
|
| -void GamepadProvider::DoInitializePollingThread(
|
| - std::unique_ptr<GamepadDataFetcher> fetcher) {
|
| - DCHECK(base::MessageLoop::current() == polling_thread_->message_loop());
|
| - DCHECK(!data_fetcher_.get()); // Should only initialize once.
|
| -
|
| - if (!fetcher)
|
| - fetcher.reset(new GamepadPlatformDataFetcher);
|
| - data_fetcher_ = std::move(fetcher);
|
| -}
|
| -
|
| -void GamepadProvider::SendPauseHint(bool paused) {
|
| - DCHECK(base::MessageLoop::current() == polling_thread_->message_loop());
|
| - if (data_fetcher_)
|
| - data_fetcher_->PauseHint(paused);
|
| -}
|
| -
|
| -bool GamepadProvider::PadState::Match(const WebGamepad& pad) const {
|
| - return connected_ == pad.connected &&
|
| - axes_length_ == pad.axesLength &&
|
| - buttons_length_ == pad.buttonsLength &&
|
| - memcmp(id_, pad.id, sizeof(id_)) == 0 &&
|
| - memcmp(mapping_, pad.mapping, sizeof(mapping_)) == 0;
|
| -}
|
| -
|
| -void GamepadProvider::PadState::SetPad(const WebGamepad& pad) {
|
| - connected_ = pad.connected;
|
| - axes_length_ = pad.axesLength;
|
| - buttons_length_ = pad.buttonsLength;
|
| - memcpy(id_, pad.id, sizeof(id_));
|
| - memcpy(mapping_, pad.mapping, sizeof(mapping_));
|
| -}
|
| -
|
| -void GamepadProvider::PadState::SetDisconnected() {
|
| - connected_ = false;
|
| - axes_length_ = 0;
|
| - buttons_length_ = 0;
|
| - memset(id_, 0, sizeof(id_));
|
| - memset(mapping_, 0, sizeof(mapping_));
|
| -}
|
| -
|
| -void GamepadProvider::PadState::AsWebGamepad(WebGamepad* pad) {
|
| - pad->connected = connected_;
|
| - pad->axesLength = axes_length_;
|
| - pad->buttonsLength = buttons_length_;
|
| - memcpy(pad->id, id_, sizeof(id_));
|
| - memcpy(pad->mapping, mapping_, sizeof(mapping_));
|
| - memset(pad->axes, 0, sizeof(pad->axes));
|
| - memset(pad->buttons, 0, sizeof(pad->buttons));
|
| -}
|
| -
|
| -void GamepadProvider::DoPoll() {
|
| - DCHECK(base::MessageLoop::current() == polling_thread_->message_loop());
|
| - DCHECK(have_scheduled_do_poll_);
|
| - have_scheduled_do_poll_ = false;
|
| -
|
| - bool changed;
|
| - GamepadHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer();
|
| -
|
| - ANNOTATE_BENIGN_RACE_SIZED(
|
| - &hwbuf->buffer,
|
| - sizeof(WebGamepads),
|
| - "Racey reads are discarded");
|
| -
|
| - {
|
| - base::AutoLock lock(devices_changed_lock_);
|
| - changed = devices_changed_;
|
| - devices_changed_ = false;
|
| - }
|
| -
|
| - {
|
| - base::AutoLock lock(shared_memory_lock_);
|
| -
|
| - // Acquire the SeqLock. There is only ever one writer to this data.
|
| - // See gamepad_hardware_buffer.h.
|
| - hwbuf->sequence.WriteBegin();
|
| - data_fetcher_->GetGamepadData(&hwbuf->buffer, changed);
|
| - hwbuf->sequence.WriteEnd();
|
| - }
|
| -
|
| - if (ever_had_user_gesture_) {
|
| - for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) {
|
| - WebGamepad& pad = hwbuf->buffer.items[i];
|
| - PadState& state = pad_states_.get()[i];
|
| - if (pad.connected && !state.connected()) {
|
| - OnGamepadConnectionChange(true, i, pad);
|
| - } else if (!pad.connected && state.connected()) {
|
| - OnGamepadConnectionChange(false, i, pad);
|
| - } else if (pad.connected && state.connected() && !state.Match(pad)) {
|
| - WebGamepad old_pad;
|
| - state.AsWebGamepad(&old_pad);
|
| - OnGamepadConnectionChange(false, i, old_pad);
|
| - OnGamepadConnectionChange(true, i, pad);
|
| - }
|
| - }
|
| - }
|
| -
|
| - CheckForUserGesture();
|
| -
|
| - // Schedule our next interval of polling.
|
| - ScheduleDoPoll();
|
| -}
|
| -
|
| -void GamepadProvider::ScheduleDoPoll() {
|
| - DCHECK(base::MessageLoop::current() == polling_thread_->message_loop());
|
| - if (have_scheduled_do_poll_)
|
| - return;
|
| -
|
| - {
|
| - base::AutoLock lock(is_paused_lock_);
|
| - if (is_paused_)
|
| - return;
|
| - }
|
| -
|
| - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
| - FROM_HERE, base::Bind(&GamepadProvider::DoPoll, Unretained(this)),
|
| - base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs));
|
| - have_scheduled_do_poll_ = true;
|
| -}
|
| -
|
| -void GamepadProvider::OnGamepadConnectionChange(
|
| - bool connected, int index, const WebGamepad& pad) {
|
| - PadState& state = pad_states_.get()[index];
|
| - if (connected)
|
| - state.SetPad(pad);
|
| - else
|
| - state.SetDisconnected();
|
| -
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO,
|
| - FROM_HERE,
|
| - base::Bind(&GamepadProvider::DispatchGamepadConnectionChange,
|
| - base::Unretained(this),
|
| - connected,
|
| - index,
|
| - pad));
|
| -}
|
| -
|
| -void GamepadProvider::DispatchGamepadConnectionChange(
|
| - bool connected, int index, const WebGamepad& pad) {
|
| - if (connected)
|
| - GamepadService::GetInstance()->OnGamepadConnected(index, pad);
|
| - else
|
| - GamepadService::GetInstance()->OnGamepadDisconnected(index, pad);
|
| -}
|
| -
|
| -GamepadHardwareBuffer* GamepadProvider::SharedMemoryAsHardwareBuffer() {
|
| - void* mem = gamepad_shared_memory_.memory();
|
| - CHECK(mem);
|
| - return static_cast<GamepadHardwareBuffer*>(mem);
|
| -}
|
| -
|
| -void GamepadProvider::CheckForUserGesture() {
|
| - base::AutoLock lock(user_gesture_lock_);
|
| - if (user_gesture_observers_.empty() && ever_had_user_gesture_)
|
| - return;
|
| -
|
| - bool had_gesture_before = ever_had_user_gesture_;
|
| - const WebGamepads& pads = SharedMemoryAsHardwareBuffer()->buffer;
|
| - if (GamepadsHaveUserGesture(pads)) {
|
| - ever_had_user_gesture_ = true;
|
| - for (size_t i = 0; i < user_gesture_observers_.size(); i++) {
|
| - user_gesture_observers_[i].task_runner->PostTask(
|
| - FROM_HERE, user_gesture_observers_[i].closure);
|
| - }
|
| - user_gesture_observers_.clear();
|
| - }
|
| - if (!had_gesture_before && ever_had_user_gesture_) {
|
| - // Initialize pad_states_ for the first time.
|
| - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
|
| - pad_states_.get()[i].SetPad(pads.items[i]);
|
| - }
|
| - }
|
| -}
|
| -
|
| -} // namespace content
|
|
|