Commit 9ec45bae authored by Jingkui Wang's avatar Jingkui Wang Committed by Commit Bot

exo: Remove old gamepad implementation

This patch removes the gaming seat implementation for evdev. All the
gamepad support will use ozone implementation.

This patch also removes the dummy interface for gaming_input_v1 in Wayland
server. The dummy interface was there to make sure the system is robust
when we moved the protocol to v2.

Bug: 717246
Change-Id: I70b29d3c6a81761d1e15c502f78fd0615bf768fe
Reviewed-on: https://chromium-review.googlesource.com/661100
Commit-Queue: Jingkui Wang <jkwang@google.com>
Reviewed-by: default avatarDavid Reveman <reveman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#501402}
parent 35476d64
...@@ -54,10 +54,6 @@ declare_args() { ...@@ -54,10 +54,6 @@ declare_args() {
enable_one_click_signin = enable_one_click_signin =
is_win || is_mac || (is_linux && !is_chromeos && !is_chromecast) is_win || is_mac || (is_linux && !is_chromeos && !is_chromecast)
# Indicates if Exo should use ozone gamepad. If this is false, exo will use
# /device/gamepad as backend.
enable_exo_ozone_gamepad = use_ozone
# Set to true to bundle all the mash related mojo services into chrome. # Set to true to bundle all the mash related mojo services into chrome.
# Specify --mash to chrome to have chrome start the mash environment. # Specify --mash to chrome to have chrome start the mash environment.
enable_package_mash_services = is_chromeos enable_package_mash_services = is_chromeos
......
...@@ -22,6 +22,7 @@ source_set("exo") { ...@@ -22,6 +22,7 @@ source_set("exo") {
"data_source_delegate.h", "data_source_delegate.h",
"display.cc", "display.cc",
"display.h", "display.h",
"gaming_seat.cc",
"gaming_seat.h", "gaming_seat.h",
"keyboard.cc", "keyboard.cc",
"keyboard.h", "keyboard.h",
...@@ -75,24 +76,17 @@ source_set("exo") { ...@@ -75,24 +76,17 @@ source_set("exo") {
"//ui/compositor", "//ui/compositor",
"//ui/display/manager", "//ui/display/manager",
"//ui/events/devices:devices", "//ui/events/devices:devices",
"//ui/events/ozone:events_ozone_evdev",
"//ui/gfx", "//ui/gfx",
"//ui/gfx/geometry", "//ui/gfx/geometry",
"//ui/gl", "//ui/gl",
"//ui/ozone",
"//ui/views", "//ui/views",
"//ui/views/mus", "//ui/views/mus",
"//ui/wm", "//ui/wm",
"//ui/wm/public", "//ui/wm/public",
] ]
if (enable_exo_ozone_gamepad) {
defines = [ "USE_OZONE_GAMEPAD" ]
sources += [ "gaming_seat_ozone.cc" ]
deps += [ "//ui/ozone" ]
deps += [ "//ui/events/ozone:events_ozone_evdev" ]
} else {
sources += [ "gaming_seat.cc" ]
}
if (is_chromeos) { if (is_chromeos) {
deps += [ "//chromeos" ] deps += [ "//chromeos" ]
} }
...@@ -128,10 +122,12 @@ source_set("unit_tests") { ...@@ -128,10 +122,12 @@ source_set("unit_tests") {
testonly = true testonly = true
sources = [ sources = [
"../../ui/events/ozone/gamepad/gamepad_event.cc",
"buffer_unittest.cc", "buffer_unittest.cc",
"data_device_unittest.cc", "data_device_unittest.cc",
"data_offer_unittest.cc", "data_offer_unittest.cc",
"display_unittest.cc", "display_unittest.cc",
"gaming_seat_unittest.cc",
"keyboard_unittest.cc", "keyboard_unittest.cc",
"pointer_unittest.cc", "pointer_unittest.cc",
"shared_memory_unittest.cc", "shared_memory_unittest.cc",
...@@ -163,6 +159,7 @@ source_set("unit_tests") { ...@@ -163,6 +159,7 @@ source_set("unit_tests") {
"//ui/compositor:test_support", "//ui/compositor:test_support",
"//ui/events:dom_keycode_converter", "//ui/events:dom_keycode_converter",
"//ui/events:test_support", "//ui/events:test_support",
"//ui/events/ozone:events_ozone_evdev",
"//ui/gfx", "//ui/gfx",
"//ui/keyboard", "//ui/keyboard",
"//ui/message_center", "//ui/message_center",
...@@ -173,14 +170,6 @@ source_set("unit_tests") { ...@@ -173,14 +170,6 @@ source_set("unit_tests") {
if (use_ozone) { if (use_ozone) {
deps += [ "//ui/ozone" ] deps += [ "//ui/ozone" ]
} }
if (enable_exo_ozone_gamepad) {
sources += [
"../../ui/events/ozone/gamepad/gamepad_event.cc",
"gaming_seat_unittest.cc",
]
deps += [ "//ui/events/ozone:events_ozone_evdev" ]
}
} }
test("exo_unittests") { test("exo_unittests") {
......
// 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 // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "components/exo/gaming_seat.h" #include "components/exo/gaming_seat.h"
#include <cmath>
#include "base/bind.h"
#include "components/exo/gamepad_delegate.h" #include "components/exo/gamepad_delegate.h"
#include "components/exo/gaming_seat_delegate.h" #include "components/exo/gaming_seat_delegate.h"
#include "components/exo/shell_surface.h" #include "components/exo/shell_surface.h"
#include "components/exo/surface.h" #include "components/exo/surface.h"
#include "device/gamepad/gamepad_data_fetcher.h" #include "ui/events/ozone/gamepad/gamepad_provider_ozone.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 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()) {
DETACH_FROM_THREAD(thread_checker_);
}
// 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_CALLED_ON_VALID_THREAD(thread_checker_);
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_CALLED_ON_VALID_THREAD(thread_checker_);
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_CALLED_ON_VALID_THREAD(thread_checker_);
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.
THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(ThreadSafeGamepadChangeFetcher);
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// GamingSeat, public: // GamingSeat, public:
GamingSeat::GamingSeat(GamingSeatDelegate* gaming_seat_delegate, GamingSeat::GamingSeat(GamingSeatDelegate* delegate) : delegate_(delegate) {
base::SingleThreadTaskRunner* polling_task_runner)
: delegate_(gaming_seat_delegate),
gamepad_delegates_{nullptr},
weak_ptr_factory_(this) {
gamepad_change_fetcher_ = new ThreadSafeGamepadChangeFetcher(
base::Bind(&GamingSeat::ProcessGamepadChanges,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(CreateGamepadPlatformDataFetcher), polling_task_runner);
auto* helper = WMHelper::GetInstance(); auto* helper = WMHelper::GetInstance();
helper->AddFocusObserver(this); helper->AddFocusObserver(this);
OnWindowFocused(helper->GetFocusedWindow(), nullptr); OnWindowFocused(helper->GetFocusedWindow(), nullptr);
} }
GamingSeat::~GamingSeat() { GamingSeat::~GamingSeat() {
// Disable polling. Since ThreadSafeGamepadChangeFetcher are reference if (focused_)
// counted, we can safely have it shut down after Gamepad has been destroyed. ui::GamepadProviderOzone::GetInstance()->RemoveGamepadObserver(this);
gamepad_change_fetcher_->EnablePolling(false);
delegate_->OnGamingSeatDestroying(this); delegate_->OnGamingSeatDestroying(this);
for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) { // Disconnect all the gamepads.
if (gamepad_delegates_[i]) { for (auto& entry : gamepads_)
gamepad_delegates_[i]->OnRemoved(); entry.second->OnRemoved();
}
}
WMHelper::GetInstance()->RemoveFocusObserver(this); WMHelper::GetInstance()->RemoveFocusObserver(this);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// aura::client::FocusChangeObserver overrides: // WMHelper::FocusObserver overrides:
void GamingSeat::OnWindowFocused(aura::Window* gained_focus, void GamingSeat::OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) { aura::Window* lost_focus) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
Surface* target = nullptr; Surface* target = nullptr;
if (gained_focus) { if (gained_focus) {
target = Surface::AsSurface(gained_focus); target = Surface::AsSurface(gained_focus);
...@@ -230,68 +47,64 @@ void GamingSeat::OnWindowFocused(aura::Window* gained_focus, ...@@ -230,68 +47,64 @@ void GamingSeat::OnWindowFocused(aura::Window* gained_focus,
} }
bool focused = target && delegate_->CanAcceptGamepadEventsForSurface(target); bool focused = target && delegate_->CanAcceptGamepadEventsForSurface(target);
if (focused_ != focused) {
gamepad_change_fetcher_->EnablePolling(focused); focused_ = focused;
if (focused) {
ui::GamepadProviderOzone::GetInstance()->AddGamepadObserver(this);
OnGamepadDevicesUpdated();
} else {
ui::GamepadProviderOzone::GetInstance()->RemoveGamepadObserver(this);
}
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// GamingSeat, private: // ui::GamepadObserver overrides:
void GamingSeat::ProcessGamepadChanges(int index, void GamingSeat::OnGamepadDevicesUpdated() {
const device::Gamepad new_pad) { std::vector<ui::InputDevice> gamepad_devices =
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); ui::GamepadProviderOzone::GetInstance()->GetGamepadDevices();
bool send_frame = false;
device::Gamepad& pad_state = pad_state_.items[index]; base::flat_map<int, GamepadDelegate*> new_gamepads;
// Update connection state.
GamepadDelegate* delegate = gamepad_delegates_[index]; // Copy the "still connected gamepads".
if (new_pad.connected != pad_state.connected) { for (auto& device : gamepad_devices) {
// New pad is disconnected. auto it = gamepads_.find(device.id);
if (!new_pad.connected) { if (it != gamepads_.end()) {
// If gamepad is disconnected now, it should be connected before, then new_gamepads[device.id] = it->second;
// gamepad_delegate should not be null. gamepads_.erase(it);
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 || // Remove each disconected gamepad.
new_pad.timestamp <= pad_state.timestamp) { for (auto& entry : gamepads_)
pad_state = new_pad; entry.second->OnRemoved();
return;
}
// Notify delegate of updated axes. // Add each new connected gamepad.
for (size_t axis = 0; for (auto& device : gamepad_devices) {
axis < std::max(pad_state.axes_length, new_pad.axes_length); ++axis) { if (new_gamepads.find(device.id) == new_gamepads.end())
if (!GamepadButtonValuesAreEqual(new_pad.axes[axis], new_gamepads[device.id] = delegate_->GamepadAdded();
pad_state.axes[axis])) {
send_frame = true;
delegate->OnAxis(axis, new_pad.axes[axis]);
}
} }
// Notify delegate of updated buttons. new_gamepads.swap(gamepads_);
for (size_t button_id = 0; }
button_id < std::max(pad_state.buttons_length, new_pad.buttons_length);
++button_id) { void GamingSeat::OnGamepadEvent(const ui::GamepadEvent& event) {
auto button = pad_state.buttons[button_id]; auto it = gamepads_.find(event.device_id());
auto new_button = new_pad.buttons[button_id]; if (it == gamepads_.end())
if (button.pressed != new_button.pressed || return;
!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; switch (event.type()) {
case ui::GamepadEventType::BUTTON:
it->second->OnButton(event.code(), event.value(), event.value());
break;
case ui::GamepadEventType::AXIS:
it->second->OnAxis(event.code(), event.value());
break;
case ui::GamepadEventType::FRAME:
it->second->OnFrame();
break;
}
} }
} // namespace exo } // namespace exo
...@@ -12,39 +12,22 @@ ...@@ -12,39 +12,22 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/exo/wm_helper.h" #include "components/exo/wm_helper.h"
#include "device/gamepad/gamepad_data_fetcher.h"
#include "ui/aura/client/focus_change_observer.h" #include "ui/aura/client/focus_change_observer.h"
#if defined(USE_OZONE_GAMEPAD)
#include "ui/events/ozone/gamepad/gamepad_observer.h" #include "ui/events/ozone/gamepad/gamepad_observer.h"
#endif
namespace exo { namespace exo {
class GamingSeatDelegate; class GamingSeatDelegate;
class GamepadDelegate; class GamepadDelegate;
using CreateGamepadDataFetcherCallback =
base::Callback<std::unique_ptr<device::GamepadDataFetcher>()>;
// TODO(jkwang): always use ozone_gamepad when ozone is default for all Chrome
// OS builds. https://crbug.com/717246
// This class represents one gaming seat. It uses /device/gamepad or // This class represents one gaming seat. It uses /device/gamepad or
// ozone/gamepad as backend and notifies corresponding GamepadDelegate of any // ozone/gamepad as backend and notifies corresponding GamepadDelegate of any
// gamepad changes. // gamepad changes.
class GamingSeat : public WMHelper::FocusObserver class GamingSeat : public WMHelper::FocusObserver, public ui::GamepadObserver {
#if defined(USE_OZONE_GAMEPAD)
,
public ui::GamepadObserver
#endif
{
public: public:
// This class will monitor gamepad connection changes and manage gamepad // This class will monitor gamepad connection changes and manage gamepad
// returned by gaming_seat_delegate. // returned by gaming_seat_delegate.
GamingSeat(GamingSeatDelegate* gaming_seat_delegate, GamingSeat(GamingSeatDelegate* gaming_seat_delegate);
base::SingleThreadTaskRunner* polling_task_runner);
~GamingSeat() override; ~GamingSeat() override;
...@@ -52,44 +35,20 @@ class GamingSeat : public WMHelper::FocusObserver ...@@ -52,44 +35,20 @@ class GamingSeat : public WMHelper::FocusObserver
void OnWindowFocused(aura::Window* gained_focus, void OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) override; aura::Window* lost_focus) override;
#if defined(USE_OZONE_GAMEPAD)
// Overridden from ui::GamepadObserver: // Overridden from ui::GamepadObserver:
void OnGamepadDevicesUpdated() override; void OnGamepadDevicesUpdated() override;
void OnGamepadEvent(const ui::GamepadEvent& event) override; void OnGamepadEvent(const ui::GamepadEvent& event) override;
#endif
private: private:
// The delegate that handles gamepad_added. // The delegate that handles gamepad_added.
GamingSeatDelegate* const delegate_; GamingSeatDelegate* const delegate_;
#if defined(USE_OZONE_GAMEPAD)
// Contains the delegate for each gamepad device. // Contains the delegate for each gamepad device.
base::flat_map<int, GamepadDelegate*> gamepads_; base::flat_map<int, GamepadDelegate*> gamepads_;
// The flag if a valid target for gaming seat is focused. In other words, if // The flag if a valid target for gaming seat is focused. In other words, if
// it's true, this class is observing gamepad events. // it's true, this class is observing gamepad events.
bool focused_ = false; bool focused_ = false;
#else
class ThreadSafeGamepadChangeFetcher;
// Processes updates of gamepad data and passes changes on to delegate.
void ProcessGamepadChanges(int index, const device::Gamepad new_pad);
// Private implementation of methods and resources that are used on the
// polling thread.
scoped_refptr<ThreadSafeGamepadChangeFetcher> gamepad_change_fetcher_;
// The delegate instances that all other events are dispatched to.
GamepadDelegate* gamepad_delegates_[device::Gamepads::kItemsLengthCap];
// The current state of the gamepad represented by this instance.
device::Gamepads pad_state_;
// ThreadChecker for the origin thread.
THREAD_CHECKER(thread_checker_);
base::WeakPtrFactory<GamingSeat> weak_ptr_factory_;
#endif
DISALLOW_COPY_AND_ASSIGN(GamingSeat); DISALLOW_COPY_AND_ASSIGN(GamingSeat);
}; };
......
// 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/gamepad_delegate.h"
#include "components/exo/gaming_seat.h"
#include "components/exo/gaming_seat_delegate.h"
#include "components/exo/shell_surface.h"
#include "components/exo/surface.h"
#include "ui/events/ozone/gamepad/gamepad_provider_ozone.h"
namespace exo {
////////////////////////////////////////////////////////////////////////////////
// GamingSeat, public:
GamingSeat::GamingSeat(GamingSeatDelegate* delegate,
base::SingleThreadTaskRunner* task_runner)
: delegate_(delegate) {
auto* helper = WMHelper::GetInstance();
helper->AddFocusObserver(this);
OnWindowFocused(helper->GetFocusedWindow(), nullptr);
}
GamingSeat::~GamingSeat() {
if (focused_)
ui::GamepadProviderOzone::GetInstance()->RemoveGamepadObserver(this);
delegate_->OnGamingSeatDestroying(this);
// Disconnect all the gamepads.
for (auto& entry : gamepads_)
entry.second->OnRemoved();
WMHelper::GetInstance()->RemoveFocusObserver(this);
}
////////////////////////////////////////////////////////////////////////////////
// WMHelper::FocusObserver overrides:
void GamingSeat::OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) {
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);
}
}
bool focused = target && delegate_->CanAcceptGamepadEventsForSurface(target);
if (focused_ != focused) {
focused_ = focused;
if (focused) {
ui::GamepadProviderOzone::GetInstance()->AddGamepadObserver(this);
OnGamepadDevicesUpdated();
} else {
ui::GamepadProviderOzone::GetInstance()->RemoveGamepadObserver(this);
}
}
}
////////////////////////////////////////////////////////////////////////////////
// ui::GamepadObserver overrides:
void GamingSeat::OnGamepadDevicesUpdated() {
std::vector<ui::InputDevice> gamepad_devices =
ui::GamepadProviderOzone::GetInstance()->GetGamepadDevices();
base::flat_map<int, GamepadDelegate*> new_gamepads;
// Copy the "still connected gamepads".
for (auto& device : gamepad_devices) {
auto it = gamepads_.find(device.id);
if (it != gamepads_.end()) {
new_gamepads[device.id] = it->second;
gamepads_.erase(it);
}
}
// Remove each disconected gamepad.
for (auto& entry : gamepads_)
entry.second->OnRemoved();
// Add each new connected gamepad.
for (auto& device : gamepad_devices) {
if (new_gamepads.find(device.id) == new_gamepads.end())
new_gamepads[device.id] = delegate_->GamepadAdded();
}
new_gamepads.swap(gamepads_);
}
void GamingSeat::OnGamepadEvent(const ui::GamepadEvent& event) {
auto it = gamepads_.find(event.device_id());
if (it == gamepads_.end())
return;
switch (event.type()) {
case ui::GamepadEventType::BUTTON:
it->second->OnButton(event.code(), event.value(), event.value());
break;
case ui::GamepadEventType::AXIS:
it->second->OnAxis(event.code(), event.value());
break;
case ui::GamepadEventType::FRAME:
it->second->OnFrame();
break;
}
}
} // namespace exo
...@@ -46,7 +46,7 @@ class GamingSeatTest : public test::ExoTestBase { ...@@ -46,7 +46,7 @@ class GamingSeatTest : public test::ExoTestBase {
public: public:
GamingSeatTest() {} GamingSeatTest() {}
void InitializeGamingSeat(MockGamingSeatDelegate* delegate) { void InitializeGamingSeat(MockGamingSeatDelegate* delegate) {
gaming_seat_.reset(new GamingSeat(delegate, nullptr)); gaming_seat_.reset(new GamingSeat(delegate));
} }
void DestroyGamingSeat(MockGamingSeatDelegate* delegate) { void DestroyGamingSeat(MockGamingSeatDelegate* delegate) {
......
...@@ -4098,12 +4098,9 @@ void gaming_input_get_gaming_seat(wl_client* client, ...@@ -4098,12 +4098,9 @@ void gaming_input_get_gaming_seat(wl_client* client,
wl_resource_create(client, &zcr_gaming_seat_v2_interface, wl_resource_create(client, &zcr_gaming_seat_v2_interface,
wl_resource_get_version(resource), id); wl_resource_get_version(resource), id);
base::Thread* gaming_input_thread = GetUserDataAs<base::Thread>(resource);
SetImplementation(gaming_seat_resource, &gaming_seat_implementation, SetImplementation(gaming_seat_resource, &gaming_seat_implementation,
base::MakeUnique<GamingSeat>( base::MakeUnique<GamingSeat>(
new WaylandGamingSeatDelegate(gaming_seat_resource), new WaylandGamingSeatDelegate(gaming_seat_resource)));
gaming_input_thread->task_runner().get()));
} }
void gaming_input_destroy(wl_client* client, wl_resource* resource) { void gaming_input_destroy(wl_client* client, wl_resource* resource) {
...@@ -4120,53 +4117,8 @@ void bind_gaming_input(wl_client* client, ...@@ -4120,53 +4117,8 @@ void bind_gaming_input(wl_client* client,
wl_resource* resource = wl_resource* resource =
wl_resource_create(client, &zcr_gaming_input_v2_interface, version, id); wl_resource_create(client, &zcr_gaming_input_v2_interface, version, id);
std::unique_ptr<base::Thread> gaming_input_thread( wl_resource_set_implementation(resource, &gaming_input_implementation,
new base::Thread("Exo gaming input polling thread.")); nullptr, nullptr);
gaming_input_thread->StartWithOptions(
base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
SetImplementation(resource, &gaming_input_implementation,
std::move(gaming_input_thread));
}
////////////////////////////////////////////////////////////////////////////////
// dummy interface for gaming_input_v1:
/* Following is a dummy interface for gaming_input_v1.
* It makes sure the "old" android with v1 interface won't break. However, "old"
* android will not receive any gamepad input. This interface implementation
* should be removed once android is updated.
*/
// TODO(jkwang): Remove the following interface function once android updated.
void gamepad_v1_destroy_DEPRECATED(wl_client* client, wl_resource* resource) {
wl_resource_destroy(resource);
}
const struct zcr_gamepad_v1_interface gamepad_v1_implementation = {
gamepad_v1_destroy_DEPRECATED};
void gaming_input_v1_get_gamepad_DEPRECATED(wl_client* client,
wl_resource* resource,
uint32_t id,
wl_resource* seat) {
wl_resource* gamepad_resource = wl_resource_create(
client, &zcr_gamepad_v1_interface, wl_resource_get_version(resource), id);
wl_resource_set_implementation(gamepad_resource, &gamepad_v1_implementation,
NULL, NULL);
}
const struct zcr_gaming_input_v1_interface gaming_input_v1_implementation = {
gaming_input_v1_get_gamepad_DEPRECATED};
void bind_gaming_input_v1_DEPRECATED(wl_client* client,
void* data,
uint32_t version,
uint32_t id) {
wl_resource* resource =
wl_resource_create(client, &zcr_gaming_input_v1_interface, version, id);
wl_resource_set_implementation(resource, &gaming_input_v1_implementation,
NULL, NULL);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -4598,8 +4550,6 @@ Server::Server(Display* display) ...@@ -4598,8 +4550,6 @@ Server::Server(Display* display)
remote_shell_version, display_, bind_remote_shell); remote_shell_version, display_, bind_remote_shell);
wl_global_create(wl_display_.get(), &zaura_shell_interface, 1, display_, wl_global_create(wl_display_.get(), &zaura_shell_interface, 1, display_,
bind_aura_shell); bind_aura_shell);
wl_global_create(wl_display_.get(), &zcr_gaming_input_v1_interface, 1,
display_, bind_gaming_input_v1_DEPRECATED);
wl_global_create(wl_display_.get(), &zcr_gaming_input_v2_interface, 1, wl_global_create(wl_display_.get(), &zcr_gaming_input_v2_interface, 1,
display_, bind_gaming_input); display_, bind_gaming_input);
wl_global_create(wl_display_.get(), &zcr_stylus_v1_interface, 2, display_, wl_global_create(wl_display_.get(), &zcr_stylus_v1_interface, 2, display_,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment