diff options
author | robert.bradford <robert.bradford@intel.com> | 2015-07-23 06:19:31 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-23 13:20:25 +0000 |
commit | 45f6aafff111f9b3553cca4d66caeb8a99d030cd (patch) | |
tree | 3ced9faeafda4c3138d922e7bc025e2bcdd3b10c /ash | |
parent | 4f3924256b450f95093d7f64f9913fbbb35ef395 (diff) | |
download | chromium_src-45f6aafff111f9b3553cca4d66caeb8a99d030cd.zip chromium_src-45f6aafff111f9b3553cca4d66caeb8a99d030cd.tar.gz chromium_src-45f6aafff111f9b3553cca4d66caeb8a99d030cd.tar.bz2 |
ash: Support multiple touch input devices per display
On devices that have an on-screen stylus this stylus appears like a touchscreen
and should generate touch events. As such it is necessary to be able to setup
multiple touch transformations to support both the conventional touchscreen and
the stylus device.
TEST=New tests added to ash_unittests for AssociateTouchscreens.
BUG=448467
Review URL: https://codereview.chromium.org/1237283003
Cr-Commit-Position: refs/heads/master@{#340080}
Diffstat (limited to 'ash')
-rw-r--r-- | ash/display/display_info.cc | 37 | ||||
-rw-r--r-- | ash/display/display_info.h | 15 | ||||
-rw-r--r-- | ash/display/display_info_unittest.cc | 20 | ||||
-rw-r--r-- | ash/touch/touch_transformer_controller.cc | 20 | ||||
-rw-r--r-- | ash/touch/touch_transformer_controller_unittest.cc | 18 | ||||
-rw-r--r-- | ash/touch/touchscreen_util.cc | 45 | ||||
-rw-r--r-- | ash/touch/touchscreen_util_unittest.cc | 89 |
7 files changed, 161 insertions, 83 deletions
diff --git a/ash/display/display_info.cc b/ash/display/display_info.cc index fa4019c..9c26281 100644 --- a/ash/display/display_info.cc +++ b/ash/display/display_info.cc @@ -239,7 +239,6 @@ DisplayInfo::DisplayInfo() : id_(gfx::Display::kInvalidDisplayID), has_overscan_(false), touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), - touch_device_id_(0), device_scale_factor_(1.0f), overscan_insets_in_dip_(0, 0, 0, 0), configured_ui_scale_(1.0f), @@ -256,7 +255,6 @@ DisplayInfo::DisplayInfo(int64 id, name_(name), has_overscan_(has_overscan), touch_support_(gfx::Display::TOUCH_SUPPORT_UNKNOWN), - touch_device_id_(0), device_scale_factor_(1.0f), overscan_insets_in_dip_(0, 0, 0, 0), configured_ui_scale_(1.0f), @@ -292,7 +290,7 @@ void DisplayInfo::Copy(const DisplayInfo& native_info) { has_overscan_ = native_info.has_overscan_; touch_support_ = native_info.touch_support_; - touch_device_id_ = native_info.touch_device_id_; + input_devices_ = native_info.input_devices_; device_scale_factor_ = native_info.device_scale_factor_; DCHECK(!native_info.bounds_in_native_.IsEmpty()); bounds_in_native_ = native_info.bounds_in_native_; @@ -385,23 +383,30 @@ gfx::Size DisplayInfo::GetNativeModeSize() const { std::string DisplayInfo::ToString() const { int rotation_degree = static_cast<int>(GetActiveRotation()) * 90; - return base::StringPrintf( + std::string devices_str; + + for (size_t i = 0; i < input_devices_.size(); ++i) { + devices_str += base::IntToString(input_devices_[i]); + if (i != input_devices_.size() - 1) + devices_str += ", "; + } + + std::string result = base::StringPrintf( "DisplayInfo[%lld] native bounds=%s, size=%s, scale=%f, " "overscan=%s, rotation=%d, ui-scale=%f, touchscreen=%s, " - "touch-device-id=%d", - static_cast<long long int>(id_), - bounds_in_native_.ToString().c_str(), - size_in_pixel_.ToString().c_str(), - device_scale_factor_, - overscan_insets_in_dip_.ToString().c_str(), - rotation_degree, + "input_devices=[%s]", + static_cast<long long int>(id_), bounds_in_native_.ToString().c_str(), + size_in_pixel_.ToString().c_str(), device_scale_factor_, + overscan_insets_in_dip_.ToString().c_str(), rotation_degree, configured_ui_scale_, touch_support_ == gfx::Display::TOUCH_SUPPORT_AVAILABLE ? "yes" : touch_support_ == gfx::Display::TOUCH_SUPPORT_UNAVAILABLE ? "no" : "unknown", - touch_device_id_); + devices_str.c_str()); + + return result; } std::string DisplayInfo::ToFullString() const { @@ -437,4 +442,12 @@ bool DisplayInfo::Use125DSFForUIScaling() const { return use_125_dsf_for_ui_scaling && IsInternalDisplayId(id_); } +void DisplayInfo::AddInputDevice(int id) { + input_devices_.push_back(id); +} + +void DisplayInfo::ClearInputDevices() { + input_devices_.clear(); +} + } // namespace ash diff --git a/ash/display/display_info.h b/ash/display/display_info.h index f6805d7..f72c596 100644 --- a/ash/display/display_info.h +++ b/ash/display/display_info.h @@ -109,8 +109,14 @@ class ASH_EXPORT DisplayInfo { } gfx::Display::TouchSupport touch_support() const { return touch_support_; } - void set_touch_device_id(int id) { touch_device_id_ = id; } - int touch_device_id() const { return touch_device_id_; } + // Associate the input device with identifier |id| with this display. + void AddInputDevice(int id); + + // Clear the list of input devices associated with this display. + void ClearInputDevices(); + + // The input device ids that are associated with this display. + std::vector<int> input_devices() const { return input_devices_; } // Gets/Sets the device scale factor of the display. float device_scale_factor() const { return device_scale_factor_; } @@ -243,9 +249,8 @@ class ASH_EXPORT DisplayInfo { std::map<gfx::Display::RotationSource, gfx::Display::Rotation> rotations_; gfx::Display::TouchSupport touch_support_; - // If the display is also a touch device, it will have a positive - // |touch_device_id_|. Otherwise |touch_device_id_| is 0. - int touch_device_id_; + // The set of input devices associated with this display. + std::vector<int> input_devices_; // This specifies the device's pixel density. (For example, a // display whose DPI is higher than the threshold is considered to have diff --git a/ash/display/display_info_unittest.cc b/ash/display/display_info_unittest.cc index 7f29d04..9dc2556 100644 --- a/ash/display/display_info_unittest.cc +++ b/ash/display/display_info_unittest.cc @@ -125,4 +125,24 @@ TEST_F(DisplayInfoTest, DisplayModeGetSizeForExternal4K) { EXPECT_EQ("3840x2160", GetModeSizeInDIP(size, 1.0f, 1.0f, false)); } +TEST_F(DisplayInfoTest, InputDevicesTest) { + DisplayInfo info = DisplayInfo::CreateFromSpecWithID("200x100", 10); + + EXPECT_EQ(0u, info.input_devices().size()); + + info.AddInputDevice(10); + EXPECT_EQ(1u, info.input_devices().size()); + EXPECT_EQ(10, info.input_devices()[0]); + info.AddInputDevice(11); + EXPECT_EQ(2u, info.input_devices().size()); + EXPECT_EQ(10, info.input_devices()[0]); + EXPECT_EQ(11, info.input_devices()[1]); + + DisplayInfo copy_info = DisplayInfo::CreateFromSpecWithID("200x100", 10); + copy_info.Copy(info); + EXPECT_EQ(2u, copy_info.input_devices().size()); + copy_info.ClearInputDevices(); + EXPECT_EQ(0u, copy_info.input_devices().size()); +} + } // namespace ash diff --git a/ash/touch/touch_transformer_controller.cc b/ash/touch/touch_transformer_controller.cc index 5f2f0fe..bc4cd64 100644 --- a/ash/touch/touch_transformer_controller.cc +++ b/ash/touch/touch_transformer_controller.cc @@ -127,10 +127,11 @@ TouchTransformerController::~TouchTransformerController() { void TouchTransformerController::UpdateTouchRadius( const DisplayInfo& display) const { ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); - device_manager->UpdateTouchRadiusScale( - display.touch_device_id(), - GetTouchResolutionScale(display, - FindTouchscreenById(display.touch_device_id()))); + for (const auto& device_id : display.input_devices()) { + device_manager->UpdateTouchRadiusScale( + device_id, + GetTouchResolutionScale(display, FindTouchscreenById(device_id))); + } } void TouchTransformerController::UpdateTouchTransform( @@ -140,11 +141,12 @@ void TouchTransformerController::UpdateTouchTransform( ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); gfx::Size fb_size = Shell::GetInstance()->display_configurator()->framebuffer_size(); - device_manager->UpdateTouchInfoForDisplay( - target_display_id, touch_display.touch_device_id(), - GetTouchTransform(target_display, touch_display, - FindTouchscreenById(touch_display.touch_device_id()), - fb_size)); + for (const auto& device_id : touch_display.input_devices()) { + device_manager->UpdateTouchInfoForDisplay( + target_display_id, device_id, + GetTouchTransform(target_display, touch_display, + FindTouchscreenById(device_id), fb_size)); + } } void TouchTransformerController::UpdateTouchTransformer() const { diff --git a/ash/touch/touch_transformer_controller_unittest.cc b/ash/touch/touch_transformer_controller_unittest.cc index 8c4eac4..6ae0bd4 100644 --- a/ash/touch/touch_transformer_controller_unittest.cc +++ b/ash/touch/touch_transformer_controller_unittest.cc @@ -19,7 +19,7 @@ DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) { DisplayInfo info(id, std::string(), false); info.SetBounds(bounds); - info.set_touch_device_id(touch_device_id); + info.AddInputDevice(touch_device_id); // Create a default mode. std::vector<DisplayMode> default_modes( @@ -70,13 +70,13 @@ TEST_F(TouchTransformerControllerTest, MirrorModeLetterboxing) { ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); device_manager->UpdateTouchInfoForDisplay( - internal_display_info.id(), internal_display_info.touch_device_id(), + internal_display_info.id(), internal_touchscreen.id, tt_controller->GetTouchTransform(internal_display_info, internal_display_info, internal_touchscreen, fb_size)); device_manager->UpdateTouchInfoForDisplay( - internal_display_info.id(), external_display_info.touch_device_id(), + internal_display_info.id(), external_touchscreen.id, tt_controller->GetTouchTransform(external_display_info, external_display_info, external_touchscreen, fb_size)); @@ -141,13 +141,13 @@ TEST_F(TouchTransformerControllerTest, MirrorModePillarboxing) { ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); device_manager->UpdateTouchInfoForDisplay( - internal_display_info.id(), internal_display_info.touch_device_id(), + internal_display_info.id(), internal_touchscreen.id, tt_controller->GetTouchTransform(internal_display_info, internal_display_info, internal_touchscreen, fb_size)); device_manager->UpdateTouchInfoForDisplay( - internal_display_info.id(), external_display_info.touch_device_id(), + internal_display_info.id(), external_touchscreen.id, tt_controller->GetTouchTransform(external_display_info, external_display_info, external_touchscreen, fb_size)); @@ -215,12 +215,12 @@ TEST_F(TouchTransformerControllerTest, SoftwareMirrorMode) { ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); device_manager->UpdateTouchInfoForDisplay( - display1_info.id(), display1_info.touch_device_id(), + display1_info.id(), display1_touchscreen.id, tt_controller->GetTouchTransform(display1_info, display1_info, display1_touchscreen, fb_size)); device_manager->UpdateTouchInfoForDisplay( - display1_info.id(), display2_info.touch_device_id(), + display1_info.id(), display2_touchscreen.id, tt_controller->GetTouchTransform(display1_info, display2_info, display2_touchscreen, fb_size)); @@ -285,12 +285,12 @@ TEST_F(TouchTransformerControllerTest, ExtendedMode) { ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); device_manager->UpdateTouchInfoForDisplay( - display1.id(), display1.touch_device_id(), + display1.id(), touchscreen1.id, tt_controller->GetTouchTransform(display1, display1, touchscreen1, fb_size)); device_manager->UpdateTouchInfoForDisplay( - display2.id(), display2.touch_device_id(), + display2.id(), touchscreen2.id, tt_controller->GetTouchTransform(display2, display2, touchscreen2, fb_size)); diff --git a/ash/touch/touchscreen_util.cc b/ash/touch/touchscreen_util.cc index e68644d..92a12e5 100644 --- a/ash/touch/touchscreen_util.cc +++ b/ash/touch/touchscreen_util.cc @@ -13,42 +13,35 @@ namespace ash { void AssociateTouchscreens(std::vector<DisplayInfo>* displays, const std::vector<ui::TouchscreenDevice>& devices) { - std::set<int> no_match_touchscreen; - int internal_touchscreen = -1; - for (size_t i = 0; i < devices.size(); ++i) { - if (devices[i].type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL) { - internal_touchscreen = i; - break; - } - } - DisplayInfo* internal_state = NULL; for (size_t i = 0; i < displays->size(); ++i) { DisplayInfo* state = &(*displays)[i]; if (state->id() == gfx::Display::InternalDisplayId() && !state->GetNativeModeSize().IsEmpty() && state->touch_support() == gfx::Display::TOUCH_SUPPORT_UNKNOWN) { + DCHECK(!internal_state); internal_state = state; - break; } + state->ClearInputDevices(); } - if (internal_state && internal_touchscreen >= 0) { - internal_state->set_touch_device_id(devices[internal_touchscreen].id); - internal_state->set_touch_support(gfx::Display::TOUCH_SUPPORT_AVAILABLE); - VLOG(2) << "Found internal touchscreen for internal display " - << internal_state->id() << " touch_device_id " - << internal_state->touch_device_id() << " size " - << devices[internal_touchscreen].size.ToString(); - } - + std::set<int> no_match_touchscreen; for (size_t i = 0; i < devices.size(); ++i) { - if (internal_state && internal_state->touch_device_id() == devices[i].id) + if (devices[i].type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL) { + VLOG(2) << "Found internal device for display " << internal_state->id() + << " with device id " << devices[i].id << " size " + << devices[i].size.ToString(); + internal_state->AddInputDevice(devices[i].id); + internal_state->set_touch_support(gfx::Display::TOUCH_SUPPORT_AVAILABLE); continue; + } bool found_mapping = false; for (size_t j = 0; j < displays->size(); ++j) { DisplayInfo* state = &(*displays)[j]; + if (state == internal_state) + continue; + const gfx::Size native_size = state->GetNativeModeSize(); if (state->touch_support() == gfx::Display::TOUCH_SUPPORT_AVAILABLE || native_size.IsEmpty()) @@ -61,11 +54,11 @@ void AssociateTouchscreens(std::vector<DisplayInfo>* displays, // configuration. if (std::abs(native_size.width() - devices[i].size.width()) <= 1 && std::abs(native_size.height() - devices[i].size.height()) <= 1) { - state->set_touch_device_id(devices[i].id); + state->AddInputDevice(devices[i].id); state->set_touch_support(gfx::Display::TOUCH_SUPPORT_AVAILABLE); VLOG(2) << "Found touchscreen for display " << state->id() - << " touch_device_id " << state->touch_device_id() << " size " + << " with device id " << devices[i].id << " size " << devices[i].size.ToString(); found_mapping = true; break; @@ -74,7 +67,7 @@ void AssociateTouchscreens(std::vector<DisplayInfo>* displays, if (!found_mapping) { no_match_touchscreen.insert(devices[i].id); - VLOG(2) << "No matching display for touch_device_id " << devices[i].id + VLOG(2) << "No matching display for device id " << devices[i].id << " size " << devices[i].size.ToString(); } } @@ -91,10 +84,10 @@ void AssociateTouchscreens(std::vector<DisplayInfo>* displays, if (state->id() != gfx::Display::InternalDisplayId() && !state->GetNativeModeSize().IsEmpty() && state->touch_support() == gfx::Display::TOUCH_SUPPORT_UNKNOWN) { - state->set_touch_device_id(*it); + state->AddInputDevice(*it); state->set_touch_support(gfx::Display::TOUCH_SUPPORT_AVAILABLE); - VLOG(2) << "Arbitrarily matching touchscreen " - << state->touch_device_id() << " to display " << state->id(); + VLOG(2) << "Arbitrarily matching touchscreen " << *it << " to display " + << state->id(); break; } } diff --git a/ash/touch/touchscreen_util_unittest.cc b/ash/touch/touchscreen_util_unittest.cc index ce14702..e5bb0b8 100644 --- a/ash/touch/touchscreen_util_unittest.cc +++ b/ash/touch/touchscreen_util_unittest.cc @@ -70,8 +70,7 @@ TEST_F(TouchscreenUtilTest, NoTouchscreens) { AssociateTouchscreens(&displays_, devices); for (size_t i = 0; i < displays_.size(); ++i) - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, - displays_[i].touch_device_id()); + EXPECT_EQ(0u, displays_[i].input_devices().size()); } TEST_F(TouchscreenUtilTest, OneToOneMapping) { @@ -85,10 +84,12 @@ TEST_F(TouchscreenUtilTest, OneToOneMapping) { AssociateTouchscreens(&displays_, devices); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[0].touch_device_id()); - EXPECT_EQ(1, displays_[1].touch_device_id()); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id()); - EXPECT_EQ(2, displays_[3].touch_device_id()); + EXPECT_EQ(0u, displays_[0].input_devices().size()); + EXPECT_EQ(1u, displays_[1].input_devices().size()); + EXPECT_EQ(1, displays_[1].input_devices()[0]); + EXPECT_EQ(0u, displays_[2].input_devices().size()); + EXPECT_EQ(1u, displays_[3].input_devices().size()); + EXPECT_EQ(2, displays_[3].input_devices()[0]); } TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) { @@ -99,10 +100,11 @@ TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) { AssociateTouchscreens(&displays_, devices); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[0].touch_device_id()); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[1].touch_device_id()); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id()); - EXPECT_EQ(2, displays_[3].touch_device_id()); + EXPECT_EQ(0u, displays_[0].input_devices().size()); + EXPECT_EQ(0u, displays_[1].input_devices().size()); + EXPECT_EQ(0u, displays_[2].input_devices().size()); + EXPECT_EQ(1u, displays_[3].input_devices().size()); + EXPECT_EQ(2, displays_[3].input_devices()[0]); } TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) { @@ -116,10 +118,12 @@ TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) { AssociateTouchscreens(&displays_, devices); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[0].touch_device_id()); - EXPECT_EQ(1, displays_[1].touch_device_id()); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id()); - EXPECT_EQ(2, displays_[3].touch_device_id()); + EXPECT_EQ(0u, displays_[0].input_devices().size()); + EXPECT_EQ(1u, displays_[1].input_devices().size()); + EXPECT_EQ(1, displays_[1].input_devices()[0]); + EXPECT_EQ(0u, displays_[2].input_devices().size()); + EXPECT_EQ(1u, displays_[3].input_devices().size()); + EXPECT_EQ(2, displays_[3].input_devices()[0]); } TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) { @@ -133,10 +137,12 @@ TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) { AssociateTouchscreens(&displays_, devices); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[0].touch_device_id()); - EXPECT_EQ(1, displays_[1].touch_device_id()); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id()); - EXPECT_EQ(2, displays_[3].touch_device_id()); + EXPECT_EQ(0u, displays_[0].input_devices().size()); + EXPECT_EQ(1u, displays_[1].input_devices().size()); + EXPECT_EQ(1, displays_[1].input_devices()[0]); + EXPECT_EQ(0u, displays_[2].input_devices().size()); + EXPECT_EQ(1u, displays_[3].input_devices().size()); + EXPECT_EQ(2, displays_[3].input_devices()[0]); } TEST_F(TouchscreenUtilTest, MapInternalTouchscreen) { @@ -151,10 +157,49 @@ TEST_F(TouchscreenUtilTest, MapInternalTouchscreen) { AssociateTouchscreens(&displays_, devices); // Internal touchscreen is always mapped to internal display. - EXPECT_EQ(2, displays_[0].touch_device_id()); - EXPECT_EQ(1, displays_[1].touch_device_id()); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[2].touch_device_id()); - EXPECT_EQ(ui::TouchscreenDevice::kInvalidId, displays_[3].touch_device_id()); + EXPECT_EQ(1u, displays_[0].input_devices().size()); + EXPECT_EQ(2, displays_[0].input_devices()[0]); + EXPECT_EQ(1u, displays_[1].input_devices().size()); + EXPECT_EQ(1, displays_[1].input_devices()[0]); + EXPECT_EQ(0u, displays_[2].input_devices().size()); + EXPECT_EQ(0u, displays_[3].input_devices().size()); +} + +TEST_F(TouchscreenUtilTest, MultipleInternal) { + std::vector<ui::TouchscreenDevice> devices; + devices.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "", + gfx::Size(1920, 1080), 0)); + devices.push_back( + ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "", + gfx::Size(1920, 1080), 0)); + + AssociateTouchscreens(&displays_, devices); + + EXPECT_EQ(2u, displays_[0].input_devices().size()); + EXPECT_EQ(0u, displays_[1].input_devices().size()); + EXPECT_EQ(0u, displays_[2].input_devices().size()); + EXPECT_EQ(0u, displays_[3].input_devices().size()); +} + +TEST_F(TouchscreenUtilTest, MultipleInternalAndExternal) { + std::vector<ui::TouchscreenDevice> devices; + devices.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "", + gfx::Size(1920, 1080), 0)); + devices.push_back( + ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "", + gfx::Size(1920, 1080), 0)); + devices.push_back( + ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", + gfx::Size(1024, 768), 0)); + + AssociateTouchscreens(&displays_, devices); + + EXPECT_EQ(2u, displays_[0].input_devices().size()); + EXPECT_EQ(0u, displays_[1].input_devices().size()); + EXPECT_EQ(0u, displays_[2].input_devices().size()); + EXPECT_EQ(1u, displays_[3].input_devices().size()); } } // namespace ash |