blob: 7680090188dc85aaa74b66f3adc674dd49175ebd [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 {
32 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;
45
46 RawPointerAxes();
47 inline int32_t getRawWidth() const { return x.maxValue - x.minValue + 1; }
48 inline int32_t getRawHeight() const { return y.maxValue - y.minValue + 1; }
49 void clear();
50};
51
52/* Raw data for a collection of pointers including a pointer id mapping table. */
53struct RawPointerData {
54 struct Pointer {
55 uint32_t id;
56 int32_t x;
57 int32_t y;
58 int32_t pressure;
59 int32_t touchMajor;
60 int32_t touchMinor;
61 int32_t toolMajor;
62 int32_t toolMinor;
63 int32_t orientation;
64 int32_t distance;
65 int32_t tiltX;
66 int32_t tiltY;
67 int32_t toolType; // a fully decoded AMOTION_EVENT_TOOL_TYPE constant
68 bool isHovering;
69 };
70
71 uint32_t pointerCount;
72 Pointer pointers[MAX_POINTERS];
arthurhungcc7f9802020-04-30 17:55:40 +080073 BitSet32 hoveringIdBits, touchingIdBits, canceledIdBits;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070074 uint32_t idToIndex[MAX_POINTER_ID + 1];
75
76 RawPointerData();
77 void clear();
78 void copyFrom(const RawPointerData& other);
79 void getCentroidOfTouchingPointers(float* outX, float* outY) const;
80
81 inline void markIdBit(uint32_t id, bool isHovering) {
82 if (isHovering) {
83 hoveringIdBits.markBit(id);
84 } else {
85 touchingIdBits.markBit(id);
86 }
87 }
88
89 inline void clearIdBits() {
90 hoveringIdBits.clear();
91 touchingIdBits.clear();
arthurhungcc7f9802020-04-30 17:55:40 +080092 canceledIdBits.clear();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070093 }
94
95 inline const Pointer& pointerForId(uint32_t id) const { return pointers[idToIndex[id]]; }
96
97 inline bool isHovering(uint32_t pointerIndex) { return pointers[pointerIndex].isHovering; }
98};
99
100/* Cooked data for a collection of pointers including a pointer id mapping table. */
101struct CookedPointerData {
102 uint32_t pointerCount;
103 PointerProperties pointerProperties[MAX_POINTERS];
104 PointerCoords pointerCoords[MAX_POINTERS];
Nathaniel R. Lewisadb58ea2019-08-21 04:46:29 +0000105 BitSet32 hoveringIdBits, touchingIdBits, canceledIdBits, validIdBits;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700106 uint32_t idToIndex[MAX_POINTER_ID + 1];
107
108 CookedPointerData();
109 void clear();
110 void copyFrom(const CookedPointerData& other);
111
112 inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
113 return pointerCoords[idToIndex[id]];
114 }
115
116 inline PointerCoords& editPointerCoordsWithId(uint32_t id) {
117 return pointerCoords[idToIndex[id]];
118 }
119
120 inline PointerProperties& editPointerPropertiesWithId(uint32_t id) {
121 return pointerProperties[idToIndex[id]];
122 }
123
124 inline bool isHovering(uint32_t pointerIndex) const {
125 return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
126 }
127
128 inline bool isTouching(uint32_t pointerIndex) const {
129 return touchingIdBits.hasBit(pointerProperties[pointerIndex].id);
130 }
Nathaniel R. Lewisadb58ea2019-08-21 04:46:29 +0000131
132 inline bool hasPointerCoordsForId(uint32_t id) const { return validIdBits.hasBit(id); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700133};
134
135class TouchInputMapper : public InputMapper {
136public:
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800137 explicit TouchInputMapper(InputDeviceContext& deviceContext);
Michael Wright227c5542020-07-02 18:30:52 +0100138 ~TouchInputMapper() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700139
Philip Junker4af3b3d2021-12-14 10:36:55 +0100140 uint32_t getSources() const override;
Michael Wright227c5542020-07-02 18:30:52 +0100141 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
142 void dump(std::string& dump) override;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700143 [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
144 const InputReaderConfiguration* config,
145 uint32_t changes) override;
146 [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
147 [[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700148
Michael Wright227c5542020-07-02 18:30:52 +0100149 int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) override;
150 int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700151 bool markSupportedKeyCodes(uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
Michael Wright227c5542020-07-02 18:30:52 +0100152 uint8_t* outFlags) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700153
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700154 [[nodiscard]] std::list<NotifyArgs> cancelTouch(nsecs_t when, nsecs_t readTime) override;
155 [[nodiscard]] std::list<NotifyArgs> timeoutExpired(nsecs_t when) override;
156 [[nodiscard]] std::list<NotifyArgs> updateExternalStylusState(
157 const StylusState& state) override;
Michael Wright227c5542020-07-02 18:30:52 +0100158 std::optional<int32_t> getAssociatedDisplayId() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700159
160protected:
161 CursorButtonAccumulator mCursorButtonAccumulator;
162 CursorScrollAccumulator mCursorScrollAccumulator;
163 TouchButtonAccumulator mTouchButtonAccumulator;
164
165 struct VirtualKey {
166 int32_t keyCode;
167 int32_t scanCode;
168 uint32_t flags;
169
170 // computed hit box, specified in touch screen coords based on known display size
171 int32_t hitLeft;
172 int32_t hitTop;
173 int32_t hitRight;
174 int32_t hitBottom;
175
176 inline bool isHit(int32_t x, int32_t y) const {
177 return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
178 }
179 };
180
181 // Input sources and device mode.
182 uint32_t mSource;
183
Michael Wright227c5542020-07-02 18:30:52 +0100184 enum class DeviceMode {
185 DISABLED, // input is disabled
186 DIRECT, // direct mapping (touchscreen)
187 UNSCALED, // unscaled mapping (touchpad)
188 NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
189 POINTER, // pointer mapping (pointer)
Dominik Laskowski75788452021-02-09 18:51:25 -0800190
191 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700192 };
193 DeviceMode mDeviceMode;
194
195 // The reader's configuration.
196 InputReaderConfiguration mConfig;
197
198 // Immutable configuration parameters.
199 struct Parameters {
Michael Wright227c5542020-07-02 18:30:52 +0100200 enum class DeviceType {
201 TOUCH_SCREEN,
Michael Wright227c5542020-07-02 18:30:52 +0100202 TOUCH_NAVIGATION,
203 POINTER,
Dominik Laskowski75788452021-02-09 18:51:25 -0800204
205 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700206 };
207
208 DeviceType deviceType;
209 bool hasAssociatedDisplay;
210 bool associatedDisplayIsExternal;
211 bool orientationAware;
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700212
213 enum class Orientation : int32_t {
214 ORIENTATION_0 = DISPLAY_ORIENTATION_0,
215 ORIENTATION_90 = DISPLAY_ORIENTATION_90,
216 ORIENTATION_180 = DISPLAY_ORIENTATION_180,
217 ORIENTATION_270 = DISPLAY_ORIENTATION_270,
Dominik Laskowski75788452021-02-09 18:51:25 -0800218
219 ftl_last = ORIENTATION_270
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700220 };
221 Orientation orientation;
222
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700223 bool hasButtonUnderPad;
224 std::string uniqueDisplayId;
225
Michael Wright227c5542020-07-02 18:30:52 +0100226 enum class GestureMode {
227 SINGLE_TOUCH,
228 MULTI_TOUCH,
Dominik Laskowski75788452021-02-09 18:51:25 -0800229
230 ftl_last = MULTI_TOUCH
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700231 };
232 GestureMode gestureMode;
233
234 bool wake;
Prabir Pradhan167c2702022-09-14 00:37:24 +0000235
236 // Whether the device supports the Universal Stylus Initiative (USI) protocol for styluses.
237 bool supportsUsi;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700238 } mParameters;
239
240 // Immutable calibration parameters in parsed form.
241 struct Calibration {
242 // Size
Michael Wright227c5542020-07-02 18:30:52 +0100243 enum class SizeCalibration {
244 DEFAULT,
245 NONE,
246 GEOMETRIC,
247 DIAMETER,
248 BOX,
249 AREA,
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800250 ftl_last = AREA
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700251 };
252
253 SizeCalibration sizeCalibration;
254
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700255 std::optional<float> sizeScale;
256 std::optional<float> sizeBias;
257 std::optional<bool> sizeIsSummed;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700258
259 // Pressure
Michael Wright227c5542020-07-02 18:30:52 +0100260 enum class PressureCalibration {
261 DEFAULT,
262 NONE,
263 PHYSICAL,
264 AMPLITUDE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700265 };
266
267 PressureCalibration pressureCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700268 std::optional<float> pressureScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700269
270 // Orientation
Michael Wright227c5542020-07-02 18:30:52 +0100271 enum class OrientationCalibration {
272 DEFAULT,
273 NONE,
274 INTERPOLATED,
275 VECTOR,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700276 };
277
278 OrientationCalibration orientationCalibration;
279
280 // Distance
Michael Wright227c5542020-07-02 18:30:52 +0100281 enum class DistanceCalibration {
282 DEFAULT,
283 NONE,
284 SCALED,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700285 };
286
287 DistanceCalibration distanceCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700288 std::optional<float> distanceScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700289
Michael Wright227c5542020-07-02 18:30:52 +0100290 enum class CoverageCalibration {
291 DEFAULT,
292 NONE,
293 BOX,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700294 };
295
296 CoverageCalibration coverageCalibration;
297
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700298 inline void applySizeScaleAndBias(float& outSize) const {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700299 if (sizeScale) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700300 outSize *= *sizeScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700301 }
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700302 if (sizeBias) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700303 outSize += *sizeBias;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700304 }
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700305 if (outSize < 0) {
306 outSize = 0;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700307 }
308 }
309 } mCalibration;
310
311 // Affine location transformation/calibration
312 struct TouchAffineTransformation mAffineTransform;
313
314 RawPointerAxes mRawPointerAxes;
315
316 struct RawState {
317 nsecs_t when;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000318 nsecs_t readTime;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700319
320 // Raw pointer sample data.
321 RawPointerData rawPointerData;
322
323 int32_t buttonState;
324
325 // Scroll state.
326 int32_t rawVScroll;
327 int32_t rawHScroll;
328
Prabir Pradhanafabcde2022-09-27 19:32:43 +0000329 explicit inline RawState() { clear(); }
330
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700331 void copyFrom(const RawState& other) {
332 when = other.when;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000333 readTime = other.readTime;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700334 rawPointerData.copyFrom(other.rawPointerData);
335 buttonState = other.buttonState;
336 rawVScroll = other.rawVScroll;
337 rawHScroll = other.rawHScroll;
338 }
339
340 void clear() {
341 when = 0;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000342 readTime = 0;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700343 rawPointerData.clear();
344 buttonState = 0;
345 rawVScroll = 0;
346 rawHScroll = 0;
347 }
348 };
349
350 struct CookedState {
351 // Cooked pointer sample data.
352 CookedPointerData cookedPointerData;
353
354 // Id bits used to differentiate fingers, stylus and mouse tools.
355 BitSet32 fingerIdBits;
356 BitSet32 stylusIdBits;
357 BitSet32 mouseIdBits;
358
359 int32_t buttonState;
360
361 void copyFrom(const CookedState& other) {
362 cookedPointerData.copyFrom(other.cookedPointerData);
363 fingerIdBits = other.fingerIdBits;
364 stylusIdBits = other.stylusIdBits;
365 mouseIdBits = other.mouseIdBits;
366 buttonState = other.buttonState;
367 }
368
369 void clear() {
370 cookedPointerData.clear();
371 fingerIdBits.clear();
372 stylusIdBits.clear();
373 mouseIdBits.clear();
374 buttonState = 0;
375 }
376 };
377
378 std::vector<RawState> mRawStatesPending;
379 RawState mCurrentRawState;
380 CookedState mCurrentCookedState;
381 RawState mLastRawState;
382 CookedState mLastCookedState;
383
384 // State provided by an external stylus
385 StylusState mExternalStylusState;
386 int64_t mExternalStylusId;
387 nsecs_t mExternalStylusFusionTimeout;
388 bool mExternalStylusDataPending;
389
390 // True if we sent a HOVER_ENTER event.
391 bool mSentHoverEnter;
392
393 // Have we assigned pointer IDs for this stream
394 bool mHavePointerIds;
395
396 // Is the current stream of direct touch events aborted
397 bool mCurrentMotionAborted;
398
399 // The time the primary pointer last went down.
400 nsecs_t mDownTime;
401
402 // The pointer controller, or null if the device is not a pointer.
Michael Wright17db18e2020-06-26 20:51:44 +0100403 std::shared_ptr<PointerControllerInterface> mPointerController;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700404
405 std::vector<VirtualKey> mVirtualKeys;
406
407 virtual void configureParameters();
408 virtual void dumpParameters(std::string& dump);
409 virtual void configureRawPointerAxes();
410 virtual void dumpRawPointerAxes(std::string& dump);
Prabir Pradhan1728b212021-10-19 16:00:03 -0700411 virtual void configureInputDevice(nsecs_t when, bool* outResetNeeded);
412 virtual void dumpDisplay(std::string& dump);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700413 virtual void configureVirtualKeys();
414 virtual void dumpVirtualKeys(std::string& dump);
415 virtual void parseCalibration();
416 virtual void resolveCalibration();
417 virtual void dumpCalibration(std::string& dump);
418 virtual void updateAffineTransformation();
419 virtual void dumpAffineTransformation(std::string& dump);
420 virtual void resolveExternalStylusPresence();
421 virtual bool hasStylus() const = 0;
422 virtual bool hasExternalStylus() const;
423
424 virtual void syncTouch(nsecs_t when, RawState* outState) = 0;
425
426private:
427 // The current viewport.
428 // The components of the viewport are specified in the display's rotated orientation.
429 DisplayViewport mViewport;
430
Prabir Pradhan1728b212021-10-19 16:00:03 -0700431 // The width and height are obtained from the viewport and are specified
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700432 // in the natural orientation.
Prabir Pradhan1728b212021-10-19 16:00:03 -0700433 int32_t mDisplayWidth;
434 int32_t mDisplayHeight;
Arthur Hung4197f6b2020-03-16 15:39:59 +0800435
Prabir Pradhan1728b212021-10-19 16:00:03 -0700436 // The physical frame is the rectangle in the display's coordinate space that maps to the
437 // the logical display frame.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700438 int32_t mPhysicalWidth;
439 int32_t mPhysicalHeight;
440 int32_t mPhysicalLeft;
441 int32_t mPhysicalTop;
442
Prabir Pradhan1728b212021-10-19 16:00:03 -0700443 // The orientation of the input device relative to that of the display panel. It specifies
444 // the rotation of the input device coordinates required to produce the display panel
445 // orientation, so it will depend on whether the device is orientation aware.
446 int32_t mInputDeviceOrientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700447
448 // Translation and scaling factors, orientation-independent.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700449 float mXScale;
450 float mXPrecision;
451
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700452 float mYScale;
453 float mYPrecision;
454
455 float mGeometricScale;
456
457 float mPressureScale;
458
459 float mSizeScale;
460
461 float mOrientationScale;
462
463 float mDistanceScale;
464
465 bool mHaveTilt;
466 float mTiltXCenter;
467 float mTiltXScale;
468 float mTiltYCenter;
469 float mTiltYScale;
470
471 bool mExternalStylusConnected;
472
473 // Oriented motion ranges for input device info.
474 struct OrientedRanges {
475 InputDeviceInfo::MotionRange x;
476 InputDeviceInfo::MotionRange y;
477 InputDeviceInfo::MotionRange pressure;
478
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700479 std::optional<InputDeviceInfo::MotionRange> size;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700480
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700481 std::optional<InputDeviceInfo::MotionRange> touchMajor;
482 std::optional<InputDeviceInfo::MotionRange> touchMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700483
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700484 std::optional<InputDeviceInfo::MotionRange> toolMajor;
485 std::optional<InputDeviceInfo::MotionRange> toolMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700486
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700487 std::optional<InputDeviceInfo::MotionRange> orientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700488
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700489 std::optional<InputDeviceInfo::MotionRange> distance;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700490
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700491 std::optional<InputDeviceInfo::MotionRange> tilt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700492
493 void clear() {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700494 size = std::nullopt;
495 touchMajor = std::nullopt;
496 touchMinor = std::nullopt;
497 toolMajor = std::nullopt;
498 toolMinor = std::nullopt;
499 orientation = std::nullopt;
500 distance = std::nullopt;
501 tilt = std::nullopt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700502 }
503 } mOrientedRanges;
504
505 // Oriented dimensions and precision.
506 float mOrientedXPrecision;
507 float mOrientedYPrecision;
508
509 struct CurrentVirtualKeyState {
510 bool down;
511 bool ignored;
512 nsecs_t downTime;
513 int32_t keyCode;
514 int32_t scanCode;
515 } mCurrentVirtualKey;
516
517 // Scale factor for gesture or mouse based pointer movements.
518 float mPointerXMovementScale;
519 float mPointerYMovementScale;
520
521 // Scale factor for gesture based zooming and other freeform motions.
522 float mPointerXZoomScale;
523 float mPointerYZoomScale;
524
HQ Liue6983c72022-04-19 22:14:56 +0000525 // The maximum swipe width between pointers to detect a swipe gesture
526 // in the number of pixels.Touches that are wider than this are translated
527 // into freeform gestures.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700528 float mPointerGestureMaxSwipeWidth;
529
530 struct PointerDistanceHeapElement {
531 uint32_t currentPointerIndex : 8;
532 uint32_t lastPointerIndex : 8;
533 uint64_t distance : 48; // squared distance
534 };
535
Michael Wright227c5542020-07-02 18:30:52 +0100536 enum class PointerUsage {
537 NONE,
538 GESTURES,
539 STYLUS,
540 MOUSE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700541 };
542 PointerUsage mPointerUsage;
543
544 struct PointerGesture {
Michael Wright227c5542020-07-02 18:30:52 +0100545 enum class Mode {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700546 // No fingers, button is not pressed.
547 // Nothing happening.
548 NEUTRAL,
549
550 // No fingers, button is not pressed.
551 // Tap detected.
552 // Emits DOWN and UP events at the pointer location.
553 TAP,
554
555 // Exactly one finger dragging following a tap.
556 // Pointer follows the active finger.
557 // Emits DOWN, MOVE and UP events at the pointer location.
558 //
559 // Detect double-taps when the finger goes up while in TAP_DRAG mode.
560 TAP_DRAG,
561
562 // Button is pressed.
563 // Pointer follows the active finger if there is one. Other fingers are ignored.
564 // Emits DOWN, MOVE and UP events at the pointer location.
565 BUTTON_CLICK_OR_DRAG,
566
567 // Exactly one finger, button is not pressed.
568 // Pointer follows the active finger.
569 // Emits HOVER_MOVE events at the pointer location.
570 //
571 // Detect taps when the finger goes up while in HOVER mode.
572 HOVER,
573
574 // Exactly two fingers but neither have moved enough to clearly indicate
575 // whether a swipe or freeform gesture was intended. We consider the
576 // pointer to be pressed so this enables clicking or long-pressing on buttons.
577 // Pointer does not move.
578 // Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
579 PRESS,
580
581 // Exactly two fingers moving in the same direction, button is not pressed.
582 // Pointer does not move.
583 // Emits DOWN, MOVE and UP events with a single pointer coordinate that
584 // follows the midpoint between both fingers.
585 SWIPE,
586
587 // Two or more fingers moving in arbitrary directions, button is not pressed.
588 // Pointer does not move.
589 // Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
590 // each finger individually relative to the initial centroid of the finger.
591 FREEFORM,
592
593 // Waiting for quiet time to end before starting the next gesture.
594 QUIET,
595 };
596
Prabir Pradhan47cf0a02021-03-11 20:30:57 -0800597 // When a gesture is sent to an unfocused window, return true if it can bring that window
598 // into focus, false otherwise.
599 static bool canGestureAffectWindowFocus(Mode mode) {
600 switch (mode) {
601 case Mode::TAP:
602 case Mode::TAP_DRAG:
603 case Mode::BUTTON_CLICK_OR_DRAG:
604 // Taps can affect window focus.
605 return true;
606 case Mode::FREEFORM:
607 case Mode::HOVER:
608 case Mode::NEUTRAL:
609 case Mode::PRESS:
610 case Mode::QUIET:
611 case Mode::SWIPE:
612 // Most gestures can be performed on an unfocused window, so they should not
613 // not affect window focus.
614 return false;
615 }
616 }
617
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700618 // Time the first finger went down.
619 nsecs_t firstTouchTime;
620
621 // The active pointer id from the raw touch data.
622 int32_t activeTouchId; // -1 if none
623
624 // The active pointer id from the gesture last delivered to the application.
625 int32_t activeGestureId; // -1 if none
626
627 // Pointer coords and ids for the current and previous pointer gesture.
628 Mode currentGestureMode;
629 BitSet32 currentGestureIdBits;
630 uint32_t currentGestureIdToIndex[MAX_POINTER_ID + 1];
631 PointerProperties currentGestureProperties[MAX_POINTERS];
632 PointerCoords currentGestureCoords[MAX_POINTERS];
633
634 Mode lastGestureMode;
635 BitSet32 lastGestureIdBits;
636 uint32_t lastGestureIdToIndex[MAX_POINTER_ID + 1];
637 PointerProperties lastGestureProperties[MAX_POINTERS];
638 PointerCoords lastGestureCoords[MAX_POINTERS];
639
640 // Time the pointer gesture last went down.
641 nsecs_t downTime;
642
643 // Time when the pointer went down for a TAP.
644 nsecs_t tapDownTime;
645
646 // Time when the pointer went up for a TAP.
647 nsecs_t tapUpTime;
648
649 // Location of initial tap.
650 float tapX, tapY;
651
652 // Time we started waiting for quiescence.
653 nsecs_t quietTime;
654
655 // Reference points for multitouch gestures.
656 float referenceTouchX; // reference touch X/Y coordinates in surface units
657 float referenceTouchY;
658 float referenceGestureX; // reference gesture X/Y coordinates in pixels
659 float referenceGestureY;
660
661 // Distance that each pointer has traveled which has not yet been
662 // subsumed into the reference gesture position.
663 BitSet32 referenceIdBits;
664 struct Delta {
665 float dx, dy;
666 };
667 Delta referenceDeltas[MAX_POINTER_ID + 1];
668
669 // Describes how touch ids are mapped to gesture ids for freeform gestures.
670 uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
671
672 // A velocity tracker for determining whether to switch active pointers during drags.
673 VelocityTracker velocityTracker;
674
675 void reset() {
676 firstTouchTime = LLONG_MIN;
677 activeTouchId = -1;
678 activeGestureId = -1;
Michael Wright227c5542020-07-02 18:30:52 +0100679 currentGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700680 currentGestureIdBits.clear();
Michael Wright227c5542020-07-02 18:30:52 +0100681 lastGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700682 lastGestureIdBits.clear();
683 downTime = 0;
684 velocityTracker.clear();
685 resetTap();
686 resetQuietTime();
687 }
688
689 void resetTap() {
690 tapDownTime = LLONG_MIN;
691 tapUpTime = LLONG_MIN;
692 }
693
694 void resetQuietTime() { quietTime = LLONG_MIN; }
695 } mPointerGesture;
696
697 struct PointerSimple {
698 PointerCoords currentCoords;
699 PointerProperties currentProperties;
700 PointerCoords lastCoords;
701 PointerProperties lastProperties;
702
703 // True if the pointer is down.
704 bool down;
705
706 // True if the pointer is hovering.
707 bool hovering;
708
709 // Time the pointer last went down.
710 nsecs_t downTime;
711
712 void reset() {
713 currentCoords.clear();
714 currentProperties.clear();
715 lastCoords.clear();
716 lastProperties.clear();
717 down = false;
718 hovering = false;
719 downTime = 0;
720 }
721 } mPointerSimple;
722
723 // The pointer and scroll velocity controls.
724 VelocityControl mPointerVelocityControl;
725 VelocityControl mWheelXVelocityControl;
726 VelocityControl mWheelYVelocityControl;
727
728 std::optional<DisplayViewport> findViewport();
729
730 void resetExternalStylus();
731 void clearStylusDataPendingFlags();
732
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800733 int32_t clampResolution(const char* axisName, int32_t resolution) const;
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800734 void initializeOrientedRanges();
735 void initializeSizeRanges();
736
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700737 [[nodiscard]] std::list<NotifyArgs> sync(nsecs_t when, nsecs_t readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700738
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700739 [[nodiscard]] std::list<NotifyArgs> consumeRawTouches(nsecs_t when, nsecs_t readTime,
740 uint32_t policyFlags, bool& outConsumed);
741 [[nodiscard]] std::list<NotifyArgs> processRawTouches(bool timeout);
742 [[nodiscard]] std::list<NotifyArgs> cookAndDispatch(nsecs_t when, nsecs_t readTime);
743 [[nodiscard]] NotifyKeyArgs dispatchVirtualKey(nsecs_t when, nsecs_t readTime,
744 uint32_t policyFlags, int32_t keyEventAction,
745 int32_t keyEventFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700746
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700747 [[nodiscard]] std::list<NotifyArgs> dispatchTouches(nsecs_t when, nsecs_t readTime,
748 uint32_t policyFlags);
749 [[nodiscard]] std::list<NotifyArgs> dispatchHoverExit(nsecs_t when, nsecs_t readTime,
750 uint32_t policyFlags);
751 [[nodiscard]] std::list<NotifyArgs> dispatchHoverEnterAndMove(nsecs_t when, nsecs_t readTime,
752 uint32_t policyFlags);
753 [[nodiscard]] std::list<NotifyArgs> dispatchButtonRelease(nsecs_t when, nsecs_t readTime,
754 uint32_t policyFlags);
755 [[nodiscard]] std::list<NotifyArgs> dispatchButtonPress(nsecs_t when, nsecs_t readTime,
756 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700757 const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData);
758 void cookPointerData();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700759 [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime,
760 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700761
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700762 [[nodiscard]] std::list<NotifyArgs> dispatchPointerUsage(nsecs_t when, nsecs_t readTime,
763 uint32_t policyFlags,
764 PointerUsage pointerUsage);
765 [[nodiscard]] std::list<NotifyArgs> abortPointerUsage(nsecs_t when, nsecs_t readTime,
766 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700767
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700768 [[nodiscard]] std::list<NotifyArgs> dispatchPointerGestures(nsecs_t when, nsecs_t readTime,
769 uint32_t policyFlags,
770 bool isTimeout);
771 [[nodiscard]] std::list<NotifyArgs> abortPointerGestures(nsecs_t when, nsecs_t readTime,
772 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700773 bool preparePointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
774 bool* outFinishPreviousGesture, bool isTimeout);
775
Harry Cuttsbea6ce52022-10-14 15:17:30 +0000776 // Returns true if we're in a period of "quiet time" when touchpad gestures should be ignored.
777 bool checkForTouchpadQuietTime(nsecs_t when);
778
779 std::pair<int32_t, float> getFastestFinger();
780
781 void prepareMultiFingerPointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
782 bool* outFinishPreviousGesture);
783
Harry Cutts714d1ad2022-08-24 16:36:43 +0000784 // Moves the on-screen mouse pointer based on the movement of the pointer of the given ID
785 // between the last and current events. Uses a relative motion.
786 void moveMousePointerFromPointerDelta(nsecs_t when, uint32_t pointerId);
787
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700788 [[nodiscard]] std::list<NotifyArgs> dispatchPointerStylus(nsecs_t when, nsecs_t readTime,
789 uint32_t policyFlags);
790 [[nodiscard]] std::list<NotifyArgs> abortPointerStylus(nsecs_t when, nsecs_t readTime,
791 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700792
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700793 [[nodiscard]] std::list<NotifyArgs> dispatchPointerMouse(nsecs_t when, nsecs_t readTime,
794 uint32_t policyFlags);
795 [[nodiscard]] std::list<NotifyArgs> abortPointerMouse(nsecs_t when, nsecs_t readTime,
796 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700797
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700798 [[nodiscard]] std::list<NotifyArgs> dispatchPointerSimple(nsecs_t when, nsecs_t readTime,
799 uint32_t policyFlags, bool down,
800 bool hovering);
801 [[nodiscard]] std::list<NotifyArgs> abortPointerSimple(nsecs_t when, nsecs_t readTime,
802 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700803
804 bool assignExternalStylusId(const RawState& state, bool timeout);
805 void applyExternalStylusButtonState(nsecs_t when);
806 void applyExternalStylusTouchState(nsecs_t when);
807
808 // Dispatches a motion event.
809 // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
810 // method will take care of setting the index and transmuting the action to DOWN or UP
811 // it is the first / last pointer to go down / up.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700812 [[nodiscard]] NotifyMotionArgs dispatchMotion(
813 nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
814 int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
815 int32_t edgeFlags, const PointerProperties* properties, const PointerCoords* coords,
816 const uint32_t* idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
817 float yPrecision, nsecs_t downTime, MotionClassification classification);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700818
819 // Updates pointer coords and properties for pointers with specified ids that have moved.
820 // Returns true if any of them changed.
821 bool updateMovedPointers(const PointerProperties* inProperties, const PointerCoords* inCoords,
822 const uint32_t* inIdToIndex, PointerProperties* outProperties,
823 PointerCoords* outCoords, const uint32_t* outIdToIndex,
824 BitSet32 idBits) const;
825
Garfield Tanc734e4f2021-01-15 20:01:39 -0800826 // Returns if this touch device is a touch screen with an associated display.
827 bool isTouchScreen();
828 // Updates touch spots if they are enabled. Should only be used when this device is a
829 // touchscreen.
830 void updateTouchSpots();
831
Prabir Pradhan1728b212021-10-19 16:00:03 -0700832 bool isPointInsidePhysicalFrame(int32_t x, int32_t y) const;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700833 const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
834
Siarhei Vishniakou57479982021-03-03 01:32:21 +0000835 static void assignPointerIds(const RawState& last, RawState& current);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700836
837 const char* modeToString(DeviceMode deviceMode);
Prabir Pradhan1728b212021-10-19 16:00:03 -0700838 void rotateAndScale(float& x, float& y) const;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700839};
840
841} // namespace android