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

Side by Side Diff: remoting/host/touch_injector_win_unittest.cc

Issue 991643002: Windows Host Touch Injection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 5 years, 9 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 | « remoting/host/touch_injector_win.cc ('k') | remoting/host/win/session_input_injector.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
5 #include "remoting/host/touch_injector_win.h"
6
7 #include <map>
8
9 #include "base/stl_util.h"
10 #include "remoting/proto/event.pb.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 using ::testing::_;
15 using ::testing::AtLeast;
16 using ::testing::InSequence;
17 using ::testing::ExpectationSet;
18 using ::testing::Return;
19
20 namespace remoting {
21
22 using protocol::TouchEvent;
23 using protocol::TouchEventPoint;
24
25 namespace {
26
27 // Maps touch pointer ID to expected flags [start, move, end, cancel] listed
28 // below.
29 typedef std::map<uint32_t, uint32_t> IdFlagMap;
30
31 const uint32_t kStartFlag =
32 POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT | POINTER_FLAG_DOWN;
33
34 const uint32_t kMoveFlag =
35 POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT | POINTER_FLAG_UPDATE;
36
37 const uint32_t kEndFlag = POINTER_FLAG_UP;
38
39 const uint32_t kCancelFlag = POINTER_FLAG_UP | POINTER_FLAG_CANCELED;
40
41 MATCHER_P(EqualsSinglePointerTouchInfo, expected, "") {
42 return arg->touchMask == expected.touchMask &&
43 arg->rcContact.left == expected.rcContact.left &&
44 arg->rcContact.top == expected.rcContact.top &&
45 arg->rcContact.right == expected.rcContact.right &&
46 arg->rcContact.bottom == expected.rcContact.bottom &&
47 arg->orientation == expected.orientation &&
48 arg->pressure == expected.pressure &&
49 arg->pointerInfo.pointerType == expected.pointerInfo.pointerType &&
50 arg->pointerInfo.pointerId == expected.pointerInfo.pointerId &&
51 arg->pointerInfo.ptPixelLocation.x ==
52 expected.pointerInfo.ptPixelLocation.x &&
53 arg->pointerInfo.ptPixelLocation.y ==
54 expected.pointerInfo.ptPixelLocation.y;
55 }
56
57 // Make sure that every touch point has the right flag (pointerFlags).
58 MATCHER_P(EqualsPointerTouchInfoFlag, id_to_flag_map, "") {
59 for (size_t i = 0; i < id_to_flag_map.size(); ++i) {
60 const POINTER_TOUCH_INFO* touch_info = arg + i;
61 const uint32_t id = touch_info->pointerInfo.pointerId;
62 if (!ContainsKey(id_to_flag_map, id))
63 return false;
64
65 if (id_to_flag_map.find(id)->second != touch_info->pointerInfo.pointerFlags)
66 return false;
67 }
68 return true;
69 }
70
71 class TouchInjectorWinDelegateMock : public TouchInjectorWinDelegate {
72 public:
73 TouchInjectorWinDelegateMock()
74 : TouchInjectorWinDelegate(nullptr, nullptr, nullptr) {}
75 ~TouchInjectorWinDelegateMock() override {};
76
77 MOCK_METHOD2(InitializeTouchInjection, BOOL(UINT32 max_count, DWORD dw_mode));
78 MOCK_METHOD2(InjectTouchInput,
79 DWORD(UINT32 count, const POINTER_TOUCH_INFO* contacts));
80 };
81
82 } // namespace
83
84 // A test to make sure that the touch event is converted correctly to
85 // POINTER_TOUCH_INFO.
86 TEST(TouchInjectorWinTest, CheckConversionWithPressure) {
87 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock(
88 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
89
90 TouchEvent event;
91 event.set_event_type(TouchEvent::TOUCH_POINT_START);
92 TouchEventPoint* point = event.add_touch_points();
93 point->set_id(1234u);
94 point->set_x(321.0f);
95 point->set_y(123.0f);
96 point->set_radius_x(10.0f);
97 point->set_radius_y(20.0f);
98 point->set_pressure(0.5f);
99 point->set_angle(45.0f);
100
101 POINTER_TOUCH_INFO expected_touch_info;
102 expected_touch_info.touchMask =
103 TOUCH_MASK_CONTACTAREA | TOUCH_MASK_ORIENTATION | TOUCH_MASK_PRESSURE;
104 expected_touch_info.rcContact.left = 311;
105 expected_touch_info.rcContact.top = 103;
106 expected_touch_info.rcContact.right = 331;
107 expected_touch_info.rcContact.bottom = 143;
108 expected_touch_info.orientation = 0;
109 expected_touch_info.pressure = 512;
110 expected_touch_info.orientation = 45;
111
112 expected_touch_info.pointerInfo.pointerType = PT_TOUCH;
113 expected_touch_info.pointerInfo.pointerId = 1234u;
114 expected_touch_info.pointerInfo.ptPixelLocation.x = 321;
115 expected_touch_info.pointerInfo.ptPixelLocation.y = 123;
116
117 InSequence s;
118 EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
119 .WillOnce(Return(1));
120 EXPECT_CALL(
121 *delegate_mock,
122 InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
123 .WillOnce(Return(1));
124
125 // Check pressure clamping as well.
126 expected_touch_info.pressure = 1024; // Max
127 EXPECT_CALL(
128 *delegate_mock,
129 InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
130 .WillOnce(Return(1));
131
132 expected_touch_info.pressure = 0; // Min
133 EXPECT_CALL(
134 *delegate_mock,
135 InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
136 .WillOnce(Return(1));
137
138 TouchInjectorWin injector;
139 injector.SetInjectorDelegateForTest(delegate_mock.Pass());
140 EXPECT_TRUE(injector.Init());
141 injector.InjectTouchEvent(event);
142
143 // Change to MOVE so that there still only one point.
144 event.set_event_type(TouchEvent::TOUCH_POINT_MOVE);
145 point->set_pressure(2.0f);
146 injector.InjectTouchEvent(event);
147
148 point->set_pressure(-3.0f);
149 injector.InjectTouchEvent(event);
150 }
151
152 // Some devices don't detect pressure. This test is a conversion check for
153 // such devices.
154 TEST(TouchInjectorWinTest, CheckConversionNoPressure) {
155 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock(
156 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
157
158 TouchEvent event;
159 event.set_event_type(TouchEvent::TOUCH_POINT_START);
160 TouchEventPoint* point = event.add_touch_points();
161 point->set_id(1234u);
162 point->set_x(321.0f);
163 point->set_y(123.0f);
164 point->set_radius_x(10.0f);
165 point->set_radius_y(20.0f);
166 point->set_angle(45.0f);
167
168 POINTER_TOUCH_INFO expected_touch_info;
169 expected_touch_info.touchMask =
170 TOUCH_MASK_CONTACTAREA | TOUCH_MASK_ORIENTATION;
171 expected_touch_info.rcContact.left = 311;
172 expected_touch_info.rcContact.top = 103;
173 expected_touch_info.rcContact.right = 331;
174 expected_touch_info.rcContact.bottom = 143;
175 expected_touch_info.orientation = 0;
176 expected_touch_info.pressure = 0;
177 expected_touch_info.orientation = 45;
178
179 expected_touch_info.pointerInfo.pointerType = PT_TOUCH;
180 expected_touch_info.pointerInfo.pointerId = 1234u;
181 expected_touch_info.pointerInfo.ptPixelLocation.x = 321;
182 expected_touch_info.pointerInfo.ptPixelLocation.y = 123;
183
184 InSequence s;
185 EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
186 .WillOnce(Return(1));
187 EXPECT_CALL(
188 *delegate_mock,
189 InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
190 .WillOnce(Return(1));
191
192 TouchInjectorWin injector;
193 injector.SetInjectorDelegateForTest(delegate_mock.Pass());
194 EXPECT_TRUE(injector.Init());
195 injector.InjectTouchEvent(event);
196 }
197
198 // If initialization fails, it should not call any touch injection functions.
199 TEST(TouchInjectorWinTest, InitFailed) {
200 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock(
201 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
202
203 TouchEvent event;
204 event.set_event_type(TouchEvent::TOUCH_POINT_START);
205
206 InSequence s;
207 EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
208 .WillOnce(Return(0));
209 EXPECT_CALL(*delegate_mock, InjectTouchInput(_, _)).Times(0);
210
211 TouchInjectorWin injector;
212 injector.SetInjectorDelegateForTest(delegate_mock.Pass());
213 EXPECT_FALSE(injector.Init());
214 injector.InjectTouchEvent(event);
215 }
216
217 // Deinitialize and initialize should clean the state.
218 TEST(TouchInjectorWinTest, Reinitialize) {
219 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock_before_deinitialize(
220 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
221 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock_after_deinitialize(
222 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
223
224 TouchEvent first_event;
225 first_event.set_event_type(TouchEvent::TOUCH_POINT_START);
226 TouchEventPoint* point0 = first_event.add_touch_points();
227 point0->set_id(0u);
228
229 TouchEvent second_event;
230 second_event.set_event_type(TouchEvent::TOUCH_POINT_START);
231 TouchEventPoint* point1 = second_event.add_touch_points();
232 point1->set_id(1u);
233
234 InSequence s;
235 EXPECT_CALL(*delegate_mock_before_deinitialize,
236 InitializeTouchInjection(_, _)).WillOnce(Return(1));
237
238 IdFlagMap id_to_flags;
239 id_to_flags[0u] = kStartFlag;
240 EXPECT_CALL(
241 *delegate_mock_before_deinitialize,
242 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
243 .WillOnce(Return(1));
244
245 EXPECT_CALL(*delegate_mock_after_deinitialize,
246 InitializeTouchInjection(_, _)).WillOnce(Return(1));
247
248 // After deinitializing and then initializing, previous touch points should be
249 // gone.
250 id_to_flags.clear();
251 id_to_flags[1u] = kStartFlag;
252 EXPECT_CALL(
253 *delegate_mock_after_deinitialize,
254 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
255 .WillOnce(Return(1));
256
257 TouchInjectorWin injector;
258 injector.SetInjectorDelegateForTest(delegate_mock_before_deinitialize.Pass());
259
260 EXPECT_TRUE(injector.Init());
261 injector.InjectTouchEvent(first_event);
262 injector.Deinitialize();
263
264 injector.SetInjectorDelegateForTest(delegate_mock_after_deinitialize.Pass());
265 EXPECT_TRUE(injector.Init());
266 injector.InjectTouchEvent(second_event);
267 }
268
269 // Make sure that the flag is set to kStartFlag.
270 TEST(TouchInjectorWinTest, StartTouchPoint) {
271 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock(
272 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
273
274 TouchEvent event;
275 event.set_event_type(TouchEvent::TOUCH_POINT_START);
276 TouchEventPoint* point = event.add_touch_points();
277 point->set_id(0u);
278
279 InSequence s;
280 EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
281 .WillOnce(Return(1));
282
283 IdFlagMap id_to_flags;
284 id_to_flags[0u] = kStartFlag;
285 EXPECT_CALL(
286 *delegate_mock,
287 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
288 .WillOnce(Return(1));
289
290 TouchInjectorWin injector;
291 injector.SetInjectorDelegateForTest(delegate_mock.Pass());
292 EXPECT_TRUE(injector.Init());
293 injector.InjectTouchEvent(event);
294 }
295
296 // Start a point and then move, make sure the flag is set to kMoveFlag.
297 TEST(TouchInjectorWinTest, MoveTouchPoint) {
298 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock(
299 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
300
301 TouchEvent event;
302 event.set_event_type(TouchEvent::TOUCH_POINT_START);
303 TouchEventPoint* point = event.add_touch_points();
304 point->set_id(0u);
305
306
307 InSequence s;
308 EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
309 .WillOnce(Return(1));
310
311 IdFlagMap id_to_flags;
312 id_to_flags[0u] = kStartFlag;
313 EXPECT_CALL(
314 *delegate_mock,
315 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
316 .WillOnce(Return(1));
317
318 id_to_flags[0u] = kMoveFlag;
319 EXPECT_CALL(
320 *delegate_mock,
321 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
322 .WillOnce(Return(1));
323
324 TouchInjectorWin injector;
325 injector.SetInjectorDelegateForTest(delegate_mock.Pass());
326 EXPECT_TRUE(injector.Init());
327 injector.InjectTouchEvent(event);
328 event.set_event_type(TouchEvent::TOUCH_POINT_MOVE);
329 injector.InjectTouchEvent(event);
330 }
331
332 // Start a point and then move, make sure the flag is set to kEndFlag.
333 TEST(TouchInjectorWinTest, EndTouchPoint) {
334 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock(
335 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
336
337 TouchEvent event;
338 event.set_event_type(TouchEvent::TOUCH_POINT_START);
339 TouchEventPoint* point = event.add_touch_points();
340 point->set_id(0u);
341
342 InSequence s;
343 EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
344 .WillOnce(Return(1));
345
346 IdFlagMap id_to_flags;
347 id_to_flags[0u] = kStartFlag;
348 EXPECT_CALL(
349 *delegate_mock,
350 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
351 .WillOnce(Return(1));
352
353 id_to_flags[0u] = kEndFlag;
354 EXPECT_CALL(
355 *delegate_mock,
356 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
357 .WillOnce(Return(1));
358
359 TouchInjectorWin injector;
360 injector.SetInjectorDelegateForTest(delegate_mock.Pass());
361 EXPECT_TRUE(injector.Init());
362 injector.InjectTouchEvent(event);
363 event.set_event_type(TouchEvent::TOUCH_POINT_END);
364 injector.InjectTouchEvent(event);
365 }
366
367 // Start a point and then move, make sure the flag is set to kCancelFlag.
368 TEST(TouchInjectorWinTest, CancelTouchPoint) {
369 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock(
370 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
371
372 TouchEvent event;
373 event.set_event_type(TouchEvent::TOUCH_POINT_START);
374 TouchEventPoint* point = event.add_touch_points();
375 point->set_id(0u);
376
377 InSequence s;
378 EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
379 .WillOnce(Return(1));
380
381 IdFlagMap id_to_flags;
382 id_to_flags[0u] = kStartFlag;
383 EXPECT_CALL(
384 *delegate_mock,
385 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
386 .WillOnce(Return(1));
387
388 id_to_flags[0u] = kCancelFlag;
389 EXPECT_CALL(
390 *delegate_mock,
391 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
392 .WillOnce(Return(1));
393
394 TouchInjectorWin injector;
395 injector.SetInjectorDelegateForTest(delegate_mock.Pass());
396 EXPECT_TRUE(injector.Init());
397 injector.InjectTouchEvent(event);
398 event.set_event_type(TouchEvent::TOUCH_POINT_CANCEL);
399 injector.InjectTouchEvent(event);
400 }
401
402 // Note that points that haven't changed should be injected as MOVE.
403 // This tests:
404 // 1. Start first touch point.
405 // 2. Start second touch point.
406 // 3. Move both touch points.
407 // 4. Start third touch point.
408 // 5. End second touch point.
409 // 6. Cancel remaining (first and third) touch points.
410 TEST(TouchInjectorWinTest, MultiTouch) {
411 scoped_ptr<TouchInjectorWinDelegateMock> delegate_mock(
412 new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
413
414 InSequence s;
415 EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
416 .WillOnce(Return(1));
417
418 IdFlagMap id_to_flags;
419 id_to_flags[0u] = kStartFlag;
420 EXPECT_CALL(
421 *delegate_mock,
422 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
423 .WillOnce(Return(1));
424
425 id_to_flags[0u] = kMoveFlag;
426 id_to_flags[1u] = kStartFlag;
427 EXPECT_CALL(
428 *delegate_mock,
429 InjectTouchInput(2, EqualsPointerTouchInfoFlag(id_to_flags)))
430 .WillOnce(Return(1));
431
432 id_to_flags[0u] = kMoveFlag;
433 id_to_flags[1u] = kMoveFlag;
434 EXPECT_CALL(
435 *delegate_mock,
436 InjectTouchInput(2, EqualsPointerTouchInfoFlag(id_to_flags)))
437 .WillOnce(Return(1));
438
439 id_to_flags[0u] = kMoveFlag;
440 id_to_flags[1u] = kMoveFlag;
441 id_to_flags[2u] = kStartFlag;
442 EXPECT_CALL(
443 *delegate_mock,
444 InjectTouchInput(3, EqualsPointerTouchInfoFlag(id_to_flags)))
445 .WillOnce(Return(1));
446
447 id_to_flags[0u] = kMoveFlag;
448 id_to_flags[1u] = kEndFlag;
449 id_to_flags[2u] = kMoveFlag;
450 EXPECT_CALL(
451 *delegate_mock,
452 InjectTouchInput(3, EqualsPointerTouchInfoFlag(id_to_flags)))
453 .WillOnce(Return(1));
454
455 id_to_flags.erase(1u);
456 id_to_flags[0u] = kCancelFlag;
457 id_to_flags[2u] = kCancelFlag;
458 EXPECT_CALL(
459 *delegate_mock,
460 InjectTouchInput(2, EqualsPointerTouchInfoFlag(id_to_flags)))
461 .WillOnce(Return(1));
462
463 TouchInjectorWin injector;
464 injector.SetInjectorDelegateForTest(delegate_mock.Pass());
465 EXPECT_TRUE(injector.Init());
466
467 // Start first touch point.
468 TouchEvent first_touch_start;
469 first_touch_start.set_event_type(TouchEvent::TOUCH_POINT_START);
470 TouchEventPoint* point0 = first_touch_start.add_touch_points();
471 point0->set_id(0u);
472 injector.InjectTouchEvent(first_touch_start);
473
474 // Add second touch point.
475 TouchEvent second_touch_start;
476 second_touch_start.set_event_type(TouchEvent::TOUCH_POINT_START);
477 TouchEventPoint* point1 = second_touch_start.add_touch_points();
478 point1->set_id(1u);
479 injector.InjectTouchEvent(second_touch_start);
480
481 // Move both touch points.
482 TouchEvent move_both;
483 move_both.set_event_type(TouchEvent::TOUCH_POINT_MOVE);
484 point0 = second_touch_start.add_touch_points();
485 point1 = second_touch_start.add_touch_points();
486 point0->set_id(0u);
487 point1->set_id(1u);
488 injector.InjectTouchEvent(move_both);
489
490 // Add another.
491 TouchEvent third_touch_start;
492 third_touch_start.set_event_type(TouchEvent::TOUCH_POINT_START);
493 TouchEventPoint* point2 = third_touch_start.add_touch_points();
494 point2->set_id(2u);
495 injector.InjectTouchEvent(third_touch_start);
496
497 // Release second touch point.
498 TouchEvent release_second;
499 release_second.set_event_type(TouchEvent::TOUCH_POINT_END);
500 point1 = release_second.add_touch_points();
501 point1->set_id(1u);
502 injector.InjectTouchEvent(release_second);
503
504 // Cancel the remaining two points.
505 TouchEvent cancel_rest;
506 cancel_rest.set_event_type(TouchEvent::TOUCH_POINT_CANCEL);
507 point0 = cancel_rest.add_touch_points();
508 point0->set_id(0u);
509 point2 = cancel_rest.add_touch_points();
510 point2->set_id(2u);
511 injector.InjectTouchEvent(cancel_rest);
512 }
513
514 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/touch_injector_win.cc ('k') | remoting/host/win/session_input_injector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698