| // Copyright 2019 The Fuchsia 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 <hid-parser/parser.h> |
| #include <hid-parser/usages.h> |
| #include <hid/paradise.h> |
| |
| #include <gtest/gtest.h> |
| #include <lib/fxl/time/time_point.h> |
| |
| #include "garnet/bin/ui/input_reader/touchscreen.h" |
| |
| namespace input { |
| |
| namespace { |
| |
| void ParseTouchpad(const uint8_t *desc, size_t desc_len, |
| mozart::Touchscreen *ts) { |
| hid::DeviceDescriptor *dev_desc = nullptr; |
| auto parse_res = hid::ParseReportDescriptor(desc, desc_len, &dev_desc); |
| ASSERT_EQ(hid::ParseResult::kParseOk, parse_res); |
| |
| auto count = dev_desc->rep_count; |
| ASSERT_LT(0UL, count); |
| |
| // Find the first input report. |
| const hid::ReportDescriptor *input_desc = nullptr; |
| for (size_t rep = 0; rep < count; rep++) { |
| const hid::ReportDescriptor *desc = &dev_desc->report[rep]; |
| if (desc->first_field[0].type == hid::kInput) { |
| input_desc = desc; |
| break; |
| } |
| } |
| ASSERT_NE(nullptr, input_desc); |
| ASSERT_LT(0UL, input_desc->count); |
| |
| auto success = ts->ParseTouchscreenDescriptor(input_desc); |
| ASSERT_EQ(true, success); |
| } |
| } // namespace |
| |
| // These unit tests exercise any touchpad report descriptors we've collected. |
| // Each test parses the report descriptor for the touchpad and then sends one |
| // report to ensure that it has been parsed correctly. |
| namespace test { |
| |
| TEST(TouchpadTest, ParadiseV1) { |
| mozart::Touchscreen ts; |
| size_t desc_size; |
| const uint8_t *paradise_touchpad_v1_report_desc = |
| get_paradise_touchpad_v1_report_desc(&desc_size); |
| |
| ParseTouchpad(paradise_touchpad_v1_report_desc, desc_size, &ts); |
| mozart::Touchscreen::Descriptor ts_desc; |
| EXPECT_TRUE(ts.SetDescriptor(&ts_desc)); |
| |
| EXPECT_EQ(5UL, ts.touch_points()); |
| EXPECT_EQ(mozart::Touchscreen::Capabilities::CONTACT_ID | |
| mozart::Touchscreen::Capabilities::CONTACT_COUNT | |
| mozart::Touchscreen::Capabilities::BUTTON | |
| mozart::Touchscreen::Capabilities::TIP_SWITCH | |
| mozart::Touchscreen::Capabilities::X | |
| mozart::Touchscreen::Capabilities::Y, |
| ts.capabilities()); |
| EXPECT_EQ(0, ts_desc.x_min); |
| EXPECT_EQ(1030000, ts_desc.x_max); |
| EXPECT_EQ(0, ts_desc.y_min); |
| EXPECT_EQ(680000, ts_desc.y_max); |
| |
| // Now use the parsed descriptor to interpret a touchpad report. |
| paradise_touchpad_v1_t touchpad_v1_report = {}; |
| touchpad_v1_report.report_id = 12; |
| touchpad_v1_report.fingers[1].tip_switch = 0x1; |
| touchpad_v1_report.fingers[1].id = 0x1; |
| touchpad_v1_report.fingers[1].x = 100; |
| touchpad_v1_report.fingers[1].y = 200; |
| |
| touchpad_v1_report.fingers[2].tip_switch = 0x1; |
| touchpad_v1_report.fingers[2].id = 0x2; |
| touchpad_v1_report.fingers[2].x = 300; |
| touchpad_v1_report.fingers[2].y = 400; |
| |
| uint8_t *report_data = reinterpret_cast<uint8_t *>(&touchpad_v1_report); |
| |
| mozart::Touchscreen::Report report; |
| auto success = |
| ts.ParseReport(report_data, sizeof(touchpad_v1_report), &report); |
| EXPECT_EQ(true, success); |
| |
| EXPECT_EQ(2UL, report.contact_count); |
| |
| // The X and Y values below have been manually calculated based on the above |
| // input and the logical/physical conversion given by the report descriptor. |
| EXPECT_EQ(1U, report.contacts[0].id); |
| EXPECT_EQ(7812, report.contacts[0].x); |
| EXPECT_EQ(15625, report.contacts[0].y); |
| |
| EXPECT_EQ(2U, report.contacts[1].id); |
| EXPECT_EQ(23437, report.contacts[1].x); |
| EXPECT_EQ(31250, report.contacts[1].y); |
| } |
| |
| TEST(TouchpadTest, ParadiseV2) { |
| mozart::Touchscreen ts; |
| size_t desc_size; |
| const uint8_t *paradise_touchpad_v2_report_desc = |
| get_paradise_touchpad_v2_report_desc(&desc_size); |
| |
| ParseTouchpad(paradise_touchpad_v2_report_desc, desc_size, &ts); |
| mozart::Touchscreen::Descriptor ts_desc; |
| EXPECT_TRUE(ts.SetDescriptor(&ts_desc)); |
| |
| EXPECT_EQ(5UL, ts.touch_points()); |
| EXPECT_EQ(mozart::Touchscreen::Capabilities::CONTACT_ID | |
| mozart::Touchscreen::Capabilities::CONTACT_COUNT | |
| mozart::Touchscreen::Capabilities::BUTTON | |
| mozart::Touchscreen::Capabilities::TIP_SWITCH | |
| mozart::Touchscreen::Capabilities::X | |
| mozart::Touchscreen::Capabilities::Y, |
| ts.capabilities()); |
| EXPECT_EQ(0, ts_desc.x_min); |
| EXPECT_EQ(1030000, ts_desc.x_max); |
| EXPECT_EQ(0, ts_desc.y_min); |
| EXPECT_EQ(680000, ts_desc.y_max); |
| |
| // Now use the parsed descriptor to interpret a touchpad report. |
| paradise_touchpad_v2_t touchpad_v2_report = {}; |
| touchpad_v2_report.report_id = 12; |
| touchpad_v2_report.fingers[1].tip_switch = 0x1; |
| touchpad_v2_report.fingers[1].id = 0x1; |
| touchpad_v2_report.fingers[1].x = 100; |
| touchpad_v2_report.fingers[1].y = 200; |
| |
| touchpad_v2_report.fingers[2].tip_switch = 0x1; |
| touchpad_v2_report.fingers[2].id = 0x2; |
| touchpad_v2_report.fingers[2].x = 300; |
| touchpad_v2_report.fingers[2].y = 400; |
| |
| uint8_t *report_data = reinterpret_cast<uint8_t *>(&touchpad_v2_report); |
| |
| mozart::Touchscreen::Report report; |
| auto success = |
| ts.ParseReport(report_data, sizeof(touchpad_v2_report), &report); |
| EXPECT_EQ(true, success); |
| |
| EXPECT_EQ(2UL, report.contact_count); |
| |
| // The X and Y values below have been manually calculated based on the above |
| // input and the logical/physical conversion given by the report descriptor. |
| EXPECT_EQ(1U, report.contacts[0].id); |
| EXPECT_EQ(7812, report.contacts[0].x); |
| EXPECT_EQ(15625, report.contacts[0].y); |
| |
| EXPECT_EQ(2U, report.contacts[1].id); |
| EXPECT_EQ(23437, report.contacts[1].x); |
| EXPECT_EQ(31250, report.contacts[1].y); |
| } |
| |
| } // namespace test |
| } // namespace input |