blob: bab15cc47df1852086b26850d3aae3dec66bad55 [file] [log] [blame]
Prabir Pradhanbaa5c822019-08-30 15:27:05 -07001/*
2 * Copyright (C) 2019 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
Prabir Pradhan48108662022-09-09 21:22:04 +000017#pragma once
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070018
Michael Wright227c5542020-07-02 18:30:52 +010019#include <stdint.h>
20
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070021#include "CursorButtonAccumulator.h"
22#include "CursorScrollAccumulator.h"
23#include "EventHub.h"
24#include "InputMapper.h"
25#include "InputReaderBase.h"
26#include "TouchButtonAccumulator.h"
27
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070028namespace android {
29
30/* Raw axis information from the driver. */
31struct RawPointerAxes {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000032 RawAbsoluteAxisInfo x{};
33 RawAbsoluteAxisInfo y{};
34 RawAbsoluteAxisInfo pressure{};
35 RawAbsoluteAxisInfo touchMajor{};
36 RawAbsoluteAxisInfo touchMinor{};
37 RawAbsoluteAxisInfo toolMajor{};
38 RawAbsoluteAxisInfo toolMinor{};
39 RawAbsoluteAxisInfo orientation{};
40 RawAbsoluteAxisInfo distance{};
41 RawAbsoluteAxisInfo tiltX{};
42 RawAbsoluteAxisInfo tiltY{};
43 RawAbsoluteAxisInfo trackingId{};
44 RawAbsoluteAxisInfo slot{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070045
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070046 inline int32_t getRawWidth() const { return x.maxValue - x.minValue + 1; }
47 inline int32_t getRawHeight() const { return y.maxValue - y.minValue + 1; }
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000048 inline void clear() { *this = RawPointerAxes(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070049};
50
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000051using PropertiesArray = std::array<PointerProperties, MAX_POINTERS>;
52using CoordsArray = std::array<PointerCoords, MAX_POINTERS>;
53using IdToIndexArray = std::array<uint32_t, MAX_POINTER_ID + 1>;
54
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070055/* Raw data for a collection of pointers including a pointer id mapping table. */
56struct RawPointerData {
57 struct Pointer {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000058 uint32_t id{0xFFFFFFFF};
59 int32_t x{};
60 int32_t y{};
61 int32_t pressure{};
62 int32_t touchMajor{};
63 int32_t touchMinor{};
64 int32_t toolMajor{};
65 int32_t toolMinor{};
66 int32_t orientation{};
67 int32_t distance{};
68 int32_t tiltX{};
69 int32_t tiltY{};
70 // A fully decoded AMOTION_EVENT_TOOL_TYPE constant.
71 int32_t toolType{AMOTION_EVENT_TOOL_TYPE_UNKNOWN};
72 bool isHovering{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070073 };
74
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000075 uint32_t pointerCount{};
76 std::array<Pointer, MAX_POINTERS> pointers{};
77 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{};
78 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070079
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000080 inline void clear() { *this = RawPointerData(); }
81
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070082 void getCentroidOfTouchingPointers(float* outX, float* outY) const;
83
84 inline void markIdBit(uint32_t id, bool isHovering) {
85 if (isHovering) {
86 hoveringIdBits.markBit(id);
87 } else {
88 touchingIdBits.markBit(id);
89 }
90 }
91
92 inline void clearIdBits() {
93 hoveringIdBits.clear();
94 touchingIdBits.clear();
arthurhungcc7f9802020-04-30 17:55:40 +080095 canceledIdBits.clear();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070096 }
97
98 inline const Pointer& pointerForId(uint32_t id) const { return pointers[idToIndex[id]]; }
99
100 inline bool isHovering(uint32_t pointerIndex) { return pointers[pointerIndex].isHovering; }
101};
102
103/* Cooked data for a collection of pointers including a pointer id mapping table. */
104struct CookedPointerData {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000105 uint32_t pointerCount{};
106 PropertiesArray pointerProperties{};
107 CoordsArray pointerCoords{};
108 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{}, validIdBits{};
109 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700110
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000111 inline void clear() { *this = CookedPointerData(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700112
113 inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
114 return pointerCoords[idToIndex[id]];
115 }
116
117 inline PointerCoords& editPointerCoordsWithId(uint32_t id) {
118 return pointerCoords[idToIndex[id]];
119 }
120
121 inline PointerProperties& editPointerPropertiesWithId(uint32_t id) {
122 return pointerProperties[idToIndex[id]];
123 }
124
125 inline bool isHovering(uint32_t pointerIndex) const {
126 return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
127 }
128
129 inline bool isTouching(uint32_t pointerIndex) const {
130 return touchingIdBits.hasBit(pointerProperties[pointerIndex].id);
131 }
Nathaniel R. Lewisadb58ea2019-08-21 04:46:29 +0000132
133 inline bool hasPointerCoordsForId(uint32_t id) const { return validIdBits.hasBit(id); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700134};
135
136class TouchInputMapper : public InputMapper {
137public:
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800138 explicit TouchInputMapper(InputDeviceContext& deviceContext);
Michael Wright227c5542020-07-02 18:30:52 +0100139 ~TouchInputMapper() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700140
Philip Junker4af3b3d2021-12-14 10:36:55 +0100141 uint32_t getSources() const override;
Michael Wright227c5542020-07-02 18:30:52 +0100142 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
143 void dump(std::string& dump) override;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700144 [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
145 const InputReaderConfiguration* config,
146 uint32_t changes) override;
147 [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
148 [[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700149
Michael Wright227c5542020-07-02 18:30:52 +0100150 int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) override;
151 int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700152 bool markSupportedKeyCodes(uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
Michael Wright227c5542020-07-02 18:30:52 +0100153 uint8_t* outFlags) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700154
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700155 [[nodiscard]] std::list<NotifyArgs> cancelTouch(nsecs_t when, nsecs_t readTime) override;
156 [[nodiscard]] std::list<NotifyArgs> timeoutExpired(nsecs_t when) override;
157 [[nodiscard]] std::list<NotifyArgs> updateExternalStylusState(
158 const StylusState& state) override;
Michael Wright227c5542020-07-02 18:30:52 +0100159 std::optional<int32_t> getAssociatedDisplayId() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700160
161protected:
162 CursorButtonAccumulator mCursorButtonAccumulator;
163 CursorScrollAccumulator mCursorScrollAccumulator;
164 TouchButtonAccumulator mTouchButtonAccumulator;
165
166 struct VirtualKey {
167 int32_t keyCode;
168 int32_t scanCode;
169 uint32_t flags;
170
171 // computed hit box, specified in touch screen coords based on known display size
172 int32_t hitLeft;
173 int32_t hitTop;
174 int32_t hitRight;
175 int32_t hitBottom;
176
177 inline bool isHit(int32_t x, int32_t y) const {
178 return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
179 }
180 };
181
182 // Input sources and device mode.
183 uint32_t mSource;
184
Michael Wright227c5542020-07-02 18:30:52 +0100185 enum class DeviceMode {
186 DISABLED, // input is disabled
187 DIRECT, // direct mapping (touchscreen)
188 UNSCALED, // unscaled mapping (touchpad)
189 NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
190 POINTER, // pointer mapping (pointer)
Dominik Laskowski75788452021-02-09 18:51:25 -0800191
192 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700193 };
194 DeviceMode mDeviceMode;
195
196 // The reader's configuration.
197 InputReaderConfiguration mConfig;
198
199 // Immutable configuration parameters.
200 struct Parameters {
Michael Wright227c5542020-07-02 18:30:52 +0100201 enum class DeviceType {
202 TOUCH_SCREEN,
Michael Wright227c5542020-07-02 18:30:52 +0100203 TOUCH_NAVIGATION,
204 POINTER,
Dominik Laskowski75788452021-02-09 18:51:25 -0800205
206 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700207 };
208
209 DeviceType deviceType;
210 bool hasAssociatedDisplay;
211 bool associatedDisplayIsExternal;
212 bool orientationAware;
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700213
214 enum class Orientation : int32_t {
215 ORIENTATION_0 = DISPLAY_ORIENTATION_0,
216 ORIENTATION_90 = DISPLAY_ORIENTATION_90,
217 ORIENTATION_180 = DISPLAY_ORIENTATION_180,
218 ORIENTATION_270 = DISPLAY_ORIENTATION_270,
Dominik Laskowski75788452021-02-09 18:51:25 -0800219
220 ftl_last = ORIENTATION_270
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700221 };
222 Orientation orientation;
223
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700224 bool hasButtonUnderPad;
225 std::string uniqueDisplayId;
226
Michael Wright227c5542020-07-02 18:30:52 +0100227 enum class GestureMode {
228 SINGLE_TOUCH,
229 MULTI_TOUCH,
Dominik Laskowski75788452021-02-09 18:51:25 -0800230
231 ftl_last = MULTI_TOUCH
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700232 };
233 GestureMode gestureMode;
234
235 bool wake;
Prabir Pradhan167c2702022-09-14 00:37:24 +0000236
237 // Whether the device supports the Universal Stylus Initiative (USI) protocol for styluses.
238 bool supportsUsi;
Yuncheol Heo50c19b12022-11-02 20:33:08 -0700239
240 // Allows touches while the display is off.
241 bool enableForInactiveViewport;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700242 } mParameters;
243
244 // Immutable calibration parameters in parsed form.
245 struct Calibration {
246 // Size
Michael Wright227c5542020-07-02 18:30:52 +0100247 enum class SizeCalibration {
248 DEFAULT,
249 NONE,
250 GEOMETRIC,
251 DIAMETER,
252 BOX,
253 AREA,
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800254 ftl_last = AREA
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700255 };
256
257 SizeCalibration sizeCalibration;
258
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700259 std::optional<float> sizeScale;
260 std::optional<float> sizeBias;
261 std::optional<bool> sizeIsSummed;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700262
263 // Pressure
Michael Wright227c5542020-07-02 18:30:52 +0100264 enum class PressureCalibration {
265 DEFAULT,
266 NONE,
267 PHYSICAL,
268 AMPLITUDE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700269 };
270
271 PressureCalibration pressureCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700272 std::optional<float> pressureScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700273
274 // Orientation
Michael Wright227c5542020-07-02 18:30:52 +0100275 enum class OrientationCalibration {
276 DEFAULT,
277 NONE,
278 INTERPOLATED,
279 VECTOR,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700280 };
281
282 OrientationCalibration orientationCalibration;
283
284 // Distance
Michael Wright227c5542020-07-02 18:30:52 +0100285 enum class DistanceCalibration {
286 DEFAULT,
287 NONE,
288 SCALED,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700289 };
290
291 DistanceCalibration distanceCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700292 std::optional<float> distanceScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700293
Michael Wright227c5542020-07-02 18:30:52 +0100294 enum class CoverageCalibration {
295 DEFAULT,
296 NONE,
297 BOX,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700298 };
299
300 CoverageCalibration coverageCalibration;
301
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700302 inline void applySizeScaleAndBias(float& outSize) const {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700303 if (sizeScale) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700304 outSize *= *sizeScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700305 }
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700306 if (sizeBias) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700307 outSize += *sizeBias;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700308 }
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700309 if (outSize < 0) {
310 outSize = 0;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700311 }
312 }
313 } mCalibration;
314
315 // Affine location transformation/calibration
316 struct TouchAffineTransformation mAffineTransform;
317
318 RawPointerAxes mRawPointerAxes;
319
320 struct RawState {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000321 nsecs_t when{};
322 nsecs_t readTime{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700323
324 // Raw pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000325 RawPointerData rawPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700326
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000327 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700328
329 // Scroll state.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000330 int32_t rawVScroll{};
331 int32_t rawHScroll{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700332
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000333 inline void clear() { *this = RawState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700334 };
335
336 struct CookedState {
337 // Cooked pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000338 CookedPointerData cookedPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700339
340 // Id bits used to differentiate fingers, stylus and mouse tools.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000341 BitSet32 fingerIdBits{};
342 BitSet32 stylusIdBits{};
343 BitSet32 mouseIdBits{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700344
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000345 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700346
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000347 inline void clear() { *this = CookedState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700348 };
349
350 std::vector<RawState> mRawStatesPending;
351 RawState mCurrentRawState;
352 CookedState mCurrentCookedState;
353 RawState mLastRawState;
354 CookedState mLastCookedState;
355
356 // State provided by an external stylus
357 StylusState mExternalStylusState;
358 int64_t mExternalStylusId;
359 nsecs_t mExternalStylusFusionTimeout;
360 bool mExternalStylusDataPending;
361
362 // True if we sent a HOVER_ENTER event.
363 bool mSentHoverEnter;
364
365 // Have we assigned pointer IDs for this stream
366 bool mHavePointerIds;
367
368 // Is the current stream of direct touch events aborted
369 bool mCurrentMotionAborted;
370
371 // The time the primary pointer last went down.
372 nsecs_t mDownTime;
373
374 // The pointer controller, or null if the device is not a pointer.
Michael Wright17db18e2020-06-26 20:51:44 +0100375 std::shared_ptr<PointerControllerInterface> mPointerController;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700376
377 std::vector<VirtualKey> mVirtualKeys;
378
379 virtual void configureParameters();
380 virtual void dumpParameters(std::string& dump);
381 virtual void configureRawPointerAxes();
382 virtual void dumpRawPointerAxes(std::string& dump);
Prabir Pradhan1728b212021-10-19 16:00:03 -0700383 virtual void configureInputDevice(nsecs_t when, bool* outResetNeeded);
384 virtual void dumpDisplay(std::string& dump);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700385 virtual void configureVirtualKeys();
386 virtual void dumpVirtualKeys(std::string& dump);
387 virtual void parseCalibration();
388 virtual void resolveCalibration();
389 virtual void dumpCalibration(std::string& dump);
390 virtual void updateAffineTransformation();
391 virtual void dumpAffineTransformation(std::string& dump);
392 virtual void resolveExternalStylusPresence();
393 virtual bool hasStylus() const = 0;
394 virtual bool hasExternalStylus() const;
395
396 virtual void syncTouch(nsecs_t when, RawState* outState) = 0;
397
398private:
399 // The current viewport.
400 // The components of the viewport are specified in the display's rotated orientation.
401 DisplayViewport mViewport;
402
Prabir Pradhan1728b212021-10-19 16:00:03 -0700403 // The width and height are obtained from the viewport and are specified
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700404 // in the natural orientation.
Prabir Pradhan1728b212021-10-19 16:00:03 -0700405 int32_t mDisplayWidth;
406 int32_t mDisplayHeight;
Arthur Hung4197f6b2020-03-16 15:39:59 +0800407
Prabir Pradhan1728b212021-10-19 16:00:03 -0700408 // The physical frame is the rectangle in the display's coordinate space that maps to the
409 // the logical display frame.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700410 int32_t mPhysicalWidth;
411 int32_t mPhysicalHeight;
412 int32_t mPhysicalLeft;
413 int32_t mPhysicalTop;
414
Prabir Pradhan1728b212021-10-19 16:00:03 -0700415 // The orientation of the input device relative to that of the display panel. It specifies
416 // the rotation of the input device coordinates required to produce the display panel
417 // orientation, so it will depend on whether the device is orientation aware.
418 int32_t mInputDeviceOrientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700419
420 // Translation and scaling factors, orientation-independent.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700421 float mXScale;
422 float mXPrecision;
423
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700424 float mYScale;
425 float mYPrecision;
426
427 float mGeometricScale;
428
429 float mPressureScale;
430
431 float mSizeScale;
432
433 float mOrientationScale;
434
435 float mDistanceScale;
436
437 bool mHaveTilt;
438 float mTiltXCenter;
439 float mTiltXScale;
440 float mTiltYCenter;
441 float mTiltYScale;
442
443 bool mExternalStylusConnected;
444
445 // Oriented motion ranges for input device info.
446 struct OrientedRanges {
447 InputDeviceInfo::MotionRange x;
448 InputDeviceInfo::MotionRange y;
449 InputDeviceInfo::MotionRange pressure;
450
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700451 std::optional<InputDeviceInfo::MotionRange> size;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700452
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700453 std::optional<InputDeviceInfo::MotionRange> touchMajor;
454 std::optional<InputDeviceInfo::MotionRange> touchMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700455
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700456 std::optional<InputDeviceInfo::MotionRange> toolMajor;
457 std::optional<InputDeviceInfo::MotionRange> toolMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700458
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700459 std::optional<InputDeviceInfo::MotionRange> orientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700460
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700461 std::optional<InputDeviceInfo::MotionRange> distance;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700462
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700463 std::optional<InputDeviceInfo::MotionRange> tilt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700464
465 void clear() {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700466 size = std::nullopt;
467 touchMajor = std::nullopt;
468 touchMinor = std::nullopt;
469 toolMajor = std::nullopt;
470 toolMinor = std::nullopt;
471 orientation = std::nullopt;
472 distance = std::nullopt;
473 tilt = std::nullopt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700474 }
475 } mOrientedRanges;
476
477 // Oriented dimensions and precision.
478 float mOrientedXPrecision;
479 float mOrientedYPrecision;
480
481 struct CurrentVirtualKeyState {
482 bool down;
483 bool ignored;
484 nsecs_t downTime;
485 int32_t keyCode;
486 int32_t scanCode;
487 } mCurrentVirtualKey;
488
489 // Scale factor for gesture or mouse based pointer movements.
490 float mPointerXMovementScale;
491 float mPointerYMovementScale;
492
493 // Scale factor for gesture based zooming and other freeform motions.
494 float mPointerXZoomScale;
495 float mPointerYZoomScale;
496
HQ Liue6983c72022-04-19 22:14:56 +0000497 // The maximum swipe width between pointers to detect a swipe gesture
498 // in the number of pixels.Touches that are wider than this are translated
499 // into freeform gestures.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700500 float mPointerGestureMaxSwipeWidth;
501
502 struct PointerDistanceHeapElement {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000503 uint32_t currentPointerIndex : 8 {};
504 uint32_t lastPointerIndex : 8 {};
505 uint64_t distance : 48 {}; // squared distance
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700506 };
507
Michael Wright227c5542020-07-02 18:30:52 +0100508 enum class PointerUsage {
509 NONE,
510 GESTURES,
511 STYLUS,
512 MOUSE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700513 };
514 PointerUsage mPointerUsage;
515
516 struct PointerGesture {
Michael Wright227c5542020-07-02 18:30:52 +0100517 enum class Mode {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700518 // No fingers, button is not pressed.
519 // Nothing happening.
520 NEUTRAL,
521
522 // No fingers, button is not pressed.
523 // Tap detected.
524 // Emits DOWN and UP events at the pointer location.
525 TAP,
526
527 // Exactly one finger dragging following a tap.
528 // Pointer follows the active finger.
529 // Emits DOWN, MOVE and UP events at the pointer location.
530 //
531 // Detect double-taps when the finger goes up while in TAP_DRAG mode.
532 TAP_DRAG,
533
534 // Button is pressed.
535 // Pointer follows the active finger if there is one. Other fingers are ignored.
536 // Emits DOWN, MOVE and UP events at the pointer location.
537 BUTTON_CLICK_OR_DRAG,
538
539 // Exactly one finger, button is not pressed.
540 // Pointer follows the active finger.
541 // Emits HOVER_MOVE events at the pointer location.
542 //
543 // Detect taps when the finger goes up while in HOVER mode.
544 HOVER,
545
546 // Exactly two fingers but neither have moved enough to clearly indicate
547 // whether a swipe or freeform gesture was intended. We consider the
548 // pointer to be pressed so this enables clicking or long-pressing on buttons.
549 // Pointer does not move.
550 // Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
551 PRESS,
552
553 // Exactly two fingers moving in the same direction, button is not pressed.
554 // Pointer does not move.
555 // Emits DOWN, MOVE and UP events with a single pointer coordinate that
556 // follows the midpoint between both fingers.
557 SWIPE,
558
559 // Two or more fingers moving in arbitrary directions, button is not pressed.
560 // Pointer does not move.
561 // Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
562 // each finger individually relative to the initial centroid of the finger.
563 FREEFORM,
564
565 // Waiting for quiet time to end before starting the next gesture.
566 QUIET,
567 };
568
Prabir Pradhan47cf0a02021-03-11 20:30:57 -0800569 // When a gesture is sent to an unfocused window, return true if it can bring that window
570 // into focus, false otherwise.
571 static bool canGestureAffectWindowFocus(Mode mode) {
572 switch (mode) {
573 case Mode::TAP:
574 case Mode::TAP_DRAG:
575 case Mode::BUTTON_CLICK_OR_DRAG:
576 // Taps can affect window focus.
577 return true;
578 case Mode::FREEFORM:
579 case Mode::HOVER:
580 case Mode::NEUTRAL:
581 case Mode::PRESS:
582 case Mode::QUIET:
583 case Mode::SWIPE:
584 // Most gestures can be performed on an unfocused window, so they should not
585 // not affect window focus.
586 return false;
587 }
588 }
589
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700590 // Time the first finger went down.
591 nsecs_t firstTouchTime;
592
593 // The active pointer id from the raw touch data.
594 int32_t activeTouchId; // -1 if none
595
596 // The active pointer id from the gesture last delivered to the application.
597 int32_t activeGestureId; // -1 if none
598
599 // Pointer coords and ids for the current and previous pointer gesture.
600 Mode currentGestureMode;
601 BitSet32 currentGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000602 IdToIndexArray currentGestureIdToIndex{};
603 PropertiesArray currentGestureProperties{};
604 CoordsArray currentGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700605
606 Mode lastGestureMode;
607 BitSet32 lastGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000608 IdToIndexArray lastGestureIdToIndex{};
609 PropertiesArray lastGestureProperties{};
610 CoordsArray lastGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700611
612 // Time the pointer gesture last went down.
613 nsecs_t downTime;
614
615 // Time when the pointer went down for a TAP.
616 nsecs_t tapDownTime;
617
618 // Time when the pointer went up for a TAP.
619 nsecs_t tapUpTime;
620
621 // Location of initial tap.
622 float tapX, tapY;
623
624 // Time we started waiting for quiescence.
625 nsecs_t quietTime;
626
627 // Reference points for multitouch gestures.
628 float referenceTouchX; // reference touch X/Y coordinates in surface units
629 float referenceTouchY;
630 float referenceGestureX; // reference gesture X/Y coordinates in pixels
631 float referenceGestureY;
632
633 // Distance that each pointer has traveled which has not yet been
634 // subsumed into the reference gesture position.
635 BitSet32 referenceIdBits;
636 struct Delta {
637 float dx, dy;
638 };
639 Delta referenceDeltas[MAX_POINTER_ID + 1];
640
641 // Describes how touch ids are mapped to gesture ids for freeform gestures.
642 uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
643
644 // A velocity tracker for determining whether to switch active pointers during drags.
645 VelocityTracker velocityTracker;
646
647 void reset() {
648 firstTouchTime = LLONG_MIN;
649 activeTouchId = -1;
650 activeGestureId = -1;
Michael Wright227c5542020-07-02 18:30:52 +0100651 currentGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700652 currentGestureIdBits.clear();
Michael Wright227c5542020-07-02 18:30:52 +0100653 lastGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700654 lastGestureIdBits.clear();
655 downTime = 0;
656 velocityTracker.clear();
657 resetTap();
658 resetQuietTime();
659 }
660
661 void resetTap() {
662 tapDownTime = LLONG_MIN;
663 tapUpTime = LLONG_MIN;
664 }
665
666 void resetQuietTime() { quietTime = LLONG_MIN; }
667 } mPointerGesture;
668
669 struct PointerSimple {
670 PointerCoords currentCoords;
671 PointerProperties currentProperties;
672 PointerCoords lastCoords;
673 PointerProperties lastProperties;
674
675 // True if the pointer is down.
676 bool down;
677
678 // True if the pointer is hovering.
679 bool hovering;
680
681 // Time the pointer last went down.
682 nsecs_t downTime;
683
684 void reset() {
685 currentCoords.clear();
686 currentProperties.clear();
687 lastCoords.clear();
688 lastProperties.clear();
689 down = false;
690 hovering = false;
691 downTime = 0;
692 }
693 } mPointerSimple;
694
695 // The pointer and scroll velocity controls.
696 VelocityControl mPointerVelocityControl;
697 VelocityControl mWheelXVelocityControl;
698 VelocityControl mWheelYVelocityControl;
699
700 std::optional<DisplayViewport> findViewport();
701
702 void resetExternalStylus();
703 void clearStylusDataPendingFlags();
704
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800705 int32_t clampResolution(const char* axisName, int32_t resolution) const;
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800706 void initializeOrientedRanges();
707 void initializeSizeRanges();
708
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700709 [[nodiscard]] std::list<NotifyArgs> sync(nsecs_t when, nsecs_t readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700710
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700711 [[nodiscard]] std::list<NotifyArgs> consumeRawTouches(nsecs_t when, nsecs_t readTime,
712 uint32_t policyFlags, bool& outConsumed);
713 [[nodiscard]] std::list<NotifyArgs> processRawTouches(bool timeout);
714 [[nodiscard]] std::list<NotifyArgs> cookAndDispatch(nsecs_t when, nsecs_t readTime);
715 [[nodiscard]] NotifyKeyArgs dispatchVirtualKey(nsecs_t when, nsecs_t readTime,
716 uint32_t policyFlags, int32_t keyEventAction,
717 int32_t keyEventFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700718
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700719 [[nodiscard]] std::list<NotifyArgs> dispatchTouches(nsecs_t when, nsecs_t readTime,
720 uint32_t policyFlags);
721 [[nodiscard]] std::list<NotifyArgs> dispatchHoverExit(nsecs_t when, nsecs_t readTime,
722 uint32_t policyFlags);
723 [[nodiscard]] std::list<NotifyArgs> dispatchHoverEnterAndMove(nsecs_t when, nsecs_t readTime,
724 uint32_t policyFlags);
725 [[nodiscard]] std::list<NotifyArgs> dispatchButtonRelease(nsecs_t when, nsecs_t readTime,
726 uint32_t policyFlags);
727 [[nodiscard]] std::list<NotifyArgs> dispatchButtonPress(nsecs_t when, nsecs_t readTime,
728 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700729 const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData);
730 void cookPointerData();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700731 [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime,
732 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700733
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700734 [[nodiscard]] std::list<NotifyArgs> dispatchPointerUsage(nsecs_t when, nsecs_t readTime,
735 uint32_t policyFlags,
736 PointerUsage pointerUsage);
737 [[nodiscard]] std::list<NotifyArgs> abortPointerUsage(nsecs_t when, nsecs_t readTime,
738 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700739
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700740 [[nodiscard]] std::list<NotifyArgs> dispatchPointerGestures(nsecs_t when, nsecs_t readTime,
741 uint32_t policyFlags,
742 bool isTimeout);
743 [[nodiscard]] std::list<NotifyArgs> abortPointerGestures(nsecs_t when, nsecs_t readTime,
744 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700745 bool preparePointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
746 bool* outFinishPreviousGesture, bool isTimeout);
747
Harry Cuttsbea6ce52022-10-14 15:17:30 +0000748 // Returns true if we're in a period of "quiet time" when touchpad gestures should be ignored.
749 bool checkForTouchpadQuietTime(nsecs_t when);
750
751 std::pair<int32_t, float> getFastestFinger();
752
753 void prepareMultiFingerPointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
754 bool* outFinishPreviousGesture);
755
Harry Cutts714d1ad2022-08-24 16:36:43 +0000756 // Moves the on-screen mouse pointer based on the movement of the pointer of the given ID
757 // between the last and current events. Uses a relative motion.
758 void moveMousePointerFromPointerDelta(nsecs_t when, uint32_t pointerId);
759
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700760 [[nodiscard]] std::list<NotifyArgs> dispatchPointerStylus(nsecs_t when, nsecs_t readTime,
761 uint32_t policyFlags);
762 [[nodiscard]] std::list<NotifyArgs> abortPointerStylus(nsecs_t when, nsecs_t readTime,
763 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700764
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700765 [[nodiscard]] std::list<NotifyArgs> dispatchPointerMouse(nsecs_t when, nsecs_t readTime,
766 uint32_t policyFlags);
767 [[nodiscard]] std::list<NotifyArgs> abortPointerMouse(nsecs_t when, nsecs_t readTime,
768 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700769
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700770 [[nodiscard]] std::list<NotifyArgs> dispatchPointerSimple(nsecs_t when, nsecs_t readTime,
771 uint32_t policyFlags, bool down,
772 bool hovering);
773 [[nodiscard]] std::list<NotifyArgs> abortPointerSimple(nsecs_t when, nsecs_t readTime,
774 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700775
776 bool assignExternalStylusId(const RawState& state, bool timeout);
777 void applyExternalStylusButtonState(nsecs_t when);
778 void applyExternalStylusTouchState(nsecs_t when);
779
780 // Dispatches a motion event.
781 // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
782 // method will take care of setting the index and transmuting the action to DOWN or UP
783 // it is the first / last pointer to go down / up.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700784 [[nodiscard]] NotifyMotionArgs dispatchMotion(
785 nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
786 int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000787 int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords,
788 const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700789 float yPrecision, nsecs_t downTime, MotionClassification classification);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700790
Garfield Tanc734e4f2021-01-15 20:01:39 -0800791 // Returns if this touch device is a touch screen with an associated display.
792 bool isTouchScreen();
793 // Updates touch spots if they are enabled. Should only be used when this device is a
794 // touchscreen.
795 void updateTouchSpots();
796
Prabir Pradhan1728b212021-10-19 16:00:03 -0700797 bool isPointInsidePhysicalFrame(int32_t x, int32_t y) const;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700798 const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
799
Siarhei Vishniakou57479982021-03-03 01:32:21 +0000800 static void assignPointerIds(const RawState& last, RawState& current);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700801
Prabir Pradhan1728b212021-10-19 16:00:03 -0700802 void rotateAndScale(float& x, float& y) const;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700803};
804
805} // namespace android