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

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: Add Deinitialize() and change test 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
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 TouchInjectFunctionsWinMock : public TouchInjectFunctionsWin {
72 public:
73 TouchInjectFunctionsWinMock() = default;
74 ~TouchInjectFunctionsWinMock() override {};
75
76 MOCK_METHOD0(Init, bool());
77 MOCK_METHOD0(Initialized, bool());
78 MOCK_METHOD2(InitializeTouchInjection, BOOL(UINT32 max_count, DWORD dw_mode));
79 MOCK_METHOD2(InjectTouchInput,
80 DWORD(UINT32 count, const POINTER_TOUCH_INFO* contacts));
81 };
82
83 } // namespace
84
85 // A test to make sure that the touch event is converted correctly to
86 // POINTER_TOUCH_INFO.
87 TEST(TouchInjectorWinTest, CheckConversionWithPressure) {
88 scoped_ptr<TouchInjectFunctionsWinMock> functions_mock(
89 new TouchInjectFunctionsWinMock());
90 ON_CALL(*functions_mock, Initialized()).WillByDefault(Return(true));
91
92 TouchEvent event;
93 event.set_event_type(TouchEvent::TOUCH_POINT_START);
94 TouchEventPoint* point = event.add_touch_points();
95 point->set_id(1234u);
96 point->set_x(321.0f);
97 point->set_y(123.0f);
98 point->set_radius_x(10.0f);
99 point->set_radius_y(20.0f);
100 point->set_pressure(0.5);
101 point->set_angle(45.0f);
102
103 POINTER_TOUCH_INFO expected_touch_info;
104 expected_touch_info.touchMask =
105 TOUCH_MASK_CONTACTAREA | TOUCH_MASK_ORIENTATION | TOUCH_MASK_PRESSURE;
106 expected_touch_info.rcContact.left = 311;
107 expected_touch_info.rcContact.top = 103;
108 expected_touch_info.rcContact.right = 331;
109 expected_touch_info.rcContact.bottom = 143;
110 expected_touch_info.orientation = 0;
111 expected_touch_info.pressure = 512;
112 expected_touch_info.orientation = 45;
113
114 expected_touch_info.pointerInfo.pointerType = PT_TOUCH;
115 expected_touch_info.pointerInfo.pointerId = 1234u;
116 expected_touch_info.pointerInfo.ptPixelLocation.x = 321;
117 expected_touch_info.pointerInfo.ptPixelLocation.y = 123;
118
119 InSequence s;
120 EXPECT_CALL(*functions_mock, Init()).WillOnce(Return(true));
121 EXPECT_CALL(*functions_mock, InitializeTouchInjection(_, _))
122 .WillOnce(Return(1));
123 EXPECT_CALL(
124 *functions_mock,
125 InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
126 .WillOnce(Return(1));
127
128 TouchInjectorWin injector;
129 injector.SetInjectFunctionsForTest(functions_mock.Pass());
130 EXPECT_TRUE(injector.Init());
131 injector.InjectTouchEvent(event);
132 }
133
134 // Some devices don't detect pressure. This test is a conversion check for
135 // such devices.
136 TEST(TouchInjectorWinTest, CheckConversionNoPressure) {
137 scoped_ptr<TouchInjectFunctionsWinMock> functions_mock(
138 new TouchInjectFunctionsWinMock());
139 ON_CALL(*functions_mock, Initialized()).WillByDefault(Return(true));
140
141 TouchEvent event;
142 event.set_event_type(TouchEvent::TOUCH_POINT_START);
143 TouchEventPoint* point = event.add_touch_points();
144 point->set_id(1234u);
145 point->set_x(321.0f);
146 point->set_y(123.0f);
147 point->set_radius_x(10.0f);
148 point->set_radius_y(20.0f);
149 point->set_angle(45.0f);
150
151 POINTER_TOUCH_INFO expected_touch_info;
152 expected_touch_info.touchMask =
153 TOUCH_MASK_CONTACTAREA | TOUCH_MASK_ORIENTATION;
154 expected_touch_info.rcContact.left = 311;
155 expected_touch_info.rcContact.top = 103;
156 expected_touch_info.rcContact.right = 331;
157 expected_touch_info.rcContact.bottom = 143;
158 expected_touch_info.orientation = 0;
159 expected_touch_info.pressure = 0;
160 expected_touch_info.orientation = 45;
161
162 expected_touch_info.pointerInfo.pointerType = PT_TOUCH;
163 expected_touch_info.pointerInfo.pointerId = 1234u;
164 expected_touch_info.pointerInfo.ptPixelLocation.x = 321;
165 expected_touch_info.pointerInfo.ptPixelLocation.y = 123;
166
167 InSequence s;
168 EXPECT_CALL(*functions_mock, Init()).WillOnce(Return(true));
169 EXPECT_CALL(*functions_mock, InitializeTouchInjection(_, _))
170 .WillOnce(Return(1));
171 EXPECT_CALL(
172 *functions_mock,
173 InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
174 .WillOnce(Return(1));
175
176 TouchInjectorWin injector;
177 injector.SetInjectFunctionsForTest(functions_mock.Pass());
178 EXPECT_TRUE(injector.Init());
179 injector.InjectTouchEvent(event);
180 }
181
182 // If initialization fails, it should not call any touch injection functions.
183 TEST(TouchInjectorWinTest, InitFailed) {
184 scoped_ptr<TouchInjectFunctionsWinMock> functions_mock(
185 new TouchInjectFunctionsWinMock());
186 ON_CALL(*functions_mock, Initialized()).WillByDefault(Return(false));
187
188 TouchEvent event;
189 event.set_event_type(TouchEvent::TOUCH_POINT_START);
190
191 InSequence s;
192 EXPECT_CALL(*functions_mock, Init()).WillOnce(Return(false));
193 EXPECT_CALL(*functions_mock, InitializeTouchInjection(_, _)).Times(0);
194 EXPECT_CALL(*functions_mock, InjectTouchInput(_, _)).Times(0);
195
196 TouchInjectorWin injector;
197 injector.SetInjectFunctionsForTest(functions_mock.Pass());
198 EXPECT_FALSE(injector.Init());
199 injector.InjectTouchEvent(event);
200 }
201
202 // Deinitialize and initialize should clean the state.
203 TEST(TouchInjectorWinTest, Reinitialize) {
204 scoped_ptr<TouchInjectFunctionsWinMock> functions_mock(
205 new TouchInjectFunctionsWinMock());
206 ON_CALL(*functions_mock, Initialized()).WillByDefault(Return(true));
207
208 TouchEvent first_event;
209 first_event.set_event_type(TouchEvent::TOUCH_POINT_START);
210 TouchEventPoint* point0 = first_event.add_touch_points();
211 point0->set_id(0u);
212
213 TouchEvent second_event;
214 second_event.set_event_type(TouchEvent::TOUCH_POINT_START);
215 TouchEventPoint* point1 = second_event.add_touch_points();
216 point1->set_id(1u);
217
218 EXPECT_CALL(*functions_mock, Init())
219 .Times(AtLeast(1))
220 .WillRepeatedly(Return(true));
221 EXPECT_CALL(*functions_mock, InitializeTouchInjection(_, _))
222 .Times(AtLeast(1))
223 .WillRepeatedly(Return(1));
224
225 InSequence s;
226 IdFlagMap id_to_flags;
227 id_to_flags[0u] = kStartFlag;
228 EXPECT_CALL(
229 *functions_mock,
230 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
231 .WillOnce(Return(1));
232
233 // After deinitializing and then initializing, previous touch points should be
234 // gone.
235 id_to_flags.clear();
236 id_to_flags[1u] = kStartFlag;
237 EXPECT_CALL(
238 *functions_mock,
239 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
240 .WillOnce(Return(1));
241
242 TouchInjectorWin injector;
243 injector.SetInjectFunctionsForTest(functions_mock.Pass());
244
245 EXPECT_TRUE(injector.Init());
246 injector.InjectTouchEvent(first_event);
247 injector.Deinitialize();
248
249 EXPECT_TRUE(injector.Init());
250 injector.InjectTouchEvent(second_event);
251 }
252
253 // Make sure that the flag is set to kStartFlag.
254 TEST(TouchInjectorWinTest, StartTouchPoint) {
255 scoped_ptr<TouchInjectFunctionsWinMock> functions_mock(
256 new TouchInjectFunctionsWinMock());
257 ON_CALL(*functions_mock, Initialized()).WillByDefault(Return(true));
258
259 TouchEvent event;
260 event.set_event_type(TouchEvent::TOUCH_POINT_START);
261 TouchEventPoint* point = event.add_touch_points();
262 point->set_id(0u);
263
264 InSequence s;
265 EXPECT_CALL(*functions_mock, Init())
266 .WillOnce(Return(true));
267 EXPECT_CALL(*functions_mock, InitializeTouchInjection(_, _))
268 .WillOnce(Return(1));
269
270 IdFlagMap id_to_flags;
271 id_to_flags[0u] = kStartFlag;
272 EXPECT_CALL(
273 *functions_mock,
274 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
275 .WillOnce(Return(1));
276
277 TouchInjectorWin injector;
278 injector.SetInjectFunctionsForTest(functions_mock.Pass());
279 EXPECT_TRUE(injector.Init());
280 injector.InjectTouchEvent(event);
281 }
282
283 // Start a point and then move, make sure the flag is set to kMoveFlag.
284 TEST(TouchInjectorWinTest, MoveTouchPoint) {
285 scoped_ptr<TouchInjectFunctionsWinMock> functions_mock(
286 new TouchInjectFunctionsWinMock());
287 ON_CALL(*functions_mock, Initialized()).WillByDefault(Return(true));
288
289 TouchEvent event;
290 event.set_event_type(TouchEvent::TOUCH_POINT_START);
291 TouchEventPoint* point = event.add_touch_points();
292 point->set_id(0u);
293
294
295 InSequence s;
296 EXPECT_CALL(*functions_mock, Init()).WillOnce(Return(true));
297 EXPECT_CALL(*functions_mock, InitializeTouchInjection(_, _))
298 .WillOnce(Return(1));
299
300 IdFlagMap id_to_flags;
301 id_to_flags[0u] = kStartFlag;
302 EXPECT_CALL(
303 *functions_mock,
304 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
305 .WillOnce(Return(1));
306
307 id_to_flags[0u] = kMoveFlag;
308 EXPECT_CALL(
309 *functions_mock,
310 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
311 .WillOnce(Return(1));
312
313 TouchInjectorWin injector;
314 injector.SetInjectFunctionsForTest(functions_mock.Pass());
315 EXPECT_TRUE(injector.Init());
316 injector.InjectTouchEvent(event);
317 event.set_event_type(TouchEvent::TOUCH_POINT_MOVE);
318 injector.InjectTouchEvent(event);
319 }
320
321 // Start a point and then move, make sure the flag is set to kEndFlag.
322 TEST(TouchInjectorWinTest, EndTouchPoint) {
323 scoped_ptr<TouchInjectFunctionsWinMock> functions_mock(
324 new TouchInjectFunctionsWinMock());
325 ON_CALL(*functions_mock, Initialized()).WillByDefault(Return(true));
326
327 TouchEvent event;
328 event.set_event_type(TouchEvent::TOUCH_POINT_START);
329 TouchEventPoint* point = event.add_touch_points();
330 point->set_id(0u);
331
332 InSequence s;
333 EXPECT_CALL(*functions_mock, Init()).WillOnce(Return(true));
334 EXPECT_CALL(*functions_mock, InitializeTouchInjection(_, _))
335 .WillOnce(Return(1));
336
337 IdFlagMap id_to_flags;
338 id_to_flags[0u] = kStartFlag;
339 EXPECT_CALL(
340 *functions_mock,
341 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
342 .WillOnce(Return(1));
343
344 id_to_flags[0u] = kEndFlag;
345 EXPECT_CALL(
346 *functions_mock,
347 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
348 .WillOnce(Return(1));
349
350 TouchInjectorWin injector;
351 injector.SetInjectFunctionsForTest(functions_mock.Pass());
352 EXPECT_TRUE(injector.Init());
353 injector.InjectTouchEvent(event);
354 event.set_event_type(TouchEvent::TOUCH_POINT_END);
355 injector.InjectTouchEvent(event);
356 }
357
358 // Start a point and then move, make sure the flag is set to kCancelFlag.
359 TEST(TouchInjectorWinTest, CancelTouchPoint) {
360 scoped_ptr<TouchInjectFunctionsWinMock> functions_mock(
361 new TouchInjectFunctionsWinMock());
362 ON_CALL(*functions_mock, Initialized()).WillByDefault(Return(true));
363
364 TouchEvent event;
365 event.set_event_type(TouchEvent::TOUCH_POINT_START);
366 TouchEventPoint* point = event.add_touch_points();
367 point->set_id(0u);
368
369 InSequence s;
370 EXPECT_CALL(*functions_mock, Init()).WillOnce(Return(true));
371 EXPECT_CALL(*functions_mock, InitializeTouchInjection(_, _))
372 .WillOnce(Return(1));
373
374 IdFlagMap id_to_flags;
375 id_to_flags[0u] = kStartFlag;
376 EXPECT_CALL(
377 *functions_mock,
378 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
379 .WillOnce(Return(1));
380
381 id_to_flags[0u] = kCancelFlag;
382 EXPECT_CALL(
383 *functions_mock,
384 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
385 .WillOnce(Return(1));
386
387 TouchInjectorWin injector;
388 injector.SetInjectFunctionsForTest(functions_mock.Pass());
389 EXPECT_TRUE(injector.Init());
390 injector.InjectTouchEvent(event);
391 event.set_event_type(TouchEvent::TOUCH_POINT_CANCEL);
392 injector.InjectTouchEvent(event);
393 }
394
395 // Note that points that haven't changed should be injected as MOVE.
396 // This tests:
397 // 1. Start first touch point.
398 // 2. Start second touch point.
399 // 3. Move both touch points.
400 // 4. Start third touch point.
401 // 5. End second touch point.
402 // 6. Cancel remaining (first and third) touch points.
403 TEST(TouchInjectorWinTest, MultiTouch) {
404 scoped_ptr<TouchInjectFunctionsWinMock> functions_mock(
405 new TouchInjectFunctionsWinMock());
406 ON_CALL(*functions_mock, Initialized()).WillByDefault(Return(true));
407
408 InSequence s;
409 EXPECT_CALL(*functions_mock, Init()).WillOnce(Return(true));
410 EXPECT_CALL(*functions_mock, InitializeTouchInjection(_, _))
411 .WillOnce(Return(1));
412
413 IdFlagMap id_to_flags;
414 id_to_flags[0u] = kStartFlag;
415 EXPECT_CALL(
416 *functions_mock,
417 InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
418 .WillOnce(Return(1));
419
420 id_to_flags[0u] = kMoveFlag;
421 id_to_flags[1u] = kStartFlag;
422 EXPECT_CALL(
423 *functions_mock,
424 InjectTouchInput(2, EqualsPointerTouchInfoFlag(id_to_flags)))
425 .WillOnce(Return(1));
426
427 id_to_flags[0u] = kMoveFlag;
428 id_to_flags[1u] = kMoveFlag;
429 EXPECT_CALL(
430 *functions_mock,
431 InjectTouchInput(2, EqualsPointerTouchInfoFlag(id_to_flags)))
432 .WillOnce(Return(1));
433
434 id_to_flags[0u] = kMoveFlag;
435 id_to_flags[1u] = kMoveFlag;
436 id_to_flags[2u] = kStartFlag;
437 EXPECT_CALL(
438 *functions_mock,
439 InjectTouchInput(3, EqualsPointerTouchInfoFlag(id_to_flags)))
440 .WillOnce(Return(1));
441
442 id_to_flags[0u] = kMoveFlag;
443 id_to_flags[1u] = kEndFlag;
444 id_to_flags[2u] = kMoveFlag;
445 EXPECT_CALL(
446 *functions_mock,
447 InjectTouchInput(3, EqualsPointerTouchInfoFlag(id_to_flags)))
448 .WillOnce(Return(1));
449
450 id_to_flags.erase(1u);
451 id_to_flags[0u] = kCancelFlag;
452 id_to_flags[2u] = kCancelFlag;
453 EXPECT_CALL(
454 *functions_mock,
455 InjectTouchInput(2, EqualsPointerTouchInfoFlag(id_to_flags)))
456 .WillOnce(Return(1));
457
458 TouchInjectorWin injector;
459 injector.SetInjectFunctionsForTest(functions_mock.Pass());
460 EXPECT_TRUE(injector.Init());
461
462 // Start first touch point.
463 TouchEvent first_touch_start;
464 first_touch_start.set_event_type(TouchEvent::TOUCH_POINT_START);
465 TouchEventPoint* point0 = first_touch_start.add_touch_points();
466 point0->set_id(0u);
467 injector.InjectTouchEvent(first_touch_start);
468
469 // Add second touch point.
470 TouchEvent second_touch_start;
471 second_touch_start.set_event_type(TouchEvent::TOUCH_POINT_START);
472 TouchEventPoint* point1 = second_touch_start.add_touch_points();
473 point1->set_id(1u);
474 injector.InjectTouchEvent(second_touch_start);
475
476 // Move both touch points.
477 TouchEvent move_both;
478 move_both.set_event_type(TouchEvent::TOUCH_POINT_MOVE);
479 point0 = second_touch_start.add_touch_points();
480 point1 = second_touch_start.add_touch_points();
481 point0->set_id(0u);
482 point1->set_id(1u);
483 injector.InjectTouchEvent(move_both);
484
485 // Add another.
486 TouchEvent third_touch_start;
487 third_touch_start.set_event_type(TouchEvent::TOUCH_POINT_START);
488 TouchEventPoint* point2 = third_touch_start.add_touch_points();
489 point2->set_id(2u);
490 injector.InjectTouchEvent(third_touch_start);
491
492 // Release second touch point.
493 TouchEvent release_second;
494 release_second.set_event_type(TouchEvent::TOUCH_POINT_END);
495 point1 = release_second.add_touch_points();
496 point1->set_id(1u);
497 injector.InjectTouchEvent(release_second);
498
499 // Cancel the remaining two points.
500 TouchEvent cancel_rest;
501 cancel_rest.set_event_type(TouchEvent::TOUCH_POINT_CANCEL);
502 point0 = cancel_rest.add_touch_points();
503 point0->set_id(0u);
504 point2 = cancel_rest.add_touch_points();
505 point2->set_id(2u);
506 injector.InjectTouchEvent(cancel_rest);
507 }
508
509 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698