Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(628)

Unified Diff: content/browser/gamepad/gamepad_provider.cc

Issue 2081583002: Migrating majority of gamepad from content/browser/ to device/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Next attempt Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698