Home | History | Annotate | Download | only in touch
      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 "ui/aura/window_tree_host.h"
     10 #include "ui/events/x/device_data_manager.h"
     11 #include "ui/gfx/display.h"
     12 
     13 namespace ash {
     14 
     15 namespace {
     16 DisplayInfo CreateDisplayInfo(int64 id,
     17                               int touch_device_id,
     18                               const gfx::Rect& bounds) {
     19   DisplayInfo info(id, std::string(), false);
     20   info.SetBounds(bounds);
     21   info.set_touch_device_id(touch_device_id);
     22   return info;
     23 }
     24 }  //  namespace
     25 
     26 typedef test::AshTestBase TouchTransformerControllerTest;
     27 
     28 TEST_F(TouchTransformerControllerTest, TouchTransformerMirrorModeLetterboxing) {
     29   // The internal display has native resolution of 2560x1700, and in
     30   // mirror mode it is configured as 1920x1200. This is in letterboxing
     31   // mode.
     32   DisplayInfo internal_display_info =
     33       CreateDisplayInfo(1, 10, gfx::Rect(0, 0, 1920, 1200));
     34   std::vector<DisplayMode> internal_modes;
     35   internal_modes.push_back(
     36       DisplayMode(gfx::Size(2560, 1700), 60, false, true));
     37   internal_modes.push_back(
     38       DisplayMode(gfx::Size(1920, 1200), 60, false, false));
     39   internal_display_info.set_display_modes(internal_modes);
     40 
     41   DisplayInfo external_display_info =
     42       CreateDisplayInfo(2, 11, gfx::Rect(0, 0, 1920, 1200));
     43 
     44   TouchTransformerController* tt_controller =
     45       Shell::GetInstance()->touch_transformer_controller();
     46   ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
     47 
     48   tt_controller->force_compute_mirror_mode_touch_transformer_ = true;
     49   device_manager->UpdateTouchInfoForDisplay(
     50       internal_display_info.id(),
     51       internal_display_info.touch_device_id(),
     52       tt_controller->GetMirrorModeTouchTransformer(internal_display_info));
     53 
     54   tt_controller->force_compute_mirror_mode_touch_transformer_ = false;
     55   device_manager->UpdateTouchInfoForDisplay(
     56       external_display_info.id(),
     57       external_display_info.touch_device_id(),
     58       tt_controller->GetMirrorModeTouchTransformer(external_display_info));
     59 
     60   EXPECT_EQ(1, device_manager->GetDisplayForTouchDevice(10));
     61   EXPECT_EQ(2, device_manager->GetDisplayForTouchDevice(11));
     62 
     63   // External touch display has the default TouchTransformer.
     64   float x = 100.0;
     65   float y = 100.0;
     66   device_manager->ApplyTouchTransformer(11, &x, &y);
     67   EXPECT_EQ(100, x);
     68   EXPECT_EQ(100, y);
     69 
     70   // In letterboxing, there is (1-2560*(1200/1920)/1700)/2 = 2.95% of the
     71   // height on both the top & bottom region of the screen is blank.
     72   // When touch events coming at Y range [0, 1200), the mapping should be
     73   // [0, ~35] ---> < 0
     74   // [~35, ~1165] ---> [0, 1200)
     75   // [~1165, 1200] ---> >= 1200
     76   x = 100.0;
     77   y = 35.0;
     78   device_manager->ApplyTouchTransformer(10, &x, &y);
     79   EXPECT_EQ(100, static_cast<int>(x));
     80   EXPECT_EQ(0, static_cast<int>(y));
     81 
     82   x = 100.0;
     83   y = 1165.0;
     84   device_manager->ApplyTouchTransformer(10, &x, &y);
     85   EXPECT_EQ(100, static_cast<int>(x));
     86   EXPECT_EQ(1200, static_cast<int>(y));
     87 }
     88 
     89 TEST_F(TouchTransformerControllerTest, TouchTransformerMirrorModePillarboxing) {
     90   // The internal display has native resolution of 1366x768, and in
     91   // mirror mode it is configured as 1024x768. This is in pillarboxing
     92   // mode.
     93   DisplayInfo internal_display_info =
     94       CreateDisplayInfo(1, 10, gfx::Rect(0, 0, 1024, 768));
     95   std::vector<DisplayMode> internal_modes;
     96   internal_modes.push_back(
     97       DisplayMode(gfx::Size(1366, 768), 60, false, true));
     98   internal_modes.push_back(
     99       DisplayMode(gfx::Size(1024, 768), 60, false, false));
    100   internal_display_info.set_display_modes(internal_modes);
    101 
    102   DisplayInfo external_display_info =
    103       CreateDisplayInfo(2, 11, gfx::Rect(0, 0, 1024, 768));
    104 
    105   TouchTransformerController* tt_controller =
    106       Shell::GetInstance()->touch_transformer_controller();
    107   ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
    108 
    109   tt_controller->force_compute_mirror_mode_touch_transformer_ = true;
    110   device_manager->UpdateTouchInfoForDisplay(
    111       internal_display_info.id(),
    112       internal_display_info.touch_device_id(),
    113       tt_controller->GetMirrorModeTouchTransformer(internal_display_info));
    114 
    115   tt_controller->force_compute_mirror_mode_touch_transformer_ = false;
    116   device_manager->UpdateTouchInfoForDisplay(
    117       external_display_info.id(),
    118       external_display_info.touch_device_id(),
    119       tt_controller->GetMirrorModeTouchTransformer(external_display_info));
    120 
    121   EXPECT_EQ(1, device_manager->GetDisplayForTouchDevice(10));
    122   EXPECT_EQ(2, device_manager->GetDisplayForTouchDevice(11));
    123 
    124   // External touch display has the default TouchTransformer.
    125   float x = 100.0;
    126   float y = 100.0;
    127   device_manager->ApplyTouchTransformer(11, &x, &y);
    128   EXPECT_EQ(100, x);
    129   EXPECT_EQ(100, y);
    130 
    131   // In pillarboxing, there is (1-768*(1024/768)/1366)/2 = 12.5% of the
    132   // width on both the left & rigth region of the screen is blank.
    133   // When touch events coming at X range [0, 1024), the mapping should be
    134   // [0, ~128] ---> < 0
    135   // [~128, ~896] ---> [0, 1024)
    136   // [~896, 1024] ---> >= 1024
    137   x = 128.0;
    138   y = 100.0;
    139   device_manager->ApplyTouchTransformer(10, &x, &y);
    140   EXPECT_EQ(0, static_cast<int>(x));
    141   EXPECT_EQ(100, static_cast<int>(y));
    142 
    143   x = 896.0;
    144   y = 100.0;
    145   device_manager->ApplyTouchTransformer(10, &x, &y);
    146   EXPECT_EQ(1024, static_cast<int>(x));
    147   EXPECT_EQ(100, static_cast<int>(y));
    148 }
    149 
    150 TEST_F(TouchTransformerControllerTest, TouchTransformerExtendedMode) {
    151   // The internal display has size 1366 x 768. The external display has
    152   // size 2560x1600. The total frame buffer is 2560x2428,
    153   // where 2428 = 768 + 60 (hidden gap) + 1600
    154   // and the sceond monitor is translated to Point (0, 828) in the
    155   // framebuffer.
    156   DisplayInfo display1 = CreateDisplayInfo(1, 5, gfx::Rect(0, 0, 1366, 768));
    157   DisplayInfo display2 = CreateDisplayInfo(2, 6, gfx::Rect(0, 828, 2560, 1600));
    158   gfx::Size fb_size(2560, 2428);
    159 
    160   TouchTransformerController* tt_controller =
    161       Shell::GetInstance()->touch_transformer_controller();
    162   ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
    163 
    164   device_manager->UpdateTouchInfoForDisplay(
    165       display1.id(),
    166       display1.touch_device_id(),
    167       tt_controller->GetExtendedModeTouchTransformer(display1, fb_size));
    168 
    169   device_manager->UpdateTouchInfoForDisplay(
    170       display2.id(),
    171       display2.touch_device_id(),
    172       tt_controller->GetExtendedModeTouchTransformer(display2, fb_size));
    173 
    174   EXPECT_EQ(1, device_manager->GetDisplayForTouchDevice(5));
    175   EXPECT_EQ(2, device_manager->GetDisplayForTouchDevice(6));
    176 
    177   // Mapping for touch events from internal touch display:
    178   // [0, 2560) x [0, 2428) -> [0, 1366) x [0, 768)
    179   float x = 0.0;
    180   float y = 0.0;
    181   device_manager->ApplyTouchTransformer(5, &x, &y);
    182   EXPECT_EQ(0, static_cast<int>(x));
    183   EXPECT_EQ(0, static_cast<int>(y));
    184 
    185   x = 2559.0;
    186   y = 2427.0;
    187   device_manager->ApplyTouchTransformer(5, &x, &y);
    188   EXPECT_EQ(1365, static_cast<int>(x));
    189   EXPECT_EQ(767, static_cast<int>(y));
    190 
    191   // Mapping for touch events from external touch display:
    192   // [0, 2560) x [0, 2428) -> [0, 2560) x [0, 1600)
    193   x = 0.0;
    194   y = 0.0;
    195   device_manager->ApplyTouchTransformer(6, &x, &y);
    196   EXPECT_EQ(0, static_cast<int>(x));
    197   EXPECT_EQ(0, static_cast<int>(y));
    198 
    199   x = 2559.0;
    200   y = 2427.0;
    201   device_manager->ApplyTouchTransformer(6, &x, &y);
    202   EXPECT_EQ(2559, static_cast<int>(x));
    203   EXPECT_EQ(1599, static_cast<int>(y));
    204 }
    205 
    206 }  // namespace ash
    207