blob: 769caf0c83897b385bd284b1fa79ebd4f3cd2913 [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
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +000030// Maximum amount of latency to add to touch events while waiting for data from an
31// external stylus.
32static constexpr nsecs_t EXTERNAL_STYLUS_DATA_TIMEOUT = ms2ns(72);
33
34// Maximum amount of time to wait on touch data before pushing out new pressure data.
35static constexpr nsecs_t TOUCH_DATA_TIMEOUT = ms2ns(20);
36
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070037/* Raw axis information from the driver. */
38struct RawPointerAxes {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000039 RawAbsoluteAxisInfo x{};
40 RawAbsoluteAxisInfo y{};
41 RawAbsoluteAxisInfo pressure{};
42 RawAbsoluteAxisInfo touchMajor{};
43 RawAbsoluteAxisInfo touchMinor{};
44 RawAbsoluteAxisInfo toolMajor{};
45 RawAbsoluteAxisInfo toolMinor{};
46 RawAbsoluteAxisInfo orientation{};
47 RawAbsoluteAxisInfo distance{};
48 RawAbsoluteAxisInfo tiltX{};
49 RawAbsoluteAxisInfo tiltY{};
50 RawAbsoluteAxisInfo trackingId{};
51 RawAbsoluteAxisInfo slot{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070052
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070053 inline int32_t getRawWidth() const { return x.maxValue - x.minValue + 1; }
54 inline int32_t getRawHeight() const { return y.maxValue - y.minValue + 1; }
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000055 inline void clear() { *this = RawPointerAxes(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070056};
57
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000058using PropertiesArray = std::array<PointerProperties, MAX_POINTERS>;
59using CoordsArray = std::array<PointerCoords, MAX_POINTERS>;
60using IdToIndexArray = std::array<uint32_t, MAX_POINTER_ID + 1>;
61
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070062/* Raw data for a collection of pointers including a pointer id mapping table. */
63struct RawPointerData {
64 struct Pointer {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000065 uint32_t id{0xFFFFFFFF};
66 int32_t x{};
67 int32_t y{};
68 int32_t pressure{};
69 int32_t touchMajor{};
70 int32_t touchMinor{};
71 int32_t toolMajor{};
72 int32_t toolMinor{};
73 int32_t orientation{};
74 int32_t distance{};
75 int32_t tiltX{};
76 int32_t tiltY{};
77 // A fully decoded AMOTION_EVENT_TOOL_TYPE constant.
78 int32_t toolType{AMOTION_EVENT_TOOL_TYPE_UNKNOWN};
79 bool isHovering{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070080 };
81
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000082 uint32_t pointerCount{};
83 std::array<Pointer, MAX_POINTERS> pointers{};
84 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{};
85 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070086
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000087 inline void clear() { *this = RawPointerData(); }
88
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070089 void getCentroidOfTouchingPointers(float* outX, float* outY) const;
90
91 inline void markIdBit(uint32_t id, bool isHovering) {
92 if (isHovering) {
93 hoveringIdBits.markBit(id);
94 } else {
95 touchingIdBits.markBit(id);
96 }
97 }
98
99 inline void clearIdBits() {
100 hoveringIdBits.clear();
101 touchingIdBits.clear();
arthurhungcc7f9802020-04-30 17:55:40 +0800102 canceledIdBits.clear();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700103 }
104
105 inline const Pointer& pointerForId(uint32_t id) const { return pointers[idToIndex[id]]; }
106
107 inline bool isHovering(uint32_t pointerIndex) { return pointers[pointerIndex].isHovering; }
108};
109
110/* Cooked data for a collection of pointers including a pointer id mapping table. */
111struct CookedPointerData {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000112 uint32_t pointerCount{};
113 PropertiesArray pointerProperties{};
114 CoordsArray pointerCoords{};
115 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{}, validIdBits{};
116 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700117
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000118 inline void clear() { *this = CookedPointerData(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700119
120 inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
121 return pointerCoords[idToIndex[id]];
122 }
123
124 inline PointerCoords& editPointerCoordsWithId(uint32_t id) {
125 return pointerCoords[idToIndex[id]];
126 }
127
128 inline PointerProperties& editPointerPropertiesWithId(uint32_t id) {
129 return pointerProperties[idToIndex[id]];
130 }
131
132 inline bool isHovering(uint32_t pointerIndex) const {
133 return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
134 }
135
136 inline bool isTouching(uint32_t pointerIndex) const {
137 return touchingIdBits.hasBit(pointerProperties[pointerIndex].id);
138 }
Nathaniel R. Lewisadb58ea2019-08-21 04:46:29 +0000139
140 inline bool hasPointerCoordsForId(uint32_t id) const { return validIdBits.hasBit(id); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700141};
142
143class TouchInputMapper : public InputMapper {
144public:
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800145 explicit TouchInputMapper(InputDeviceContext& deviceContext);
Michael Wright227c5542020-07-02 18:30:52 +0100146 ~TouchInputMapper() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700147
Philip Junker4af3b3d2021-12-14 10:36:55 +0100148 uint32_t getSources() const override;
Michael Wright227c5542020-07-02 18:30:52 +0100149 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
150 void dump(std::string& dump) override;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700151 [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
152 const InputReaderConfiguration* config,
153 uint32_t changes) override;
154 [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
155 [[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700156
Michael Wright227c5542020-07-02 18:30:52 +0100157 int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) override;
158 int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700159 bool markSupportedKeyCodes(uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
Michael Wright227c5542020-07-02 18:30:52 +0100160 uint8_t* outFlags) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700161
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700162 [[nodiscard]] std::list<NotifyArgs> cancelTouch(nsecs_t when, nsecs_t readTime) override;
163 [[nodiscard]] std::list<NotifyArgs> timeoutExpired(nsecs_t when) override;
164 [[nodiscard]] std::list<NotifyArgs> updateExternalStylusState(
165 const StylusState& state) override;
Michael Wright227c5542020-07-02 18:30:52 +0100166 std::optional<int32_t> getAssociatedDisplayId() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700167
168protected:
169 CursorButtonAccumulator mCursorButtonAccumulator;
170 CursorScrollAccumulator mCursorScrollAccumulator;
171 TouchButtonAccumulator mTouchButtonAccumulator;
172
173 struct VirtualKey {
174 int32_t keyCode;
175 int32_t scanCode;
176 uint32_t flags;
177
178 // computed hit box, specified in touch screen coords based on known display size
179 int32_t hitLeft;
180 int32_t hitTop;
181 int32_t hitRight;
182 int32_t hitBottom;
183
184 inline bool isHit(int32_t x, int32_t y) const {
185 return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
186 }
187 };
188
189 // Input sources and device mode.
190 uint32_t mSource;
191
Michael Wright227c5542020-07-02 18:30:52 +0100192 enum class DeviceMode {
193 DISABLED, // input is disabled
194 DIRECT, // direct mapping (touchscreen)
195 UNSCALED, // unscaled mapping (touchpad)
196 NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
197 POINTER, // pointer mapping (pointer)
Dominik Laskowski75788452021-02-09 18:51:25 -0800198
199 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700200 };
201 DeviceMode mDeviceMode;
202
203 // The reader's configuration.
204 InputReaderConfiguration mConfig;
205
206 // Immutable configuration parameters.
207 struct Parameters {
Michael Wright227c5542020-07-02 18:30:52 +0100208 enum class DeviceType {
209 TOUCH_SCREEN,
Michael Wright227c5542020-07-02 18:30:52 +0100210 TOUCH_NAVIGATION,
211 POINTER,
Dominik Laskowski75788452021-02-09 18:51:25 -0800212
213 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700214 };
215
216 DeviceType deviceType;
217 bool hasAssociatedDisplay;
218 bool associatedDisplayIsExternal;
219 bool orientationAware;
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700220
221 enum class Orientation : int32_t {
222 ORIENTATION_0 = DISPLAY_ORIENTATION_0,
223 ORIENTATION_90 = DISPLAY_ORIENTATION_90,
224 ORIENTATION_180 = DISPLAY_ORIENTATION_180,
225 ORIENTATION_270 = DISPLAY_ORIENTATION_270,
Dominik Laskowski75788452021-02-09 18:51:25 -0800226
227 ftl_last = ORIENTATION_270
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700228 };
229 Orientation orientation;
230
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700231 bool hasButtonUnderPad;
232 std::string uniqueDisplayId;
233
Michael Wright227c5542020-07-02 18:30:52 +0100234 enum class GestureMode {
235 SINGLE_TOUCH,
236 MULTI_TOUCH,
Dominik Laskowski75788452021-02-09 18:51:25 -0800237
238 ftl_last = MULTI_TOUCH
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700239 };
240 GestureMode gestureMode;
241
242 bool wake;
Prabir Pradhan167c2702022-09-14 00:37:24 +0000243
244 // Whether the device supports the Universal Stylus Initiative (USI) protocol for styluses.
245 bool supportsUsi;
Yuncheol Heo50c19b12022-11-02 20:33:08 -0700246
247 // Allows touches while the display is off.
248 bool enableForInactiveViewport;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700249 } mParameters;
250
251 // Immutable calibration parameters in parsed form.
252 struct Calibration {
253 // Size
Michael Wright227c5542020-07-02 18:30:52 +0100254 enum class SizeCalibration {
255 DEFAULT,
256 NONE,
257 GEOMETRIC,
258 DIAMETER,
259 BOX,
260 AREA,
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800261 ftl_last = AREA
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700262 };
263
264 SizeCalibration sizeCalibration;
265
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700266 std::optional<float> sizeScale;
267 std::optional<float> sizeBias;
268 std::optional<bool> sizeIsSummed;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700269
270 // Pressure
Michael Wright227c5542020-07-02 18:30:52 +0100271 enum class PressureCalibration {
272 DEFAULT,
273 NONE,
274 PHYSICAL,
275 AMPLITUDE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700276 };
277
278 PressureCalibration pressureCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700279 std::optional<float> pressureScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700280
281 // Orientation
Michael Wright227c5542020-07-02 18:30:52 +0100282 enum class OrientationCalibration {
283 DEFAULT,
284 NONE,
285 INTERPOLATED,
286 VECTOR,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700287 };
288
289 OrientationCalibration orientationCalibration;
290
291 // Distance
Michael Wright227c5542020-07-02 18:30:52 +0100292 enum class DistanceCalibration {
293 DEFAULT,
294 NONE,
295 SCALED,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700296 };
297
298 DistanceCalibration distanceCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700299 std::optional<float> distanceScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700300
Michael Wright227c5542020-07-02 18:30:52 +0100301 enum class CoverageCalibration {
302 DEFAULT,
303 NONE,
304 BOX,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700305 };
306
307 CoverageCalibration coverageCalibration;
308
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700309 inline void applySizeScaleAndBias(float& outSize) const {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700310 if (sizeScale) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700311 outSize *= *sizeScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700312 }
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700313 if (sizeBias) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700314 outSize += *sizeBias;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700315 }
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700316 if (outSize < 0) {
317 outSize = 0;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700318 }
319 }
320 } mCalibration;
321
322 // Affine location transformation/calibration
323 struct TouchAffineTransformation mAffineTransform;
324
325 RawPointerAxes mRawPointerAxes;
326
327 struct RawState {
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +0000328 nsecs_t when{std::numeric_limits<nsecs_t>::min()};
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000329 nsecs_t readTime{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700330
331 // Raw pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000332 RawPointerData rawPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700333
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000334 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700335
336 // Scroll state.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000337 int32_t rawVScroll{};
338 int32_t rawHScroll{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700339
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000340 inline void clear() { *this = RawState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700341 };
342
343 struct CookedState {
344 // Cooked pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000345 CookedPointerData cookedPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700346
347 // Id bits used to differentiate fingers, stylus and mouse tools.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000348 BitSet32 fingerIdBits{};
349 BitSet32 stylusIdBits{};
350 BitSet32 mouseIdBits{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700351
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000352 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700353
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000354 inline void clear() { *this = CookedState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700355 };
356
357 std::vector<RawState> mRawStatesPending;
358 RawState mCurrentRawState;
359 CookedState mCurrentCookedState;
360 RawState mLastRawState;
361 CookedState mLastCookedState;
362
363 // State provided by an external stylus
364 StylusState mExternalStylusState;
Prabir Pradhan8d9ba912022-11-11 22:26:33 +0000365 // If an external stylus is capable of reporting pointer-specific data like pressure, we will
366 // attempt to fuse the pointer data reported by the stylus to the first touch pointer. This is
367 // the id of the pointer to which the external stylus data is fused.
368 std::optional<uint32_t> mFusedStylusPointerId;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700369 nsecs_t mExternalStylusFusionTimeout;
370 bool mExternalStylusDataPending;
Prabir Pradhan124ea442022-10-28 20:27:44 +0000371 // A subset of the buttons in mCurrentRawState that came from an external stylus.
372 int32_t mExternalStylusButtonsApplied;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700373
374 // True if we sent a HOVER_ENTER event.
375 bool mSentHoverEnter;
376
377 // Have we assigned pointer IDs for this stream
378 bool mHavePointerIds;
379
380 // Is the current stream of direct touch events aborted
381 bool mCurrentMotionAborted;
382
383 // The time the primary pointer last went down.
384 nsecs_t mDownTime;
385
386 // The pointer controller, or null if the device is not a pointer.
Michael Wright17db18e2020-06-26 20:51:44 +0100387 std::shared_ptr<PointerControllerInterface> mPointerController;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700388
389 std::vector<VirtualKey> mVirtualKeys;
390
391 virtual void configureParameters();
392 virtual void dumpParameters(std::string& dump);
393 virtual void configureRawPointerAxes();
394 virtual void dumpRawPointerAxes(std::string& dump);
Prabir Pradhan1728b212021-10-19 16:00:03 -0700395 virtual void configureInputDevice(nsecs_t when, bool* outResetNeeded);
396 virtual void dumpDisplay(std::string& dump);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700397 virtual void configureVirtualKeys();
398 virtual void dumpVirtualKeys(std::string& dump);
399 virtual void parseCalibration();
400 virtual void resolveCalibration();
401 virtual void dumpCalibration(std::string& dump);
402 virtual void updateAffineTransformation();
403 virtual void dumpAffineTransformation(std::string& dump);
404 virtual void resolveExternalStylusPresence();
405 virtual bool hasStylus() const = 0;
406 virtual bool hasExternalStylus() const;
407
408 virtual void syncTouch(nsecs_t when, RawState* outState) = 0;
409
410private:
411 // The current viewport.
412 // The components of the viewport are specified in the display's rotated orientation.
413 DisplayViewport mViewport;
414
Prabir Pradhan7ddbc952022-11-09 22:03:40 +0000415 // The display size obtained from the viewport in the natural orientation.
416 // Always starts at (0, 0).
417 ui::Size mDisplayBounds{ui::kInvalidSize};
Arthur Hung4197f6b2020-03-16 15:39:59 +0800418
Prabir Pradhan7ddbc952022-11-09 22:03:40 +0000419 // The physical frame is the rectangle in the display's coordinate space that maps to
Prabir Pradhan1728b212021-10-19 16:00:03 -0700420 // the logical display frame.
Prabir Pradhan7ddbc952022-11-09 22:03:40 +0000421 Rect mPhysicalFrameInDisplay{Rect::INVALID_RECT};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700422
Prabir Pradhan1728b212021-10-19 16:00:03 -0700423 // The orientation of the input device relative to that of the display panel. It specifies
424 // the rotation of the input device coordinates required to produce the display panel
425 // orientation, so it will depend on whether the device is orientation aware.
426 int32_t mInputDeviceOrientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700427
428 // Translation and scaling factors, orientation-independent.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700429 float mXScale;
430 float mXPrecision;
431
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700432 float mYScale;
433 float mYPrecision;
434
435 float mGeometricScale;
436
437 float mPressureScale;
438
439 float mSizeScale;
440
441 float mOrientationScale;
442
443 float mDistanceScale;
444
445 bool mHaveTilt;
446 float mTiltXCenter;
447 float mTiltXScale;
448 float mTiltYCenter;
449 float mTiltYScale;
450
451 bool mExternalStylusConnected;
452
453 // Oriented motion ranges for input device info.
454 struct OrientedRanges {
455 InputDeviceInfo::MotionRange x;
456 InputDeviceInfo::MotionRange y;
457 InputDeviceInfo::MotionRange pressure;
458
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700459 std::optional<InputDeviceInfo::MotionRange> size;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700460
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700461 std::optional<InputDeviceInfo::MotionRange> touchMajor;
462 std::optional<InputDeviceInfo::MotionRange> touchMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700463
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700464 std::optional<InputDeviceInfo::MotionRange> toolMajor;
465 std::optional<InputDeviceInfo::MotionRange> toolMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700466
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700467 std::optional<InputDeviceInfo::MotionRange> orientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700468
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700469 std::optional<InputDeviceInfo::MotionRange> distance;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700470
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700471 std::optional<InputDeviceInfo::MotionRange> tilt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700472
473 void clear() {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700474 size = std::nullopt;
475 touchMajor = std::nullopt;
476 touchMinor = std::nullopt;
477 toolMajor = std::nullopt;
478 toolMinor = std::nullopt;
479 orientation = std::nullopt;
480 distance = std::nullopt;
481 tilt = std::nullopt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700482 }
483 } mOrientedRanges;
484
485 // Oriented dimensions and precision.
486 float mOrientedXPrecision;
487 float mOrientedYPrecision;
488
489 struct CurrentVirtualKeyState {
490 bool down;
491 bool ignored;
492 nsecs_t downTime;
493 int32_t keyCode;
494 int32_t scanCode;
495 } mCurrentVirtualKey;
496
497 // Scale factor for gesture or mouse based pointer movements.
498 float mPointerXMovementScale;
499 float mPointerYMovementScale;
500
501 // Scale factor for gesture based zooming and other freeform motions.
502 float mPointerXZoomScale;
503 float mPointerYZoomScale;
504
HQ Liue6983c72022-04-19 22:14:56 +0000505 // The maximum swipe width between pointers to detect a swipe gesture
506 // in the number of pixels.Touches that are wider than this are translated
507 // into freeform gestures.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700508 float mPointerGestureMaxSwipeWidth;
509
510 struct PointerDistanceHeapElement {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000511 uint32_t currentPointerIndex : 8 {};
512 uint32_t lastPointerIndex : 8 {};
513 uint64_t distance : 48 {}; // squared distance
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700514 };
515
Michael Wright227c5542020-07-02 18:30:52 +0100516 enum class PointerUsage {
517 NONE,
518 GESTURES,
519 STYLUS,
520 MOUSE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700521 };
522 PointerUsage mPointerUsage;
523
524 struct PointerGesture {
Michael Wright227c5542020-07-02 18:30:52 +0100525 enum class Mode {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700526 // No fingers, button is not pressed.
527 // Nothing happening.
528 NEUTRAL,
529
530 // No fingers, button is not pressed.
531 // Tap detected.
532 // Emits DOWN and UP events at the pointer location.
533 TAP,
534
535 // Exactly one finger dragging following a tap.
536 // Pointer follows the active finger.
537 // Emits DOWN, MOVE and UP events at the pointer location.
538 //
539 // Detect double-taps when the finger goes up while in TAP_DRAG mode.
540 TAP_DRAG,
541
542 // Button is pressed.
543 // Pointer follows the active finger if there is one. Other fingers are ignored.
544 // Emits DOWN, MOVE and UP events at the pointer location.
545 BUTTON_CLICK_OR_DRAG,
546
547 // Exactly one finger, button is not pressed.
548 // Pointer follows the active finger.
549 // Emits HOVER_MOVE events at the pointer location.
550 //
551 // Detect taps when the finger goes up while in HOVER mode.
552 HOVER,
553
554 // Exactly two fingers but neither have moved enough to clearly indicate
555 // whether a swipe or freeform gesture was intended. We consider the
556 // pointer to be pressed so this enables clicking or long-pressing on buttons.
557 // Pointer does not move.
558 // Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
559 PRESS,
560
561 // Exactly two fingers moving in the same direction, button is not pressed.
562 // Pointer does not move.
563 // Emits DOWN, MOVE and UP events with a single pointer coordinate that
564 // follows the midpoint between both fingers.
565 SWIPE,
566
567 // Two or more fingers moving in arbitrary directions, button is not pressed.
568 // Pointer does not move.
569 // Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
570 // each finger individually relative to the initial centroid of the finger.
571 FREEFORM,
572
573 // Waiting for quiet time to end before starting the next gesture.
574 QUIET,
575 };
576
Prabir Pradhan47cf0a02021-03-11 20:30:57 -0800577 // When a gesture is sent to an unfocused window, return true if it can bring that window
578 // into focus, false otherwise.
579 static bool canGestureAffectWindowFocus(Mode mode) {
580 switch (mode) {
581 case Mode::TAP:
582 case Mode::TAP_DRAG:
583 case Mode::BUTTON_CLICK_OR_DRAG:
584 // Taps can affect window focus.
585 return true;
586 case Mode::FREEFORM:
587 case Mode::HOVER:
588 case Mode::NEUTRAL:
589 case Mode::PRESS:
590 case Mode::QUIET:
591 case Mode::SWIPE:
592 // Most gestures can be performed on an unfocused window, so they should not
593 // not affect window focus.
594 return false;
595 }
596 }
597
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700598 // Time the first finger went down.
599 nsecs_t firstTouchTime;
600
601 // The active pointer id from the raw touch data.
602 int32_t activeTouchId; // -1 if none
603
604 // The active pointer id from the gesture last delivered to the application.
605 int32_t activeGestureId; // -1 if none
606
607 // Pointer coords and ids for the current and previous pointer gesture.
608 Mode currentGestureMode;
609 BitSet32 currentGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000610 IdToIndexArray currentGestureIdToIndex{};
611 PropertiesArray currentGestureProperties{};
612 CoordsArray currentGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700613
614 Mode lastGestureMode;
615 BitSet32 lastGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000616 IdToIndexArray lastGestureIdToIndex{};
617 PropertiesArray lastGestureProperties{};
618 CoordsArray lastGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700619
620 // Time the pointer gesture last went down.
621 nsecs_t downTime;
622
623 // Time when the pointer went down for a TAP.
624 nsecs_t tapDownTime;
625
626 // Time when the pointer went up for a TAP.
627 nsecs_t tapUpTime;
628
629 // Location of initial tap.
630 float tapX, tapY;
631
632 // Time we started waiting for quiescence.
633 nsecs_t quietTime;
634
635 // Reference points for multitouch gestures.
636 float referenceTouchX; // reference touch X/Y coordinates in surface units
637 float referenceTouchY;
638 float referenceGestureX; // reference gesture X/Y coordinates in pixels
639 float referenceGestureY;
640
641 // Distance that each pointer has traveled which has not yet been
642 // subsumed into the reference gesture position.
643 BitSet32 referenceIdBits;
644 struct Delta {
645 float dx, dy;
646 };
647 Delta referenceDeltas[MAX_POINTER_ID + 1];
648
649 // Describes how touch ids are mapped to gesture ids for freeform gestures.
650 uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
651
652 // A velocity tracker for determining whether to switch active pointers during drags.
653 VelocityTracker velocityTracker;
654
655 void reset() {
656 firstTouchTime = LLONG_MIN;
657 activeTouchId = -1;
658 activeGestureId = -1;
Michael Wright227c5542020-07-02 18:30:52 +0100659 currentGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700660 currentGestureIdBits.clear();
Michael Wright227c5542020-07-02 18:30:52 +0100661 lastGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700662 lastGestureIdBits.clear();
663 downTime = 0;
664 velocityTracker.clear();
665 resetTap();
666 resetQuietTime();
667 }
668
669 void resetTap() {
670 tapDownTime = LLONG_MIN;
671 tapUpTime = LLONG_MIN;
672 }
673
674 void resetQuietTime() { quietTime = LLONG_MIN; }
675 } mPointerGesture;
676
677 struct PointerSimple {
678 PointerCoords currentCoords;
679 PointerProperties currentProperties;
680 PointerCoords lastCoords;
681 PointerProperties lastProperties;
682
683 // True if the pointer is down.
684 bool down;
685
686 // True if the pointer is hovering.
687 bool hovering;
688
689 // Time the pointer last went down.
690 nsecs_t downTime;
691
Prabir Pradhanb80b6c02022-11-02 20:05:13 +0000692 // Values reported for the last pointer event.
693 uint32_t source;
694 int32_t displayId;
695 float lastCursorX;
696 float lastCursorY;
697
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700698 void reset() {
699 currentCoords.clear();
700 currentProperties.clear();
701 lastCoords.clear();
702 lastProperties.clear();
703 down = false;
704 hovering = false;
705 downTime = 0;
Prabir Pradhanb80b6c02022-11-02 20:05:13 +0000706 source = 0;
707 displayId = ADISPLAY_ID_NONE;
708 lastCursorX = 0.f;
709 lastCursorY = 0.f;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700710 }
711 } mPointerSimple;
712
713 // The pointer and scroll velocity controls.
714 VelocityControl mPointerVelocityControl;
715 VelocityControl mWheelXVelocityControl;
716 VelocityControl mWheelYVelocityControl;
717
718 std::optional<DisplayViewport> findViewport();
719
720 void resetExternalStylus();
721 void clearStylusDataPendingFlags();
722
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800723 int32_t clampResolution(const char* axisName, int32_t resolution) const;
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800724 void initializeOrientedRanges();
725 void initializeSizeRanges();
726
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700727 [[nodiscard]] std::list<NotifyArgs> sync(nsecs_t when, nsecs_t readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700728
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700729 [[nodiscard]] std::list<NotifyArgs> consumeRawTouches(nsecs_t when, nsecs_t readTime,
730 uint32_t policyFlags, bool& outConsumed);
731 [[nodiscard]] std::list<NotifyArgs> processRawTouches(bool timeout);
732 [[nodiscard]] std::list<NotifyArgs> cookAndDispatch(nsecs_t when, nsecs_t readTime);
733 [[nodiscard]] NotifyKeyArgs dispatchVirtualKey(nsecs_t when, nsecs_t readTime,
734 uint32_t policyFlags, int32_t keyEventAction,
735 int32_t keyEventFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700736
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700737 [[nodiscard]] std::list<NotifyArgs> dispatchTouches(nsecs_t when, nsecs_t readTime,
738 uint32_t policyFlags);
739 [[nodiscard]] std::list<NotifyArgs> dispatchHoverExit(nsecs_t when, nsecs_t readTime,
740 uint32_t policyFlags);
741 [[nodiscard]] std::list<NotifyArgs> dispatchHoverEnterAndMove(nsecs_t when, nsecs_t readTime,
742 uint32_t policyFlags);
743 [[nodiscard]] std::list<NotifyArgs> dispatchButtonRelease(nsecs_t when, nsecs_t readTime,
744 uint32_t policyFlags);
745 [[nodiscard]] std::list<NotifyArgs> dispatchButtonPress(nsecs_t when, nsecs_t readTime,
746 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700747 const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData);
748 void cookPointerData();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700749 [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime,
750 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700751
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700752 [[nodiscard]] std::list<NotifyArgs> dispatchPointerUsage(nsecs_t when, nsecs_t readTime,
753 uint32_t policyFlags,
754 PointerUsage pointerUsage);
755 [[nodiscard]] std::list<NotifyArgs> abortPointerUsage(nsecs_t when, nsecs_t readTime,
756 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700757
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700758 [[nodiscard]] std::list<NotifyArgs> dispatchPointerGestures(nsecs_t when, nsecs_t readTime,
759 uint32_t policyFlags,
760 bool isTimeout);
761 [[nodiscard]] std::list<NotifyArgs> abortPointerGestures(nsecs_t when, nsecs_t readTime,
762 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700763 bool preparePointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
764 bool* outFinishPreviousGesture, bool isTimeout);
765
Harry Cuttsbea6ce52022-10-14 15:17:30 +0000766 // Returns true if we're in a period of "quiet time" when touchpad gestures should be ignored.
767 bool checkForTouchpadQuietTime(nsecs_t when);
768
769 std::pair<int32_t, float> getFastestFinger();
770
771 void prepareMultiFingerPointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
772 bool* outFinishPreviousGesture);
773
Harry Cutts714d1ad2022-08-24 16:36:43 +0000774 // Moves the on-screen mouse pointer based on the movement of the pointer of the given ID
775 // between the last and current events. Uses a relative motion.
776 void moveMousePointerFromPointerDelta(nsecs_t when, uint32_t pointerId);
777
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700778 [[nodiscard]] std::list<NotifyArgs> dispatchPointerStylus(nsecs_t when, nsecs_t readTime,
779 uint32_t policyFlags);
780 [[nodiscard]] std::list<NotifyArgs> abortPointerStylus(nsecs_t when, nsecs_t readTime,
781 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700782
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700783 [[nodiscard]] std::list<NotifyArgs> dispatchPointerMouse(nsecs_t when, nsecs_t readTime,
784 uint32_t policyFlags);
785 [[nodiscard]] std::list<NotifyArgs> abortPointerMouse(nsecs_t when, nsecs_t readTime,
786 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700787
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700788 [[nodiscard]] std::list<NotifyArgs> dispatchPointerSimple(nsecs_t when, nsecs_t readTime,
789 uint32_t policyFlags, bool down,
790 bool hovering);
791 [[nodiscard]] std::list<NotifyArgs> abortPointerSimple(nsecs_t when, nsecs_t readTime,
792 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700793
Prabir Pradhan3f7545f2022-10-19 16:56:39 +0000794 // Attempts to assign a pointer id to the external stylus. Returns true if the state should be
795 // withheld from further processing while waiting for data from the stylus.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700796 bool assignExternalStylusId(const RawState& state, bool timeout);
797 void applyExternalStylusButtonState(nsecs_t when);
798 void applyExternalStylusTouchState(nsecs_t when);
799
800 // Dispatches a motion event.
801 // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
802 // method will take care of setting the index and transmuting the action to DOWN or UP
803 // it is the first / last pointer to go down / up.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700804 [[nodiscard]] NotifyMotionArgs dispatchMotion(
805 nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
806 int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000807 int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords,
808 const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700809 float yPrecision, nsecs_t downTime, MotionClassification classification);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700810
Garfield Tanc734e4f2021-01-15 20:01:39 -0800811 // Returns if this touch device is a touch screen with an associated display.
812 bool isTouchScreen();
813 // Updates touch spots if they are enabled. Should only be used when this device is a
814 // touchscreen.
815 void updateTouchSpots();
816
Prabir Pradhan1728b212021-10-19 16:00:03 -0700817 bool isPointInsidePhysicalFrame(int32_t x, int32_t y) const;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700818 const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
819
Siarhei Vishniakou57479982021-03-03 01:32:21 +0000820 static void assignPointerIds(const RawState& last, RawState& current);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700821
Prabir Pradhan1728b212021-10-19 16:00:03 -0700822 void rotateAndScale(float& x, float& y) const;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700823};
824
825} // namespace android