#include "ui/display/manager/touch_transform_controller.h"
#include <array>
#include <memory>
#include <string>
#include <utility>
#include "base/memory/raw_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/manager/default_touch_transform_setter.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/test/touch_device_manager_test_api.h"
#include "ui/display/manager/touch_device_manager.h"
#include "ui/display/screen_base.h"
#include "ui/display/tablet_state.h"
#include "ui/display/test/test_screen.h"
#include "ui/events/devices/device_data_manager.h"
namespace display::test {
namespace {
constexpr int kDisplayId1 = 1;
constexpr int kDisplayId2 = 2;
constexpr int kTouchId1 = 5;
constexpr int kTouchId2 = 6;
ui::TouchDeviceTransform CreateTouchDeviceTransform(
int64_t display_id,
int32_t device_id,
const gfx::Transform& transform,
double radius_scale = 1.0) {
ui::TouchDeviceTransform touch_device_transform;
touch_device_transform.display_id = display_id;
touch_device_transform.device_id = device_id;
touch_device_transform.transform = transform;
touch_device_transform.radius_scale = radius_scale;
return touch_device_transform;
}
ui::TouchscreenDevice CreateTouchscreenDevice(unsigned int id,
const gfx::Size& size) {
return ui::TouchscreenDevice(id, ui::InputDeviceType::INPUT_DEVICE_USB,
std::string(), size, 0);
}
std::string GetTouchPointString(
const TouchCalibrationData::CalibrationPointPairQuad& pts) {
std::string str = "Failed for point pairs: ";
for (std::size_t row = 0; row < pts.size(); row++) {
str += "{(" + base::NumberToString(pts[row].first.x()) + "," +
base::NumberToString(pts[row].first.y()) + "), (" +
base::NumberToString(pts[row].second.x()) + "," +
base::NumberToString(pts[row].second.y()) + ")} ";
}
return str;
}
void CheckPointsOfInterests(const int touch_id,
const gfx::Size& touch_size,
const gfx::Size& display_size,
const gfx::Size& max_error_delta,
const std::string& error_msg) {
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
float x, y;
x = y = 0.0;
device_manager->ApplyTouchTransformer(touch_id, &x, &y);
EXPECT_NEAR(0, x, max_error_delta.width()) << error_msg;
EXPECT_NEAR(0, y, max_error_delta.height()) << error_msg;
x = touch_size.width() / 2;
y = touch_size.height() / 2;
device_manager->ApplyTouchTransformer(touch_id, &x, &y);
EXPECT_NEAR(display_size.width() / 2, x, max_error_delta.width())
<< error_msg;
EXPECT_NEAR(display_size.height() / 2, y, max_error_delta.height())
<< error_msg;
x = touch_size.width();
y = touch_size.height();
device_manager->ApplyTouchTransformer(touch_id, &x, &y);
EXPECT_NEAR(display_size.width(), x, max_error_delta.width()) << error_msg;
EXPECT_NEAR(display_size.height(), y, max_error_delta.height()) << error_msg;
}
}
class TouchTransformControllerTest : public testing::Test {
public:
TouchTransformControllerTest() {}
TouchTransformControllerTest(const TouchTransformControllerTest&) = delete;
TouchTransformControllerTest& operator=(const TouchTransformControllerTest&) =
delete;
~TouchTransformControllerTest() override {}
gfx::Transform GetTouchTransform(
const ManagedDisplayInfo& display,
const ManagedDisplayInfo& touch_display,
const ui::TouchscreenDevice& touchscreen) const {
return touch_transform_controller_->GetTouchTransform(
display, touch_display, touchscreen);
}
void SetIsCalibrating(bool is_calibrating) {
touch_transform_controller_->SetForCalibration(is_calibrating);
}
double GetTouchResolutionScale(
const ManagedDisplayInfo& touch_display,
const ui::TouchscreenDevice& touch_device) const {
return touch_transform_controller_->GetTouchResolutionScale(touch_display,
touch_device);
}
void SetTabletState(TabletState state) {
static_cast<test::TestScreen&>(*Screen::Get())
.OverrideTabletStateForTesting(state);
}
TouchDeviceManager* touch_device_manager() { return touch_device_manager_; }
void SetUp() override {
ui::DeviceDataManager::CreateInstance();
std::unique_ptr<ScreenBase> test_screen = std::make_unique<TestScreen>();
Screen::SetScreenInstance(test_screen.get());
display_manager_ = std::make_unique<DisplayManager>(std::move(test_screen));
touch_device_manager_ = display_manager_->touch_device_manager();
touch_transform_controller_ = std::make_unique<TouchTransformController>(
display_manager_.get(),
std::make_unique<DefaultTouchTransformSetter>());
}
void TearDown() override {
Screen::SetScreenInstance(nullptr);
ui::DeviceDataManager::DeleteInstance();
}
ManagedDisplayInfo CreateDisplayInfo(int64_t id,
const ui::TouchscreenDevice& device,
const gfx::Rect& bounds) {
ManagedDisplayInfo info = display::CreateDisplayInfo(id, bounds);
ManagedDisplayInfo::ManagedDisplayModeList default_modes(
1, ManagedDisplayMode(bounds.size(), 60, false, true));
info.SetManagedDisplayModes(default_modes);
test::TouchDeviceManagerTestApi tdm_test_api(touch_device_manager_);
tdm_test_api.Associate(&info, device);
return info;
}
private:
std::unique_ptr<DisplayManager> display_manager_;
std::unique_ptr<TouchTransformController> touch_transform_controller_;
raw_ptr<TouchDeviceManager> touch_device_manager_;
};
TEST_F(TouchTransformControllerTest, MirrorModeLetterboxing) {
gfx::Size fb_size(1920, 1200);
ui::TouchscreenDevice internal_touchscreen =
CreateTouchscreenDevice(10, fb_size);
ui::TouchscreenDevice external_touchscreen =
CreateTouchscreenDevice(11, fb_size);
ManagedDisplayInfo internal_display_info =
CreateDisplayInfo(1, internal_touchscreen, gfx::Rect(0, 0, 1920, 1200));
internal_display_info.set_is_aspect_preserving_scaling(true);
ManagedDisplayInfo::ManagedDisplayModeList internal_modes;
internal_modes.push_back(
ManagedDisplayMode(gfx::Size(2560, 1700), 60, false, true));
internal_modes.push_back(
ManagedDisplayMode(gfx::Size(1920, 1200), 60, false, false));
internal_display_info.SetManagedDisplayModes(internal_modes);
ManagedDisplayInfo external_display_info =
CreateDisplayInfo(2, external_touchscreen, gfx::Rect(0, 0, 1920, 1200));
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
internal_display_info.id(), internal_touchscreen.id,
GetTouchTransform(internal_display_info, internal_display_info,
internal_touchscreen)));
transforms.push_back(CreateTouchDeviceTransform(
internal_display_info.id(), external_touchscreen.id,
GetTouchTransform(external_display_info, external_display_info,
external_touchscreen)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(10));
EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(11));
float x = 100.0;
float y = 100.0;
device_manager->ApplyTouchTransformer(11, &x, &y);
EXPECT_EQ(100, x);
EXPECT_EQ(100, y);
x = 100.0;
y = 35.0;
device_manager->ApplyTouchTransformer(10, &x, &y);
EXPECT_NEAR(100, x, 0.5);
EXPECT_NEAR(0, y, 0.5);
x = 100.0;
y = 1165.0;
device_manager->ApplyTouchTransformer(10, &x, &y);
EXPECT_NEAR(100, x, 0.5);
EXPECT_NEAR(1200, y, 0.5);
}
TEST_F(TouchTransformControllerTest, MirrorModePillarboxing) {
gfx::Size fb_size(1024, 768);
ui::TouchscreenDevice internal_touchscreen =
CreateTouchscreenDevice(10, fb_size);
ui::TouchscreenDevice external_touchscreen =
CreateTouchscreenDevice(11, fb_size);
ManagedDisplayInfo internal_display_info =
CreateDisplayInfo(1, internal_touchscreen, gfx::Rect(0, 0, 1024, 768));
internal_display_info.set_is_aspect_preserving_scaling(true);
ManagedDisplayInfo::ManagedDisplayModeList internal_modes;
internal_modes.push_back(
ManagedDisplayMode(gfx::Size(1366, 768), 60, false, true));
internal_modes.push_back(
ManagedDisplayMode(gfx::Size(1024, 768), 60, false, false));
internal_display_info.SetManagedDisplayModes(internal_modes);
ManagedDisplayInfo external_display_info =
CreateDisplayInfo(2, external_touchscreen, gfx::Rect(0, 0, 1024, 768));
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
internal_display_info.id(), internal_touchscreen.id,
GetTouchTransform(internal_display_info, internal_display_info,
internal_touchscreen)));
transforms.push_back(CreateTouchDeviceTransform(
internal_display_info.id(), external_touchscreen.id,
GetTouchTransform(external_display_info, external_display_info,
external_touchscreen)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(10));
EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(11));
float x = 100.0;
float y = 100.0;
device_manager->ApplyTouchTransformer(11, &x, &y);
EXPECT_EQ(100, x);
EXPECT_EQ(100, y);
x = 128.0;
y = 100.0;
device_manager->ApplyTouchTransformer(10, &x, &y);
EXPECT_NEAR(0, x, 0.5);
EXPECT_NEAR(100, y, 0.5);
x = 896.0;
y = 100.0;
device_manager->ApplyTouchTransformer(10, &x, &y);
EXPECT_NEAR(1024, x, 0.5);
EXPECT_NEAR(100, y, 0.5);
}
TEST_F(TouchTransformControllerTest, SoftwareMirrorMode) {
gfx::Size fb_size(1920, 1990);
ui::TouchscreenDevice display1_touchscreen =
CreateTouchscreenDevice(10, fb_size);
ui::TouchscreenDevice display2_touchscreen =
CreateTouchscreenDevice(11, fb_size);
ManagedDisplayInfo display1_info =
CreateDisplayInfo(1, display1_touchscreen, gfx::Rect(0, 0, 1280, 850));
ManagedDisplayInfo::ManagedDisplayModeList display1_modes;
display1_modes.push_back(
ManagedDisplayMode(gfx::Size(1280, 850), 60, false, true));
display1_info.SetManagedDisplayModes(display1_modes);
ManagedDisplayInfo display2_info =
CreateDisplayInfo(2, display2_touchscreen, gfx::Rect(0, 950, 1920, 1080));
ManagedDisplayInfo::ManagedDisplayModeList display2_modes;
display2_modes.push_back(
ManagedDisplayMode(gfx::Size(1920, 1080), 60, false, true));
display2_info.SetManagedDisplayModes(display2_modes);
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
display1_info.id(), display1_touchscreen.id,
GetTouchTransform(display1_info, display1_info, display1_touchscreen)));
transforms.push_back(CreateTouchDeviceTransform(
display1_info.id(), display2_touchscreen.id,
GetTouchTransform(display1_info, display2_info, display2_touchscreen)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(10));
EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(11));
float x = 0.0;
float y = 0.0;
device_manager->ApplyTouchTransformer(10, &x, &y);
EXPECT_NEAR(0, x, 0.5);
EXPECT_NEAR(0, y, 0.5);
x = 1920.0;
y = 1990.0;
device_manager->ApplyTouchTransformer(10, &x, &y);
EXPECT_NEAR(1280, x, 0.5);
EXPECT_NEAR(850, y, 0.5);
x = 147.0;
y = 0.0;
device_manager->ApplyTouchTransformer(11, &x, &y);
EXPECT_NEAR(0, x, 0.5);
EXPECT_NEAR(0, y, 0.5);
x = 1773.0;
y = 1990.0;
device_manager->ApplyTouchTransformer(11, &x, &y);
EXPECT_NEAR(1280, x, 0.5);
EXPECT_NEAR(850, y, 0.5);
}
TEST_F(TouchTransformControllerTest, ExtendedMode) {
gfx::Size fb_size(2560, 2428);
ui::TouchscreenDevice touchscreen1 = CreateTouchscreenDevice(5, fb_size);
ui::TouchscreenDevice touchscreen2 = CreateTouchscreenDevice(6, fb_size);
ManagedDisplayInfo display1 =
CreateDisplayInfo(1, touchscreen1, gfx::Rect(0, 0, 1366, 768));
ManagedDisplayInfo display2 =
CreateDisplayInfo(2, touchscreen2, gfx::Rect(0, 828, 2560, 1600));
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
display1.id(), touchscreen1.id,
GetTouchTransform(display1, display1, touchscreen1)));
transforms.push_back(CreateTouchDeviceTransform(
display2.id(), touchscreen2.id,
GetTouchTransform(display2, display2, touchscreen2)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(1, device_manager->GetTargetDisplayForTouchDevice(5));
EXPECT_EQ(2, device_manager->GetTargetDisplayForTouchDevice(6));
float x = 0.0;
float y = 0.0;
device_manager->ApplyTouchTransformer(5, &x, &y);
EXPECT_NEAR(0, x, 0.5);
EXPECT_NEAR(0, y, 0.5);
x = 2559.0;
y = 2427.0;
device_manager->ApplyTouchTransformer(5, &x, &y);
EXPECT_NEAR(1365, x, 0.5);
EXPECT_NEAR(768, y, 0.5);
x = 0.0;
y = 0.0;
device_manager->ApplyTouchTransformer(6, &x, &y);
EXPECT_NEAR(0 + 0, x, 0.5);
EXPECT_NEAR(0 + 828, y, 0.5);
x = 2559.0;
y = 2427.0;
device_manager->ApplyTouchTransformer(6, &x, &y);
EXPECT_NEAR(2559 + 0, x, 0.5);
EXPECT_NEAR(1599 + 828, y, 0.5);
}
TEST_F(TouchTransformControllerTest, TouchRadiusScale) {
ui::TouchscreenDevice touch_device =
CreateTouchscreenDevice(5, gfx::Size(100001, 100001));
ManagedDisplayInfo display =
CreateDisplayInfo(1, touch_device, gfx::Rect(0, 0, 2560, 1600));
EXPECT_EQ(sqrt((2560.0 * 1600.0) / (100001.0 * 100001.0)),
GetTouchResolutionScale(display, touch_device));
}
TEST_F(TouchTransformControllerTest, OzoneTranslation) {
const gfx::Size kDisplaySize(1920, 1200);
const int kHiddenGap = 50;
ui::TouchscreenDevice touchscreen1 =
CreateTouchscreenDevice(kTouchId1, kDisplaySize);
ui::TouchscreenDevice touchscreen2 =
CreateTouchscreenDevice(kTouchId2, kDisplaySize);
ManagedDisplayInfo display1 = CreateDisplayInfo(
kDisplayId1, touchscreen1,
gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
ManagedDisplayInfo display2 =
CreateDisplayInfo(kDisplayId2, touchscreen2,
gfx::Rect(0, kDisplaySize.height() + kHiddenGap,
kDisplaySize.width(), kDisplaySize.height()));
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
display1.id(), touchscreen1.id,
GetTouchTransform(display1, display1, touchscreen1)));
transforms.push_back(CreateTouchDeviceTransform(
display1.id(), touchscreen2.id,
GetTouchTransform(display1, display2, touchscreen2)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId2));
float x, y;
x = y = 0.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_NEAR(0, x, 0.5);
EXPECT_NEAR(0, y, 0.5);
x = y = 0.0;
device_manager->ApplyTouchTransformer(kTouchId2, &x, &y);
EXPECT_NEAR(0, x, 0.5);
EXPECT_NEAR(0, y, 0.5);
x = 1920.0;
y = 1200.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_NEAR(1920, x, 0.5);
EXPECT_NEAR(1200, y, 0.5);
x = 1920.0;
y = 1200.0;
device_manager->ApplyTouchTransformer(kTouchId2, &x, &y);
EXPECT_NEAR(1920, x, 0.5);
EXPECT_NEAR(1200, y, 0.5);
transforms.push_back(CreateTouchDeviceTransform(
display2.id(), touchscreen2.id,
GetTouchTransform(display2, display2, touchscreen2)));
device_manager->ConfigureTouchDevices(transforms);
x = 1920.0;
y = 1200.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_NEAR(1920, x, 0.5);
EXPECT_NEAR(1200, y, 0.5);
x = 1920.0;
y = 1200.0;
device_manager->ApplyTouchTransformer(kTouchId2, &x, &y);
EXPECT_NEAR(1920, x, 0.5);
EXPECT_NEAR(1200 + kDisplaySize.height() + kHiddenGap, y, 0.5);
transforms.push_back(CreateTouchDeviceTransform(
display2.id(), touchscreen1.id,
GetTouchTransform(display2, display1, touchscreen1)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId2,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
EXPECT_EQ(kDisplayId2,
device_manager->GetTargetDisplayForTouchDevice(kTouchId2));
x = 1920.0;
y = 1200.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_NEAR(1920, x, 0.5);
EXPECT_NEAR(1200 + kDisplaySize.height() + kHiddenGap, y, 0.5);
x = y = 0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_NEAR(0, x, 0.5);
EXPECT_NEAR(kDisplaySize.height() + kHiddenGap, y, 0.5);
}
TEST_F(TouchTransformControllerTest, RotationInTabletMirrorMode) {
constexpr gfx::Size kDisplaySize1(1920, 1200);
constexpr gfx::Size kDisplaySize2(1920, 1080);
constexpr int kHiddenGap = 50;
SetTabletState(TabletState::kInTabletMode);
ui::TouchscreenDevice touchscreen1 =
CreateTouchscreenDevice(kTouchId1, kDisplaySize1);
ui::TouchscreenDevice touchscreen2 =
CreateTouchscreenDevice(kTouchId2, kDisplaySize2);
ManagedDisplayInfo display1 =
CreateDisplayInfo(kDisplayId1, touchscreen1,
{kDisplaySize1.width(), kDisplaySize1.height()});
ManagedDisplayInfo display2 =
CreateDisplayInfo(kDisplayId2, touchscreen2,
{0, kDisplaySize2.height() + kHiddenGap,
kDisplaySize2.width(), kDisplaySize2.height()});
constexpr std::array<Display::Rotation, 4> rotList = {
Display::ROTATE_0, Display::ROTATE_90, Display::ROTATE_180,
Display::ROTATE_270};
struct TestPoint {
float x;
float y;
};
constexpr std::pair<TestPoint, TestPoint> test1_touch = {{96, 0},
{1824, 1080}};
constexpr std::pair<TestPoint, TestPoint> test1_transformed = {{0, 0},
{1920, 1200}};
const std::pair<TestPoint, TestPoint> test2_touch = {{622.5, 0},
{1297.5, 1080}};
const std::pair<TestPoint, TestPoint> test2_transformed = {{0, 1200},
{1920, 0}};
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
for (const Display::Rotation rot1 : rotList) {
for (const Display::Rotation rot2 : rotList) {
display1.SetRotation(rot1, Display::RotationSource::ACTIVE);
display2.SetRotation(rot2, Display::RotationSource::ACTIVE);
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
display1.id(), touchscreen1.id,
GetTouchTransform(display1, display1, touchscreen1)));
transforms.push_back(CreateTouchDeviceTransform(
display1.id(), touchscreen2.id,
GetTouchTransform(display1, display2, touchscreen2)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId2));
std::pair<TestPoint, TestPoint> touches;
std::pair<TestPoint, TestPoint> expected;
if ((rot1 - rot2) % 2 == 0) {
touches = test1_touch;
expected = test1_transformed;
} else {
touches = test2_touch;
expected = test2_transformed;
}
if (((rot2 - rot1 + 4) % 4 > 1)) {
expected = std::pair(expected.second, expected.first);
}
float x = touches.first.x;
float y = touches.first.y;
device_manager->ApplyTouchTransformer(kTouchId2, &x, &y);
EXPECT_NEAR(expected.first.x, x, 0.5);
EXPECT_NEAR(expected.first.y, y, 0.5);
x = touches.second.x;
y = touches.second.y;
device_manager->ApplyTouchTransformer(kTouchId2, &x, &y);
EXPECT_NEAR(expected.second.x, x, 0.5);
EXPECT_NEAR(expected.second.y, y, 0.5);
}
}
SetTabletState(TabletState::kInClamshellMode);
}
TEST_F(TouchTransformControllerTest, NoMirrorTransformWhileCalibrating) {
constexpr gfx::Size kDisplaySize(1920, 1200);
ui::TouchscreenDevice touchscreen1 =
CreateTouchscreenDevice(kTouchId1, kDisplaySize);
ui::TouchscreenDevice touchscreen2 =
CreateTouchscreenDevice(kTouchId2, kDisplaySize);
ManagedDisplayInfo display1 = CreateDisplayInfo(
kDisplayId1, touchscreen1, {kDisplaySize.width(), kDisplaySize.height()});
ManagedDisplayInfo display2 = CreateDisplayInfo(
kDisplayId2, touchscreen2,
{0, kDisplaySize.height(), kDisplaySize.width(), kDisplaySize.height()});
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
display2.id(), touchscreen1.id,
GetTouchTransform(display2, display1, touchscreen1)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId2,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
float x, y;
x = y = 0.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_NEAR(0, x, 0.5);
EXPECT_NEAR(kDisplaySize.height(), y, 0.5);
SetIsCalibrating(true);
transforms.push_back(CreateTouchDeviceTransform(
display2.id(), touchscreen1.id,
GetTouchTransform(display2, display1, touchscreen1)));
device_manager->ConfigureTouchDevices(transforms);
x = y = 0.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_NEAR(0, x, 0.5);
EXPECT_NEAR(0, y, 0.5);
SetIsCalibrating(false);
}
TEST_F(TouchTransformControllerTest, AccurateUserTouchCalibration) {
const gfx::Size kDisplaySize(1920, 1200);
const gfx::Size kTouchSize(1920, 1200);
ui::TouchscreenDevice touchscreen =
CreateTouchscreenDevice(kTouchId1, kTouchSize);
ManagedDisplayInfo display = CreateDisplayInfo(
kDisplayId1, touchscreen,
gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
TouchCalibrationData::CalibrationPointPairQuad user_input = {{
std::make_pair(gfx::Point(100, 100), gfx::Point(100, 100)),
std::make_pair(gfx::Point(1820, 100), gfx::Point(1820, 100)),
std::make_pair(gfx::Point(100, 1100), gfx::Point(100, 1100)),
std::make_pair(gfx::Point(1820, 1100), gfx::Point(1820, 1100)),
}};
TouchCalibrationData touch_data(user_input, kDisplaySize);
const std::string msg = GetTouchPointString(user_input);
touch_device_manager()->AddTouchCalibrationData(touchscreen, display.id(),
touch_data);
EXPECT_FALSE(touch_device_manager()
->GetCalibrationData(touchscreen, display.id())
.IsEmpty());
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
display.id(), touchscreen.id,
GetTouchTransform(display, display, touchscreen)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
CheckPointsOfInterests(kTouchId1, kTouchSize, kDisplaySize, gfx::Size(1, 1),
msg);
}
TEST_F(TouchTransformControllerTest, ErrorProneUserTouchCalibration) {
const gfx::Size kDisplaySize(1920, 1200);
const gfx::Size kTouchSize(1920, 1200);
const float kError = 0.05;
const gfx::Size kMaxErrorDelta = gfx::ScaleToCeiledSize(kTouchSize, kError);
ui::TouchscreenDevice touchscreen =
CreateTouchscreenDevice(kTouchId1, kTouchSize);
ManagedDisplayInfo display = CreateDisplayInfo(
kDisplayId1, touchscreen,
gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
TouchCalibrationData::CalibrationPointPairQuad user_input = {
{std::make_pair(gfx::Point(100, 100), gfx::Point(130, 60)),
std::make_pair(gfx::Point(1820, 100), gfx::Point(1878, 130)),
std::make_pair(gfx::Point(100, 1100), gfx::Point(158, 1060)),
std::make_pair(gfx::Point(1820, 1100), gfx::Point(1790, 1140))}};
TouchCalibrationData touch_data(user_input, kDisplaySize);
const std::string msg = GetTouchPointString(user_input);
touch_device_manager()->AddTouchCalibrationData(touchscreen, display.id(),
touch_data);
EXPECT_FALSE(touch_device_manager()
->GetCalibrationData(touchscreen, display.id())
.IsEmpty());
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
display.id(), touchscreen.id,
GetTouchTransform(display, display, touchscreen)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
CheckPointsOfInterests(kTouchId1, kTouchSize, kDisplaySize, kMaxErrorDelta,
msg);
}
TEST_F(TouchTransformControllerTest, ResolutionChangeUserTouchCalibration) {
const gfx::Size kDisplaySize(2560, 1600);
const gfx::Size kTouchSize(1920, 1200);
const float kError = 0.05;
gfx::Size kMaxErrorDelta = gfx::ScaleToCeiledSize(kDisplaySize, kError);
ui::TouchscreenDevice touchscreen =
CreateTouchscreenDevice(kTouchId1, kTouchSize);
ManagedDisplayInfo display = CreateDisplayInfo(
kDisplayId1, touchscreen,
gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
const gfx::Size CALIBRATION_SIZE(1920, 1200);
TouchCalibrationData::CalibrationPointPairQuad user_input = {
{std::make_pair(gfx::Point(100, 100), gfx::Point(50, 70)),
std::make_pair(gfx::Point(1820, 100), gfx::Point(1780, 70)),
std::make_pair(gfx::Point(100, 1100), gfx::Point(70, 1060)),
std::make_pair(gfx::Point(1820, 1100), gfx::Point(1770, 1140))}};
TouchCalibrationData touch_data(user_input, CALIBRATION_SIZE);
const std::string msg = GetTouchPointString(user_input);
touch_device_manager()->AddTouchCalibrationData(touchscreen, display.id(),
touch_data);
EXPECT_FALSE(touch_device_manager()
->GetCalibrationData(touchscreen, display.id())
.IsEmpty());
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
display.id(), touchscreen.id,
GetTouchTransform(display, display, touchscreen)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
CheckPointsOfInterests(kTouchId1, kTouchSize, kDisplaySize, kMaxErrorDelta,
msg);
}
TEST_F(TouchTransformControllerTest, DifferentBoundsUserTouchCalibration) {
const gfx::Size kDisplaySize(1024, 600);
const gfx::Size kTouchSize(4096, 4096);
const float kAcceptableError = 0.04;
gfx::Size kMaxErrorDelta =
gfx::ScaleToCeiledSize(kDisplaySize, kAcceptableError);
ui::TouchscreenDevice touchscreen =
CreateTouchscreenDevice(kTouchId1, kTouchSize);
ManagedDisplayInfo display = CreateDisplayInfo(
kDisplayId1, touchscreen,
gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
TouchCalibrationData::CalibrationPointPairQuad user_input = {
{std::make_pair(gfx::Point(136, 136), gfx::Point(538, 931)),
std::make_pair(gfx::Point(873, 136), gfx::Point(3475, 922)),
std::make_pair(gfx::Point(136, 411), gfx::Point(611, 2800)),
std::make_pair(gfx::Point(873, 411), gfx::Point(3535, 2949))}};
TouchCalibrationData touch_data(user_input, kDisplaySize);
const std::string msg = GetTouchPointString(user_input);
touch_device_manager()->AddTouchCalibrationData(touchscreen, display.id(),
touch_data);
EXPECT_FALSE(touch_device_manager()
->GetCalibrationData(touchscreen, display.id())
.IsEmpty());
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
display.id(), touchscreen.id,
GetTouchTransform(display, display, touchscreen)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
CheckPointsOfInterests(kTouchId1, kTouchSize, kDisplaySize, kMaxErrorDelta,
msg);
}
TEST_F(TouchTransformControllerTest, LetterboxingUserTouchCalibration) {
const gfx::Size kNativeDisplaySize(2560, 1700);
const gfx::Size kDisplaySize(1920, 1200);
const gfx::Size kTouchSize(1920, 1200);
ui::TouchscreenDevice internal_touchscreen =
CreateTouchscreenDevice(kTouchId1, kTouchSize);
ManagedDisplayInfo internal_display_info = CreateDisplayInfo(
kDisplayId1, internal_touchscreen,
gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
internal_display_info.set_is_aspect_preserving_scaling(true);
ManagedDisplayInfo::ManagedDisplayModeList internal_modes;
internal_modes.push_back(ManagedDisplayMode(
gfx::Size(kNativeDisplaySize.width(), kNativeDisplaySize.height()), 60,
false, true));
internal_modes.push_back(
ManagedDisplayMode(gfx::Size(kDisplaySize.width(), kDisplaySize.height()),
60, false, false));
internal_display_info.SetManagedDisplayModes(internal_modes);
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
TouchCalibrationData::CalibrationPointPairQuad user_input = {{
std::make_pair(gfx::Point(100, 100), gfx::Point(75, 71)),
std::make_pair(gfx::Point(2460, 100), gfx::Point(1845, 71)),
std::make_pair(gfx::Point(100, 1600), gfx::Point(75, 1130)),
std::make_pair(gfx::Point(2460, 1600), gfx::Point(1845, 1130)),
}};
TouchCalibrationData touch_data(user_input, kNativeDisplaySize);
touch_device_manager()->AddTouchCalibrationData(
internal_touchscreen, internal_display_info.id(), touch_data);
EXPECT_FALSE(
touch_device_manager()
->GetCalibrationData(internal_touchscreen, internal_display_info.id())
.IsEmpty());
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
internal_display_info.id(), internal_touchscreen.id,
GetTouchTransform(internal_display_info, internal_display_info,
internal_touchscreen)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
float x, y;
x = 100.0;
y = 35.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_NEAR(100, x, 0.5);
EXPECT_NEAR(0, y, 0.5);
x = 100.0;
y = 1165.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_NEAR(100, x, 0.5);
EXPECT_NEAR(1200, y, 0.5);
}
TEST_F(TouchTransformControllerTest, PillarBoxingUserTouchCalibration) {
const gfx::Size kNativeDisplaySize(2560, 1600);
const gfx::Size kDisplaySize(1920, 1400);
ui::TouchscreenDevice internal_touchscreen =
CreateTouchscreenDevice(kTouchId1, kDisplaySize);
ManagedDisplayInfo internal_display_info = CreateDisplayInfo(
kDisplayId1, internal_touchscreen,
gfx::Rect(0, 0, kDisplaySize.width(), kDisplaySize.height()));
internal_display_info.set_is_aspect_preserving_scaling(true);
ManagedDisplayInfo::ManagedDisplayModeList internal_modes;
internal_modes.push_back(ManagedDisplayMode(
gfx::Size(kNativeDisplaySize.width(), kNativeDisplaySize.height()), 60,
false, true));
internal_modes.push_back(
ManagedDisplayMode(gfx::Size(kDisplaySize.width(), kDisplaySize.height()),
60, false, false));
internal_display_info.SetManagedDisplayModes(internal_modes);
ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
TouchCalibrationData::CalibrationPointPairQuad user_input = {{
std::make_pair(gfx::Point(100, 100), gfx::Point(75, 88)),
std::make_pair(gfx::Point(2460, 100), gfx::Point(1845, 88)),
std::make_pair(gfx::Point(100, 1500), gfx::Point(75, 1313)),
std::make_pair(gfx::Point(2460, 1500), gfx::Point(1845, 1313)),
}};
TouchCalibrationData touch_data(user_input, kNativeDisplaySize);
touch_device_manager()->AddTouchCalibrationData(
internal_touchscreen, internal_display_info.id(), touch_data);
EXPECT_FALSE(
touch_device_manager()
->GetCalibrationData(internal_touchscreen, internal_display_info.id())
.IsEmpty());
std::vector<ui::TouchDeviceTransform> transforms;
transforms.push_back(CreateTouchDeviceTransform(
internal_display_info.id(), internal_touchscreen.id,
GetTouchTransform(internal_display_info, internal_display_info,
internal_touchscreen)));
device_manager->ConfigureTouchDevices(transforms);
EXPECT_EQ(kDisplayId1,
device_manager->GetTargetDisplayForTouchDevice(kTouchId1));
float x, y;
x = 136.0;
y = 0.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_LT(-1.0f, x);
EXPECT_LT(x, 0.0f);
EXPECT_NEAR(0.0f, y, 0.01f);
x = 137.0;
y = 0.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_LT(0.0f, x);
EXPECT_LT(x, 1.0f);
EXPECT_NEAR(0.0f, y, 0.01f);
x = 1782.0;
y = 0.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_LT(1919.0f, x);
EXPECT_LT(x, 1920.0f);
EXPECT_NEAR(0.0f, y, 0.01f);
x = 1783.0;
y = 0.0;
device_manager->ApplyTouchTransformer(kTouchId1, &x, &y);
EXPECT_LT(1920.0f, x);
EXPECT_LT(x, 1921.0f);
EXPECT_NEAR(0.0f, y, 0.01f);
}
}