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

Unified Diff: components/exo/gaming_seat.cc

Issue 2900773003: Allow gaming_seat to use ozone gamepad as back-end (Closed)
Patch Set: Add gaming_seat_ozone to exo Created 3 years, 7 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: components/exo/gaming_seat.cc
diff --git a/components/exo/gaming_seat.cc b/components/exo/gaming_seat.cc
index 016be145bb90f467d7c47fe6376c15ef15f3cce4..64e3876cd39a4c25551447e3ef5286504c9ddf26 100644
--- a/components/exo/gaming_seat.cc
+++ b/components/exo/gaming_seat.cc
@@ -1,308 +1,44 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// Copyright 2017 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 "components/exo/gaming_seat.h"
-
-#include <cmath>
+#include <memory>
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
+#include "base/macros.h"
+#include "base/sequenced_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "components/exo/gamepad_delegate.h"
-#include "components/exo/gaming_seat_delegate.h"
-#include "components/exo/shell_surface.h"
-#include "components/exo/surface.h"
-#include "device/gamepad/gamepad_data_fetcher.h"
-#include "device/gamepad/gamepad_pad_state_provider.h"
-#include "device/gamepad/gamepad_platform_data_fetcher_linux.h"
-#include "ui/aura/window.h"
-
-namespace exo {
-namespace {
-
-constexpr double kGamepadButtonValueEpsilon = 0.001;
-bool GamepadButtonValuesAreEqual(double a, double b) {
- return fabs(a - b) < kGamepadButtonValueEpsilon;
-}
-
-std::unique_ptr<device::GamepadDataFetcher> CreateGamepadPlatformDataFetcher() {
- return std::unique_ptr<device::GamepadDataFetcher>(
- new device::GamepadPlatformDataFetcherLinux());
-}
-
-// Time between gamepad polls in milliseconds.
-constexpr unsigned kPollingTimeIntervalMs = 16;
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-// GamingSeat::ThreadSafeGamepadChangeFetcher
-
-// Implements all methods and resources running on the polling thread.
-// This class is reference counted to allow it to shut down safely on the
-// polling thread even if the Gamepad has been destroyed on the origin thread.
-class GamingSeat::ThreadSafeGamepadChangeFetcher
- : public device::GamepadPadStateProvider,
- public base::RefCountedThreadSafe<
- GamingSeat::ThreadSafeGamepadChangeFetcher> {
- public:
- using ProcessGamepadChangesCallback =
- base::Callback<void(int index, const device::Gamepad)>;
-
- ThreadSafeGamepadChangeFetcher(
- const ProcessGamepadChangesCallback& post_gamepad_changes,
- const CreateGamepadDataFetcherCallback& create_fetcher_callback,
- base::SingleThreadTaskRunner* task_runner)
- : process_gamepad_changes_(post_gamepad_changes),
- create_fetcher_callback_(create_fetcher_callback),
- polling_task_runner_(task_runner),
- origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
- thread_checker_.DetachFromThread();
- }
-
- // Enable or disable gamepad polling. Can be called from any thread.
- void EnablePolling(bool enabled) {
- polling_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &ThreadSafeGamepadChangeFetcher::EnablePollingOnPollingThread,
- make_scoped_refptr(this), enabled));
- }
-
- private:
- friend class base::RefCountedThreadSafe<ThreadSafeGamepadChangeFetcher>;
-
- ~ThreadSafeGamepadChangeFetcher() override {}
-
- // Enables or disables polling.
- void EnablePollingOnPollingThread(bool enabled) {
- DCHECK(thread_checker_.CalledOnValidThread());
- is_enabled_ = enabled;
-
- if (is_enabled_) {
- if (!fetcher_) {
- fetcher_ = create_fetcher_callback_.Run();
- InitializeDataFetcher(fetcher_.get());
- DCHECK(fetcher_);
- }
- SchedulePollOnPollingThread();
- } else {
- fetcher_.reset();
- }
- }
-
- // Schedules the next poll on the polling thread.
- void SchedulePollOnPollingThread() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(fetcher_);
-
- if (!is_enabled_ || has_poll_scheduled_)
- return;
-
- has_poll_scheduled_ = true;
- polling_task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&ThreadSafeGamepadChangeFetcher::PollOnPollingThread,
- make_scoped_refptr(this)),
- base::TimeDelta::FromMilliseconds(kPollingTimeIntervalMs));
- }
-
- // Polls devices for new data and posts gamepad changes back to origin thread.
- void PollOnPollingThread() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- has_poll_scheduled_ = false;
- if (!is_enabled_)
- return;
-
- DCHECK(fetcher_);
-
- device::Gamepads new_state = state_;
- fetcher_->GetGamepadData(
- false /* No hardware changed notification from the system */);
-
- for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
- device::PadState& pad_state = pad_states_.get()[i];
-
- // After querying the gamepad clear the state if it did not have it's
- // active
- // state updated but is still listed as being associated with a specific
- // source. This indicates the gamepad is disconnected.
- if (!pad_state.active_state &&
- pad_state.source != device::GAMEPAD_SOURCE_NONE) {
- ClearPadState(pad_state);
- }
-
- MapAndSanitizeGamepadData(&pad_state, &new_state.items[i],
- false /* Don't sanitize gamepad data */);
-
- // If the gamepad is still actively reporting the next call to
- // GetGamepadData will set the active state to active again.
- if (pad_state.active_state)
- pad_state.active_state = device::GAMEPAD_INACTIVE;
-
- if (new_state.items[i].connected != state_.items[i].connected ||
- new_state.items[i].timestamp > state_.items[i].timestamp) {
- origin_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(process_gamepad_changes_, i, new_state.items[i]));
- }
- }
- state_ = new_state;
- SchedulePollOnPollingThread();
- }
-
- // Callback to ProcessGamepadChanges using weak reference to Gamepad.
- ProcessGamepadChangesCallback process_gamepad_changes_;
-
- // Callback method to create a gamepad data fetcher.
- CreateGamepadDataFetcherCallback create_fetcher_callback_;
-
- // Reference to task runner on polling thread.
- scoped_refptr<base::SingleThreadTaskRunner> polling_task_runner_;
-
- // Reference to task runner on origin thread.
- scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
-
- // Gamepad data fetcher used for querying gamepad devices.
- std::unique_ptr<device::GamepadDataFetcher> fetcher_;
-
- // The current state of all gamepads.
- device::Gamepads state_;
-
- // True if a poll has been scheduled.
- bool has_poll_scheduled_ = false;
-
- // True if the polling thread is paused.
- bool is_enabled_ = false;
-
- // ThreadChecker for the polling thread.
- base::ThreadChecker thread_checker_;
-
- DISALLOW_COPY_AND_ASSIGN(ThreadSafeGamepadChangeFetcher);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// GamingSeat, public:
-
-GamingSeat::GamingSeat(GamingSeatDelegate* gaming_seat_delegate,
- base::SingleThreadTaskRunner* polling_task_runner)
- : GamingSeat(gaming_seat_delegate,
- polling_task_runner,
- base::Bind(CreateGamepadPlatformDataFetcher)) {}
-
-GamingSeat::GamingSeat(GamingSeatDelegate* gaming_seat_delegate,
- base::SingleThreadTaskRunner* polling_task_runner,
- CreateGamepadDataFetcherCallback create_fetcher_callback)
- : delegate_(gaming_seat_delegate),
- gamepad_delegates_{nullptr},
- weak_ptr_factory_(this) {
- gamepad_change_fetcher_ = new ThreadSafeGamepadChangeFetcher(
- base::Bind(&GamingSeat::ProcessGamepadChanges,
- weak_ptr_factory_.GetWeakPtr()),
- create_fetcher_callback, polling_task_runner);
-
- auto* helper = WMHelper::GetInstance();
- helper->AddFocusObserver(this);
- OnWindowFocused(helper->GetFocusedWindow(), nullptr);
-}
-
-GamingSeat::~GamingSeat() {
- // Disable polling. Since ThreadSafeGamepadChangeFetcher are reference
- // counted, we can safely have it shut down after Gamepad has been destroyed.
- gamepad_change_fetcher_->EnablePolling(false);
-
- delegate_->OnGamingSeatDestroying(this);
- for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
- if (gamepad_delegates_[i]) {
- gamepad_delegates_[i]->OnRemoved();
- }
- }
- WMHelper::GetInstance()->RemoveFocusObserver(this);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// aura::client::FocusChangeObserver overrides:
+#include "components/exo/gaming_seat.h"
+#include "components/exo/gaming_seat_joydev.h"
-void GamingSeat::OnWindowFocused(aura::Window* gained_focus,
- aura::Window* lost_focus) {
- DCHECK(thread_checker_.CalledOnValidThread());
- Surface* target = nullptr;
- if (gained_focus) {
- target = Surface::AsSurface(gained_focus);
- if (!target) {
- aura::Window* top_level_window = gained_focus->GetToplevelWindow();
- if (top_level_window)
- target = ShellSurface::GetMainSurface(top_level_window);
- }
- }
+#if defined(USE_OZONE)
+#include "components/exo/gaming_seat_ozone.h"
+#endif
- bool focused = target && delegate_->CanAcceptGamepadEventsForSurface(target);
+namespace exo {
- gamepad_change_fetcher_->EnablePolling(focused);
+base::Thread* GamingSeat::CreatePollingThreadIfNeeded() {
+#if defined(USE_OZONE) && defined(USE_OZONE_GAMEPAD)
+ return nullptr;
+#else
+ base::Thread* polling_thread =
+ new base::Thread("Exo gaming input polling thread.");
+ polling_thread->StartWithOptions(
+ base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
+ return polling_thread;
+#endif
}
-////////////////////////////////////////////////////////////////////////////////
-// GamingSeat, private:
-
-void GamingSeat::ProcessGamepadChanges(int index,
- const device::Gamepad new_pad) {
- DCHECK(thread_checker_.CalledOnValidThread());
- bool send_frame = false;
-
- device::Gamepad& pad_state = pad_state_.items[index];
- // Update connection state.
- GamepadDelegate* delegate = gamepad_delegates_[index];
- if (new_pad.connected != pad_state.connected) {
- // New pad is disconnected.
- if (!new_pad.connected) {
- // If gamepad is disconnected now, it should be connected before, then
- // gamepad_delegate should not be null.
- DCHECK(delegate);
- delegate->OnRemoved();
- gamepad_delegates_[index] = nullptr;
- pad_state = new_pad;
- return;
- } else if (new_pad.connected) {
- gamepad_delegates_[index] = delegate_->GamepadAdded();
- }
- }
-
- if (!delegate || !new_pad.connected ||
- new_pad.timestamp <= pad_state.timestamp) {
- pad_state = new_pad;
- return;
- }
-
- // Notify delegate of updated axes.
- for (size_t axis = 0;
- axis < std::max(pad_state.axes_length, new_pad.axes_length); ++axis) {
- if (!GamepadButtonValuesAreEqual(new_pad.axes[axis],
- pad_state.axes[axis])) {
- send_frame = true;
- delegate->OnAxis(axis, new_pad.axes[axis]);
- }
- }
-
- // Notify delegate of updated buttons.
- for (size_t button_id = 0;
- button_id < std::max(pad_state.buttons_length, new_pad.buttons_length);
- ++button_id) {
- auto button = pad_state.buttons[button_id];
- auto new_button = new_pad.buttons[button_id];
- if (button.pressed != new_button.pressed ||
- !GamepadButtonValuesAreEqual(button.value, new_button.value)) {
- send_frame = true;
- delegate->OnButton(button_id, new_button.pressed, new_button.value);
- }
- }
- if (send_frame)
- delegate->OnFrame();
-
- pad_state = new_pad;
+GamingSeat* GamingSeat::CreateGamingSeat(
+ GamingSeatDelegate* gaming_seat_delegate,
+ base::Thread* polling_thread) {
+#if defined(USE_OZONE) && defined(USE_OZONE_GAMEPAD)
+ return new GamingSeatOzone(gaming_seat_delegate);
+#else
+ DCHECK(polling_thread);
+ return new GamingSeatJoydev(gaming_seat_delegate,
+ polling_thread->task_runner().get());
+#endif
}
} // namespace exo

Powered by Google App Engine
This is Rietveld 408576698