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

Side by Side Diff: components/exo/gaming_seat_unittest.cc

Issue 2900773003: Allow gaming_seat to use ozone gamepad as back-end (Closed)
Patch Set: Allow gaming_seat to use ozone gamepad as backend Created 3 years, 6 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 unified diff | Download patch
« no previous file with comments | « components/exo/gaming_seat_ozone.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/exo/gaming_seat.h" 5 #include "components/exo/gaming_seat.h"
6 #include "ash/shell.h" 6 #include "ash/shell.h"
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "base/test/test_simple_task_runner.h"
10 #include "components/exo/buffer.h" 9 #include "components/exo/buffer.h"
11 #include "components/exo/gamepad_delegate.h" 10 #include "components/exo/gamepad_delegate.h"
12 #include "components/exo/gaming_seat_delegate.h" 11 #include "components/exo/gaming_seat_delegate.h"
13 #include "components/exo/shell_surface.h" 12 #include "components/exo/shell_surface.h"
14 #include "components/exo/surface.h" 13 #include "components/exo/surface.h"
15 #include "components/exo/test/exo_test_base.h" 14 #include "components/exo/test/exo_test_base.h"
16 #include "components/exo/test/exo_test_helper.h" 15 #include "components/exo/test/exo_test_helper.h"
17 #include "device/gamepad/gamepad_test_helpers.h" 16 #include "device/gamepad/gamepad_test_helpers.h"
18 #include "testing/gmock/include/gmock/gmock.h" 17 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/aura/client/focus_client.h" 19 #include "ui/aura/client/focus_client.h"
20 #include "ui/events/ozone/gamepad/gamepad_provider_ozone.h"
21 21
22 namespace exo { 22 namespace exo {
23 namespace { 23 namespace {
24 24
25 class MockGamingSeatDelegate : public GamingSeatDelegate { 25 class MockGamingSeatDelegate : public GamingSeatDelegate {
26 public: 26 public:
27 MOCK_CONST_METHOD1(CanAcceptGamepadEventsForSurface, bool(Surface*)); 27 MOCK_CONST_METHOD1(CanAcceptGamepadEventsForSurface, bool(Surface*));
28 MOCK_METHOD0(GamepadAdded, GamepadDelegate*()); 28 MOCK_METHOD0(GamepadAdded, GamepadDelegate*());
29 MOCK_METHOD0(Die, void()); 29 MOCK_METHOD0(Die, void());
30 void OnGamingSeatDestroying(GamingSeat*) override { delete this; }; 30 void OnGamingSeatDestroying(GamingSeat*) override { delete this; };
31 ~MockGamingSeatDelegate() { Die(); }; 31 ~MockGamingSeatDelegate() { Die(); };
32 }; 32 };
33 33
34 class MockGamepadDelegate : public GamepadDelegate { 34 class MockGamepadDelegate : public GamepadDelegate {
35 public: 35 public:
36 MockGamepadDelegate() {} 36 MockGamepadDelegate() {}
37 37
38 // Overridden from GamepadDelegate: 38 // Overridden from GamepadDelegate:
39 MOCK_METHOD0(OnRemoved, void()); 39 MOCK_METHOD0(OnRemoved, void());
40 MOCK_METHOD2(OnAxis, void(int, double)); 40 MOCK_METHOD2(OnAxis, void(int, double));
41 MOCK_METHOD3(OnButton, void(int, bool, double)); 41 MOCK_METHOD3(OnButton, void(int, bool, double));
42 MOCK_METHOD0(OnFrame, void()); 42 MOCK_METHOD0(OnFrame, void());
43 }; 43 };
44 44
45 class GamingSeatTest : public test::ExoTestBase { 45 class GamingSeatTest : public test::ExoTestBase {
46 public: 46 public:
47 GamingSeatTest() {} 47 GamingSeatTest() {}
48
49 std::unique_ptr<device::GamepadDataFetcher> MockDataFetcherFactory() {
50 device::Gamepads initial_data;
51 std::unique_ptr<device::MockGamepadDataFetcher> fetcher(
52 new device::MockGamepadDataFetcher(initial_data));
53 mock_data_fetcher_ = fetcher.get();
54 return std::move(fetcher);
55 }
56
57 void InitializeGamingSeat(MockGamingSeatDelegate* delegate) { 48 void InitializeGamingSeat(MockGamingSeatDelegate* delegate) {
58 polling_task_runner_ = new base::TestSimpleTaskRunner(); 49 gaming_seat_.reset(new GamingSeat(delegate, nullptr));
59 gaming_seat_.reset(
60 new GamingSeat(delegate, polling_task_runner_.get(),
61 base::Bind(&GamingSeatTest::MockDataFetcherFactory,
62 base::Unretained(this))));
63 // Run the polling task runner to have it create the data fetcher.
64 polling_task_runner_->RunPendingTasks();
65 } 50 }
66 51
67 void DestroyGamingSeat(MockGamingSeatDelegate* delegate) { 52 void DestroyGamingSeat(MockGamingSeatDelegate* delegate) {
68 EXPECT_CALL(*delegate, Die()).Times(1); 53 EXPECT_CALL(*delegate, Die()).Times(1);
69 mock_data_fetcher_ = nullptr;
70 gaming_seat_.reset(); 54 gaming_seat_.reset();
71 // Process tasks until polling is shut down.
72 polling_task_runner_->RunPendingTasks();
73 polling_task_runner_ = nullptr;
74 } 55 }
75 56
76 void SetDataAndPostToDelegate(const device::Gamepads& new_data) { 57 void UpdateGamepadDevice(const std::vector<int>& gamepad_device_ids) {
77 ASSERT_TRUE(mock_data_fetcher_ != nullptr); 58 std::vector<ui::InputDevice> gamepad_devices;
78 mock_data_fetcher_->SetTestData(new_data); 59 for (auto& id : gamepad_device_ids) {
79 // Run one polling cycle, which will post a task to the origin task runner. 60 gamepad_devices.push_back(ui::InputDevice(
80 polling_task_runner_->RunPendingTasks(); 61 id, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "gamepad"));
81 // Run origin task runner to invoke delegate. 62 }
82 base::RunLoop().RunUntilIdle(); 63 ui::GamepadProviderOzone::GetInstance()->DispatchGamepadDevicesUpdated(
64 gamepad_devices);
65 }
66
67 void SendFrameToGamepads(const std::vector<int>& gamepad_device_ids) {
68 for (auto& id : gamepad_device_ids) {
69 ui::GamepadEvent event(id, ui::GamepadEventType::FRAME, 0, 0,
70 base::TimeTicks());
71 ui::GamepadProviderOzone::GetInstance()->DispatchGamepadEvent(event);
72 }
83 } 73 }
84 74
85 protected: 75 protected:
86 std::unique_ptr<GamingSeat> gaming_seat_; 76 std::unique_ptr<GamingSeat> gaming_seat_;
87 77
88 // Task runner to simulate the polling thread.
89 scoped_refptr<base::TestSimpleTaskRunner> polling_task_runner_;
90
91 // Weak reference to the mock data fetcher provided by MockDataFetcherFactory.
92 // This instance is valid until both gamepad_ and polling_task_runner_ are
93 // shut down.
94 device::MockGamepadDataFetcher* mock_data_fetcher_;
95
96 DISALLOW_COPY_AND_ASSIGN(GamingSeatTest); 78 DISALLOW_COPY_AND_ASSIGN(GamingSeatTest);
97 }; 79 };
98 80
99 TEST_F(GamingSeatTest, ConnectionChange) { 81 TEST_F(GamingSeatTest, ConnectionChange) {
100 std::unique_ptr<Surface> surface(new Surface); 82 std::unique_ptr<Surface> surface(new Surface);
101 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); 83 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
102 gfx::Size buffer_size(10, 10); 84 gfx::Size buffer_size(10, 10);
103 std::unique_ptr<Buffer> buffer( 85 std::unique_ptr<Buffer> buffer(
104 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); 86 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
105 surface->Attach(buffer.get()); 87 surface->Attach(buffer.get());
106 surface->Commit(); 88 surface->Commit();
107 89
108 testing::StrictMock<MockGamingSeatDelegate>* gaming_seat_delegate = 90 testing::StrictMock<MockGamingSeatDelegate>* gaming_seat_delegate =
109 new testing::StrictMock<MockGamingSeatDelegate>(); 91 new testing::StrictMock<MockGamingSeatDelegate>();
110 EXPECT_CALL(*gaming_seat_delegate, 92 EXPECT_CALL(*gaming_seat_delegate,
111 CanAcceptGamepadEventsForSurface(testing::_)) 93 CanAcceptGamepadEventsForSurface(testing::_))
112 .WillOnce(testing::Return(true)); 94 .WillOnce(testing::Return(true));
113 95
114 InitializeGamingSeat(gaming_seat_delegate); 96 InitializeGamingSeat(gaming_seat_delegate);
115 testing::StrictMock<MockGamepadDelegate> gamepad_delegate0; 97 testing::StrictMock<MockGamepadDelegate> gamepad_delegate[6];
116 testing::StrictMock<MockGamepadDelegate> gamepad_delegate1;
117 testing::StrictMock<MockGamepadDelegate> gamepad_delegate2;
118 98
119 { // Test sequence 99 { // Test sequence
120 testing::InSequence s; 100 testing::InSequence s;
121 // connect gamepad 0 101 // Connect 2 gamepads.
122 // connect gamepad 2
123 // connect gamepad 1
124 EXPECT_CALL(*gaming_seat_delegate, GamepadAdded()) 102 EXPECT_CALL(*gaming_seat_delegate, GamepadAdded())
125 .WillOnce(testing::Return(&gamepad_delegate0)) 103 .WillOnce(testing::Return(&gamepad_delegate[0]))
126 .WillOnce(testing::Return(&gamepad_delegate2)) 104 .WillOnce(testing::Return(&gamepad_delegate[1]));
127 .WillOnce(testing::Return(&gamepad_delegate1)); 105 // Send frame to connected gamepad.
128 // disconnect gamepad 1 106 EXPECT_CALL(gamepad_delegate[0], OnFrame()).Times(1);
129 EXPECT_CALL(gamepad_delegate1, OnRemoved()).Times(1); 107 EXPECT_CALL(gamepad_delegate[1], OnFrame()).Times(1);
108 // Connect 3 more.
109 EXPECT_CALL(*gaming_seat_delegate, GamepadAdded())
110 .WillOnce(testing::Return(&gamepad_delegate[2]))
111 .WillOnce(testing::Return(&gamepad_delegate[3]))
112 .WillOnce(testing::Return(&gamepad_delegate[4]));
113 // Send frame to all gamepads.
114 EXPECT_CALL(gamepad_delegate[0], OnFrame()).Times(1);
115 EXPECT_CALL(gamepad_delegate[1], OnFrame()).Times(1);
116 EXPECT_CALL(gamepad_delegate[2], OnFrame()).Times(1);
117 EXPECT_CALL(gamepad_delegate[3], OnFrame()).Times(1);
118 EXPECT_CALL(gamepad_delegate[4], OnFrame()).Times(1);
119 // Disconnect gamepad 0 and gamepad 2 and connect a new gamepad.
120 EXPECT_CALL(gamepad_delegate[0], OnRemoved()).Times(1);
121 EXPECT_CALL(gamepad_delegate[2], OnRemoved()).Times(1);
122 EXPECT_CALL(gamepad_delegate[4], OnRemoved()).Times(1);
123 EXPECT_CALL(*gaming_seat_delegate, GamepadAdded())
124 .WillOnce(testing::Return(&gamepad_delegate[5]));
125 // Send frame to all gamepads.
126 EXPECT_CALL(gamepad_delegate[1], OnFrame()).Times(1);
127 EXPECT_CALL(gamepad_delegate[3], OnFrame()).Times(1);
128 EXPECT_CALL(gamepad_delegate[5], OnFrame()).Times(1);
129
130 // disconnect other gamepads 130 // disconnect other gamepads
131 EXPECT_CALL(gamepad_delegate0, OnRemoved()).Times(1); 131 EXPECT_CALL(gamepad_delegate[1], OnRemoved()).Times(1);
132 EXPECT_CALL(gamepad_delegate2, OnRemoved()).Times(1); 132 EXPECT_CALL(gamepad_delegate[3], OnRemoved()).Times(1);
133 EXPECT_CALL(gamepad_delegate[5], OnRemoved()).Times(1);
133 } 134 }
134 // Gamepad connected. 135 // Gamepad connected.
135 device::Gamepads gamepad_connected; 136 UpdateGamepadDevice({0, 1});
136 gamepad_connected.items[0].connected = true; 137 SendFrameToGamepads({0, 1});
137 gamepad_connected.items[0].timestamp = 1; 138 UpdateGamepadDevice({0, 1, 2, 3, 4});
138 SetDataAndPostToDelegate(gamepad_connected); 139 SendFrameToGamepads({0, 1, 2, 3, 4});
139 140 UpdateGamepadDevice({1, 3, 5});
140 gamepad_connected.items[2].connected = true; 141 SendFrameToGamepads({1, 2, 3, 4, 5});
141 gamepad_connected.items[2].timestamp = 1;
142 SetDataAndPostToDelegate(gamepad_connected);
143
144 gamepad_connected.items[1].connected = true;
145 gamepad_connected.items[1].timestamp = 1;
146 SetDataAndPostToDelegate(gamepad_connected);
147
148 // Gamepad 1 is dis connected
149 gamepad_connected.items[1].connected = false;
150 gamepad_connected.items[1].timestamp = 2;
151
152 SetDataAndPostToDelegate(gamepad_connected);
153
154 // Gamepad disconnected.
155 device::Gamepads all_disconnected;
156 SetDataAndPostToDelegate(all_disconnected);
157
158 DestroyGamingSeat(gaming_seat_delegate); 142 DestroyGamingSeat(gaming_seat_delegate);
159 } 143 }
160 144
161 TEST_F(GamingSeatTest, OnAxis) {
162 std::unique_ptr<Surface> surface(new Surface);
163 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
164 gfx::Size buffer_size(10, 10);
165 std::unique_ptr<Buffer> buffer(
166 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
167 surface->Attach(buffer.get());
168 surface->Commit();
169
170 testing::StrictMock<MockGamingSeatDelegate>* gaming_seat_delegate =
171 new testing::StrictMock<MockGamingSeatDelegate>();
172 EXPECT_CALL(*gaming_seat_delegate,
173 CanAcceptGamepadEventsForSurface(testing::_))
174 .WillOnce(testing::Return(true));
175
176 InitializeGamingSeat(gaming_seat_delegate);
177 testing::StrictMock<MockGamepadDelegate> gamepad_delegate0;
178 testing::StrictMock<MockGamepadDelegate> gamepad_delegate2;
179
180 // connect gamepad 0 and 2
181 EXPECT_CALL(*gaming_seat_delegate, GamepadAdded())
182 .WillOnce(testing::Return(&gamepad_delegate0))
183 .WillOnce(testing::Return(&gamepad_delegate2));
184
185 device::Gamepads gamepad_connected;
186 gamepad_connected.items[0].connected = true;
187 gamepad_connected.items[0].timestamp = 1;
188 SetDataAndPostToDelegate(gamepad_connected);
189
190 gamepad_connected.items[2].connected = true;
191 gamepad_connected.items[2].timestamp = 1;
192 SetDataAndPostToDelegate(gamepad_connected);
193
194 // send axis event to 2 and then 0
195 device::Gamepads axis_moved;
196 axis_moved.items[0].connected = true;
197 axis_moved.items[0].timestamp = 1;
198 axis_moved.items[2].connected = true;
199 axis_moved.items[2].timestamp = 2;
200 axis_moved.items[2].axes_length = 1;
201 axis_moved.items[2].axes[0] = 1.0;
202
203 EXPECT_CALL(gamepad_delegate2, OnAxis(0, 1.0)).Times(1);
204 EXPECT_CALL(gamepad_delegate2, OnFrame()).Times(1);
205 SetDataAndPostToDelegate(axis_moved);
206
207 axis_moved.items[0].timestamp = 2;
208 axis_moved.items[0].axes_length = 1;
209 axis_moved.items[0].axes[0] = 2.0;
210
211 EXPECT_CALL(gamepad_delegate0, OnAxis(0, 2.0)).Times(1);
212 EXPECT_CALL(gamepad_delegate0, OnFrame()).Times(1);
213 SetDataAndPostToDelegate(axis_moved);
214
215 EXPECT_CALL(gamepad_delegate0, OnRemoved()).Times(1);
216 EXPECT_CALL(gamepad_delegate2, OnRemoved()).Times(1);
217 DestroyGamingSeat(gaming_seat_delegate);
218 }
219
220 TEST_F(GamingSeatTest, OnButton) {
221 std::unique_ptr<Surface> surface(new Surface);
222 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
223 gfx::Size buffer_size(10, 10);
224 std::unique_ptr<Buffer> buffer(
225 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
226 surface->Attach(buffer.get());
227 surface->Commit();
228
229 testing::StrictMock<MockGamingSeatDelegate>* gaming_seat_delegate =
230 new testing::StrictMock<MockGamingSeatDelegate>();
231 EXPECT_CALL(*gaming_seat_delegate,
232 CanAcceptGamepadEventsForSurface(testing::_))
233 .WillOnce(testing::Return(true));
234
235 InitializeGamingSeat(gaming_seat_delegate);
236 testing::StrictMock<MockGamepadDelegate> gamepad_delegate0;
237 testing::StrictMock<MockGamepadDelegate> gamepad_delegate2;
238
239 // connect gamepad 0 and 2
240 EXPECT_CALL(*gaming_seat_delegate, GamepadAdded())
241 .WillOnce(testing::Return(&gamepad_delegate0))
242 .WillOnce(testing::Return(&gamepad_delegate2));
243
244 device::Gamepads gamepad_connected;
245 gamepad_connected.items[0].connected = true;
246 gamepad_connected.items[0].timestamp = 1;
247 SetDataAndPostToDelegate(gamepad_connected);
248
249 gamepad_connected.items[2].connected = true;
250 gamepad_connected.items[2].timestamp = 1;
251 SetDataAndPostToDelegate(gamepad_connected);
252
253 // send axis event to 2 and then 0
254 device::Gamepads axis_moved;
255 axis_moved.items[0].connected = true;
256 axis_moved.items[0].timestamp = 1;
257 axis_moved.items[2].connected = true;
258 axis_moved.items[2].timestamp = 2;
259
260 axis_moved.items[2].buttons_length = 1;
261 axis_moved.items[2].buttons[0].pressed = true;
262 axis_moved.items[2].buttons[0].value = 1.0;
263
264 EXPECT_CALL(gamepad_delegate2, OnButton(0, true, 1.0)).Times(1);
265 EXPECT_CALL(gamepad_delegate2, OnFrame()).Times(1);
266 SetDataAndPostToDelegate(axis_moved);
267
268 axis_moved.items[0].timestamp = 2;
269 axis_moved.items[0].buttons_length = 1;
270 axis_moved.items[0].buttons[0].pressed = true;
271 axis_moved.items[0].buttons[0].value = 2.0;
272
273 EXPECT_CALL(gamepad_delegate0, OnButton(0, true, 2.0)).Times(1);
274 EXPECT_CALL(gamepad_delegate0, OnFrame()).Times(1);
275 SetDataAndPostToDelegate(axis_moved);
276
277 EXPECT_CALL(gamepad_delegate0, OnRemoved()).Times(1);
278 EXPECT_CALL(gamepad_delegate2, OnRemoved()).Times(1);
279
280 DestroyGamingSeat(gaming_seat_delegate);
281 }
282
283 TEST_F(GamingSeatTest, OnWindowFocused) {
284 // Create surface and move focus to it.
285 std::unique_ptr<Surface> surface(new Surface);
286 std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get()));
287 gfx::Size buffer_size(10, 10);
288 std::unique_ptr<Buffer> buffer(
289 new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
290 surface->Attach(buffer.get());
291 surface->Commit();
292
293 testing::StrictMock<MockGamingSeatDelegate>* gaming_seat_delegate =
294 new testing::StrictMock<MockGamingSeatDelegate>();
295 EXPECT_CALL(*gaming_seat_delegate,
296 CanAcceptGamepadEventsForSurface(testing::_))
297 .WillOnce(testing::Return(true));
298
299 InitializeGamingSeat(gaming_seat_delegate);
300
301 // In focus. Should be polling indefinitely, check a couple of time that the
302 // poll task is re-posted.
303 for (size_t i = 0; i < 5; ++i) {
304 polling_task_runner_->RunPendingTasks();
305 ASSERT_TRUE(polling_task_runner_->HasPendingTask());
306 }
307
308 // Remove focus from window.
309 aura::client::FocusClient* focus_client =
310 aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
311 focus_client->FocusWindow(nullptr);
312
313 // Run EnablePolling and OnPoll task, no more polls should be scheduled.
314 // In the first round of RunPendingTasks we will execute
315 // EnablePollingOnPollingThread, which will cause the polling to stop being
316 // scheduled in the next round.
317 polling_task_runner_->RunPendingTasks();
318 polling_task_runner_->RunPendingTasks();
319 ASSERT_FALSE(polling_task_runner_->HasPendingTask());
320
321 DestroyGamingSeat(gaming_seat_delegate);
322 }
323
324 } // namespace 145 } // namespace
325 } // namespace exo 146 } // namespace exo
OLDNEW
« no previous file with comments | « components/exo/gaming_seat_ozone.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698