xref: /aosp_15_r20/frameworks/native/services/inputflinger/reader/mapper/gestures/GestureConverter.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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 #pragma once
18 
19 #include <array>
20 #include <list>
21 #include <memory>
22 
23 #include <android/input.h>
24 #include <utils/Timers.h>
25 
26 #include "EventHub.h"
27 #include "InputDevice.h"
28 #include "InputReaderContext.h"
29 #include "NotifyArgs.h"
30 #include "ui/Rotation.h"
31 
32 #include "include/gestures.h"
33 
34 namespace android {
35 
36 using std::chrono_literals::operator""ms;
37 /**
38  * This duration is decided based on internal team testing, it may be updated after testing with
39  * larger groups
40  */
41 constexpr std::chrono::nanoseconds TAP_ENABLE_DELAY_NANOS = 400ms;
42 
43 // Converts Gesture structs from the gestures library into NotifyArgs.
44 class GestureConverter {
45 public:
46     GestureConverter(InputReaderContext& readerContext, const InputDeviceContext& deviceContext,
47                      int32_t deviceId);
48 
49     std::string dump() const;
50 
setOrientation(ui::Rotation orientation)51     void setOrientation(ui::Rotation orientation) { mOrientation = orientation; }
52     [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when);
53 
setDisplayId(std::optional<ui::LogicalDisplayId> displayId)54     void setDisplayId(std::optional<ui::LogicalDisplayId> displayId) { mDisplayId = displayId; }
55 
setBoundsInLogicalDisplay(FloatRect bounds)56     void setBoundsInLogicalDisplay(FloatRect bounds) { mBoundsInLogicalDisplay = bounds; }
57 
setThreeFingerTapShortcutEnabled(bool enabled)58     void setThreeFingerTapShortcutEnabled(bool enabled) {
59         mThreeFingerTapShortcutEnabled = enabled;
60     }
61 
62     [[nodiscard]] std::list<NotifyArgs> setEnableSystemGestures(nsecs_t when, bool enable);
63 
64     void populateMotionRanges(InputDeviceInfo& info) const;
65 
66     [[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
67                                                       nsecs_t gestureStartTime,
68                                                       const Gesture& gesture);
69 
70 private:
71     [[nodiscard]] std::list<NotifyArgs> handleMove(nsecs_t when, nsecs_t readTime,
72                                                    nsecs_t gestureStartTime,
73                                                    const Gesture& gesture);
74     [[nodiscard]] std::list<NotifyArgs> handleButtonsChange(nsecs_t when, nsecs_t readTime,
75                                                             const Gesture& gesture);
76     [[nodiscard]] std::list<NotifyArgs> releaseAllButtons(nsecs_t when, nsecs_t readTime);
77     [[nodiscard]] std::list<NotifyArgs> handleScroll(nsecs_t when, nsecs_t readTime,
78                                                      const Gesture& gesture);
79     [[nodiscard]] std::list<NotifyArgs> handleFling(nsecs_t when, nsecs_t readTime,
80                                                     nsecs_t gestureStartTime,
81                                                     const Gesture& gesture);
82     [[nodiscard]] std::list<NotifyArgs> endScroll(nsecs_t when, nsecs_t readTime);
83 
84     [[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipe(nsecs_t when, nsecs_t readTime,
85                                                                uint32_t fingerCount, float dx,
86                                                                float dy);
87     [[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipeLift(nsecs_t when, nsecs_t readTime);
88     [[nodiscard]] std::list<NotifyArgs> handlePinch(nsecs_t when, nsecs_t readTime,
89                                                     const Gesture& gesture);
90     [[nodiscard]] std::list<NotifyArgs> endPinch(nsecs_t when, nsecs_t readTime);
91 
92     [[nodiscard]] std::list<NotifyArgs> enterHover(nsecs_t when, nsecs_t readTime);
93     [[nodiscard]] std::list<NotifyArgs> exitHover(nsecs_t when, nsecs_t readTime);
94 
95     NotifyMotionArgs makeHoverEvent(nsecs_t when, nsecs_t readTime, int32_t action);
96 
97     NotifyMotionArgs makeMotionArgs(nsecs_t when, nsecs_t readTime, int32_t action,
98                                     int32_t actionButton, int32_t buttonState,
99                                     uint32_t pointerCount, const PointerCoords* pointerCoords);
100 
101     void enableTapToClick(nsecs_t when);
102     bool mIsHoverCancelled{false};
103     nsecs_t mWhenToEnableTapToClick{0};
104 
105     const int32_t mDeviceId;
106     InputReaderContext& mReaderContext;
107     const bool mEnableFlingStop;
108     const bool mEnableNoFocusChange;
109     bool mEnableSystemGestures{true};
110 
111     bool mThreeFingerTapShortcutEnabled;
112 
113     std::optional<ui::LogicalDisplayId> mDisplayId;
114     FloatRect mBoundsInLogicalDisplay{};
115     ui::Rotation mOrientation = ui::ROTATION_0;
116     RawAbsoluteAxisInfo mXAxisInfo;
117     RawAbsoluteAxisInfo mYAxisInfo;
118 
119     // The current button state according to the gestures library, but converted into MotionEvent
120     // button values (AMOTION_EVENT_BUTTON_...).
121     uint32_t mButtonState = 0;
122     nsecs_t mDownTime = 0;
123     // Whether we are currently in a hover state (i.e. a HOVER_ENTER event has been sent without a
124     // matching HOVER_EXIT).
125     bool mIsHovering = false;
126     // Whether we've received a "fling start" gesture (i.e. the end of a scroll) but no "fling tap
127     // down" gesture to match it yet.
128     bool mFlingMayBeInProgress = false;
129 
130     MotionClassification mCurrentClassification = MotionClassification::NONE;
131     // Only used when mCurrentClassification is MULTI_FINGER_SWIPE.
132     uint32_t mSwipeFingerCount = 0;
133     static constexpr float INITIAL_PINCH_SEPARATION_PX = 200.0;
134     // Only used when mCurrentClassification is PINCH.
135     float mPinchFingerSeparation;
136     static constexpr size_t MAX_FAKE_FINGERS = 4;
137     // We never need any PointerProperties other than the finger tool type, so we can just keep a
138     // const array of them.
139     const std::array<PointerProperties, MAX_FAKE_FINGERS> mFingerProps = {{
140             {.id = 0, .toolType = ToolType::FINGER},
141             {.id = 1, .toolType = ToolType::FINGER},
142             {.id = 2, .toolType = ToolType::FINGER},
143             {.id = 3, .toolType = ToolType::FINGER},
144     }};
145     std::array<PointerCoords, MAX_FAKE_FINGERS> mFakeFingerCoords = {};
146 
147     // TODO(b/260226362): consider what the appropriate source for these events is.
148     static constexpr uint32_t SOURCE = AINPUT_SOURCE_MOUSE;
149 };
150 
151 } // namespace android
152