• 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 
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     [[nodiscard]] std::list<NotifyArgs> prepareForFakeFingerGesture(nsecs_t when, nsecs_t readTime);
96 
97     NotifyMotionArgs makeHoverEvent(nsecs_t when, nsecs_t readTime, int32_t action);
98 
99     NotifyMotionArgs makeMotionArgs(nsecs_t when, nsecs_t readTime, int32_t action,
100                                     int32_t actionButton, int32_t buttonState,
101                                     uint32_t pointerCount, const PointerCoords* pointerCoords);
102 
103     void enableTapToClick(nsecs_t when);
104     bool mIsHoverCancelled{false};
105     nsecs_t mWhenToEnableTapToClick{0};
106 
107     const int32_t mDeviceId;
108     InputReaderContext& mReaderContext;
109     const bool mEnableNoFocusChange;
110     bool mEnableSystemGestures{true};
111 
112     bool mThreeFingerTapShortcutEnabled{false};
113 
114     std::optional<ui::LogicalDisplayId> mDisplayId;
115     FloatRect mBoundsInLogicalDisplay{};
116     ui::Rotation mOrientation = ui::ROTATION_0;
117     RawAbsoluteAxisInfo mXAxisInfo;
118     RawAbsoluteAxisInfo mYAxisInfo;
119 
120     // The current button state according to the gestures library, but converted into MotionEvent
121     // button values (AMOTION_EVENT_BUTTON_...).
122     uint32_t mButtonState = 0;
123     nsecs_t mDownTime = 0;
124     // Whether we are currently in a hover state (i.e. a HOVER_ENTER event has been sent without a
125     // matching HOVER_EXIT).
126     bool mIsHovering = false;
127     // Whether we've received a "fling start" gesture (i.e. the end of a scroll) but no "fling tap
128     // down" gesture to match it yet.
129     bool mFlingMayBeInProgress = false;
130 
131     MotionClassification mCurrentClassification = MotionClassification::NONE;
132     // Only used when mCurrentClassification is MULTI_FINGER_SWIPE.
133     uint32_t mSwipeFingerCount = 0;
134     static constexpr float INITIAL_PINCH_SEPARATION_PX = 200.0;
135     // Only used when mCurrentClassification is PINCH.
136     float mPinchFingerSeparation;
137     static constexpr size_t MAX_FAKE_FINGERS = 4;
138     // We never need any PointerProperties other than the finger tool type, so we can just keep a
139     // const array of them.
140     const std::array<PointerProperties, MAX_FAKE_FINGERS> mFingerProps = {{
141             {.id = 0, .toolType = ToolType::FINGER},
142             {.id = 1, .toolType = ToolType::FINGER},
143             {.id = 2, .toolType = ToolType::FINGER},
144             {.id = 3, .toolType = ToolType::FINGER},
145     }};
146     std::array<PointerCoords, MAX_FAKE_FINGERS> mFakeFingerCoords = {};
147 
148     // TODO(b/260226362): consider what the appropriate source for these events is.
149     static constexpr uint32_t SOURCE = AINPUT_SOURCE_MOUSE;
150 };
151 
152 } // namespace android
153