| Harry Cutts | 3952c83 | 2023-08-22 15:26:56 +0000 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2023 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 | #include <gestures/HardwareProperties.h> | 
|  | 17 |  | 
|  | 18 | #include <memory> | 
|  | 19 | #include <set> | 
|  | 20 |  | 
|  | 21 | #include <gtest/gtest.h> | 
|  | 22 | #include <linux/input-event-codes.h> | 
|  | 23 |  | 
|  | 24 | #include "EventHub.h" | 
|  | 25 | #include "InputDevice.h" | 
|  | 26 | #include "InterfaceMocks.h" | 
|  | 27 | #include "TestConstants.h" | 
|  | 28 | #include "include/gestures.h" | 
|  | 29 |  | 
|  | 30 | namespace android { | 
|  | 31 |  | 
|  | 32 | using testing::Return; | 
|  | 33 |  | 
|  | 34 | class HardwarePropertiesTest : public testing::Test { | 
|  | 35 | public: | 
|  | 36 | HardwarePropertiesTest() { | 
|  | 37 | EXPECT_CALL(mMockInputReaderContext, getEventHub()).WillRepeatedly(Return(&mMockEventHub)); | 
|  | 38 | InputDeviceIdentifier identifier; | 
|  | 39 | identifier.name = "device"; | 
|  | 40 | identifier.location = "USB1"; | 
|  | 41 | mDevice = std::make_unique<InputDevice>(&mMockInputReaderContext, DEVICE_ID, | 
|  | 42 | /*generation=*/2, identifier); | 
|  | 43 | mDeviceContext = std::make_unique<InputDeviceContext>(*mDevice, EVENTHUB_ID); | 
|  | 44 | } | 
|  | 45 |  | 
|  | 46 | protected: | 
|  | 47 | static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000; | 
|  | 48 | static constexpr int32_t EVENTHUB_ID = 1; | 
|  | 49 |  | 
|  | 50 | void setupValidAxis(int axis, int32_t min, int32_t max, int32_t resolution) { | 
|  | 51 | EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis, testing::_)) | 
|  | 52 | .WillRepeatedly([=](int32_t, int32_t, RawAbsoluteAxisInfo* outAxisInfo) { | 
|  | 53 | outAxisInfo->valid = true; | 
|  | 54 | outAxisInfo->minValue = min; | 
|  | 55 | outAxisInfo->maxValue = max; | 
|  | 56 | outAxisInfo->flat = 0; | 
|  | 57 | outAxisInfo->fuzz = 0; | 
|  | 58 | outAxisInfo->resolution = resolution; | 
|  | 59 | return OK; | 
|  | 60 | }); | 
|  | 61 | } | 
|  | 62 |  | 
|  | 63 | void setupInvalidAxis(int axis) { | 
|  | 64 | EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis, testing::_)) | 
|  | 65 | .WillRepeatedly([=](int32_t, int32_t, RawAbsoluteAxisInfo* outAxisInfo) { | 
|  | 66 | outAxisInfo->valid = false; | 
|  | 67 | return -1; | 
|  | 68 | }); | 
|  | 69 | } | 
|  | 70 |  | 
|  | 71 | void setProperty(int property, bool value) { | 
|  | 72 | EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, property)) | 
|  | 73 | .WillRepeatedly(Return(value)); | 
|  | 74 | } | 
|  | 75 |  | 
|  | 76 | void setButtonsPresent(std::set<int> buttonCodes, bool present) { | 
|  | 77 | for (const auto& buttonCode : buttonCodes) { | 
|  | 78 | EXPECT_CALL(mMockEventHub, hasScanCode(EVENTHUB_ID, buttonCode)) | 
|  | 79 | .WillRepeatedly(Return(present)); | 
|  | 80 | } | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | MockEventHubInterface mMockEventHub; | 
|  | 84 | MockInputReaderContext mMockInputReaderContext; | 
|  | 85 | std::unique_ptr<InputDevice> mDevice; | 
|  | 86 | std::unique_ptr<InputDeviceContext> mDeviceContext; | 
|  | 87 | }; | 
|  | 88 |  | 
|  | 89 | TEST_F(HardwarePropertiesTest, FancyTouchpad) { | 
|  | 90 | setupValidAxis(ABS_MT_POSITION_X, 0, 2048, 27); | 
|  | 91 | setupValidAxis(ABS_MT_POSITION_Y, 0, 1500, 30); | 
|  | 92 | setupValidAxis(ABS_MT_ORIENTATION, -3, 4, 0); | 
|  | 93 | setupValidAxis(ABS_MT_SLOT, 0, 15, 0); | 
|  | 94 | setupValidAxis(ABS_MT_PRESSURE, 0, 256, 0); | 
|  | 95 |  | 
|  | 96 | setProperty(INPUT_PROP_SEMI_MT, false); | 
|  | 97 | setProperty(INPUT_PROP_BUTTONPAD, true); | 
|  | 98 |  | 
|  | 99 | setButtonsPresent({BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP, | 
|  | 100 | BTN_TOOL_QUINTTAP}, | 
|  | 101 | true); | 
|  | 102 |  | 
|  | 103 | HardwareProperties hwprops = createHardwareProperties(*mDeviceContext); | 
|  | 104 | EXPECT_NEAR(0, hwprops.left, EPSILON); | 
|  | 105 | EXPECT_NEAR(0, hwprops.top, EPSILON); | 
|  | 106 | EXPECT_NEAR(2048, hwprops.right, EPSILON); | 
|  | 107 | EXPECT_NEAR(1500, hwprops.bottom, EPSILON); | 
|  | 108 |  | 
|  | 109 | EXPECT_NEAR(27, hwprops.res_x, EPSILON); | 
|  | 110 | EXPECT_NEAR(30, hwprops.res_y, EPSILON); | 
|  | 111 |  | 
|  | 112 | EXPECT_NEAR(-3, hwprops.orientation_minimum, EPSILON); | 
|  | 113 | EXPECT_NEAR(4, hwprops.orientation_maximum, EPSILON); | 
|  | 114 |  | 
|  | 115 | EXPECT_EQ(16, hwprops.max_finger_cnt); | 
|  | 116 | EXPECT_EQ(5, hwprops.max_touch_cnt); | 
|  | 117 |  | 
|  | 118 | EXPECT_FALSE(hwprops.supports_t5r2); | 
|  | 119 | EXPECT_FALSE(hwprops.support_semi_mt); | 
|  | 120 | EXPECT_TRUE(hwprops.is_button_pad); | 
|  | 121 | EXPECT_FALSE(hwprops.has_wheel); | 
|  | 122 | EXPECT_FALSE(hwprops.wheel_is_hi_res); | 
|  | 123 | EXPECT_FALSE(hwprops.is_haptic_pad); | 
|  | 124 | EXPECT_TRUE(hwprops.reports_pressure); | 
|  | 125 | } | 
|  | 126 |  | 
|  | 127 | TEST_F(HardwarePropertiesTest, BasicTouchpad) { | 
|  | 128 | setupValidAxis(ABS_MT_POSITION_X, 0, 1024, 0); | 
|  | 129 | setupValidAxis(ABS_MT_POSITION_Y, 0, 768, 0); | 
|  | 130 | setupValidAxis(ABS_MT_SLOT, 0, 7, 0); | 
|  | 131 |  | 
|  | 132 | setupInvalidAxis(ABS_MT_ORIENTATION); | 
|  | 133 | setupInvalidAxis(ABS_MT_PRESSURE); | 
|  | 134 |  | 
|  | 135 | setProperty(INPUT_PROP_SEMI_MT, false); | 
|  | 136 | setProperty(INPUT_PROP_BUTTONPAD, false); | 
|  | 137 |  | 
|  | 138 | setButtonsPresent({BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP}, true); | 
|  | 139 | setButtonsPresent({BTN_TOOL_QUADTAP, BTN_TOOL_QUINTTAP}, false); | 
|  | 140 |  | 
|  | 141 | HardwareProperties hwprops = createHardwareProperties(*mDeviceContext); | 
|  | 142 | EXPECT_NEAR(0, hwprops.left, EPSILON); | 
|  | 143 | EXPECT_NEAR(0, hwprops.top, EPSILON); | 
|  | 144 | EXPECT_NEAR(1024, hwprops.right, EPSILON); | 
|  | 145 | EXPECT_NEAR(768, hwprops.bottom, EPSILON); | 
|  | 146 |  | 
|  | 147 | EXPECT_NEAR(0, hwprops.res_x, EPSILON); | 
|  | 148 | EXPECT_NEAR(0, hwprops.res_y, EPSILON); | 
|  | 149 |  | 
|  | 150 | EXPECT_NEAR(0, hwprops.orientation_minimum, EPSILON); | 
|  | 151 | EXPECT_NEAR(0, hwprops.orientation_maximum, EPSILON); | 
|  | 152 |  | 
|  | 153 | EXPECT_EQ(8, hwprops.max_finger_cnt); | 
|  | 154 | EXPECT_EQ(3, hwprops.max_touch_cnt); | 
|  | 155 |  | 
|  | 156 | EXPECT_FALSE(hwprops.supports_t5r2); | 
|  | 157 | EXPECT_FALSE(hwprops.support_semi_mt); | 
|  | 158 | EXPECT_FALSE(hwprops.is_button_pad); | 
|  | 159 | EXPECT_FALSE(hwprops.has_wheel); | 
|  | 160 | EXPECT_FALSE(hwprops.wheel_is_hi_res); | 
|  | 161 | EXPECT_FALSE(hwprops.is_haptic_pad); | 
|  | 162 | EXPECT_FALSE(hwprops.reports_pressure); | 
|  | 163 | } | 
|  | 164 |  | 
|  | 165 | } // namespace android |