1 /* 2 * Copyright 2022 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 // clang-format off 18 #include "../Macros.h" 19 // clang-format on 20 #include "gestures/HardwareStateConverter.h" 21 22 #include <chrono> 23 #include <vector> 24 25 #include <com_android_input_flags.h> 26 #include <linux/input-event-codes.h> 27 28 namespace android { 29 HardwareStateConverter(const InputDeviceContext & deviceContext,MultiTouchMotionAccumulator & motionAccumulator)30HardwareStateConverter::HardwareStateConverter(const InputDeviceContext& deviceContext, 31 MultiTouchMotionAccumulator& motionAccumulator) 32 : mDeviceContext(deviceContext), 33 mMotionAccumulator(motionAccumulator), 34 mTouchButtonAccumulator(deviceContext) { 35 mTouchButtonAccumulator.configure(); 36 } 37 processRawEvent(const RawEvent & rawEvent)38std::optional<SelfContainedHardwareState> HardwareStateConverter::processRawEvent( 39 const RawEvent& rawEvent) { 40 std::optional<SelfContainedHardwareState> out; 41 if (rawEvent.type == EV_SYN && rawEvent.code == SYN_REPORT) { 42 out = produceHardwareState(rawEvent.when); 43 mMotionAccumulator.finishSync(); 44 mMscTimestamp = 0; 45 } 46 if (rawEvent.type == EV_MSC && rawEvent.code == MSC_TIMESTAMP) { 47 mMscTimestamp = rawEvent.value; 48 } 49 mCursorButtonAccumulator.process(rawEvent); 50 mMotionAccumulator.process(rawEvent); 51 mTouchButtonAccumulator.process(rawEvent); 52 return out; 53 } 54 produceHardwareState(nsecs_t when)55SelfContainedHardwareState HardwareStateConverter::produceHardwareState(nsecs_t when) { 56 SelfContainedHardwareState schs; 57 // The gestures library uses doubles to represent timestamps in seconds. 58 schs.state.timestamp = std::chrono::duration<stime_t>(std::chrono::nanoseconds(when)).count(); 59 schs.state.msc_timestamp = 60 std::chrono::duration<stime_t>(std::chrono::microseconds(mMscTimestamp)).count(); 61 62 schs.state.buttons_down = 0; 63 if (mCursorButtonAccumulator.isLeftPressed()) { 64 schs.state.buttons_down |= GESTURES_BUTTON_LEFT; 65 } 66 if (mCursorButtonAccumulator.isMiddlePressed()) { 67 schs.state.buttons_down |= GESTURES_BUTTON_MIDDLE; 68 } 69 if (mCursorButtonAccumulator.isRightPressed()) { 70 schs.state.buttons_down |= GESTURES_BUTTON_RIGHT; 71 } 72 if (mCursorButtonAccumulator.isBackPressed() || mCursorButtonAccumulator.isSidePressed()) { 73 schs.state.buttons_down |= GESTURES_BUTTON_BACK; 74 } 75 if (mCursorButtonAccumulator.isForwardPressed() || mCursorButtonAccumulator.isExtraPressed()) { 76 schs.state.buttons_down |= GESTURES_BUTTON_FORWARD; 77 } 78 79 schs.fingers.clear(); 80 for (size_t i = 0; i < mMotionAccumulator.getSlotCount(); i++) { 81 MultiTouchMotionAccumulator::Slot slot = mMotionAccumulator.getSlot(i); 82 if (!slot.isInUse()) { 83 continue; 84 } 85 86 FingerState& fingerState = schs.fingers.emplace_back(); 87 fingerState = {}; 88 fingerState.touch_major = slot.getTouchMajor(); 89 fingerState.touch_minor = slot.getTouchMinor(); 90 fingerState.width_major = slot.getToolMajor(); 91 fingerState.width_minor = slot.getToolMinor(); 92 fingerState.pressure = slot.getPressure(); 93 fingerState.orientation = slot.getOrientation(); 94 fingerState.position_x = slot.getX(); 95 fingerState.position_y = slot.getY(); 96 fingerState.tracking_id = slot.getTrackingId(); 97 fingerState.tool_type = slot.getToolType() == ToolType::PALM 98 ? FingerState::ToolType::kPalm 99 : FingerState::ToolType::kFinger; 100 } 101 schs.state.fingers = schs.fingers.data(); 102 schs.state.finger_cnt = schs.fingers.size(); 103 schs.state.touch_cnt = mTouchButtonAccumulator.getTouchCount(); 104 return schs; 105 } 106 reset()107void HardwareStateConverter::reset() { 108 mCursorButtonAccumulator.reset(mDeviceContext); 109 mTouchButtonAccumulator.reset(); 110 mMscTimestamp = 0; 111 } 112 113 } // namespace android 114