1 /*
2  * Copyright (C) 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 #pragma once
18 
19 #include <linux/input-event-codes.h>
20 #include <stdint.h>
21 #include <vector>
22 
23 #include "EventHub.h"
24 #include "InputDevice.h"
25 
26 namespace android {
27 
28 /* Keeps track of the state of multi-touch protocol. */
29 class MultiTouchMotionAccumulator {
30 public:
31     class Slot {
32     public:
isInUse()33         inline bool isInUse() const { return mInUse; }
getX()34         inline int32_t getX() const { return mAbsMtPositionX; }
getY()35         inline int32_t getY() const { return mAbsMtPositionY; }
getTouchMajor()36         inline int32_t getTouchMajor() const { return mAbsMtTouchMajor; }
getTouchMinor()37         inline int32_t getTouchMinor() const {
38             return mHaveAbsMtTouchMinor ? mAbsMtTouchMinor : mAbsMtTouchMajor;
39         }
getToolMajor()40         inline int32_t getToolMajor() const { return mAbsMtWidthMajor; }
getToolMinor()41         inline int32_t getToolMinor() const {
42             return mHaveAbsMtWidthMinor ? mAbsMtWidthMinor : mAbsMtWidthMajor;
43         }
getOrientation()44         inline int32_t getOrientation() const { return mAbsMtOrientation; }
getTrackingId()45         inline int32_t getTrackingId() const { return mAbsMtTrackingId; }
getPressure()46         inline int32_t getPressure() const { return mAbsMtPressure; }
getDistance()47         inline int32_t getDistance() const { return mAbsMtDistance; }
48         ToolType getToolType() const;
49 
50     private:
51         friend class MultiTouchMotionAccumulator;
52 
53         bool mInUse = false;
54         bool mHaveAbsMtTouchMinor = false;
55         bool mHaveAbsMtWidthMinor = false;
56         bool mHaveAbsMtToolType = false;
57 
58         int32_t mAbsMtPositionX = 0;
59         int32_t mAbsMtPositionY = 0;
60         int32_t mAbsMtTouchMajor = 0;
61         int32_t mAbsMtTouchMinor = 0;
62         int32_t mAbsMtWidthMajor = 0;
63         int32_t mAbsMtWidthMinor = 0;
64         int32_t mAbsMtOrientation = 0;
65         int32_t mAbsMtTrackingId = -1;
66         int32_t mAbsMtPressure = 0;
67         int32_t mAbsMtDistance = 0;
68         int32_t mAbsMtToolType = 0;
69 
clear()70         void clear() { *this = Slot(); }
71         void populateAxisValue(int32_t axisCode, int32_t value);
72     };
73 
74     MultiTouchMotionAccumulator();
75 
76     void configure(const InputDeviceContext& deviceContext, size_t slotCount,
77                    bool usingSlotsProtocol);
78     void reset(const InputDeviceContext& deviceContext);
79     void process(const RawEvent& rawEvent);
80     void finishSync();
81 
82     size_t getActiveSlotsCount() const;
getSlotCount()83     inline size_t getSlotCount() const { return mSlots.size(); }
getSlot(size_t index)84     inline const Slot& getSlot(size_t index) const {
85         LOG_ALWAYS_FATAL_IF(index < 0 || index >= mSlots.size(), "Invalid index: %zu", index);
86         return mSlots[index];
87     }
88 
89 private:
90     int32_t mCurrentSlot{-1};
91     std::vector<Slot> mSlots;
92     bool mUsingSlotsProtocol;
93 
94     void resetSlots();
95     void syncSlots(const InputDeviceContext& deviceContext);
96     void warnIfNotInUse(const RawEvent& event, const Slot& slot);
97     void populateCurrentSlot(const android::InputDeviceContext& deviceContext);
98 };
99 
100 } // namespace android
101