123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- // Copyright 2015 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 <memory>
- #include <vector>
- #include "ash/shell.h"
- #include "base/command_line.h"
- #include "base/run_loop.h"
- #include "base/time/time.h"
- #include "components/exo/buffer.h"
- #include "components/exo/gamepad.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 "components/exo/test/exo_test_base.h"
- #include "components/exo/test/exo_test_helper.h"
- #include "device/gamepad/gamepad_test_helpers.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "ui/aura/client/focus_client.h"
- #include "ui/events/ozone/gamepad/gamepad_provider_ozone.h"
- namespace exo {
- namespace {
- class MockGamepadDelegate : public GamepadDelegate {
- public:
- MockGamepadDelegate() {}
- // Overridden from GamepadDelegate:
- MOCK_METHOD(void, OnRemoved, (), (override));
- MOCK_METHOD(void,
- OnAxis,
- (int axis, double value, base::TimeTicks timestamp),
- (override));
- MOCK_METHOD(void,
- OnButton,
- (int button, bool pressed, base::TimeTicks timestamp),
- (override));
- MOCK_METHOD(void, OnFrame, (base::TimeTicks timestamp), (override));
- };
- class MockGamingSeatDelegate : public GamingSeatDelegate {
- public:
- MOCK_METHOD(bool,
- CanAcceptGamepadEventsForSurface,
- (Surface * surface),
- (const, override));
- MOCK_METHOD(void, GamepadAdded, (Gamepad & gamepad), (override));
- MOCK_METHOD(void, Die, (), ());
- void OnGamingSeatDestroying(GamingSeat*) override { delete this; }
- ~MockGamingSeatDelegate() { Die(); }
- };
- class GamingSeatTest : public test::ExoTestBase {
- public:
- GamingSeatTest() {}
- GamingSeatTest(const GamingSeatTest&) = delete;
- GamingSeatTest& operator=(const GamingSeatTest&) = delete;
- void InitializeGamingSeat(MockGamingSeatDelegate* delegate) {
- gaming_seat_ = std::make_unique<GamingSeat>(delegate);
- }
- void DestroyGamingSeat(MockGamingSeatDelegate* delegate) {
- EXPECT_CALL(*delegate, Die()).Times(1);
- gaming_seat_.reset();
- }
- void UpdateGamepadDevice(const std::vector<int>& gamepad_device_ids) {
- std::vector<ui::GamepadDevice> gamepad_devices;
- for (auto& id : gamepad_device_ids) {
- gamepad_devices.emplace_back(
- ui::InputDevice(id, ui::InputDeviceType::INPUT_DEVICE_USB, "gamepad"),
- std::vector<ui::GamepadDevice::Axis>(),
- /*supports_vibration_rumble=*/false);
- }
- ui::GamepadProviderOzone::GetInstance()->DispatchGamepadDevicesUpdated(
- gamepad_devices);
- }
- void SendFrameToGamepads(const std::vector<int>& gamepad_device_ids) {
- for (auto& id : gamepad_device_ids) {
- ui::GamepadEvent event(id, ui::GamepadEventType::FRAME, 0, 0,
- base::TimeTicks());
- ui::GamepadProviderOzone::GetInstance()->DispatchGamepadEvent(event);
- }
- }
- void SendButtonToGamepads(const std::vector<int>& gamepad_device_ids,
- base::TimeTicks timestamp) {
- for (auto& id : gamepad_device_ids) {
- ui::GamepadEvent event(id, ui::GamepadEventType::BUTTON, 310, 1,
- timestamp);
- ui::GamepadProviderOzone::GetInstance()->DispatchGamepadEvent(event);
- }
- }
- protected:
- std::unique_ptr<GamingSeat> gaming_seat_;
- };
- TEST_F(GamingSeatTest, ConnectionChange) {
- std::unique_ptr<Surface> surface(new Surface);
- std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
- gfx::Size buffer_size(10, 10);
- std::unique_ptr<Buffer> buffer(
- new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
- surface->Attach(buffer.get());
- surface->Commit();
- testing::StrictMock<MockGamingSeatDelegate>* gaming_seat_delegate =
- new testing::StrictMock<MockGamingSeatDelegate>();
- EXPECT_CALL(*gaming_seat_delegate,
- CanAcceptGamepadEventsForSurface(testing::_))
- .WillOnce(testing::Return(true));
- InitializeGamingSeat(gaming_seat_delegate);
- std::unique_ptr<MockGamepadDelegate> gamepad_delegates[6];
- for (auto& delegate : gamepad_delegates)
- delegate = std::make_unique<testing::StrictMock<MockGamepadDelegate>>();
- { // Test sequence
- testing::InSequence s;
- // Connect 2 gamepads.
- EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
- .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
- gamepad.SetDelegate(std::move(gamepad_delegates[0]));
- }));
- EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
- .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
- gamepad.SetDelegate(std::move(gamepad_delegates[1]));
- }));
- // Send frame to connected gamepad.
- EXPECT_CALL(*gamepad_delegates[0], OnFrame(testing::_)).Times(1);
- EXPECT_CALL(*gamepad_delegates[1], OnFrame(testing::_)).Times(1);
- // Connect 3 more.
- EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
- .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
- gamepad.SetDelegate(std::move(gamepad_delegates[2]));
- }));
- EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
- .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
- gamepad.SetDelegate(std::move(gamepad_delegates[3]));
- }));
- EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
- .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
- gamepad.SetDelegate(std::move(gamepad_delegates[4]));
- }));
- // Send frame to all gamepads.
- EXPECT_CALL(*gamepad_delegates[0], OnFrame(testing::_)).Times(1);
- EXPECT_CALL(*gamepad_delegates[1], OnFrame(testing::_)).Times(1);
- EXPECT_CALL(*gamepad_delegates[2], OnFrame(testing::_)).Times(1);
- EXPECT_CALL(*gamepad_delegates[3], OnFrame(testing::_)).Times(1);
- EXPECT_CALL(*gamepad_delegates[4], OnFrame(testing::_)).Times(1);
- // Disconnect gamepads 0, 2 and 4.
- EXPECT_CALL(*gamepad_delegates[0], OnRemoved()).Times(1);
- EXPECT_CALL(*gamepad_delegates[2], OnRemoved()).Times(1);
- EXPECT_CALL(*gamepad_delegates[4], OnRemoved()).Times(1);
- // Connect a new gamepad.
- EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
- .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
- gamepad.SetDelegate(std::move(gamepad_delegates[5]));
- }));
- // Send frame to all gamepads.
- EXPECT_CALL(*gamepad_delegates[1], OnFrame(testing::_)).Times(1);
- EXPECT_CALL(*gamepad_delegates[3], OnFrame(testing::_)).Times(1);
- EXPECT_CALL(*gamepad_delegates[5], OnFrame(testing::_)).Times(1);
- }
- // The rest of gamepads should be disconnected after GamingSeat is
- // destroyed.
- EXPECT_CALL(*gamepad_delegates[1], OnRemoved()).Times(1);
- EXPECT_CALL(*gamepad_delegates[3], OnRemoved()).Times(1);
- EXPECT_CALL(*gamepad_delegates[5], OnRemoved()).Times(1);
- // Gamepad connected.
- UpdateGamepadDevice({0, 1});
- SendFrameToGamepads({0, 1});
- UpdateGamepadDevice({0, 1, 2, 3, 4});
- SendFrameToGamepads({0, 1, 2, 3, 4});
- UpdateGamepadDevice({1, 2, 3, 4});
- UpdateGamepadDevice({1, 3, 4});
- UpdateGamepadDevice({1, 3});
- UpdateGamepadDevice({1, 3, 5});
- SendFrameToGamepads({1, 2, 3, 4, 5});
- DestroyGamingSeat(gaming_seat_delegate);
- UpdateGamepadDevice({});
- }
- TEST_F(GamingSeatTest, Timestamp) {
- std::unique_ptr<Surface> surface(new Surface);
- std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
- gfx::Size buffer_size(10, 10);
- std::unique_ptr<Buffer> buffer(
- new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
- surface->Attach(buffer.get());
- surface->Commit();
- testing::StrictMock<MockGamingSeatDelegate>* gaming_seat_delegate =
- new testing::StrictMock<MockGamingSeatDelegate>();
- EXPECT_CALL(*gaming_seat_delegate,
- CanAcceptGamepadEventsForSurface(testing::_))
- .WillOnce(testing::Return(true));
- InitializeGamingSeat(gaming_seat_delegate);
- auto gamepad_delegate =
- std::make_unique<testing::StrictMock<MockGamepadDelegate>>();
- base::TimeTicks expected_time = base::TimeTicks::Now();
- { // Test sequence
- testing::InSequence s;
- // Connect gamepad.
- EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
- .WillOnce(testing::Invoke([&gamepad_delegate](auto& gamepad) {
- gamepad.SetDelegate(std::move(gamepad_delegate));
- }));
- // Send button to connected gamepad. Expect correct timestamp.
- EXPECT_CALL(*gamepad_delegate,
- OnButton(testing::_, testing::_, testing::Eq(expected_time)))
- .Times(1);
- }
- // Disconnect gamepad.
- EXPECT_CALL(*gamepad_delegate, OnRemoved()).Times(1);
- // Gamepad connected.
- UpdateGamepadDevice({1});
- SendButtonToGamepads({1}, expected_time);
- UpdateGamepadDevice({});
- DestroyGamingSeat(gaming_seat_delegate);
- }
- } // namespace
- } // namespace exo
|