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

Side by Side Diff: ash/touch/touch_transformer_controller_unittest.cc

Issue 2617043003: Move TouchTransformerController to ui/display/. (Closed)
Patch Set: Add comments. Created 3 years, 11 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 2014 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 "ash/touch/touch_transformer_controller.h"
6
7 #include "ash/shell.h"
8 #include "ash/test/ash_test_base.h"
9 #include "base/rand_util.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "ui/aura/window_tree_host.h"
12 #include "ui/events/devices/device_data_manager.h"
13
14 namespace ash {
15
16 namespace {
17
18 constexpr int kDisplayId1 = 1;
19 constexpr int kTouchId1 = 5;
20
21 display::ManagedDisplayInfo CreateDisplayInfo(int64_t id,
22 unsigned int touch_device_id,
23 const gfx::Rect& bounds) {
24 display::ManagedDisplayInfo info(id, std::string(), false);
25 info.SetBounds(bounds);
26 info.AddInputDevice(touch_device_id);
27
28 // Create a default mode.
29 display::ManagedDisplayInfo::ManagedDisplayModeList default_modes(
30 1, make_scoped_refptr(
31 new display::ManagedDisplayMode(bounds.size(), 60, false, true)));
32 info.SetManagedDisplayModes(default_modes);
33
34 return info;
35 }
36
37 ui::TouchscreenDevice CreateTouchscreenDevice(unsigned int id,
38 const gfx::Size& size) {
39 return ui::TouchscreenDevice(id, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL,
40 std::string(), size, 0);
41 }
42
43 std::string GetTouchPointString(
44 const display::TouchCalibrationData::CalibrationPointPairQuad& pts) {
45 std::string str = "Failed for point pairs: ";
46 for (std::size_t row = 0; row < pts.size(); row++) {
47 str += "{(" + base::IntToString(pts[row].first.x()) + "," +
48 base::IntToString(pts[row].first.y()) + "), (" +
49 base::IntToString(pts[row].second.x()) + "," +
50 base::IntToString(pts[row].second.y()) + ")} ";
51 }
52 return str;
53 }
54
55 // Checks if the touch input has been calibrated properly. The input is said to
56 // be calibrated if any touch input is transformed to the correct corresponding
57 // display point within an error delta of |max_error_delta.width()| along the X
58 // axis and |max_error_delta.height()| along the Y axis;
59 void CheckPointsOfInterests(const int touch_id,
60 const gfx::Size& touch_size,
61 const gfx::Size& display_size,
62 const gfx::Size& max_error_delta,
63 const std::string& error_msg) {
64 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
65 float x, y;
66
67 // Origin of the touch device should correspond to origin of the display.
68 x = y = 0.0;
69 device_manager->ApplyTouchTransformer(touch_id, &x, &y);
70 EXPECT_NEAR(0, x, max_error_delta.width()) << error_msg;
71 EXPECT_NEAR(0, y, max_error_delta.height()) << error_msg;
72
73 // Center of the touch device should correspond to the center of the display
74 // device.
75 x = touch_size.width() / 2;
76 y = touch_size.height() / 2;
77 device_manager->ApplyTouchTransformer(touch_id, &x, &y);
78 EXPECT_NEAR(display_size.width() / 2, x, max_error_delta.width())
79 << error_msg;
80 EXPECT_NEAR(display_size.height() / 2, y, max_error_delta.height())
81 << error_msg;
82
83 // Bottom right corner of the touch device should correspond to rightmost
84 // corner of display device.
85 x = touch_size.width();
86 y = touch_size.height();
87 device_manager->ApplyTouchTransformer(touch_id, &x, &y);
88 EXPECT_NEAR(display_size.width(), x, max_error_delta.width()) << error_msg;
89 EXPECT_NEAR(display_size.height(), y, max_error_delta.height()) << error_msg;
90 }
91
92 } // namespace
93
94 class TouchTransformerControllerTest : public test::AshTestBase {
95 public:
96 TouchTransformerControllerTest() {}
97 ~TouchTransformerControllerTest() override {}
98
99 gfx::Transform GetTouchTransform(
100 const display::ManagedDisplayInfo& display,
101 const display::ManagedDisplayInfo& touch_display,
102 const ui::TouchscreenDevice& touchscreen,
103 const gfx::Size& framebuffer_size) const {
104 return Shell::GetInstance()
105 ->touch_transformer_controller()
106 ->GetTouchTransform(display, touch_display, touchscreen,
107 framebuffer_size);
108 }
109
110 double GetTouchResolutionScale(
111 const display::ManagedDisplayInfo& touch_display,
112 const ui::TouchscreenDevice& touch_device) const {
113 return Shell::GetInstance()
114 ->touch_transformer_controller()
115 ->GetTouchResolutionScale(touch_display, touch_device);
116 }
117
118 private:
119 DISALLOW_COPY_AND_ASSIGN(TouchTransformerControllerTest);
120 };
121
122 TEST_F(TouchTransformerControllerTest, MirrorModeLetterboxing) {
123 // The internal display has native resolution of 2560x1700, and in
124 // mirror mode it is configured as 1920x1200. This is in letterboxing
125 // mode.
126 display::ManagedDisplayInfo internal_display_info =
127 CreateDisplayInfo(1, 10u, gfx::Rect(0, 0, 1920, 1200));
128 internal_display_info.set_is_aspect_preserving_scaling(true);
129
130 display::ManagedDisplayInfo::ManagedDisplayModeList internal_modes;
131
132 internal_modes.push_back(make_scoped_refptr(
133 new display::ManagedDisplayMode(gfx::Size(2560, 1700), 60, false, true)));
134 internal_modes.push_back(make_scoped_refptr(new display::ManagedDisplayMode(
135 gfx::Size(1920, 1200), 60, false, false)));
136 internal_display_info.SetManagedDisplayModes(internal_modes);
137
138 display::ManagedDisplayInfo external_display_info =
139 CreateDisplayInfo(2, 11u, gfx::Rect(0, 0, 1920, 1200));
140
141 gfx::Size fb_size(1920, 1200);
142
143 // Create the touchscreens with the same size as the framebuffer so we can
144 // share the tests between Ozone & X11.
145 ui::TouchscreenDevice internal_touchscreen =
146 CreateTouchscreenDevice(10, fb_size);
147 ui::TouchscreenDevice external_touchscreen =
148 CreateTouchscreenDevice(11, fb_size);
149
150 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
151
152 device_manager->UpdateTouchInfoForDisplay(
153 internal_display_info.id(), internal_touchscreen.id,
154 GetTouchTransform(internal_display_info, internal_display_info,
155 internal_touchscreen, fb_size));
156
157 device_manager->UpdateTouchInfoForDisplay(
158 internal_display_info.id(), external_touchscreen.id,
159 GetTouchTransform(external_display_info, external_display_info,
160 external_touchscreen, fb_size));
161
162 EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(10));
163 EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(11));
164
165 // External touch display has the default TouchTransformer.
166 float x = 100.0;
167 float y = 100.0;
168 device_manager->ApplyTouchTransformer(11, &x, &y);
169 EXPECT_EQ(100, x);
170 EXPECT_EQ(100, y);
171
172 // In letterboxing, there is (1-2560*(1200/1920)/1700)/2 = 2.95% of the
173 // height on both the top & bottom region of the screen is blank.
174 // When touch events coming at Y range [0, 1200), the mapping should be
175 // [0, ~35] ---> < 0
176 // [~35, ~1165] ---> [0, 1200)
177 // [~1165, 1200] ---> >= 1200
178 x = 100.0;
179 y = 35.0;
180 device_manager->ApplyTouchTransformer(10, &x, &y);
181 EXPECT_NEAR(100, x, 0.5);
182 EXPECT_NEAR(0, y, 0.5);
183
184 x = 100.0;
185 y = 1165.0;
186 device_manager->ApplyTouchTransformer(10, &x, &y);
187 EXPECT_NEAR(100, x, 0.5);
188 EXPECT_NEAR(1200, y, 0.5);
189 }
190
191 TEST_F(TouchTransformerControllerTest, MirrorModePillarboxing) {
192 // The internal display has native resolution of 1366x768, and in
193 // mirror mode it is configured as 1024x768. This is in pillarboxing
194 // mode.
195 display::ManagedDisplayInfo internal_display_info =
196 CreateDisplayInfo(1, 10, gfx::Rect(0, 0, 1024, 768));
197 internal_display_info.set_is_aspect_preserving_scaling(true);
198 display::ManagedDisplayInfo::ManagedDisplayModeList internal_modes;
199 internal_modes.push_back(make_scoped_refptr(
200 new display::ManagedDisplayMode(gfx::Size(1366, 768), 60, false, true)));
201 internal_modes.push_back(make_scoped_refptr(
202 new display::ManagedDisplayMode(gfx::Size(1024, 768), 60, false, false)));
203 internal_display_info.SetManagedDisplayModes(internal_modes);
204
205 display::ManagedDisplayInfo external_display_info =
206 CreateDisplayInfo(2, 11, gfx::Rect(0, 0, 1024, 768));
207
208 gfx::Size fb_size(1024, 768);
209
210 // Create the touchscreens with the same size as the framebuffer so we can
211 // share the tests between Ozone & X11.
212 ui::TouchscreenDevice internal_touchscreen =
213 CreateTouchscreenDevice(10, fb_size);
214 ui::TouchscreenDevice external_touchscreen =
215 CreateTouchscreenDevice(11, fb_size);
216
217 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
218
219 device_manager->UpdateTouchInfoForDisplay(
220 internal_display_info.id(), internal_touchscreen.id,
221 GetTouchTransform(internal_display_info, internal_display_info,
222 internal_touchscreen, fb_size));
223
224 device_manager->UpdateTouchInfoForDisplay(
225 internal_display_info.id(), external_touchscreen.id,
226 GetTouchTransform(external_display_info, external_display_info,
227 external_touchscreen, fb_size));
228
229 EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(10));
230 EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(11));
231
232 // External touch display has the default TouchTransformer.
233 float x = 100.0;
234 float y = 100.0;
235 device_manager->ApplyTouchTransformer(11, &x, &y);
236 EXPECT_EQ(100, x);
237 EXPECT_EQ(100, y);
238
239 // In pillarboxing, there is (1-768*(1024/768)/1366)/2 = 12.5% of the
240 // width on both the left & rigth region of the screen is blank.
241 // When touch events coming at X range [0, 1024), the mapping should be
242 // [0, ~128] ---> < 0
243 // [~128, ~896] ---> [0, 1024)
244 // [~896, 1024] ---> >= 1024
245 x = 128.0;
246 y = 100.0;
247 device_manager->ApplyTouchTransformer(10, &x, &y);
248 EXPECT_NEAR(0, x, 0.5);
249 EXPECT_NEAR(100, y, 0.5);
250
251 x = 896.0;
252 y = 100.0;
253 device_manager->ApplyTouchTransformer(10, &x, &y);
254 EXPECT_NEAR(1024, x, 0.5);
255 EXPECT_NEAR(100, y, 0.5);
256 }
257
258 TEST_F(TouchTransformerControllerTest, SoftwareMirrorMode) {
259 // External display 1 has size 1280x850. External display 2 has size
260 // 1920x1080. When using software mirroring to mirror display 1 onto
261 // display 2, the displays are in extended mode and we map touches from both
262 // displays to display 1.
263 // The total frame buffer is 1920x1990,
264 // where 1990 = 850 + 60 (hidden gap) + 1080 and the second monitor is
265 // translated to point (0, 950) in the framebuffer.
266 display::ManagedDisplayInfo display1_info =
267 CreateDisplayInfo(1, 10u, gfx::Rect(0, 0, 1280, 850));
268 display::ManagedDisplayInfo::ManagedDisplayModeList display1_modes;
269 display1_modes.push_back(make_scoped_refptr(
270 new display::ManagedDisplayMode(gfx::Size(1280, 850), 60, false, true)));
271 display1_info.SetManagedDisplayModes(display1_modes);
272
273 display::ManagedDisplayInfo display2_info =
274 CreateDisplayInfo(2, 11u, gfx::Rect(0, 950, 1920, 1080));
275 display::ManagedDisplayInfo::ManagedDisplayModeList display2_modes;
276 display2_modes.push_back(make_scoped_refptr(
277 new display::ManagedDisplayMode(gfx::Size(1920, 1080), 60, false, true)));
278 display2_info.SetManagedDisplayModes(display2_modes);
279
280 gfx::Size fb_size(1920, 1990);
281
282 // Create the touchscreens with the same size as the framebuffer so we can
283 // share the tests between Ozone & X11.
284 ui::TouchscreenDevice display1_touchscreen =
285 CreateTouchscreenDevice(10, fb_size);
286 ui::TouchscreenDevice display2_touchscreen =
287 CreateTouchscreenDevice(11, fb_size);
288
289 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
290
291 device_manager->UpdateTouchInfoForDisplay(
292 display1_info.id(), display1_touchscreen.id,
293 GetTouchTransform(display1_info, display1_info, display1_touchscreen,
294 fb_size));
295
296 device_manager->UpdateTouchInfoForDisplay(
297 display1_info.id(), display2_touchscreen.id,
298 GetTouchTransform(display1_info, display2_info, display2_touchscreen,
299 fb_size));
300
301 EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(10));
302 EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(11));
303
304 // Mapping for touch events from display 1's touchscreen:
305 // [0, 1920) x [0, 1990) -> [0, 1280) x [0, 850)
306 float x = 0.0;
307 float y = 0.0;
308 device_manager->ApplyTouchTransformer(10, &x, &y);
309 EXPECT_NEAR(0, x, 0.5);
310 EXPECT_NEAR(0, y, 0.5);
311
312 x = 1920.0;
313 y = 1990.0;
314 device_manager->ApplyTouchTransformer(10, &x, &y);
315 EXPECT_NEAR(1280, x, 0.5);
316 EXPECT_NEAR(850, y, 0.5);
317
318 // In pillarboxing, there is (1-1280*(1080/850)/1920)/2 = 7.65% of the
319 // width on both the left & right region of the screen is blank.
320 // Events come in the range [0, 1920) x [0, 1990).
321 //
322 // X mapping:
323 // [0, ~147] ---> < 0
324 // [~147, ~1773] ---> [0, 1280)
325 // [~1773, 1920] ---> >= 1280
326 // Y mapping:
327 // [0, 1990) -> [0, 1080)
328 x = 147.0;
329 y = 0.0;
330 device_manager->ApplyTouchTransformer(11, &x, &y);
331 EXPECT_NEAR(0, x, 0.5);
332 EXPECT_NEAR(0, y, 0.5);
333
334 x = 1773.0;
335 y = 1990.0;
336 device_manager->ApplyTouchTransformer(11, &x, &y);
337 EXPECT_NEAR(1280, x, 0.5);
338 EXPECT_NEAR(850, y, 0.5);
339 }
340
341 TEST_F(TouchTransformerControllerTest, ExtendedMode) {
342 // The internal display has size 1366 x 768. The external display has
343 // size 2560x1600. The total frame buffer is 2560x2428,
344 // where 2428 = 768 + 60 (hidden gap) + 1600
345 // and the second monitor is translated to Point (0, 828) in the
346 // framebuffer.
347 display::ManagedDisplayInfo display1 =
348 CreateDisplayInfo(1, 5u, gfx::Rect(0, 0, 1366, 768));
349 display::ManagedDisplayInfo display2 =
350 CreateDisplayInfo(2, 6u, gfx::Rect(0, 828, 2560, 1600));
351 gfx::Size fb_size(2560, 2428);
352
353 // Create the touchscreens with the same size as the framebuffer so we can
354 // share the tests between Ozone & X11.
355 ui::TouchscreenDevice touchscreen1 = CreateTouchscreenDevice(5, fb_size);
356 ui::TouchscreenDevice touchscreen2 = CreateTouchscreenDevice(6, fb_size);
357
358 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
359
360 device_manager->UpdateTouchInfoForDisplay(
361 display1.id(), touchscreen1.id,
362 GetTouchTransform(display1, display1, touchscreen1, fb_size));
363
364 device_manager->UpdateTouchInfoForDisplay(
365 display2.id(), touchscreen2.id,
366 GetTouchTransform(display2, display2, touchscreen2, fb_size));
367
368 EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(5));
369 EXPECT_EQ(2, device_manager->GetTargetDisplayForTouchDevice(6));
370
371 // Mapping for touch events from internal touch display:
372 // [0, 2560) x [0, 2428) -> [0, 1366) x [0, 768)
373 float x = 0.0;
374 float y = 0.0;
375 device_manager->ApplyTouchTransformer(5, &x, &y);
376 EXPECT_NEAR(0, x, 0.5);
377 EXPECT_NEAR(0, y, 0.5);
378
379 x = 2559.0;
380 y = 2427.0;
381 device_manager->ApplyTouchTransformer(5, &x, &y);
382 EXPECT_NEAR(1365, x, 0.5);
383 EXPECT_NEAR(768, y, 0.5);
384
385 // Mapping for touch events from external touch display:
386 // [0, 2560) x [0, 2428) -> [0, 2560) x [0, 1600)
387 x = 0.0;
388 y = 0.0;
389 device_manager->ApplyTouchTransformer(6, &x, &y);
390 #if defined(USE_OZONE)
391 // On ozone we expect screen coordinates so add display origin.
392 EXPECT_NEAR(0 + 0, x, 0.5);
393 EXPECT_NEAR(0 + 828, y, 0.5);
394 #else
395 EXPECT_NEAR(0, x, 0.5);
396 EXPECT_NEAR(0, y, 0.5);
397 #endif
398
399 x = 2559.0;
400 y = 2427.0;
401 device_manager->ApplyTouchTransformer(6, &x, &y);
402 #if defined(USE_OZONE)
403 // On ozone we expect screen coordinates so add display origin.
404 EXPECT_NEAR(2559 + 0, x, 0.5);
405 EXPECT_NEAR(1599 + 828, y, 0.5);
406 #else
407 EXPECT_NEAR(2559, x, 0.5);
408 EXPECT_NEAR(1599, y, 0.5);
409 #endif
410 }
411
412 TEST_F(TouchTransformerControllerTest, TouchRadiusScale) {
413 display::ManagedDisplayInfo display =
414 CreateDisplayInfo(1, 5u, gfx::Rect(0, 0, 2560, 1600));
415 ui::TouchscreenDevice touch_device =
416 CreateTouchscreenDevice(5, gfx::Size(1001, 1001));
417
418 // Default touchscreen position range is 1001x1001;
419 EXPECT_EQ(sqrt((2560.0 * 1600.0) / (1001.0 * 1001.0)),
420 GetTouchResolutionScale(display, touch_device));
421 }
422
423 TEST_F(TouchTransformerControllerTest, OzoneTranslation) {
424 #if defined(USE_OZONE)
425 // The internal display has size 1920 x 1200. The external display has
426 // size 1920x1200. The total frame buffer is 1920x2450,
427 // where 2458 = 1200 + 50 (hidden gap) + 1200
428 // and the second monitor is translated to Point (0, 1250) in the
429 // framebuffer.
430 const int kDisplayId2 = 2;
431 const int kTouchId2 = 6;
432 const gfx::Size kDisplaySize(1920, 1200);
433 const gfx::Size kTouchSize(1920, 1200);
434 const int kHiddenGap = 50;
435
436 display::ManagedDisplayInfo display1 = CreateDisplayInfo(
437 kDisplayId1, kTouchId1,
438 gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
439 display::ManagedDisplayInfo display2 =
440 CreateDisplayInfo(kDisplayId2, kTouchId2,
441 gfx::Rect(0, kDisplaySize.height() + kHiddenGap,
442 kDisplaySize.width(), kDisplaySize.height()));
443
444 gfx::Size fb_size(1920, 2450);
445
446 ui::TouchscreenDevice touchscreen1 =
447 CreateTouchscreenDevice(kTouchId1, kDisplaySize);
448 ui::TouchscreenDevice touchscreen2 =
449 CreateTouchscreenDevice(kTouchId2, kDisplaySize);
450
451 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
452
453 // Mirror displays. Touch screen 2 is associated to display 1.
454 device_manager->UpdateTouchInfoForDisplay(
455 display1.id(), touchscreen1.id,
456 GetTouchTransform(display1, display1, touchscreen1, kTouchSize));
457
458 device_manager->UpdateTouchInfoForDisplay(
459 display1.id(), touchscreen2.id,
460 GetTouchTransform(display1, display2, touchscreen2, kTouchSize));
461
462 EXPECT_EQ(kDisplayId1,
463 device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
464 EXPECT_EQ(kDisplayId1,
465 device_manager->GetTargetDisplayForTouchDevice(kTouchId2));
466
467 float x, y;
468
469 x = y = 0.0;
470 device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
471 EXPECT_NEAR(0, x, 0.5);
472 EXPECT_NEAR(0, y, 0.5);
473
474 x = y = 0.0;
475 device_manager->ApplyTouchTransformer(kTouchId2, &x, &y);
476 EXPECT_NEAR(0, x, 0.5);
477 EXPECT_NEAR(0, y, 0.5);
478
479 x = 1920.0;
480 y = 1200.0;
481 device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
482 EXPECT_NEAR(1920, x, 0.5);
483 EXPECT_NEAR(1200, y, 0.5);
484
485 x = 1920.0;
486 y = 1200.0;
487 device_manager->ApplyTouchTransformer(kTouchId2, &x, &y);
488 EXPECT_NEAR(1920, x, 0.5);
489 EXPECT_NEAR(1200, y, 0.5);
490
491 // Remove mirroring of displays.
492 device_manager->UpdateTouchInfoForDisplay(
493 display2.id(), touchscreen2.id,
494 GetTouchTransform(display2, display2, touchscreen2, kTouchSize));
495
496 x = 1920.0;
497 y = 1200.0;
498 device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
499 EXPECT_NEAR(1920, x, 0.5);
500 EXPECT_NEAR(1200, y, 0.5);
501
502 x = 1920.0;
503 y = 1200.0;
504 device_manager->ApplyTouchTransformer(kTouchId2, &x, &y);
505 EXPECT_NEAR(1920, x, 0.5);
506 EXPECT_NEAR(1200 + kDisplaySize.height() + kHiddenGap, y, 0.5);
507 #endif // USE_OZONE
508 }
509
510 TEST_F(TouchTransformerControllerTest, AccurateUserTouchCalibration) {
511 const gfx::Size kDisplaySize(1920, 1200);
512 const gfx::Size kTouchSize(1920, 1200);
513
514 display::ManagedDisplayInfo display = CreateDisplayInfo(
515 kDisplayId1, kTouchId1,
516 gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
517
518 // Assuming the user provided accurate inputs during calibration. ie the user
519 // actually tapped (100,100) when asked to tap (100,100) with no human error.
520 display::TouchCalibrationData::CalibrationPointPairQuad user_input = {{
521 std::make_pair(gfx::Point(100, 100), gfx::Point(100, 100)),
522 std::make_pair(gfx::Point(1820, 100), gfx::Point(1820, 100)),
523 std::make_pair(gfx::Point(100, 1100), gfx::Point(100, 1100)),
524 std::make_pair(gfx::Point(1820, 1100), gfx::Point(1820, 1100)),
525 }};
526 display::TouchCalibrationData touch_data(user_input, kDisplaySize);
527 display.SetTouchCalibrationData(touch_data);
528 EXPECT_TRUE(display.has_touch_calibration_data());
529
530 const std::string msg = GetTouchPointString(user_input);
531
532 gfx::Size fb_size(1920, 1200);
533
534 ui::TouchscreenDevice touchscreen =
535 CreateTouchscreenDevice(kTouchId1, kTouchSize);
536
537 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
538
539 device_manager->UpdateTouchInfoForDisplay(
540 display.id(), touchscreen.id,
541 GetTouchTransform(display, display, touchscreen, kTouchSize));
542
543 EXPECT_EQ(kDisplayId1,
544 device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
545
546 CheckPointsOfInterests(kTouchId1, kTouchSize, kDisplaySize, gfx::Size(1, 1),
547 msg);
548 }
549
550 TEST_F(TouchTransformerControllerTest, ErrorProneUserTouchCalibration) {
551 const gfx::Size kDisplaySize(1920, 1200);
552 const gfx::Size kTouchSize(1920, 1200);
553 // User touch inputs have a max error of 5%.
554 const float kError = 0.05;
555 // The maximum user error rate is |kError|%. Since the calibration is
556 // performed with a best fit algorithm, the error rate observed should be less
557 // than |kError|.
558 const gfx::Size kMaxErrorDelta = gfx::ScaleToCeiledSize(kTouchSize, kError);
559
560 display::ManagedDisplayInfo display = CreateDisplayInfo(
561 kDisplayId1, kTouchId1,
562 gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
563
564 // Assuming the user provided inaccurate inputs during calibration. ie the
565 // user did not tap (100,100) when asked to tap (100,100) due to human error.
566 display::TouchCalibrationData::CalibrationPointPairQuad user_input = {
567 {std::make_pair(gfx::Point(100, 100), gfx::Point(130, 60)),
568 std::make_pair(gfx::Point(1820, 100), gfx::Point(1878, 130)),
569 std::make_pair(gfx::Point(100, 1100), gfx::Point(158, 1060)),
570 std::make_pair(gfx::Point(1820, 1100), gfx::Point(1790, 1140))}};
571 display::TouchCalibrationData touch_data(user_input, kDisplaySize);
572 display.SetTouchCalibrationData(touch_data);
573 EXPECT_TRUE(display.has_touch_calibration_data());
574
575 const std::string msg = GetTouchPointString(user_input);
576
577 ui::TouchscreenDevice touchscreen =
578 CreateTouchscreenDevice(kTouchId1, kTouchSize);
579
580 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
581
582 device_manager->UpdateTouchInfoForDisplay(
583 display.id(), touchscreen.id,
584 GetTouchTransform(display, display, touchscreen, kTouchSize));
585
586 EXPECT_EQ(kDisplayId1,
587 device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
588
589 CheckPointsOfInterests(kTouchId1, kTouchSize, kDisplaySize, kMaxErrorDelta,
590 msg);
591 }
592
593 TEST_F(TouchTransformerControllerTest, ResolutionChangeUserTouchCalibration) {
594 const gfx::Size kDisplaySize(2560, 1600);
595 const gfx::Size kTouchSize(1920, 1200);
596 // User touch inputs have a max error of 5%.
597 const float kError = 0.05;
598 // The maximum user error rate is |kError|%. Since the calibration is
599 // performed with a best fit algorithm, the error rate observed should be less
600 // tha |kError|.
601 gfx::Size kMaxErrorDelta = gfx::ScaleToCeiledSize(kDisplaySize, kError);
602
603 display::ManagedDisplayInfo display = CreateDisplayInfo(
604 kDisplayId1, kTouchId1,
605 gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
606
607 // The calibration was performed at a resolution different from the curent
608 // resolution of the display.
609 const gfx::Size CALIBRATION_SIZE(1920, 1200);
610 display::TouchCalibrationData::CalibrationPointPairQuad user_input = {
611 {std::make_pair(gfx::Point(100, 100), gfx::Point(50, 70)),
612 std::make_pair(gfx::Point(1820, 100), gfx::Point(1780, 70)),
613 std::make_pair(gfx::Point(100, 1100), gfx::Point(70, 1060)),
614 std::make_pair(gfx::Point(1820, 1100), gfx::Point(1770, 1140))}};
615
616 display::TouchCalibrationData touch_data(user_input, CALIBRATION_SIZE);
617 display.SetTouchCalibrationData(touch_data);
618 EXPECT_TRUE(display.has_touch_calibration_data());
619
620 const std::string msg = GetTouchPointString(user_input);
621
622 ui::TouchscreenDevice touchscreen =
623 CreateTouchscreenDevice(kTouchId1, kTouchSize);
624
625 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
626
627 device_manager->UpdateTouchInfoForDisplay(
628 display.id(), touchscreen.id,
629 GetTouchTransform(display, display, touchscreen, kTouchSize));
630
631 EXPECT_EQ(kDisplayId1,
632 device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
633
634 CheckPointsOfInterests(kTouchId1, kTouchSize, kDisplaySize, kMaxErrorDelta,
635 msg);
636 }
637
638 TEST_F(TouchTransformerControllerTest, DifferentBoundsUserTouchCalibration) {
639 // The display bounds is different from the touch device bounds in this test.
640 const gfx::Size kDisplaySize(1024, 600);
641 const gfx::Size kTouchSize(4096, 4096);
642 const float kAcceptableError = 0.04;
643 gfx::Size kMaxErrorDelta =
644 gfx::ScaleToCeiledSize(kDisplaySize, kAcceptableError);
645
646 display::ManagedDisplayInfo display = CreateDisplayInfo(
647 kDisplayId1, kTouchId1,
648 gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
649
650 // Real world data.
651 display::TouchCalibrationData::CalibrationPointPairQuad user_input = {
652 {std::make_pair(gfx::Point(136, 136), gfx::Point(538, 931)),
653 std::make_pair(gfx::Point(873, 136), gfx::Point(3475, 922)),
654 std::make_pair(gfx::Point(136, 411), gfx::Point(611, 2800)),
655 std::make_pair(gfx::Point(873, 411), gfx::Point(3535, 2949))}};
656 display::TouchCalibrationData touch_data(user_input, kDisplaySize);
657 display.SetTouchCalibrationData(touch_data);
658 EXPECT_TRUE(display.has_touch_calibration_data());
659
660 const std::string msg = GetTouchPointString(user_input);
661
662 ui::TouchscreenDevice touchscreen =
663 CreateTouchscreenDevice(kTouchId1, kTouchSize);
664
665 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
666
667 device_manager->UpdateTouchInfoForDisplay(
668 display.id(), touchscreen.id,
669 GetTouchTransform(display, display, touchscreen, kTouchSize));
670
671 EXPECT_EQ(kDisplayId1,
672 device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
673
674 CheckPointsOfInterests(kTouchId1, kTouchSize, kDisplaySize, kMaxErrorDelta,
675 msg);
676 }
677
678 TEST_F(TouchTransformerControllerTest, LetterboxingUserTouchCalibration) {
679 // The internal display has native resolution of 2560x1700, and in
680 // mirror mode it is configured as 1920x1200. This is in letterboxing
681 // mode.
682 const gfx::Size kNativeDisplaySize(2560, 1700);
683 const gfx::Size kDisplaySize(1920, 1200);
684 const gfx::Size kTouchSize(1920, 1200);
685
686 display::ManagedDisplayInfo internal_display_info = CreateDisplayInfo(
687 kDisplayId1, kTouchId1,
688 gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
689 internal_display_info.set_is_aspect_preserving_scaling(true);
690
691 display::ManagedDisplayInfo::ManagedDisplayModeList internal_modes;
692
693 internal_modes.push_back(make_scoped_refptr(new display::ManagedDisplayMode(
694 gfx::Size(kNativeDisplaySize.width(), kNativeDisplaySize.height()), 60,
695 false, true)));
696 internal_modes.push_back(make_scoped_refptr(new display::ManagedDisplayMode(
697 gfx::Size(kDisplaySize.width(), kDisplaySize.height()), 60, false,
698 false)));
699 internal_display_info.SetManagedDisplayModes(internal_modes);
700
701 gfx::Size fb_size(kDisplaySize);
702
703 // Create the touchscreens with the same size as the framebuffer so we can
704 // share the tests between Ozone & X11.
705 ui::TouchscreenDevice internal_touchscreen =
706 CreateTouchscreenDevice(kTouchId1, fb_size);
707
708 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
709
710 // Assuming the user provided inaccurate inputs during calibration. ie the
711 // user did not tap (100,100) when asked to tap (100,100) due to human error.
712 // Since the display is of size 2560x1700 and the touch device is of size
713 // 1920x1200, the corresponding points have to be scaled.
714 display::TouchCalibrationData::CalibrationPointPairQuad user_input = {{
715 std::make_pair(gfx::Point(100, 100), gfx::Point(75, 71)),
716 std::make_pair(gfx::Point(2460, 100), gfx::Point(1845, 71)),
717 std::make_pair(gfx::Point(100, 1600), gfx::Point(75, 1130)),
718 std::make_pair(gfx::Point(2460, 1600), gfx::Point(1845, 1130)),
719 }};
720 // The calibration was performed at the native display resolution.
721 display::TouchCalibrationData touch_data(user_input, kNativeDisplaySize);
722 internal_display_info.SetTouchCalibrationData(touch_data);
723 EXPECT_TRUE(internal_display_info.has_touch_calibration_data());
724
725 device_manager->UpdateTouchInfoForDisplay(
726 internal_display_info.id(), internal_touchscreen.id,
727 GetTouchTransform(internal_display_info, internal_display_info,
728 internal_touchscreen, fb_size));
729
730 EXPECT_EQ(kDisplayId1,
731 device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
732
733 float x, y;
734 // In letterboxing, there is (1-2560*(1200/1920)/1700)/2 = 2.95% of the
735 // height on both the top & bottom region of the screen is blank.
736 // When touch events coming at Y range [0, 1200), the mapping should be
737 // [0, ~35] ---> < 0
738 // [~35, ~1165] ---> [0, 1200)
739 // [~1165, 1200] ---> >= 1200
740 x = 100.0;
741 y = 35.0;
742 device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
743 EXPECT_NEAR(100, x, 0.5);
744 EXPECT_NEAR(0, y, 0.5);
745
746 x = 100.0;
747 y = 1165.0;
748 device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
749 EXPECT_NEAR(100, x, 0.5);
750 EXPECT_NEAR(1200, y, 0.5);
751 }
752
753 TEST_F(TouchTransformerControllerTest, PillarBoxingUserTouchCalibration) {
754 // The internal display has native resolution of 2560x1700, and in
755 // mirror mode it is configured as 1920x1200. This is in letterboxing
756 // mode.
757 const gfx::Size kNativeDisplaySize(2560, 1600);
758 const gfx::Size kDisplaySize(1920, 1400);
759 const gfx::Size kTouchSize(1920, 1400);
760
761 display::ManagedDisplayInfo internal_display_info = CreateDisplayInfo(
762 kDisplayId1, kTouchId1,
763 gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
764 internal_display_info.set_is_aspect_preserving_scaling(true);
765
766 display::ManagedDisplayInfo::ManagedDisplayModeList internal_modes;
767
768 internal_modes.push_back(make_scoped_refptr(new display::ManagedDisplayMode(
769 gfx::Size(kNativeDisplaySize.width(), kNativeDisplaySize.height()), 60,
770 false, true)));
771 internal_modes.push_back(make_scoped_refptr(new display::ManagedDisplayMode(
772 gfx::Size(kDisplaySize.width(), kDisplaySize.height()), 60, false,
773 false)));
774 internal_display_info.SetManagedDisplayModes(internal_modes);
775
776 gfx::Size fb_size(kDisplaySize);
777
778 // Create the touchscreens with the same size as the framebuffer so we can
779 // share the tests between Ozone & X11.
780 ui::TouchscreenDevice internal_touchscreen =
781 CreateTouchscreenDevice(kTouchId1, fb_size);
782
783 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
784
785 // Assuming the user provided accurate inputs during calibration. ie the user
786 // actually tapped (100,100) when asked to tap (100,100) with no human error.
787 // Since the display is of size 2560x1600 and the touch device is of size
788 // 1920x1400, the corresponding points have to be scaled.
789 display::TouchCalibrationData::CalibrationPointPairQuad user_input = {{
790 std::make_pair(gfx::Point(100, 100), gfx::Point(75, 88)),
791 std::make_pair(gfx::Point(2460, 100), gfx::Point(1845, 88)),
792 std::make_pair(gfx::Point(100, 1500), gfx::Point(75, 1313)),
793 std::make_pair(gfx::Point(2460, 1500), gfx::Point(1845, 1313)),
794 }};
795 // The calibration was performed at the native display resolution.
796 display::TouchCalibrationData touch_data(user_input, kNativeDisplaySize);
797 internal_display_info.SetTouchCalibrationData(touch_data);
798 EXPECT_TRUE(internal_display_info.has_touch_calibration_data());
799
800 device_manager->UpdateTouchInfoForDisplay(
801 internal_display_info.id(), internal_touchscreen.id,
802 GetTouchTransform(internal_display_info, internal_display_info,
803 internal_touchscreen, fb_size));
804
805 EXPECT_EQ(kDisplayId1,
806 device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
807
808 float x, y;
809 // In pillarboxing, there is (1-1600*(1920/1400)/2560)/2 = 7.14% of the
810 // width on both the left & region region of the screen is blank.
811 // When touch events coming at X range [0, 1920), the mapping should be
812 // [0, ~137] ---> < 0
813 // [~137, ~1782] ---> [0, 1920)
814 // [~1782, 1920] ---> >= 1920
815 x = 137.0;
816 y = 0.0;
817 device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
818 EXPECT_NEAR(0, x, 0.5);
819 EXPECT_NEAR(0, y, 0.5);
820
821 x = 1782.0;
822 y = 0.0;
823 device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
824 EXPECT_NEAR(1920, x, 0.5);
825 EXPECT_NEAR(0, y, 0.5);
826 }
827
828 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698