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 17 #include "HardwareProperties.h" 18 19 #include <optional> 20 21 namespace android { 22 23 namespace { 24 getMaxTouchCount(const InputDeviceContext & context)25unsigned short getMaxTouchCount(const InputDeviceContext& context) { 26 if (context.hasScanCode(BTN_TOOL_QUINTTAP)) return 5; 27 if (context.hasScanCode(BTN_TOOL_QUADTAP)) return 4; 28 if (context.hasScanCode(BTN_TOOL_TRIPLETAP)) return 3; 29 if (context.hasScanCode(BTN_TOOL_DOUBLETAP)) return 2; 30 if (context.hasScanCode(BTN_TOOL_FINGER)) return 1; 31 return 0; 32 } 33 34 } // namespace 35 createHardwareProperties(const InputDeviceContext & context)36HardwareProperties createHardwareProperties(const InputDeviceContext& context) { 37 HardwareProperties props; 38 // We can safely assume that ABS_MT_POSITION_X and _Y axes will be available, as EventHub won't 39 // classify a device as a touchpad if they're not present. 40 RawAbsoluteAxisInfo absMtPositionX = context.getAbsoluteAxisInfo(ABS_MT_POSITION_X).value(); 41 props.left = absMtPositionX.minValue; 42 props.right = absMtPositionX.maxValue; 43 props.res_x = absMtPositionX.resolution; 44 45 RawAbsoluteAxisInfo absMtPositionY = context.getAbsoluteAxisInfo(ABS_MT_POSITION_Y).value(); 46 props.top = absMtPositionY.minValue; 47 props.bottom = absMtPositionY.maxValue; 48 props.res_y = absMtPositionY.resolution; 49 50 if (std::optional<RawAbsoluteAxisInfo> absMtOrientation = 51 context.getAbsoluteAxisInfo(ABS_MT_ORIENTATION); 52 absMtOrientation) { 53 props.orientation_minimum = absMtOrientation->minValue; 54 props.orientation_maximum = absMtOrientation->maxValue; 55 } else { 56 props.orientation_minimum = 0; 57 props.orientation_maximum = 0; 58 } 59 60 if (std::optional<RawAbsoluteAxisInfo> absMtSlot = context.getAbsoluteAxisInfo(ABS_MT_SLOT); 61 absMtSlot) { 62 props.max_finger_cnt = absMtSlot->maxValue - absMtSlot->minValue + 1; 63 } else { 64 props.max_finger_cnt = 1; 65 } 66 props.max_touch_cnt = getMaxTouchCount(context); 67 68 // T5R2 ("Track 5, Report 2") is a feature of some old Synaptics touchpads that could track 5 69 // fingers but only report the coordinates of 2 of them. We don't know of any external touchpads 70 // that did this, so assume false. 71 props.supports_t5r2 = false; 72 73 props.support_semi_mt = context.hasInputProperty(INPUT_PROP_SEMI_MT); 74 props.is_button_pad = context.hasInputProperty(INPUT_PROP_BUTTONPAD); 75 76 // Mouse-only properties, which will always be false. 77 props.has_wheel = false; 78 props.wheel_is_hi_res = false; 79 80 // Linux Kernel haptic touchpad support isn't merged yet, so for now assume that no touchpads 81 // are haptic. 82 props.is_haptic_pad = false; 83 84 props.reports_pressure = context.hasAbsoluteAxis(ABS_MT_PRESSURE); 85 return props; 86 } 87 88 } // namespace android 89