gaming_seat_unittest.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/exo/gaming_seat.h"
  5. #include <memory>
  6. #include <vector>
  7. #include "ash/shell.h"
  8. #include "base/command_line.h"
  9. #include "base/run_loop.h"
  10. #include "base/time/time.h"
  11. #include "components/exo/buffer.h"
  12. #include "components/exo/gamepad.h"
  13. #include "components/exo/gamepad_delegate.h"
  14. #include "components/exo/gaming_seat_delegate.h"
  15. #include "components/exo/shell_surface.h"
  16. #include "components/exo/surface.h"
  17. #include "components/exo/test/exo_test_base.h"
  18. #include "components/exo/test/exo_test_helper.h"
  19. #include "device/gamepad/gamepad_test_helpers.h"
  20. #include "testing/gmock/include/gmock/gmock.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. #include "ui/aura/client/focus_client.h"
  23. #include "ui/events/ozone/gamepad/gamepad_provider_ozone.h"
  24. namespace exo {
  25. namespace {
  26. class MockGamepadDelegate : public GamepadDelegate {
  27. public:
  28. MockGamepadDelegate() {}
  29. // Overridden from GamepadDelegate:
  30. MOCK_METHOD(void, OnRemoved, (), (override));
  31. MOCK_METHOD(void,
  32. OnAxis,
  33. (int axis, double value, base::TimeTicks timestamp),
  34. (override));
  35. MOCK_METHOD(void,
  36. OnButton,
  37. (int button, bool pressed, base::TimeTicks timestamp),
  38. (override));
  39. MOCK_METHOD(void, OnFrame, (base::TimeTicks timestamp), (override));
  40. };
  41. class MockGamingSeatDelegate : public GamingSeatDelegate {
  42. public:
  43. MOCK_METHOD(bool,
  44. CanAcceptGamepadEventsForSurface,
  45. (Surface * surface),
  46. (const, override));
  47. MOCK_METHOD(void, GamepadAdded, (Gamepad & gamepad), (override));
  48. MOCK_METHOD(void, Die, (), ());
  49. void OnGamingSeatDestroying(GamingSeat*) override { delete this; }
  50. ~MockGamingSeatDelegate() { Die(); }
  51. };
  52. class GamingSeatTest : public test::ExoTestBase {
  53. public:
  54. GamingSeatTest() {}
  55. GamingSeatTest(const GamingSeatTest&) = delete;
  56. GamingSeatTest& operator=(const GamingSeatTest&) = delete;
  57. void InitializeGamingSeat(MockGamingSeatDelegate* delegate) {
  58. gaming_seat_ = std::make_unique<GamingSeat>(delegate);
  59. }
  60. void DestroyGamingSeat(MockGamingSeatDelegate* delegate) {
  61. EXPECT_CALL(*delegate, Die()).Times(1);
  62. gaming_seat_.reset();
  63. }
  64. void UpdateGamepadDevice(const std::vector<int>& gamepad_device_ids) {
  65. std::vector<ui::GamepadDevice> gamepad_devices;
  66. for (auto& id : gamepad_device_ids) {
  67. gamepad_devices.emplace_back(
  68. ui::InputDevice(id, ui::InputDeviceType::INPUT_DEVICE_USB, "gamepad"),
  69. std::vector<ui::GamepadDevice::Axis>(),
  70. /*supports_vibration_rumble=*/false);
  71. }
  72. ui::GamepadProviderOzone::GetInstance()->DispatchGamepadDevicesUpdated(
  73. gamepad_devices);
  74. }
  75. void SendFrameToGamepads(const std::vector<int>& gamepad_device_ids) {
  76. for (auto& id : gamepad_device_ids) {
  77. ui::GamepadEvent event(id, ui::GamepadEventType::FRAME, 0, 0,
  78. base::TimeTicks());
  79. ui::GamepadProviderOzone::GetInstance()->DispatchGamepadEvent(event);
  80. }
  81. }
  82. void SendButtonToGamepads(const std::vector<int>& gamepad_device_ids,
  83. base::TimeTicks timestamp) {
  84. for (auto& id : gamepad_device_ids) {
  85. ui::GamepadEvent event(id, ui::GamepadEventType::BUTTON, 310, 1,
  86. timestamp);
  87. ui::GamepadProviderOzone::GetInstance()->DispatchGamepadEvent(event);
  88. }
  89. }
  90. protected:
  91. std::unique_ptr<GamingSeat> gaming_seat_;
  92. };
  93. TEST_F(GamingSeatTest, ConnectionChange) {
  94. std::unique_ptr<Surface> surface(new Surface);
  95. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  96. gfx::Size buffer_size(10, 10);
  97. std::unique_ptr<Buffer> buffer(
  98. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  99. surface->Attach(buffer.get());
  100. surface->Commit();
  101. testing::StrictMock<MockGamingSeatDelegate>* gaming_seat_delegate =
  102. new testing::StrictMock<MockGamingSeatDelegate>();
  103. EXPECT_CALL(*gaming_seat_delegate,
  104. CanAcceptGamepadEventsForSurface(testing::_))
  105. .WillOnce(testing::Return(true));
  106. InitializeGamingSeat(gaming_seat_delegate);
  107. std::unique_ptr<MockGamepadDelegate> gamepad_delegates[6];
  108. for (auto& delegate : gamepad_delegates)
  109. delegate = std::make_unique<testing::StrictMock<MockGamepadDelegate>>();
  110. { // Test sequence
  111. testing::InSequence s;
  112. // Connect 2 gamepads.
  113. EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
  114. .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
  115. gamepad.SetDelegate(std::move(gamepad_delegates[0]));
  116. }));
  117. EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
  118. .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
  119. gamepad.SetDelegate(std::move(gamepad_delegates[1]));
  120. }));
  121. // Send frame to connected gamepad.
  122. EXPECT_CALL(*gamepad_delegates[0], OnFrame(testing::_)).Times(1);
  123. EXPECT_CALL(*gamepad_delegates[1], OnFrame(testing::_)).Times(1);
  124. // Connect 3 more.
  125. EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
  126. .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
  127. gamepad.SetDelegate(std::move(gamepad_delegates[2]));
  128. }));
  129. EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
  130. .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
  131. gamepad.SetDelegate(std::move(gamepad_delegates[3]));
  132. }));
  133. EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
  134. .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
  135. gamepad.SetDelegate(std::move(gamepad_delegates[4]));
  136. }));
  137. // Send frame to all gamepads.
  138. EXPECT_CALL(*gamepad_delegates[0], OnFrame(testing::_)).Times(1);
  139. EXPECT_CALL(*gamepad_delegates[1], OnFrame(testing::_)).Times(1);
  140. EXPECT_CALL(*gamepad_delegates[2], OnFrame(testing::_)).Times(1);
  141. EXPECT_CALL(*gamepad_delegates[3], OnFrame(testing::_)).Times(1);
  142. EXPECT_CALL(*gamepad_delegates[4], OnFrame(testing::_)).Times(1);
  143. // Disconnect gamepads 0, 2 and 4.
  144. EXPECT_CALL(*gamepad_delegates[0], OnRemoved()).Times(1);
  145. EXPECT_CALL(*gamepad_delegates[2], OnRemoved()).Times(1);
  146. EXPECT_CALL(*gamepad_delegates[4], OnRemoved()).Times(1);
  147. // Connect a new gamepad.
  148. EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
  149. .WillOnce(testing::Invoke([&gamepad_delegates](auto& gamepad) {
  150. gamepad.SetDelegate(std::move(gamepad_delegates[5]));
  151. }));
  152. // Send frame to all gamepads.
  153. EXPECT_CALL(*gamepad_delegates[1], OnFrame(testing::_)).Times(1);
  154. EXPECT_CALL(*gamepad_delegates[3], OnFrame(testing::_)).Times(1);
  155. EXPECT_CALL(*gamepad_delegates[5], OnFrame(testing::_)).Times(1);
  156. }
  157. // The rest of gamepads should be disconnected after GamingSeat is
  158. // destroyed.
  159. EXPECT_CALL(*gamepad_delegates[1], OnRemoved()).Times(1);
  160. EXPECT_CALL(*gamepad_delegates[3], OnRemoved()).Times(1);
  161. EXPECT_CALL(*gamepad_delegates[5], OnRemoved()).Times(1);
  162. // Gamepad connected.
  163. UpdateGamepadDevice({0, 1});
  164. SendFrameToGamepads({0, 1});
  165. UpdateGamepadDevice({0, 1, 2, 3, 4});
  166. SendFrameToGamepads({0, 1, 2, 3, 4});
  167. UpdateGamepadDevice({1, 2, 3, 4});
  168. UpdateGamepadDevice({1, 3, 4});
  169. UpdateGamepadDevice({1, 3});
  170. UpdateGamepadDevice({1, 3, 5});
  171. SendFrameToGamepads({1, 2, 3, 4, 5});
  172. DestroyGamingSeat(gaming_seat_delegate);
  173. UpdateGamepadDevice({});
  174. }
  175. TEST_F(GamingSeatTest, Timestamp) {
  176. std::unique_ptr<Surface> surface(new Surface);
  177. std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
  178. gfx::Size buffer_size(10, 10);
  179. std::unique_ptr<Buffer> buffer(
  180. new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
  181. surface->Attach(buffer.get());
  182. surface->Commit();
  183. testing::StrictMock<MockGamingSeatDelegate>* gaming_seat_delegate =
  184. new testing::StrictMock<MockGamingSeatDelegate>();
  185. EXPECT_CALL(*gaming_seat_delegate,
  186. CanAcceptGamepadEventsForSurface(testing::_))
  187. .WillOnce(testing::Return(true));
  188. InitializeGamingSeat(gaming_seat_delegate);
  189. auto gamepad_delegate =
  190. std::make_unique<testing::StrictMock<MockGamepadDelegate>>();
  191. base::TimeTicks expected_time = base::TimeTicks::Now();
  192. { // Test sequence
  193. testing::InSequence s;
  194. // Connect gamepad.
  195. EXPECT_CALL(*gaming_seat_delegate, GamepadAdded(testing::_))
  196. .WillOnce(testing::Invoke([&gamepad_delegate](auto& gamepad) {
  197. gamepad.SetDelegate(std::move(gamepad_delegate));
  198. }));
  199. // Send button to connected gamepad. Expect correct timestamp.
  200. EXPECT_CALL(*gamepad_delegate,
  201. OnButton(testing::_, testing::_, testing::Eq(expected_time)))
  202. .Times(1);
  203. }
  204. // Disconnect gamepad.
  205. EXPECT_CALL(*gamepad_delegate, OnRemoved()).Times(1);
  206. // Gamepad connected.
  207. UpdateGamepadDevice({1});
  208. SendButtonToGamepads({1}, expected_time);
  209. UpdateGamepadDevice({});
  210. DestroyGamingSeat(gaming_seat_delegate);
  211. }
  212. } // namespace
  213. } // namespace exo