blob: 7b464efccbe0ea9f64a76568b6adae157bece2b0 [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>
Michael Wrighta9cf4192022-12-01 23:46:39 +000020#include <ui/Rotation.h>
Michael Wright227c5542020-07-02 18:30:52 +010021
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070022#include "CursorButtonAccumulator.h"
23#include "CursorScrollAccumulator.h"
24#include "EventHub.h"
25#include "InputMapper.h"
26#include "InputReaderBase.h"
27#include "TouchButtonAccumulator.h"
28
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070029namespace android {
30
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +000031// Maximum amount of latency to add to touch events while waiting for data from an
32// external stylus.
33static constexpr nsecs_t EXTERNAL_STYLUS_DATA_TIMEOUT = ms2ns(72);
34
35// Maximum amount of time to wait on touch data before pushing out new pressure data.
36static constexpr nsecs_t TOUCH_DATA_TIMEOUT = ms2ns(20);
37
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070038/* Raw axis information from the driver. */
39struct RawPointerAxes {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000040 RawAbsoluteAxisInfo x{};
41 RawAbsoluteAxisInfo y{};
42 RawAbsoluteAxisInfo pressure{};
43 RawAbsoluteAxisInfo touchMajor{};
44 RawAbsoluteAxisInfo touchMinor{};
45 RawAbsoluteAxisInfo toolMajor{};
46 RawAbsoluteAxisInfo toolMinor{};
47 RawAbsoluteAxisInfo orientation{};
48 RawAbsoluteAxisInfo distance{};
49 RawAbsoluteAxisInfo tiltX{};
50 RawAbsoluteAxisInfo tiltY{};
51 RawAbsoluteAxisInfo trackingId{};
52 RawAbsoluteAxisInfo slot{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070053
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070054 inline int32_t getRawWidth() const { return x.maxValue - x.minValue + 1; }
55 inline int32_t getRawHeight() const { return y.maxValue - y.minValue + 1; }
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000056 inline void clear() { *this = RawPointerAxes(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070057};
58
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000059using PropertiesArray = std::array<PointerProperties, MAX_POINTERS>;
60using CoordsArray = std::array<PointerCoords, MAX_POINTERS>;
61using IdToIndexArray = std::array<uint32_t, MAX_POINTER_ID + 1>;
62
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070063/* Raw data for a collection of pointers including a pointer id mapping table. */
64struct RawPointerData {
65 struct Pointer {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000066 uint32_t id{0xFFFFFFFF};
67 int32_t x{};
68 int32_t y{};
69 int32_t pressure{};
70 int32_t touchMajor{};
71 int32_t touchMinor{};
72 int32_t toolMajor{};
73 int32_t toolMinor{};
74 int32_t orientation{};
75 int32_t distance{};
76 int32_t tiltX{};
77 int32_t tiltY{};
78 // A fully decoded AMOTION_EVENT_TOOL_TYPE constant.
79 int32_t toolType{AMOTION_EVENT_TOOL_TYPE_UNKNOWN};
80 bool isHovering{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070081 };
82
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000083 uint32_t pointerCount{};
84 std::array<Pointer, MAX_POINTERS> pointers{};
85 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{};
86 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070087
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000088 inline void clear() { *this = RawPointerData(); }
89
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070090 void getCentroidOfTouchingPointers(float* outX, float* outY) const;
91
92 inline void markIdBit(uint32_t id, bool isHovering) {
93 if (isHovering) {
94 hoveringIdBits.markBit(id);
95 } else {
96 touchingIdBits.markBit(id);
97 }
98 }
99
100 inline void clearIdBits() {
101 hoveringIdBits.clear();
102 touchingIdBits.clear();
arthurhungcc7f9802020-04-30 17:55:40 +0800103 canceledIdBits.clear();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700104 }
105
106 inline const Pointer& pointerForId(uint32_t id) const { return pointers[idToIndex[id]]; }
107
108 inline bool isHovering(uint32_t pointerIndex) { return pointers[pointerIndex].isHovering; }
109};
110
111/* Cooked data for a collection of pointers including a pointer id mapping table. */
112struct CookedPointerData {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000113 uint32_t pointerCount{};
114 PropertiesArray pointerProperties{};
115 CoordsArray pointerCoords{};
116 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{}, validIdBits{};
117 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700118
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000119 inline void clear() { *this = CookedPointerData(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700120
121 inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
122 return pointerCoords[idToIndex[id]];
123 }
124
125 inline PointerCoords& editPointerCoordsWithId(uint32_t id) {
126 return pointerCoords[idToIndex[id]];
127 }
128
129 inline PointerProperties& editPointerPropertiesWithId(uint32_t id) {
130 return pointerProperties[idToIndex[id]];
131 }
132
133 inline bool isHovering(uint32_t pointerIndex) const {
134 return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
135 }
136
137 inline bool isTouching(uint32_t pointerIndex) const {
138 return touchingIdBits.hasBit(pointerProperties[pointerIndex].id);
139 }
Nathaniel R. Lewisadb58ea2019-08-21 04:46:29 +0000140
141 inline bool hasPointerCoordsForId(uint32_t id) const { return validIdBits.hasBit(id); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700142};
143
144class TouchInputMapper : public InputMapper {
145public:
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800146 explicit TouchInputMapper(InputDeviceContext& deviceContext);
Michael Wright227c5542020-07-02 18:30:52 +0100147 ~TouchInputMapper() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700148
Philip Junker4af3b3d2021-12-14 10:36:55 +0100149 uint32_t getSources() const override;
Michael Wright227c5542020-07-02 18:30:52 +0100150 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
151 void dump(std::string& dump) override;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700152 [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
153 const InputReaderConfiguration* config,
154 uint32_t changes) override;
155 [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
156 [[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700157
Michael Wright227c5542020-07-02 18:30:52 +0100158 int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) override;
159 int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700160 bool markSupportedKeyCodes(uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
Michael Wright227c5542020-07-02 18:30:52 +0100161 uint8_t* outFlags) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700162
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700163 [[nodiscard]] std::list<NotifyArgs> cancelTouch(nsecs_t when, nsecs_t readTime) override;
164 [[nodiscard]] std::list<NotifyArgs> timeoutExpired(nsecs_t when) override;
165 [[nodiscard]] std::list<NotifyArgs> updateExternalStylusState(
166 const StylusState& state) override;
Michael Wright227c5542020-07-02 18:30:52 +0100167 std::optional<int32_t> getAssociatedDisplayId() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700168
169protected:
170 CursorButtonAccumulator mCursorButtonAccumulator;
171 CursorScrollAccumulator mCursorScrollAccumulator;
172 TouchButtonAccumulator mTouchButtonAccumulator;
173
174 struct VirtualKey {
175 int32_t keyCode;
176 int32_t scanCode;
177 uint32_t flags;
178
179 // computed hit box, specified in touch screen coords based on known display size
180 int32_t hitLeft;
181 int32_t hitTop;
182 int32_t hitRight;
183 int32_t hitBottom;
184
185 inline bool isHit(int32_t x, int32_t y) const {
186 return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
187 }
188 };
189
190 // Input sources and device mode.
191 uint32_t mSource;
192
Michael Wright227c5542020-07-02 18:30:52 +0100193 enum class DeviceMode {
194 DISABLED, // input is disabled
195 DIRECT, // direct mapping (touchscreen)
196 UNSCALED, // unscaled mapping (touchpad)
197 NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
198 POINTER, // pointer mapping (pointer)
Dominik Laskowski75788452021-02-09 18:51:25 -0800199
200 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700201 };
202 DeviceMode mDeviceMode;
203
204 // The reader's configuration.
205 InputReaderConfiguration mConfig;
206
207 // Immutable configuration parameters.
208 struct Parameters {
Michael Wright227c5542020-07-02 18:30:52 +0100209 enum class DeviceType {
210 TOUCH_SCREEN,
Michael Wright227c5542020-07-02 18:30:52 +0100211 TOUCH_NAVIGATION,
212 POINTER,
Dominik Laskowski75788452021-02-09 18:51:25 -0800213
214 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700215 };
216
217 DeviceType deviceType;
218 bool hasAssociatedDisplay;
219 bool associatedDisplayIsExternal;
220 bool orientationAware;
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700221
Michael Wrighta9cf4192022-12-01 23:46:39 +0000222 ui::Rotation orientation;
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700223
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
Prabir Pradhane04ffaa2022-12-13 23:04:04 +0000237 // The Universal Stylus Initiative (USI) protocol version supported by this device.
238 std::optional<InputDeviceUsiVersion> usiVersion;
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
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700294 inline void applySizeScaleAndBias(float& outSize) const {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700295 if (sizeScale) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700296 outSize *= *sizeScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700297 }
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700298 if (sizeBias) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700299 outSize += *sizeBias;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700300 }
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700301 if (outSize < 0) {
302 outSize = 0;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700303 }
304 }
305 } mCalibration;
306
307 // Affine location transformation/calibration
308 struct TouchAffineTransformation mAffineTransform;
309
310 RawPointerAxes mRawPointerAxes;
311
312 struct RawState {
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +0000313 nsecs_t when{std::numeric_limits<nsecs_t>::min()};
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000314 nsecs_t readTime{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700315
316 // Raw pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000317 RawPointerData rawPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700318
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000319 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700320
321 // Scroll state.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000322 int32_t rawVScroll{};
323 int32_t rawHScroll{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700324
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000325 inline void clear() { *this = RawState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700326 };
327
328 struct CookedState {
329 // Cooked pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000330 CookedPointerData cookedPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700331
332 // Id bits used to differentiate fingers, stylus and mouse tools.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000333 BitSet32 fingerIdBits{};
334 BitSet32 stylusIdBits{};
335 BitSet32 mouseIdBits{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700336
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000337 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700338
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000339 inline void clear() { *this = CookedState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700340 };
341
342 std::vector<RawState> mRawStatesPending;
343 RawState mCurrentRawState;
344 CookedState mCurrentCookedState;
345 RawState mLastRawState;
346 CookedState mLastCookedState;
347
348 // State provided by an external stylus
349 StylusState mExternalStylusState;
Prabir Pradhan8d9ba912022-11-11 22:26:33 +0000350 // If an external stylus is capable of reporting pointer-specific data like pressure, we will
351 // attempt to fuse the pointer data reported by the stylus to the first touch pointer. This is
352 // the id of the pointer to which the external stylus data is fused.
353 std::optional<uint32_t> mFusedStylusPointerId;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700354 nsecs_t mExternalStylusFusionTimeout;
355 bool mExternalStylusDataPending;
Prabir Pradhan124ea442022-10-28 20:27:44 +0000356 // A subset of the buttons in mCurrentRawState that came from an external stylus.
357 int32_t mExternalStylusButtonsApplied;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700358
359 // True if we sent a HOVER_ENTER event.
360 bool mSentHoverEnter;
361
362 // Have we assigned pointer IDs for this stream
363 bool mHavePointerIds;
364
365 // Is the current stream of direct touch events aborted
366 bool mCurrentMotionAborted;
367
368 // The time the primary pointer last went down.
369 nsecs_t mDownTime;
370
371 // The pointer controller, or null if the device is not a pointer.
Michael Wright17db18e2020-06-26 20:51:44 +0100372 std::shared_ptr<PointerControllerInterface> mPointerController;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700373
374 std::vector<VirtualKey> mVirtualKeys;
375
376 virtual void configureParameters();
377 virtual void dumpParameters(std::string& dump);
378 virtual void configureRawPointerAxes();
379 virtual void dumpRawPointerAxes(std::string& dump);
Prabir Pradhan1728b212021-10-19 16:00:03 -0700380 virtual void configureInputDevice(nsecs_t when, bool* outResetNeeded);
381 virtual void dumpDisplay(std::string& dump);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700382 virtual void configureVirtualKeys();
383 virtual void dumpVirtualKeys(std::string& dump);
384 virtual void parseCalibration();
385 virtual void resolveCalibration();
386 virtual void dumpCalibration(std::string& dump);
387 virtual void updateAffineTransformation();
388 virtual void dumpAffineTransformation(std::string& dump);
389 virtual void resolveExternalStylusPresence();
390 virtual bool hasStylus() const = 0;
391 virtual bool hasExternalStylus() const;
392
393 virtual void syncTouch(nsecs_t when, RawState* outState) = 0;
394
395private:
396 // The current viewport.
397 // The components of the viewport are specified in the display's rotated orientation.
398 DisplayViewport mViewport;
399
Prabir Pradhan2d613f42022-11-10 20:22:06 +0000400 // We refer to the display as being in the "natural orientation" when there is no rotation
401 // applied. The display size obtained from the viewport in the natural orientation.
Prabir Pradhan7ddbc952022-11-09 22:03:40 +0000402 // Always starts at (0, 0).
403 ui::Size mDisplayBounds{ui::kInvalidSize};
Arthur Hung4197f6b2020-03-16 15:39:59 +0800404
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000405 // The physical frame is the rectangle in the rotated display's coordinate space that maps to
Prabir Pradhan1728b212021-10-19 16:00:03 -0700406 // the logical display frame.
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000407 Rect mPhysicalFrameInRotatedDisplay{Rect::INVALID_RECT};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700408
Prabir Pradhan1728b212021-10-19 16:00:03 -0700409 // The orientation of the input device relative to that of the display panel. It specifies
410 // the rotation of the input device coordinates required to produce the display panel
411 // orientation, so it will depend on whether the device is orientation aware.
Michael Wrighta9cf4192022-12-01 23:46:39 +0000412 ui::Rotation mInputDeviceOrientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700413
Prabir Pradhanea31d4f2022-11-10 20:48:01 +0000414 // The transform that maps the input device's raw coordinate space to the un-rotated display's
415 // coordinate space. InputReader generates events in the un-rotated display's coordinate space.
416 ui::Transform mRawToDisplay;
417
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000418 // The transform that maps the input device's raw coordinate space to the rotated display's
419 // coordinate space. This used to perform hit-testing of raw events with the physical frame in
420 // the rotated coordinate space. See mPhysicalFrameInRotatedDisplay.
421 ui::Transform mRawToRotatedDisplay;
422
Prabir Pradhane2e10b42022-11-17 20:59:36 +0000423 // The transform used for non-planar raw axes, such as orientation and tilt.
424 ui::Transform mRawRotation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700425
426 float mGeometricScale;
427
428 float mPressureScale;
429
430 float mSizeScale;
431
432 float mOrientationScale;
433
434 float mDistanceScale;
435
436 bool mHaveTilt;
437 float mTiltXCenter;
438 float mTiltXScale;
439 float mTiltYCenter;
440 float mTiltYScale;
441
442 bool mExternalStylusConnected;
443
444 // Oriented motion ranges for input device info.
445 struct OrientedRanges {
446 InputDeviceInfo::MotionRange x;
447 InputDeviceInfo::MotionRange y;
448 InputDeviceInfo::MotionRange pressure;
449
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700450 std::optional<InputDeviceInfo::MotionRange> size;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700451
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700452 std::optional<InputDeviceInfo::MotionRange> touchMajor;
453 std::optional<InputDeviceInfo::MotionRange> touchMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700454
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700455 std::optional<InputDeviceInfo::MotionRange> toolMajor;
456 std::optional<InputDeviceInfo::MotionRange> toolMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700457
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700458 std::optional<InputDeviceInfo::MotionRange> orientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700459
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700460 std::optional<InputDeviceInfo::MotionRange> distance;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700461
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700462 std::optional<InputDeviceInfo::MotionRange> tilt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700463
464 void clear() {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700465 size = std::nullopt;
466 touchMajor = std::nullopt;
467 touchMinor = std::nullopt;
468 toolMajor = std::nullopt;
469 toolMinor = std::nullopt;
470 orientation = std::nullopt;
471 distance = std::nullopt;
472 tilt = std::nullopt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700473 }
474 } mOrientedRanges;
475
476 // Oriented dimensions and precision.
477 float mOrientedXPrecision;
478 float mOrientedYPrecision;
479
480 struct CurrentVirtualKeyState {
481 bool down;
482 bool ignored;
483 nsecs_t downTime;
484 int32_t keyCode;
485 int32_t scanCode;
486 } mCurrentVirtualKey;
487
488 // Scale factor for gesture or mouse based pointer movements.
489 float mPointerXMovementScale;
490 float mPointerYMovementScale;
491
492 // Scale factor for gesture based zooming and other freeform motions.
493 float mPointerXZoomScale;
494 float mPointerYZoomScale;
495
HQ Liue6983c72022-04-19 22:14:56 +0000496 // The maximum swipe width between pointers to detect a swipe gesture
497 // in the number of pixels.Touches that are wider than this are translated
498 // into freeform gestures.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700499 float mPointerGestureMaxSwipeWidth;
500
501 struct PointerDistanceHeapElement {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000502 uint32_t currentPointerIndex : 8 {};
503 uint32_t lastPointerIndex : 8 {};
504 uint64_t distance : 48 {}; // squared distance
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700505 };
506
Michael Wright227c5542020-07-02 18:30:52 +0100507 enum class PointerUsage {
508 NONE,
509 GESTURES,
510 STYLUS,
511 MOUSE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700512 };
513 PointerUsage mPointerUsage;
514
515 struct PointerGesture {
Michael Wright227c5542020-07-02 18:30:52 +0100516 enum class Mode {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700517 // No fingers, button is not pressed.
518 // Nothing happening.
519 NEUTRAL,
520
521 // No fingers, button is not pressed.
522 // Tap detected.
523 // Emits DOWN and UP events at the pointer location.
524 TAP,
525
526 // Exactly one finger dragging following a tap.
527 // Pointer follows the active finger.
528 // Emits DOWN, MOVE and UP events at the pointer location.
529 //
530 // Detect double-taps when the finger goes up while in TAP_DRAG mode.
531 TAP_DRAG,
532
533 // Button is pressed.
534 // Pointer follows the active finger if there is one. Other fingers are ignored.
535 // Emits DOWN, MOVE and UP events at the pointer location.
536 BUTTON_CLICK_OR_DRAG,
537
538 // Exactly one finger, button is not pressed.
539 // Pointer follows the active finger.
540 // Emits HOVER_MOVE events at the pointer location.
541 //
542 // Detect taps when the finger goes up while in HOVER mode.
543 HOVER,
544
545 // Exactly two fingers but neither have moved enough to clearly indicate
546 // whether a swipe or freeform gesture was intended. We consider the
547 // pointer to be pressed so this enables clicking or long-pressing on buttons.
548 // Pointer does not move.
549 // Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
550 PRESS,
551
552 // Exactly two fingers moving in the same direction, button is not pressed.
553 // Pointer does not move.
554 // Emits DOWN, MOVE and UP events with a single pointer coordinate that
555 // follows the midpoint between both fingers.
556 SWIPE,
557
558 // Two or more fingers moving in arbitrary directions, button is not pressed.
559 // Pointer does not move.
560 // Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
561 // each finger individually relative to the initial centroid of the finger.
562 FREEFORM,
563
564 // Waiting for quiet time to end before starting the next gesture.
565 QUIET,
566 };
567
Prabir Pradhan47cf0a02021-03-11 20:30:57 -0800568 // When a gesture is sent to an unfocused window, return true if it can bring that window
569 // into focus, false otherwise.
570 static bool canGestureAffectWindowFocus(Mode mode) {
571 switch (mode) {
572 case Mode::TAP:
573 case Mode::TAP_DRAG:
574 case Mode::BUTTON_CLICK_OR_DRAG:
575 // Taps can affect window focus.
576 return true;
577 case Mode::FREEFORM:
578 case Mode::HOVER:
579 case Mode::NEUTRAL:
580 case Mode::PRESS:
581 case Mode::QUIET:
582 case Mode::SWIPE:
583 // Most gestures can be performed on an unfocused window, so they should not
584 // not affect window focus.
585 return false;
586 }
587 }
588
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700589 // Time the first finger went down.
590 nsecs_t firstTouchTime;
591
592 // The active pointer id from the raw touch data.
593 int32_t activeTouchId; // -1 if none
594
595 // The active pointer id from the gesture last delivered to the application.
596 int32_t activeGestureId; // -1 if none
597
598 // Pointer coords and ids for the current and previous pointer gesture.
599 Mode currentGestureMode;
600 BitSet32 currentGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000601 IdToIndexArray currentGestureIdToIndex{};
602 PropertiesArray currentGestureProperties{};
603 CoordsArray currentGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700604
605 Mode lastGestureMode;
606 BitSet32 lastGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000607 IdToIndexArray lastGestureIdToIndex{};
608 PropertiesArray lastGestureProperties{};
609 CoordsArray lastGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700610
611 // Time the pointer gesture last went down.
612 nsecs_t downTime;
613
614 // Time when the pointer went down for a TAP.
615 nsecs_t tapDownTime;
616
617 // Time when the pointer went up for a TAP.
618 nsecs_t tapUpTime;
619
620 // Location of initial tap.
621 float tapX, tapY;
622
623 // Time we started waiting for quiescence.
624 nsecs_t quietTime;
625
626 // Reference points for multitouch gestures.
627 float referenceTouchX; // reference touch X/Y coordinates in surface units
628 float referenceTouchY;
629 float referenceGestureX; // reference gesture X/Y coordinates in pixels
630 float referenceGestureY;
631
632 // Distance that each pointer has traveled which has not yet been
633 // subsumed into the reference gesture position.
634 BitSet32 referenceIdBits;
635 struct Delta {
636 float dx, dy;
637 };
638 Delta referenceDeltas[MAX_POINTER_ID + 1];
639
640 // Describes how touch ids are mapped to gesture ids for freeform gestures.
641 uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
642
643 // A velocity tracker for determining whether to switch active pointers during drags.
644 VelocityTracker velocityTracker;
645
646 void reset() {
647 firstTouchTime = LLONG_MIN;
648 activeTouchId = -1;
649 activeGestureId = -1;
Michael Wright227c5542020-07-02 18:30:52 +0100650 currentGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700651 currentGestureIdBits.clear();
Michael Wright227c5542020-07-02 18:30:52 +0100652 lastGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700653 lastGestureIdBits.clear();
654 downTime = 0;
655 velocityTracker.clear();
656 resetTap();
657 resetQuietTime();
658 }
659
660 void resetTap() {
661 tapDownTime = LLONG_MIN;
662 tapUpTime = LLONG_MIN;
663 }
664
665 void resetQuietTime() { quietTime = LLONG_MIN; }
666 } mPointerGesture;
667
668 struct PointerSimple {
669 PointerCoords currentCoords;
670 PointerProperties currentProperties;
671 PointerCoords lastCoords;
672 PointerProperties lastProperties;
673
674 // True if the pointer is down.
675 bool down;
676
677 // True if the pointer is hovering.
678 bool hovering;
679
680 // Time the pointer last went down.
681 nsecs_t downTime;
682
Prabir Pradhanb80b6c02022-11-02 20:05:13 +0000683 // Values reported for the last pointer event.
684 uint32_t source;
685 int32_t displayId;
686 float lastCursorX;
687 float lastCursorY;
688
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700689 void reset() {
690 currentCoords.clear();
691 currentProperties.clear();
692 lastCoords.clear();
693 lastProperties.clear();
694 down = false;
695 hovering = false;
696 downTime = 0;
Prabir Pradhanb80b6c02022-11-02 20:05:13 +0000697 source = 0;
698 displayId = ADISPLAY_ID_NONE;
699 lastCursorX = 0.f;
700 lastCursorY = 0.f;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700701 }
702 } mPointerSimple;
703
704 // The pointer and scroll velocity controls.
705 VelocityControl mPointerVelocityControl;
706 VelocityControl mWheelXVelocityControl;
707 VelocityControl mWheelYVelocityControl;
708
709 std::optional<DisplayViewport> findViewport();
710
711 void resetExternalStylus();
712 void clearStylusDataPendingFlags();
713
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800714 int32_t clampResolution(const char* axisName, int32_t resolution) const;
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800715 void initializeOrientedRanges();
716 void initializeSizeRanges();
717
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700718 [[nodiscard]] std::list<NotifyArgs> sync(nsecs_t when, nsecs_t readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700719
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700720 [[nodiscard]] std::list<NotifyArgs> consumeRawTouches(nsecs_t when, nsecs_t readTime,
721 uint32_t policyFlags, bool& outConsumed);
722 [[nodiscard]] std::list<NotifyArgs> processRawTouches(bool timeout);
723 [[nodiscard]] std::list<NotifyArgs> cookAndDispatch(nsecs_t when, nsecs_t readTime);
724 [[nodiscard]] NotifyKeyArgs dispatchVirtualKey(nsecs_t when, nsecs_t readTime,
725 uint32_t policyFlags, int32_t keyEventAction,
726 int32_t keyEventFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700727
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700728 [[nodiscard]] std::list<NotifyArgs> dispatchTouches(nsecs_t when, nsecs_t readTime,
729 uint32_t policyFlags);
730 [[nodiscard]] std::list<NotifyArgs> dispatchHoverExit(nsecs_t when, nsecs_t readTime,
731 uint32_t policyFlags);
732 [[nodiscard]] std::list<NotifyArgs> dispatchHoverEnterAndMove(nsecs_t when, nsecs_t readTime,
733 uint32_t policyFlags);
734 [[nodiscard]] std::list<NotifyArgs> dispatchButtonRelease(nsecs_t when, nsecs_t readTime,
735 uint32_t policyFlags);
736 [[nodiscard]] std::list<NotifyArgs> dispatchButtonPress(nsecs_t when, nsecs_t readTime,
737 uint32_t policyFlags);
LiZhihong758eb562022-11-03 15:28:29 +0800738 [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonPress(nsecs_t when,
739 uint32_t policyFlags,
740 BitSet32 idBits,
741 nsecs_t readTime);
742 [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonRelease(nsecs_t when,
743 uint32_t policyFlags,
744 BitSet32 idBits,
745 nsecs_t readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700746 const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData);
747 void cookPointerData();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700748 [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime,
749 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700750
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700751 [[nodiscard]] std::list<NotifyArgs> dispatchPointerUsage(nsecs_t when, nsecs_t readTime,
752 uint32_t policyFlags,
753 PointerUsage pointerUsage);
754 [[nodiscard]] std::list<NotifyArgs> abortPointerUsage(nsecs_t when, nsecs_t readTime,
755 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700756
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700757 [[nodiscard]] std::list<NotifyArgs> dispatchPointerGestures(nsecs_t when, nsecs_t readTime,
758 uint32_t policyFlags,
759 bool isTimeout);
760 [[nodiscard]] std::list<NotifyArgs> abortPointerGestures(nsecs_t when, nsecs_t readTime,
761 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700762 bool preparePointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
763 bool* outFinishPreviousGesture, bool isTimeout);
764
Harry Cuttsbea6ce52022-10-14 15:17:30 +0000765 // Returns true if we're in a period of "quiet time" when touchpad gestures should be ignored.
766 bool checkForTouchpadQuietTime(nsecs_t when);
767
768 std::pair<int32_t, float> getFastestFinger();
769
770 void prepareMultiFingerPointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
771 bool* outFinishPreviousGesture);
772
Harry Cutts714d1ad2022-08-24 16:36:43 +0000773 // Moves the on-screen mouse pointer based on the movement of the pointer of the given ID
774 // between the last and current events. Uses a relative motion.
775 void moveMousePointerFromPointerDelta(nsecs_t when, uint32_t pointerId);
776
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700777 [[nodiscard]] std::list<NotifyArgs> dispatchPointerStylus(nsecs_t when, nsecs_t readTime,
778 uint32_t policyFlags);
779 [[nodiscard]] std::list<NotifyArgs> abortPointerStylus(nsecs_t when, nsecs_t readTime,
780 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700781
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700782 [[nodiscard]] std::list<NotifyArgs> dispatchPointerMouse(nsecs_t when, nsecs_t readTime,
783 uint32_t policyFlags);
784 [[nodiscard]] std::list<NotifyArgs> abortPointerMouse(nsecs_t when, nsecs_t readTime,
785 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700786
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700787 [[nodiscard]] std::list<NotifyArgs> dispatchPointerSimple(nsecs_t when, nsecs_t readTime,
788 uint32_t policyFlags, bool down,
789 bool hovering);
790 [[nodiscard]] std::list<NotifyArgs> abortPointerSimple(nsecs_t when, nsecs_t readTime,
791 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700792
Prabir Pradhan3f7545f2022-10-19 16:56:39 +0000793 // Attempts to assign a pointer id to the external stylus. Returns true if the state should be
794 // withheld from further processing while waiting for data from the stylus.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700795 bool assignExternalStylusId(const RawState& state, bool timeout);
796 void applyExternalStylusButtonState(nsecs_t when);
797 void applyExternalStylusTouchState(nsecs_t when);
798
799 // Dispatches a motion event.
800 // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
801 // method will take care of setting the index and transmuting the action to DOWN or UP
802 // it is the first / last pointer to go down / up.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700803 [[nodiscard]] NotifyMotionArgs dispatchMotion(
804 nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
805 int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000806 int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords,
807 const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700808 float yPrecision, nsecs_t downTime, MotionClassification classification);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700809
Garfield Tanc734e4f2021-01-15 20:01:39 -0800810 // Returns if this touch device is a touch screen with an associated display.
811 bool isTouchScreen();
812 // Updates touch spots if they are enabled. Should only be used when this device is a
813 // touchscreen.
814 void updateTouchSpots();
815
Prabir Pradhan1728b212021-10-19 16:00:03 -0700816 bool isPointInsidePhysicalFrame(int32_t x, int32_t y) const;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700817 const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
818
Siarhei Vishniakou57479982021-03-03 01:32:21 +0000819 static void assignPointerIds(const RawState& last, RawState& current);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700820
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000821 void computeInputTransforms();
Ambrus Weisz7bc23bf2022-10-04 13:13:07 +0000822
823 void configureDeviceType();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700824};
825
826} // namespace android