• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
58     void populateMotionRanges(InputDeviceInfo& info) const;
59 
60     [[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
61                                                       nsecs_t gestureStartTime,
62                                                       const Gesture& gesture);
63 
64 private:
65     [[nodiscard]] std::list<NotifyArgs> handleMove(nsecs_t when, nsecs_t readTime,
66                                                    nsecs_t gestureStartTime,
67                                                    const Gesture& gesture);
68     [[nodiscard]] std::list<NotifyArgs> handleButtonsChange(nsecs_t when, nsecs_t readTime,
69                                                             const Gesture& gesture);
70     [[nodiscard]] std::list<NotifyArgs> releaseAllButtons(nsecs_t when, nsecs_t readTime);
71     [[nodiscard]] std::list<NotifyArgs> handleScroll(nsecs_t when, nsecs_t readTime,
72                                                      const Gesture& gesture);
73     [[nodiscard]] std::list<NotifyArgs> handleFling(nsecs_t when, nsecs_t readTime,
74                                                     nsecs_t gestureStartTime,
75                                                     const Gesture& gesture);
76     [[nodiscard]] std::list<NotifyArgs> endScroll(nsecs_t when, nsecs_t readTime);
77 
78     [[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipe(nsecs_t when, nsecs_t readTime,
79                                                                uint32_t fingerCount, float dx,
80                                                                float dy);
81     [[nodiscard]] std::list<NotifyArgs> handleMultiFingerSwipeLift(nsecs_t when, nsecs_t readTime);
82     [[nodiscard]] std::list<NotifyArgs> handlePinch(nsecs_t when, nsecs_t readTime,
83                                                     const Gesture& gesture);
84     [[nodiscard]] std::list<NotifyArgs> endPinch(nsecs_t when, nsecs_t readTime);
85 
86     [[nodiscard]] std::list<NotifyArgs> enterHover(nsecs_t when, nsecs_t readTime);
87     [[nodiscard]] std::list<NotifyArgs> exitHover(nsecs_t when, nsecs_t readTime);
88 
89     NotifyMotionArgs makeHoverEvent(nsecs_t when, nsecs_t readTime, int32_t action);
90 
91     NotifyMotionArgs makeMotionArgs(nsecs_t when, nsecs_t readTime, int32_t action,
92                                     int32_t actionButton, int32_t buttonState,
93                                     uint32_t pointerCount, const PointerCoords* pointerCoords);
94 
95     void enableTapToClick(nsecs_t when);
96     bool mIsHoverCancelled{false};
97     nsecs_t mWhenToEnableTapToClick{0};
98 
99     const int32_t mDeviceId;
100     InputReaderContext& mReaderContext;
101     const bool mEnableFlingStop;
102 
103     std::optional<ui::LogicalDisplayId> mDisplayId;
104     FloatRect mBoundsInLogicalDisplay{};
105     ui::Rotation mOrientation = ui::ROTATION_0;
106     RawAbsoluteAxisInfo mXAxisInfo;
107     RawAbsoluteAxisInfo mYAxisInfo;
108 
109     // The current button state according to the gestures library, but converted into MotionEvent
110     // button values (AMOTION_EVENT_BUTTON_...).
111     uint32_t mButtonState = 0;
112     nsecs_t mDownTime = 0;
113     // Whether we are currently in a hover state (i.e. a HOVER_ENTER event has been sent without a
114     // matching HOVER_EXIT).
115     bool mIsHovering = false;
116     // Whether we've received a "fling start" gesture (i.e. the end of a scroll) but no "fling tap
117     // down" gesture to match it yet.
118     bool mFlingMayBeInProgress = false;
119 
120     MotionClassification mCurrentClassification = MotionClassification::NONE;
121     // Only used when mCurrentClassification is MULTI_FINGER_SWIPE.
122     uint32_t mSwipeFingerCount = 0;
123     static constexpr float INITIAL_PINCH_SEPARATION_PX = 200.0;
124     // Only used when mCurrentClassification is PINCH.
125     float mPinchFingerSeparation;
126     static constexpr size_t MAX_FAKE_FINGERS = 4;
127     // We never need any PointerProperties other than the finger tool type, so we can just keep a
128     // const array of them.
129     const std::array<PointerProperties, MAX_FAKE_FINGERS> mFingerProps = {{
130             {.id = 0, .toolType = ToolType::FINGER},
131             {.id = 1, .toolType = ToolType::FINGER},
132             {.id = 2, .toolType = ToolType::FINGER},
133             {.id = 3, .toolType = ToolType::FINGER},
134     }};
135     std::array<PointerCoords, MAX_FAKE_FINGERS> mFakeFingerCoords = {};
136 
137     // TODO(b/260226362): consider what the appropriate source for these events is.
138     static constexpr uint32_t SOURCE = AINPUT_SOURCE_MOUSE;
139 };
140 
141 } // namespace android
142