blob: b94271d017afb406006732519c1b725ded7f39f3 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/display/manager/touch_device_manager.h"
#include <memory>
#include <string>
#include <vector>
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/managed_display_info.h"
#include "ui/display/manager/test/touch_device_manager_test_api.h"
#include "ui/display/screen_base.h"
#include "ui/display/test/display_manager_test_api.h"
#include "ui/events/devices/input_device.h"
#include "ui/events/devices/touchscreen_device.h"
namespace display {
namespace {
ui::TouchscreenDevice CreateTouchscreenDevice(int id,
ui::InputDeviceType type,
const gfx::Size& size) {
ui::TouchscreenDevice device(id, type, base::NumberToString(id), size, 0);
device.vendor_id = id * id;
device.product_id = device.vendor_id * id;
return device;
}
TouchDeviceManager::TouchAssociationInfo CreateTouchAssociationInfo(
int days_old) {
TouchDeviceManager::TouchAssociationInfo info;
info.timestamp = base::Time::Now() - base::TimeDelta::FromDays(days_old);
return info;
}
} // namespace
using DisplayInfoList = std::vector<ManagedDisplayInfo>;
class TouchAssociationTest : public testing::Test {
public:
TouchAssociationTest() {}
~TouchAssociationTest() override {}
DisplayManager* display_manager() { return display_manager_.get(); }
TouchDeviceManager* touch_device_manager() { return touch_device_manager_; }
// testing::Test:
void SetUp() override {
// Recreate for each test, DisplayManager has a lot of state.
display_manager_ =
std::make_unique<DisplayManager>(std::make_unique<ScreenBase>());
touch_device_manager_ = display_manager_->touch_device_manager();
// Internal display will always match to internal touchscreen. If internal
// touchscreen can't be detected, it is then associated to a touch screen
// with matching size.
{
ManagedDisplayInfo display(1, "1", false);
const ManagedDisplayMode mode(gfx::Size(1920, 1080), 60.0,
false /* interlaced */, true /* native */,
1.0 /* device_scale_factor */);
ManagedDisplayInfo::ManagedDisplayModeList modes(1, mode);
display.SetManagedDisplayModes(modes);
displays_.push_back(display);
}
{
ManagedDisplayInfo display(2, "2", false);
const ManagedDisplayMode mode(gfx::Size(800, 600), 60.0,
false /* interlaced */, true /* native */,
1.0 /* device_scale_factor */);
ManagedDisplayInfo::ManagedDisplayModeList modes(1, mode);
display.SetManagedDisplayModes(modes);
displays_.push_back(display);
}
// Display without native mode. Must not be matched to any touch screen.
{
ManagedDisplayInfo display(3, "3", false);
displays_.push_back(display);
}
{
ManagedDisplayInfo display(4, "4", false);
const ManagedDisplayMode mode(
gfx::Size(1024, 768), 60.0, false /* interlaced */,
/* native */ true, 1.0 /* device_scale_factor */);
ManagedDisplayInfo::ManagedDisplayModeList modes(1, mode);
display.SetManagedDisplayModes(modes);
displays_.push_back(display);
}
}
void TearDown() override { displays_.clear(); }
// Helper method to return the count of touch devices associated with the
// display |info|.
std::size_t GetTouchDeviceCount(const ManagedDisplayInfo& info) const {
test::TouchDeviceManagerTestApi tdm_api(touch_device_manager_);
return tdm_api.GetTouchDeviceCount(info);
}
// Helper method that returns true if the display |info| is associated with
// the touch device |device|.
bool AreAssociated(const ManagedDisplayInfo& info,
const ui::TouchscreenDevice& device) const {
test::TouchDeviceManagerTestApi tdm_api(touch_device_manager_);
return tdm_api.AreAssociated(info, device);
}
protected:
DisplayInfoList displays_;
std::unique_ptr<DisplayManager> display_manager_;
TouchDeviceManager* touch_device_manager_;
private:
DISALLOW_COPY_AND_ASSIGN(TouchAssociationTest);
};
TEST_F(TouchAssociationTest, NoTouchscreens) {
std::vector<ui::TouchscreenDevice> devices;
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[0].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
for (size_t i = 0; i < displays_.size(); ++i)
EXPECT_EQ(GetTouchDeviceCount(displays_[i]), 0u);
}
// Verify that if there are a lot of touchscreens, they will all get associated
// with a display.
TEST_F(TouchAssociationTest, ManyTouchscreens) {
std::vector<ui::TouchscreenDevice> devices;
for (int i = 0; i < 5; ++i) {
devices.push_back(CreateTouchscreenDevice(
i, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(256, 256)));
}
DisplayInfoList displays;
displays.push_back(displays_[3]);
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[0].id());
touch_device_manager()->AssociateTouchscreens(&displays, devices);
for (int i = 0; i < 5; ++i)
EXPECT_TRUE(AreAssociated(displays[0], devices[i]));
}
TEST_F(TouchAssociationTest, OneToOneMapping) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(800, 600)));
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1024, 768)));
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[0].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 1u);
EXPECT_TRUE(AreAssociated(displays_[3], devices[1]));
}
TEST_F(TouchAssociationTest, MapToCorrectDisplaySize) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1024, 768)));
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[0].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 1u);
EXPECT_TRUE(AreAssociated(displays_[3], devices[0]));
}
TEST_F(TouchAssociationTest, MapWhenSizeDiffersByOne) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(801, 600)));
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1023, 768)));
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[0].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 1u);
EXPECT_TRUE(AreAssociated(displays_[3], devices[1]));
}
TEST_F(TouchAssociationTest, MapWhenSizesDoNotMatch) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1022, 768)));
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(802, 600)));
DisplayInfoList displays;
displays.push_back(displays_[0]);
displays.push_back(displays_[1]);
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays[0].id());
touch_device_manager()->AssociateTouchscreens(&displays, devices);
// The touch devices should match to the internal display if they were not
// matched in any of the steps.
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 2u);
EXPECT_TRUE(AreAssociated(displays_[1], devices[0]));
EXPECT_TRUE(AreAssociated(displays_[1], devices[1]));
}
TEST_F(TouchAssociationTest, MapInternalTouchscreen) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1920, 1080)));
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(9999, 888)));
DisplayInfoList displays;
displays.push_back(displays_[0]);
displays.push_back(displays_[1]);
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays[0].id());
touch_device_manager()->AssociateTouchscreens(&displays, devices);
// Internal touchscreen is always mapped to internal display.
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices[1]));
EXPECT_TRUE(AreAssociated(displays_[1], devices[0]));
}
TEST_F(TouchAssociationTest, MultipleInternal) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1920, 1080)));
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1920, 1080)));
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[0].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 2u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 0u);
}
TEST_F(TouchAssociationTest, MultipleInternalAndExternal) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1920, 1080)));
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1920, 1080)));
devices.push_back(CreateTouchscreenDevice(
3, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1024, 768)));
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[0].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 2u);
EXPECT_TRUE(AreAssociated(displays_[0], devices[0]));
EXPECT_TRUE(AreAssociated(displays_[0], devices[1]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 1u);
EXPECT_TRUE(AreAssociated(displays_[3], devices[2]));
}
// crbug.com/515201
TEST_F(TouchAssociationTest, TestWithNoInternalDisplay) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1920, 1080)));
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(9999, 888)));
// Internal touchscreen should not be associated with any display
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 0u);
}
TEST_F(TouchAssociationTest, MatchRemainingDevicesToInternalDisplay) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(123, 456)));
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(234, 567)));
devices.push_back(CreateTouchscreenDevice(
3, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(345, 678)));
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[0].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 3u);
EXPECT_TRUE(AreAssociated(displays_[0], devices[0]));
EXPECT_TRUE(AreAssociated(displays_[0], devices[1]));
EXPECT_TRUE(AreAssociated(displays_[0], devices[2]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 0u);
}
TEST_F(TouchAssociationTest,
MatchRemainingDevicesWithNoInternalDisplayPresent) {
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(123, 456)));
devices.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(234, 567)));
devices.push_back(CreateTouchscreenDevice(
3, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(345, 678)));
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
std::size_t total = 0;
for (const auto& display : displays_)
total += GetTouchDeviceCount(display);
// Make sure all devices were matched.
EXPECT_EQ(total, devices.size());
}
class TouchAssociationFromPrefTest : public TouchAssociationTest {
public:
TouchAssociationFromPrefTest() {}
~TouchAssociationFromPrefTest() override {}
void SetUp() override {
TouchAssociationTest::SetUp();
TouchDeviceManager::TouchAssociationMap touch_associations;
devices_.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1920, 1080)));
devices_.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1024, 768)));
devices_.push_back(CreateTouchscreenDevice(
3, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(640, 480)));
devices_.push_back(CreateTouchscreenDevice(
4, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(800, 600)));
// Create priority list for Device Id = 1
// - Display Index 0
// - Display Index 1
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[0])] =
TouchDeviceManager::AssociationInfoMap();
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[0])]
[displays_[0].id()] = CreateTouchAssociationInfo(1);
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[0])]
[displays_[1].id()] = CreateTouchAssociationInfo(2);
// Create priority list for Device Id = 2
// - Display Index 3
// - Display Index 1
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[1])] =
TouchDeviceManager::AssociationInfoMap();
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[1])]
[displays_[3].id()] = CreateTouchAssociationInfo(1);
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[1])]
[displays_[1].id()] = CreateTouchAssociationInfo(2);
// Craete priority list for Device Id = 3
// - Display Index 2
// - Display Index 3
// - Display Index 0
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[2])] =
TouchDeviceManager::AssociationInfoMap();
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[2])]
[displays_[2].id()] = CreateTouchAssociationInfo(1);
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[2])]
[displays_[3].id()] = CreateTouchAssociationInfo(2);
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[2])]
[displays_[0].id()] = CreateTouchAssociationInfo(3);
touch_device_manager_->RegisterTouchAssociations(
touch_associations, TouchDeviceManager::PortAssociationMap());
}
void TearDown() override {
TouchAssociationTest::TearDown();
devices_.clear();
}
protected:
std::vector<ui::TouchscreenDevice> devices_;
private:
DISALLOW_COPY_AND_ASSIGN(TouchAssociationFromPrefTest);
};
TEST_F(TouchAssociationFromPrefTest, CorrectMapping) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices_[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 1u);
EXPECT_TRUE(AreAssociated(displays_[2], devices_[2]));
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 1u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
}
TEST_F(TouchAssociationFromPrefTest, CorrectMappingWithSomeMissing) {
DisplayInfoList displays;
displays.push_back(displays_[1]);
displays.push_back(displays_[3]);
touch_device_manager()->AssociateTouchscreens(&displays, devices_);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 2u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[2]));
}
TEST_F(TouchAssociationFromPrefTest, UpdateMappingBeforeAssociation) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
// Reassociate display with id 4 to touch device with id 3. This will
// bring the display to the top of the priority list.
touch_device_manager()->AddTouchCalibrationData(
TouchDeviceIdentifier::FromDevice(devices_[2]), displays_[3].id(),
TouchCalibrationData());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices_[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 2u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[2]));
}
TEST_F(TouchAssociationFromPrefTest, UpdateMappingAfterAssociation) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
// Reassociate display with id 4 to touch device with id 3. This will
// bring the display to the top of the priority list. This should work even
// though the association of devices and displays is complete.
touch_device_manager()->AddTouchCalibrationData(
TouchDeviceIdentifier::FromDevice(devices_[2]), displays_[3].id(),
TouchCalibrationData());
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices_[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 2u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[2]));
}
TEST_F(TouchAssociationFromPrefTest, AssociatingDeviceToNewDisplay) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
// Reassociate display with id 4 to touch device with id 3. This will
// bring the display to the top of the priority list.
touch_device_manager()->AddTouchCalibrationData(
TouchDeviceIdentifier::FromDevice(devices_[0]), displays_[2].id(),
TouchCalibrationData());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 2u);
EXPECT_TRUE(AreAssociated(displays_[2], devices_[0]));
EXPECT_TRUE(AreAssociated(displays_[2], devices_[2]));
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 1u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
}
TEST_F(TouchAssociationFromPrefTest,
AssociatingDeviceToNewDisplayAfterAssociation) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
// Reassociate display with id 4 to touch device with id 3. This will
// bring the display to the top of the priority list. This should work even
// though the association of devices and displays is already complete.
touch_device_manager()->AddTouchCalibrationData(
TouchDeviceIdentifier::FromDevice(devices_[0]), displays_[2].id(),
TouchCalibrationData());
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 2u);
EXPECT_TRUE(AreAssociated(displays_[2], devices_[0]));
EXPECT_TRUE(AreAssociated(displays_[2], devices_[2]));
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 1u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
}
TEST_F(TouchAssociationFromPrefTest, InternalDisplayIsNotMatched) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[0].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 1u);
EXPECT_TRUE(AreAssociated(displays_[2], devices_[2]));
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 1u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
}
class TouchAssociationWithDuplicateDeviceTest : public TouchAssociationTest {
public:
TouchAssociationWithDuplicateDeviceTest() {}
~TouchAssociationWithDuplicateDeviceTest() override {}
void SetUp() override {
TouchAssociationTest::SetUp();
TouchDeviceManager::TouchAssociationMap touch_associations;
TouchDeviceManager::PortAssociationMap port_associations;
// Create different ports.
const std::vector<std::string> ports = {"port 0", "port 1", "port 2",
"port 3", "port 4"};
std::string device_name_1 = "device 1";
std::string device_name_2 = "device 2";
// Create a device with name |device_name_1| connected to |ports[0]|.
devices_.push_back(CreateTouchscreenDevice(
1, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1920, 1080)));
devices_.back().name = device_name_1;
devices_.back().phys = ports[0];
int vendor_id = devices_.back().vendor_id;
int product_id = devices_.back().product_id;
devices_.push_back(CreateTouchscreenDevice(
2, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1920, 1080)));
// Create another device with the same name but different port. Ensure that
// the touch device idnetifier is the same by setting the same vendor id,
// product id and name.
devices_.back().name = device_name_1;
devices_.back().phys = ports[1];
devices_.back().vendor_id = vendor_id;
devices_.back().product_id = product_id;
devices_.push_back(CreateTouchscreenDevice(
3, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(1920, 1080)));
devices_.back().name = device_name_1;
devices_.back().phys = ports[2];
devices_.back().vendor_id = vendor_id;
devices_.back().product_id = product_id;
devices_.push_back(CreateTouchscreenDevice(
4, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(800, 600)));
devices_.push_back(CreateTouchscreenDevice(
5, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(4096, 4096)));
devices_.back().name = device_name_2;
devices_.back().phys = ports[3];
vendor_id = devices_.back().vendor_id;
product_id = devices_.back().product_id;
devices_.push_back(CreateTouchscreenDevice(
6, ui::InputDeviceType::INPUT_DEVICE_USB, gfx::Size(4096, 4096)));
devices_.back().name = device_name_2;
devices_.back().phys = ports[4];
devices_.back().vendor_id = vendor_id;
devices_.back().product_id = product_id;
// Create priority list for Device Id = 1
// - Display Index 0
// - Display Index 2
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[0])] =
TouchDeviceManager::AssociationInfoMap();
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[0])]
[displays_[0].id()] = CreateTouchAssociationInfo(1);
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[0])]
[displays_[2].id()] = CreateTouchAssociationInfo(2);
// Create priority list for Device Id = 2
// - Display Index 3
// - Display Index 1
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[1])] =
TouchDeviceManager::AssociationInfoMap();
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[1])]
[displays_[3].id()] = CreateTouchAssociationInfo(1);
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[1])]
[displays_[1].id()] = CreateTouchAssociationInfo(2);
// Craete priority list for Device Id = 3
// - Display Index 2
// - Display Index 3
// - Display Index 0
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[2])] =
TouchDeviceManager::AssociationInfoMap();
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[2])]
[displays_[2].id()] = CreateTouchAssociationInfo(1);
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[2])]
[displays_[3].id()] = CreateTouchAssociationInfo(2);
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[2])]
[displays_[0].id()] = CreateTouchAssociationInfo(3);
// Craete priority list for Device Id = 5
// - Display Index 3
// - Display Index 2
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[4])] =
TouchDeviceManager::AssociationInfoMap();
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[4])]
[displays_[3].id()] = CreateTouchAssociationInfo(1);
touch_associations[TouchDeviceIdentifier::FromDevice(devices_[4])]
[displays_[2].id()] = CreateTouchAssociationInfo(2);
// Map ports:
// - { Touch Device 1, ports[0] } -> Display Index 2
// - { Touch Device 2, ports[1] } -> Display Index 3
// - { Touch Device 3, ports[2] } -> Display Index 2
// - { Touch Device 5, ports[4] } -> Display Index 0
port_associations[TouchDeviceIdentifier::FromDevice(devices_[0])] =
displays_[2].id();
port_associations[TouchDeviceIdentifier::FromDevice(devices_[1])] =
displays_[3].id();
port_associations[TouchDeviceIdentifier::FromDevice(devices_[2])] =
displays_[2].id();
port_associations[TouchDeviceIdentifier::FromDevice(devices_[4])] =
displays_[0].id();
touch_device_manager_->RegisterTouchAssociations(touch_associations,
port_associations);
}
void TearDown() override {
TouchAssociationTest::TearDown();
devices_.clear();
}
protected:
std::vector<ui::TouchscreenDevice> devices_;
private:
DISALLOW_COPY_AND_ASSIGN(TouchAssociationWithDuplicateDeviceTest);
};
TEST_F(TouchAssociationWithDuplicateDeviceTest, CorrectMapping) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices_[4]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 2u);
EXPECT_TRUE(AreAssociated(displays_[2], devices_[0]));
EXPECT_TRUE(AreAssociated(displays_[2], devices_[2]));
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 2u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[5]));
}
TEST_F(TouchAssociationWithDuplicateDeviceTest, NoDuplicateIds) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
std::vector<ui::TouchscreenDevice> devices;
devices.push_back(devices_[1]);
devices.push_back(devices_[3]);
devices.push_back(devices_[4]);
touch_device_manager()->AssociateTouchscreens(&displays_, devices);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 0u);
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 1u);
EXPECT_TRUE(AreAssociated(displays_[2], devices_[1]));
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 1u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[4]));
}
TEST_F(TouchAssociationWithDuplicateDeviceTest, CorrectMappingWithSomeMissing) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
DisplayInfoList displays;
displays.push_back(displays_[0]);
displays.push_back(displays_[1]);
displays.push_back(displays_[3]);
touch_device_manager()->AssociateTouchscreens(&displays, devices_);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices_[4]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 4u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[0]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[2]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[5]));
}
TEST_F(TouchAssociationWithDuplicateDeviceTest, UpdatePortBeforeAssociation) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
// Reassociate display at index 3 to touch device at index 2. This will
// bring the display to the top of the priority list and map the port the
// device is connected to, to display 3.
touch_device_manager()->AddTouchCalibrationData(
TouchDeviceIdentifier::FromDevice(devices_[2]), displays_[3].id(),
TouchCalibrationData());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices_[4]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 1u);
EXPECT_TRUE(AreAssociated(displays_[2], devices_[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 3u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[2]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[5]));
}
TEST_F(TouchAssociationWithDuplicateDeviceTest, ChangeAssociation) {
test::ScopedSetInternalDisplayId set_internal(display_manager(),
displays_[1].id());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
// Reassociate display at index 3 to touch device at index 2. This will
// bring the display to the top of the priority list and map the port the
// device is connected to, to display 3.
touch_device_manager()->AddTouchCalibrationData(
TouchDeviceIdentifier::FromDevice(devices_[2]), displays_[3].id(),
TouchCalibrationData());
touch_device_manager()->AssociateTouchscreens(&displays_, devices_);
EXPECT_EQ(GetTouchDeviceCount(displays_[0]), 1u);
EXPECT_TRUE(AreAssociated(displays_[0], devices_[4]));
EXPECT_EQ(GetTouchDeviceCount(displays_[1]), 1u);
EXPECT_TRUE(AreAssociated(displays_[1], devices_[3]));
EXPECT_EQ(GetTouchDeviceCount(displays_[2]), 1u);
EXPECT_TRUE(AreAssociated(displays_[2], devices_[0]));
EXPECT_EQ(GetTouchDeviceCount(displays_[3]), 3u);
EXPECT_TRUE(AreAssociated(displays_[3], devices_[1]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[2]));
EXPECT_TRUE(AreAssociated(displays_[3], devices_[5]));
}
} // namespace display