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 |