blob: d8b59ca39b395f1d2a5c7ca793908ad79af63db3 [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
Harry Cuttsf13161a2023-03-08 14:15:49 +000019#include <optional>
20#include <string>
21
Michael Wright227c5542020-07-02 18:30:52 +010022#include <stdint.h>
Michael Wrighta9cf4192022-12-01 23:46:39 +000023#include <ui/Rotation.h>
Michael Wright227c5542020-07-02 18:30:52 +010024
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070025#include "CursorButtonAccumulator.h"
26#include "CursorScrollAccumulator.h"
27#include "EventHub.h"
28#include "InputMapper.h"
29#include "InputReaderBase.h"
30#include "TouchButtonAccumulator.h"
31
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070032namespace android {
33
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +000034// Maximum amount of latency to add to touch events while waiting for data from an
35// external stylus.
36static constexpr nsecs_t EXTERNAL_STYLUS_DATA_TIMEOUT = ms2ns(72);
37
38// Maximum amount of time to wait on touch data before pushing out new pressure data.
39static constexpr nsecs_t TOUCH_DATA_TIMEOUT = ms2ns(20);
40
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070041/* Raw axis information from the driver. */
42struct RawPointerAxes {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000043 RawAbsoluteAxisInfo x{};
44 RawAbsoluteAxisInfo y{};
45 RawAbsoluteAxisInfo pressure{};
46 RawAbsoluteAxisInfo touchMajor{};
47 RawAbsoluteAxisInfo touchMinor{};
48 RawAbsoluteAxisInfo toolMajor{};
49 RawAbsoluteAxisInfo toolMinor{};
50 RawAbsoluteAxisInfo orientation{};
51 RawAbsoluteAxisInfo distance{};
52 RawAbsoluteAxisInfo tiltX{};
53 RawAbsoluteAxisInfo tiltY{};
54 RawAbsoluteAxisInfo trackingId{};
55 RawAbsoluteAxisInfo slot{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070056
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070057 inline int32_t getRawWidth() const { return x.maxValue - x.minValue + 1; }
58 inline int32_t getRawHeight() const { return y.maxValue - y.minValue + 1; }
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000059 inline void clear() { *this = RawPointerAxes(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070060};
61
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000062using PropertiesArray = std::array<PointerProperties, MAX_POINTERS>;
63using CoordsArray = std::array<PointerCoords, MAX_POINTERS>;
64using IdToIndexArray = std::array<uint32_t, MAX_POINTER_ID + 1>;
65
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070066/* Raw data for a collection of pointers including a pointer id mapping table. */
67struct RawPointerData {
68 struct Pointer {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000069 uint32_t id{0xFFFFFFFF};
70 int32_t x{};
71 int32_t y{};
72 int32_t pressure{};
73 int32_t touchMajor{};
74 int32_t touchMinor{};
75 int32_t toolMajor{};
76 int32_t toolMinor{};
77 int32_t orientation{};
78 int32_t distance{};
79 int32_t tiltX{};
80 int32_t tiltY{};
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070081 // A fully decoded ToolType constant.
82 ToolType toolType{ToolType::UNKNOWN};
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000083 bool isHovering{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070084 };
85
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000086 uint32_t pointerCount{};
87 std::array<Pointer, MAX_POINTERS> pointers{};
88 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{};
89 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070090
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000091 inline void clear() { *this = RawPointerData(); }
92
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070093 void getCentroidOfTouchingPointers(float* outX, float* outY) const;
94
95 inline void markIdBit(uint32_t id, bool isHovering) {
96 if (isHovering) {
97 hoveringIdBits.markBit(id);
98 } else {
99 touchingIdBits.markBit(id);
100 }
101 }
102
103 inline void clearIdBits() {
104 hoveringIdBits.clear();
105 touchingIdBits.clear();
arthurhungcc7f9802020-04-30 17:55:40 +0800106 canceledIdBits.clear();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700107 }
108
109 inline const Pointer& pointerForId(uint32_t id) const { return pointers[idToIndex[id]]; }
110
111 inline bool isHovering(uint32_t pointerIndex) { return pointers[pointerIndex].isHovering; }
112};
113
114/* Cooked data for a collection of pointers including a pointer id mapping table. */
115struct CookedPointerData {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000116 uint32_t pointerCount{};
117 PropertiesArray pointerProperties{};
118 CoordsArray pointerCoords{};
119 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{}, validIdBits{};
120 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700121
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000122 inline void clear() { *this = CookedPointerData(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700123
124 inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
125 return pointerCoords[idToIndex[id]];
126 }
127
128 inline PointerCoords& editPointerCoordsWithId(uint32_t id) {
129 return pointerCoords[idToIndex[id]];
130 }
131
132 inline PointerProperties& editPointerPropertiesWithId(uint32_t id) {
133 return pointerProperties[idToIndex[id]];
134 }
135
136 inline bool isHovering(uint32_t pointerIndex) const {
137 return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
138 }
139
140 inline bool isTouching(uint32_t pointerIndex) const {
141 return touchingIdBits.hasBit(pointerProperties[pointerIndex].id);
142 }
Nathaniel R. Lewisadb58ea2019-08-21 04:46:29 +0000143
144 inline bool hasPointerCoordsForId(uint32_t id) const { return validIdBits.hasBit(id); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700145};
146
147class TouchInputMapper : public InputMapper {
148public:
Michael Wright227c5542020-07-02 18:30:52 +0100149 ~TouchInputMapper() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700150
Philip Junker4af3b3d2021-12-14 10:36:55 +0100151 uint32_t getSources() const override;
Harry Cuttsd02ea102023-03-17 18:21:30 +0000152 void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
Michael Wright227c5542020-07-02 18:30:52 +0100153 void dump(std::string& dump) override;
Arpit Singh4be4eef2023-03-28 14:26:01 +0000154 [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
Arpit Singhed6c3de2023-04-05 19:24:37 +0000155 const InputReaderConfiguration& config,
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000156 ConfigurationChanges changes) override;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700157 [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
158 [[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700159
Michael Wright227c5542020-07-02 18:30:52 +0100160 int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) override;
161 int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700162 bool markSupportedKeyCodes(uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
Michael Wright227c5542020-07-02 18:30:52 +0100163 uint8_t* outFlags) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700164
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700165 [[nodiscard]] std::list<NotifyArgs> cancelTouch(nsecs_t when, nsecs_t readTime) override;
166 [[nodiscard]] std::list<NotifyArgs> timeoutExpired(nsecs_t when) override;
167 [[nodiscard]] std::list<NotifyArgs> updateExternalStylusState(
168 const StylusState& state) override;
Michael Wright227c5542020-07-02 18:30:52 +0100169 std::optional<int32_t> getAssociatedDisplayId() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700170
171protected:
172 CursorButtonAccumulator mCursorButtonAccumulator;
173 CursorScrollAccumulator mCursorScrollAccumulator;
174 TouchButtonAccumulator mTouchButtonAccumulator;
175
176 struct VirtualKey {
177 int32_t keyCode;
178 int32_t scanCode;
179 uint32_t flags;
180
181 // computed hit box, specified in touch screen coords based on known display size
182 int32_t hitLeft;
183 int32_t hitTop;
184 int32_t hitRight;
185 int32_t hitBottom;
186
187 inline bool isHit(int32_t x, int32_t y) const {
188 return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
189 }
190 };
191
192 // Input sources and device mode.
Arpit Singh403e53c2023-04-18 11:46:56 +0000193 uint32_t mSource{0};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700194
Michael Wright227c5542020-07-02 18:30:52 +0100195 enum class DeviceMode {
196 DISABLED, // input is disabled
197 DIRECT, // direct mapping (touchscreen)
198 UNSCALED, // unscaled mapping (touchpad)
199 NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
200 POINTER, // pointer mapping (pointer)
Dominik Laskowski75788452021-02-09 18:51:25 -0800201
202 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700203 };
Arpit Singh403e53c2023-04-18 11:46:56 +0000204 DeviceMode mDeviceMode{DeviceMode::DISABLED};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700205
206 // The reader's configuration.
207 InputReaderConfiguration mConfig;
208
209 // Immutable configuration parameters.
210 struct Parameters {
Michael Wright227c5542020-07-02 18:30:52 +0100211 enum class DeviceType {
212 TOUCH_SCREEN,
Michael Wright227c5542020-07-02 18:30:52 +0100213 TOUCH_NAVIGATION,
214 POINTER,
Dominik Laskowski75788452021-02-09 18:51:25 -0800215
216 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700217 };
218
219 DeviceType deviceType;
220 bool hasAssociatedDisplay;
221 bool associatedDisplayIsExternal;
222 bool orientationAware;
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700223
Michael Wrighta9cf4192022-12-01 23:46:39 +0000224 ui::Rotation orientation;
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700225
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700226 bool hasButtonUnderPad;
227 std::string uniqueDisplayId;
228
Michael Wright227c5542020-07-02 18:30:52 +0100229 enum class GestureMode {
230 SINGLE_TOUCH,
231 MULTI_TOUCH,
Dominik Laskowski75788452021-02-09 18:51:25 -0800232
233 ftl_last = MULTI_TOUCH
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700234 };
235 GestureMode gestureMode;
236
237 bool wake;
Prabir Pradhan167c2702022-09-14 00:37:24 +0000238
Prabir Pradhane04ffaa2022-12-13 23:04:04 +0000239 // The Universal Stylus Initiative (USI) protocol version supported by this device.
240 std::optional<InputDeviceUsiVersion> usiVersion;
Yuncheol Heo50c19b12022-11-02 20:33:08 -0700241
242 // Allows touches while the display is off.
243 bool enableForInactiveViewport;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700244 } mParameters;
245
246 // Immutable calibration parameters in parsed form.
247 struct Calibration {
248 // Size
Michael Wright227c5542020-07-02 18:30:52 +0100249 enum class SizeCalibration {
250 DEFAULT,
251 NONE,
252 GEOMETRIC,
253 DIAMETER,
254 BOX,
255 AREA,
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800256 ftl_last = AREA
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700257 };
258
259 SizeCalibration sizeCalibration;
260
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700261 std::optional<float> sizeScale;
262 std::optional<float> sizeBias;
263 std::optional<bool> sizeIsSummed;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700264
265 // Pressure
Michael Wright227c5542020-07-02 18:30:52 +0100266 enum class PressureCalibration {
267 DEFAULT,
268 NONE,
269 PHYSICAL,
270 AMPLITUDE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700271 };
272
273 PressureCalibration pressureCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700274 std::optional<float> pressureScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700275
276 // Orientation
Michael Wright227c5542020-07-02 18:30:52 +0100277 enum class OrientationCalibration {
278 DEFAULT,
279 NONE,
280 INTERPOLATED,
281 VECTOR,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700282 };
283
284 OrientationCalibration orientationCalibration;
285
286 // Distance
Michael Wright227c5542020-07-02 18:30:52 +0100287 enum class DistanceCalibration {
288 DEFAULT,
289 NONE,
290 SCALED,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700291 };
292
293 DistanceCalibration distanceCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700294 std::optional<float> distanceScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700295
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700296 inline void applySizeScaleAndBias(float& outSize) const {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700297 if (sizeScale) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700298 outSize *= *sizeScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700299 }
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700300 if (sizeBias) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700301 outSize += *sizeBias;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700302 }
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700303 if (outSize < 0) {
304 outSize = 0;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700305 }
306 }
307 } mCalibration;
308
309 // Affine location transformation/calibration
310 struct TouchAffineTransformation mAffineTransform;
311
312 RawPointerAxes mRawPointerAxes;
313
314 struct RawState {
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +0000315 nsecs_t when{std::numeric_limits<nsecs_t>::min()};
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000316 nsecs_t readTime{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700317
318 // Raw pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000319 RawPointerData rawPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700320
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000321 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700322
323 // Scroll state.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000324 int32_t rawVScroll{};
325 int32_t rawHScroll{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700326
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000327 inline void clear() { *this = RawState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700328 };
329
330 struct CookedState {
331 // Cooked pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000332 CookedPointerData cookedPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700333
334 // Id bits used to differentiate fingers, stylus and mouse tools.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000335 BitSet32 fingerIdBits{};
336 BitSet32 stylusIdBits{};
337 BitSet32 mouseIdBits{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700338
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000339 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700340
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000341 inline void clear() { *this = CookedState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700342 };
343
344 std::vector<RawState> mRawStatesPending;
345 RawState mCurrentRawState;
346 CookedState mCurrentCookedState;
347 RawState mLastRawState;
348 CookedState mLastCookedState;
349
350 // State provided by an external stylus
351 StylusState mExternalStylusState;
Prabir Pradhan8d9ba912022-11-11 22:26:33 +0000352 // If an external stylus is capable of reporting pointer-specific data like pressure, we will
353 // attempt to fuse the pointer data reported by the stylus to the first touch pointer. This is
354 // the id of the pointer to which the external stylus data is fused.
355 std::optional<uint32_t> mFusedStylusPointerId;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700356 nsecs_t mExternalStylusFusionTimeout;
357 bool mExternalStylusDataPending;
Prabir Pradhan124ea442022-10-28 20:27:44 +0000358 // A subset of the buttons in mCurrentRawState that came from an external stylus.
Arpit Singha8c236b2023-04-25 13:56:05 +0000359 int32_t mExternalStylusButtonsApplied{0};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700360
361 // True if we sent a HOVER_ENTER event.
Arpit Singha8c236b2023-04-25 13:56:05 +0000362 bool mSentHoverEnter{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700363
364 // Have we assigned pointer IDs for this stream
Arpit Singha8c236b2023-04-25 13:56:05 +0000365 bool mHavePointerIds{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700366
367 // Is the current stream of direct touch events aborted
Arpit Singha8c236b2023-04-25 13:56:05 +0000368 bool mCurrentMotionAborted{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700369
370 // The time the primary pointer last went down.
Arpit Singha8c236b2023-04-25 13:56:05 +0000371 nsecs_t mDownTime{0};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700372
373 // The pointer controller, or null if the device is not a pointer.
Michael Wright17db18e2020-06-26 20:51:44 +0100374 std::shared_ptr<PointerControllerInterface> mPointerController;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700375
376 std::vector<VirtualKey> mVirtualKeys;
377
Arpit Singha8c236b2023-04-25 13:56:05 +0000378 explicit TouchInputMapper(InputDeviceContext& deviceContext,
379 const InputReaderConfiguration& readerConfig);
380
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700381 virtual void dumpParameters(std::string& dump);
382 virtual void configureRawPointerAxes();
383 virtual void dumpRawPointerAxes(std::string& dump);
Prabir Pradhan1728b212021-10-19 16:00:03 -0700384 virtual void configureInputDevice(nsecs_t when, bool* outResetNeeded);
385 virtual void dumpDisplay(std::string& dump);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700386 virtual void configureVirtualKeys();
387 virtual void dumpVirtualKeys(std::string& dump);
388 virtual void parseCalibration();
389 virtual void resolveCalibration();
390 virtual void dumpCalibration(std::string& dump);
391 virtual void updateAffineTransformation();
392 virtual void dumpAffineTransformation(std::string& dump);
393 virtual void resolveExternalStylusPresence();
394 virtual bool hasStylus() const = 0;
395 virtual bool hasExternalStylus() const;
396
397 virtual void syncTouch(nsecs_t when, RawState* outState) = 0;
398
399private:
400 // The current viewport.
401 // The components of the viewport are specified in the display's rotated orientation.
402 DisplayViewport mViewport;
403
Prabir Pradhan2d613f42022-11-10 20:22:06 +0000404 // We refer to the display as being in the "natural orientation" when there is no rotation
405 // applied. The display size obtained from the viewport in the natural orientation.
Prabir Pradhan7ddbc952022-11-09 22:03:40 +0000406 // Always starts at (0, 0).
407 ui::Size mDisplayBounds{ui::kInvalidSize};
Arthur Hung4197f6b2020-03-16 15:39:59 +0800408
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000409 // The physical frame is the rectangle in the rotated display's coordinate space that maps to
Prabir Pradhan1728b212021-10-19 16:00:03 -0700410 // the logical display frame.
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000411 Rect mPhysicalFrameInRotatedDisplay{Rect::INVALID_RECT};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700412
Prabir Pradhan1728b212021-10-19 16:00:03 -0700413 // The orientation of the input device relative to that of the display panel. It specifies
414 // the rotation of the input device coordinates required to produce the display panel
415 // orientation, so it will depend on whether the device is orientation aware.
Arpit Singh403e53c2023-04-18 11:46:56 +0000416 ui::Rotation mInputDeviceOrientation{ui::ROTATION_0};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700417
Prabir Pradhanea31d4f2022-11-10 20:48:01 +0000418 // The transform that maps the input device's raw coordinate space to the un-rotated display's
419 // coordinate space. InputReader generates events in the un-rotated display's coordinate space.
420 ui::Transform mRawToDisplay;
421
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000422 // The transform that maps the input device's raw coordinate space to the rotated display's
423 // coordinate space. This used to perform hit-testing of raw events with the physical frame in
424 // the rotated coordinate space. See mPhysicalFrameInRotatedDisplay.
425 ui::Transform mRawToRotatedDisplay;
426
Prabir Pradhane2e10b42022-11-17 20:59:36 +0000427 // The transform used for non-planar raw axes, such as orientation and tilt.
428 ui::Transform mRawRotation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700429
430 float mGeometricScale;
431
432 float mPressureScale;
433
434 float mSizeScale;
435
436 float mOrientationScale;
437
438 float mDistanceScale;
439
440 bool mHaveTilt;
441 float mTiltXCenter;
442 float mTiltXScale;
443 float mTiltYCenter;
444 float mTiltYScale;
445
446 bool mExternalStylusConnected;
447
448 // Oriented motion ranges for input device info.
449 struct OrientedRanges {
450 InputDeviceInfo::MotionRange x;
451 InputDeviceInfo::MotionRange y;
452 InputDeviceInfo::MotionRange pressure;
453
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700454 std::optional<InputDeviceInfo::MotionRange> size;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700455
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700456 std::optional<InputDeviceInfo::MotionRange> touchMajor;
457 std::optional<InputDeviceInfo::MotionRange> touchMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700458
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700459 std::optional<InputDeviceInfo::MotionRange> toolMajor;
460 std::optional<InputDeviceInfo::MotionRange> toolMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700461
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700462 std::optional<InputDeviceInfo::MotionRange> orientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700463
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700464 std::optional<InputDeviceInfo::MotionRange> distance;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700465
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700466 std::optional<InputDeviceInfo::MotionRange> tilt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700467
468 void clear() {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700469 size = std::nullopt;
470 touchMajor = std::nullopt;
471 touchMinor = std::nullopt;
472 toolMajor = std::nullopt;
473 toolMinor = std::nullopt;
474 orientation = std::nullopt;
475 distance = std::nullopt;
476 tilt = std::nullopt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700477 }
478 } mOrientedRanges;
479
480 // Oriented dimensions and precision.
481 float mOrientedXPrecision;
482 float mOrientedYPrecision;
483
484 struct CurrentVirtualKeyState {
485 bool down;
486 bool ignored;
487 nsecs_t downTime;
488 int32_t keyCode;
489 int32_t scanCode;
490 } mCurrentVirtualKey;
491
492 // Scale factor for gesture or mouse based pointer movements.
493 float mPointerXMovementScale;
494 float mPointerYMovementScale;
495
496 // Scale factor for gesture based zooming and other freeform motions.
497 float mPointerXZoomScale;
498 float mPointerYZoomScale;
499
HQ Liue6983c72022-04-19 22:14:56 +0000500 // The maximum swipe width between pointers to detect a swipe gesture
501 // in the number of pixels.Touches that are wider than this are translated
502 // into freeform gestures.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700503 float mPointerGestureMaxSwipeWidth;
504
505 struct PointerDistanceHeapElement {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000506 uint32_t currentPointerIndex : 8 {};
507 uint32_t lastPointerIndex : 8 {};
508 uint64_t distance : 48 {}; // squared distance
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700509 };
510
Michael Wright227c5542020-07-02 18:30:52 +0100511 enum class PointerUsage {
512 NONE,
513 GESTURES,
514 STYLUS,
515 MOUSE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700516 };
Arpit Singha8c236b2023-04-25 13:56:05 +0000517 PointerUsage mPointerUsage{PointerUsage::NONE};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700518
519 struct PointerGesture {
Michael Wright227c5542020-07-02 18:30:52 +0100520 enum class Mode {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700521 // No fingers, button is not pressed.
522 // Nothing happening.
523 NEUTRAL,
524
525 // No fingers, button is not pressed.
526 // Tap detected.
527 // Emits DOWN and UP events at the pointer location.
528 TAP,
529
530 // Exactly one finger dragging following a tap.
531 // Pointer follows the active finger.
532 // Emits DOWN, MOVE and UP events at the pointer location.
533 //
534 // Detect double-taps when the finger goes up while in TAP_DRAG mode.
535 TAP_DRAG,
536
537 // Button is pressed.
538 // Pointer follows the active finger if there is one. Other fingers are ignored.
539 // Emits DOWN, MOVE and UP events at the pointer location.
540 BUTTON_CLICK_OR_DRAG,
541
542 // Exactly one finger, button is not pressed.
543 // Pointer follows the active finger.
544 // Emits HOVER_MOVE events at the pointer location.
545 //
546 // Detect taps when the finger goes up while in HOVER mode.
547 HOVER,
548
549 // Exactly two fingers but neither have moved enough to clearly indicate
550 // whether a swipe or freeform gesture was intended. We consider the
551 // pointer to be pressed so this enables clicking or long-pressing on buttons.
552 // Pointer does not move.
553 // Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
554 PRESS,
555
556 // Exactly two fingers moving in the same direction, button is not pressed.
557 // Pointer does not move.
558 // Emits DOWN, MOVE and UP events with a single pointer coordinate that
559 // follows the midpoint between both fingers.
560 SWIPE,
561
562 // Two or more fingers moving in arbitrary directions, button is not pressed.
563 // Pointer does not move.
564 // Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
565 // each finger individually relative to the initial centroid of the finger.
566 FREEFORM,
567
568 // Waiting for quiet time to end before starting the next gesture.
569 QUIET,
570 };
571
Prabir Pradhan47cf0a02021-03-11 20:30:57 -0800572 // When a gesture is sent to an unfocused window, return true if it can bring that window
573 // into focus, false otherwise.
574 static bool canGestureAffectWindowFocus(Mode mode) {
575 switch (mode) {
576 case Mode::TAP:
577 case Mode::TAP_DRAG:
578 case Mode::BUTTON_CLICK_OR_DRAG:
579 // Taps can affect window focus.
580 return true;
581 case Mode::FREEFORM:
582 case Mode::HOVER:
583 case Mode::NEUTRAL:
584 case Mode::PRESS:
585 case Mode::QUIET:
586 case Mode::SWIPE:
587 // Most gestures can be performed on an unfocused window, so they should not
588 // not affect window focus.
589 return false;
590 }
591 }
592
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700593 // Time the first finger went down.
594 nsecs_t firstTouchTime;
595
596 // The active pointer id from the raw touch data.
597 int32_t activeTouchId; // -1 if none
598
599 // The active pointer id from the gesture last delivered to the application.
600 int32_t activeGestureId; // -1 if none
601
602 // Pointer coords and ids for the current and previous pointer gesture.
603 Mode currentGestureMode;
604 BitSet32 currentGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000605 IdToIndexArray currentGestureIdToIndex{};
606 PropertiesArray currentGestureProperties{};
607 CoordsArray currentGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700608
609 Mode lastGestureMode;
610 BitSet32 lastGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000611 IdToIndexArray lastGestureIdToIndex{};
612 PropertiesArray lastGestureProperties{};
613 CoordsArray lastGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700614
615 // Time the pointer gesture last went down.
616 nsecs_t downTime;
617
618 // Time when the pointer went down for a TAP.
619 nsecs_t tapDownTime;
620
621 // Time when the pointer went up for a TAP.
622 nsecs_t tapUpTime;
623
624 // Location of initial tap.
625 float tapX, tapY;
626
627 // Time we started waiting for quiescence.
628 nsecs_t quietTime;
629
630 // Reference points for multitouch gestures.
631 float referenceTouchX; // reference touch X/Y coordinates in surface units
632 float referenceTouchY;
633 float referenceGestureX; // reference gesture X/Y coordinates in pixels
634 float referenceGestureY;
635
636 // Distance that each pointer has traveled which has not yet been
637 // subsumed into the reference gesture position.
638 BitSet32 referenceIdBits;
639 struct Delta {
640 float dx, dy;
641 };
642 Delta referenceDeltas[MAX_POINTER_ID + 1];
643
644 // Describes how touch ids are mapped to gesture ids for freeform gestures.
645 uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
646
647 // A velocity tracker for determining whether to switch active pointers during drags.
648 VelocityTracker velocityTracker;
649
650 void reset() {
651 firstTouchTime = LLONG_MIN;
652 activeTouchId = -1;
653 activeGestureId = -1;
Michael Wright227c5542020-07-02 18:30:52 +0100654 currentGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700655 currentGestureIdBits.clear();
Michael Wright227c5542020-07-02 18:30:52 +0100656 lastGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700657 lastGestureIdBits.clear();
658 downTime = 0;
659 velocityTracker.clear();
660 resetTap();
661 resetQuietTime();
662 }
663
664 void resetTap() {
665 tapDownTime = LLONG_MIN;
666 tapUpTime = LLONG_MIN;
667 }
668
669 void resetQuietTime() { quietTime = LLONG_MIN; }
670 } mPointerGesture;
671
672 struct PointerSimple {
673 PointerCoords currentCoords;
674 PointerProperties currentProperties;
675 PointerCoords lastCoords;
676 PointerProperties lastProperties;
677
678 // True if the pointer is down.
679 bool down;
680
681 // True if the pointer is hovering.
682 bool hovering;
683
684 // Time the pointer last went down.
685 nsecs_t downTime;
686
Prabir Pradhanb80b6c02022-11-02 20:05:13 +0000687 // Values reported for the last pointer event.
688 uint32_t source;
689 int32_t displayId;
690 float lastCursorX;
691 float lastCursorY;
692
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700693 void reset() {
694 currentCoords.clear();
695 currentProperties.clear();
696 lastCoords.clear();
697 lastProperties.clear();
698 down = false;
699 hovering = false;
700 downTime = 0;
Prabir Pradhanb80b6c02022-11-02 20:05:13 +0000701 source = 0;
702 displayId = ADISPLAY_ID_NONE;
703 lastCursorX = 0.f;
704 lastCursorY = 0.f;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700705 }
706 } mPointerSimple;
707
708 // The pointer and scroll velocity controls.
709 VelocityControl mPointerVelocityControl;
710 VelocityControl mWheelXVelocityControl;
711 VelocityControl mWheelYVelocityControl;
712
713 std::optional<DisplayViewport> findViewport();
714
715 void resetExternalStylus();
716 void clearStylusDataPendingFlags();
717
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800718 int32_t clampResolution(const char* axisName, int32_t resolution) const;
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800719 void initializeOrientedRanges();
720 void initializeSizeRanges();
721
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700722 [[nodiscard]] std::list<NotifyArgs> sync(nsecs_t when, nsecs_t readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700723
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700724 [[nodiscard]] std::list<NotifyArgs> consumeRawTouches(nsecs_t when, nsecs_t readTime,
725 uint32_t policyFlags, bool& outConsumed);
726 [[nodiscard]] std::list<NotifyArgs> processRawTouches(bool timeout);
727 [[nodiscard]] std::list<NotifyArgs> cookAndDispatch(nsecs_t when, nsecs_t readTime);
728 [[nodiscard]] NotifyKeyArgs dispatchVirtualKey(nsecs_t when, nsecs_t readTime,
729 uint32_t policyFlags, int32_t keyEventAction,
730 int32_t keyEventFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700731
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700732 [[nodiscard]] std::list<NotifyArgs> dispatchTouches(nsecs_t when, nsecs_t readTime,
733 uint32_t policyFlags);
734 [[nodiscard]] std::list<NotifyArgs> dispatchHoverExit(nsecs_t when, nsecs_t readTime,
735 uint32_t policyFlags);
736 [[nodiscard]] std::list<NotifyArgs> dispatchHoverEnterAndMove(nsecs_t when, nsecs_t readTime,
737 uint32_t policyFlags);
738 [[nodiscard]] std::list<NotifyArgs> dispatchButtonRelease(nsecs_t when, nsecs_t readTime,
739 uint32_t policyFlags);
740 [[nodiscard]] std::list<NotifyArgs> dispatchButtonPress(nsecs_t when, nsecs_t readTime,
741 uint32_t policyFlags);
LiZhihong758eb562022-11-03 15:28:29 +0800742 [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonPress(nsecs_t when,
743 uint32_t policyFlags,
744 BitSet32 idBits,
745 nsecs_t readTime);
746 [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonRelease(nsecs_t when,
747 uint32_t policyFlags,
748 BitSet32 idBits,
749 nsecs_t readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700750 const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData);
751 void cookPointerData();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700752 [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime,
753 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700754
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700755 [[nodiscard]] std::list<NotifyArgs> dispatchPointerUsage(nsecs_t when, nsecs_t readTime,
756 uint32_t policyFlags,
757 PointerUsage pointerUsage);
758 [[nodiscard]] std::list<NotifyArgs> abortPointerUsage(nsecs_t when, nsecs_t readTime,
759 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700760
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700761 [[nodiscard]] std::list<NotifyArgs> dispatchPointerGestures(nsecs_t when, nsecs_t readTime,
762 uint32_t policyFlags,
763 bool isTimeout);
764 [[nodiscard]] std::list<NotifyArgs> abortPointerGestures(nsecs_t when, nsecs_t readTime,
765 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700766 bool preparePointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
767 bool* outFinishPreviousGesture, bool isTimeout);
768
Harry Cuttsbea6ce52022-10-14 15:17:30 +0000769 // Returns true if we're in a period of "quiet time" when touchpad gestures should be ignored.
770 bool checkForTouchpadQuietTime(nsecs_t when);
771
772 std::pair<int32_t, float> getFastestFinger();
773
774 void prepareMultiFingerPointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
775 bool* outFinishPreviousGesture);
776
Harry Cutts714d1ad2022-08-24 16:36:43 +0000777 // Moves the on-screen mouse pointer based on the movement of the pointer of the given ID
778 // between the last and current events. Uses a relative motion.
779 void moveMousePointerFromPointerDelta(nsecs_t when, uint32_t pointerId);
780
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700781 [[nodiscard]] std::list<NotifyArgs> dispatchPointerStylus(nsecs_t when, nsecs_t readTime,
782 uint32_t policyFlags);
783 [[nodiscard]] std::list<NotifyArgs> abortPointerStylus(nsecs_t when, nsecs_t readTime,
784 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700785
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700786 [[nodiscard]] std::list<NotifyArgs> dispatchPointerMouse(nsecs_t when, nsecs_t readTime,
787 uint32_t policyFlags);
788 [[nodiscard]] std::list<NotifyArgs> abortPointerMouse(nsecs_t when, nsecs_t readTime,
789 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700790
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700791 [[nodiscard]] std::list<NotifyArgs> dispatchPointerSimple(nsecs_t when, nsecs_t readTime,
792 uint32_t policyFlags, bool down,
Prabir Pradhane71e5702023-03-29 14:51:38 +0000793 bool hovering, int32_t displayId);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700794 [[nodiscard]] std::list<NotifyArgs> abortPointerSimple(nsecs_t when, nsecs_t readTime,
795 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700796
Prabir Pradhan3f7545f2022-10-19 16:56:39 +0000797 // Attempts to assign a pointer id to the external stylus. Returns true if the state should be
798 // withheld from further processing while waiting for data from the stylus.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700799 bool assignExternalStylusId(const RawState& state, bool timeout);
800 void applyExternalStylusButtonState(nsecs_t when);
801 void applyExternalStylusTouchState(nsecs_t when);
802
803 // Dispatches a motion event.
804 // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
805 // method will take care of setting the index and transmuting the action to DOWN or UP
806 // it is the first / last pointer to go down / up.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700807 [[nodiscard]] NotifyMotionArgs dispatchMotion(
808 nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
809 int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000810 int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords,
811 const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700812 float yPrecision, nsecs_t downTime, MotionClassification classification);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700813
Garfield Tanc734e4f2021-01-15 20:01:39 -0800814 // Returns if this touch device is a touch screen with an associated display.
815 bool isTouchScreen();
816 // Updates touch spots if they are enabled. Should only be used when this device is a
817 // touchscreen.
818 void updateTouchSpots();
819
Prabir Pradhan1728b212021-10-19 16:00:03 -0700820 bool isPointInsidePhysicalFrame(int32_t x, int32_t y) const;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700821 const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
822
Siarhei Vishniakou57479982021-03-03 01:32:21 +0000823 static void assignPointerIds(const RawState& last, RawState& current);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700824
Prabir Pradhan7d9cb5a2023-03-14 21:18:07 +0000825 // Compute input transforms for DIRECT and POINTER modes.
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000826 void computeInputTransforms();
Arpit Singh403e53c2023-04-18 11:46:56 +0000827 static Parameters::DeviceType computeDeviceType(const InputDeviceContext& deviceContext);
828 static Parameters computeParameters(const InputDeviceContext& deviceContext);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700829};
830
831} // namespace android