blob: 9b7fe93d101c51041301abc10af81b249fb53bc1 [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 Cutts3f570c72024-04-05 16:44:28 +000019#include <array>
20#include <climits>
21#include <limits>
22#include <list>
23#include <memory>
Harry Cuttsf13161a2023-03-08 14:15:49 +000024#include <optional>
25#include <string>
Harry Cutts3f570c72024-04-05 16:44:28 +000026#include <utility>
27#include <vector>
Harry Cuttsf13161a2023-03-08 14:15:49 +000028
Michael Wright227c5542020-07-02 18:30:52 +010029#include <stdint.h>
Harry Cutts3f570c72024-04-05 16:44:28 +000030#include <gui/constants.h>
31#include <input/DisplayViewport.h>
32#include <input/Input.h>
33#include <input/InputDevice.h>
34#include <input/VelocityControl.h>
35#include <input/VelocityTracker.h>
36#include <ui/Rect.h>
Michael Wrighta9cf4192022-12-01 23:46:39 +000037#include <ui/Rotation.h>
Harry Cutts3f570c72024-04-05 16:44:28 +000038#include <ui/Size.h>
39#include <ui/Transform.h>
40#include <utils/BitSet.h>
41#include <utils/Timers.h>
Michael Wright227c5542020-07-02 18:30:52 +010042
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070043#include "CursorButtonAccumulator.h"
44#include "CursorScrollAccumulator.h"
45#include "EventHub.h"
46#include "InputMapper.h"
47#include "InputReaderBase.h"
Harry Cutts3f570c72024-04-05 16:44:28 +000048#include "NotifyArgs.h"
49#include "PointerControllerInterface.h"
50#include "StylusState.h"
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070051#include "TouchButtonAccumulator.h"
52
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070053namespace android {
54
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +000055// Maximum amount of latency to add to touch events while waiting for data from an
56// external stylus.
57static constexpr nsecs_t EXTERNAL_STYLUS_DATA_TIMEOUT = ms2ns(72);
58
59// Maximum amount of time to wait on touch data before pushing out new pressure data.
60static constexpr nsecs_t TOUCH_DATA_TIMEOUT = ms2ns(20);
61
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070062/* Raw axis information from the driver. */
63struct RawPointerAxes {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000064 RawAbsoluteAxisInfo x{};
65 RawAbsoluteAxisInfo y{};
66 RawAbsoluteAxisInfo pressure{};
67 RawAbsoluteAxisInfo touchMajor{};
68 RawAbsoluteAxisInfo touchMinor{};
69 RawAbsoluteAxisInfo toolMajor{};
70 RawAbsoluteAxisInfo toolMinor{};
71 RawAbsoluteAxisInfo orientation{};
72 RawAbsoluteAxisInfo distance{};
73 RawAbsoluteAxisInfo tiltX{};
74 RawAbsoluteAxisInfo tiltY{};
75 RawAbsoluteAxisInfo trackingId{};
76 RawAbsoluteAxisInfo slot{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070077
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070078 inline int32_t getRawWidth() const { return x.maxValue - x.minValue + 1; }
79 inline int32_t getRawHeight() const { return y.maxValue - y.minValue + 1; }
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000080 inline void clear() { *this = RawPointerAxes(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070081};
82
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000083using PropertiesArray = std::array<PointerProperties, MAX_POINTERS>;
84using CoordsArray = std::array<PointerCoords, MAX_POINTERS>;
85using IdToIndexArray = std::array<uint32_t, MAX_POINTER_ID + 1>;
86
Prabir Pradhanbaa5c822019-08-30 15:27:05 -070087/* Raw data for a collection of pointers including a pointer id mapping table. */
88struct RawPointerData {
89 struct Pointer {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +000090 uint32_t id{0xFFFFFFFF};
91 int32_t x{};
92 int32_t y{};
93 int32_t pressure{};
94 int32_t touchMajor{};
95 int32_t touchMinor{};
96 int32_t toolMajor{};
97 int32_t toolMinor{};
98 int32_t orientation{};
99 int32_t distance{};
100 int32_t tiltX{};
101 int32_t tiltY{};
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -0700102 // A fully decoded ToolType constant.
103 ToolType toolType{ToolType::UNKNOWN};
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000104 bool isHovering{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700105 };
106
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000107 uint32_t pointerCount{};
108 std::array<Pointer, MAX_POINTERS> pointers{};
109 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{};
110 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700111
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000112 inline void clear() { *this = RawPointerData(); }
113
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700114 void getCentroidOfTouchingPointers(float* outX, float* outY) const;
115
116 inline void markIdBit(uint32_t id, bool isHovering) {
117 if (isHovering) {
118 hoveringIdBits.markBit(id);
119 } else {
120 touchingIdBits.markBit(id);
121 }
122 }
123
124 inline void clearIdBits() {
125 hoveringIdBits.clear();
126 touchingIdBits.clear();
arthurhungcc7f9802020-04-30 17:55:40 +0800127 canceledIdBits.clear();
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700128 }
129
130 inline const Pointer& pointerForId(uint32_t id) const { return pointers[idToIndex[id]]; }
131
132 inline bool isHovering(uint32_t pointerIndex) { return pointers[pointerIndex].isHovering; }
133};
134
135/* Cooked data for a collection of pointers including a pointer id mapping table. */
136struct CookedPointerData {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000137 uint32_t pointerCount{};
138 PropertiesArray pointerProperties{};
139 CoordsArray pointerCoords{};
140 BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{}, validIdBits{};
141 IdToIndexArray idToIndex{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700142
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000143 inline void clear() { *this = CookedPointerData(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700144
145 inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
146 return pointerCoords[idToIndex[id]];
147 }
148
149 inline PointerCoords& editPointerCoordsWithId(uint32_t id) {
150 return pointerCoords[idToIndex[id]];
151 }
152
153 inline PointerProperties& editPointerPropertiesWithId(uint32_t id) {
154 return pointerProperties[idToIndex[id]];
155 }
156
157 inline bool isHovering(uint32_t pointerIndex) const {
158 return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
159 }
160
161 inline bool isTouching(uint32_t pointerIndex) const {
162 return touchingIdBits.hasBit(pointerProperties[pointerIndex].id);
163 }
Nathaniel R. Lewisadb58ea2019-08-21 04:46:29 +0000164
165 inline bool hasPointerCoordsForId(uint32_t id) const { return validIdBits.hasBit(id); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700166};
167
168class TouchInputMapper : public InputMapper {
169public:
Michael Wright227c5542020-07-02 18:30:52 +0100170 ~TouchInputMapper() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700171
Philip Junker4af3b3d2021-12-14 10:36:55 +0100172 uint32_t getSources() const override;
Harry Cuttsd02ea102023-03-17 18:21:30 +0000173 void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
Michael Wright227c5542020-07-02 18:30:52 +0100174 void dump(std::string& dump) override;
Arpit Singh4be4eef2023-03-28 14:26:01 +0000175 [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
Arpit Singhed6c3de2023-04-05 19:24:37 +0000176 const InputReaderConfiguration& config,
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000177 ConfigurationChanges changes) override;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700178 [[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
179 [[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700180
Michael Wright227c5542020-07-02 18:30:52 +0100181 int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) override;
182 int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700183 bool markSupportedKeyCodes(uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
Michael Wright227c5542020-07-02 18:30:52 +0100184 uint8_t* outFlags) override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700185
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700186 [[nodiscard]] std::list<NotifyArgs> cancelTouch(nsecs_t when, nsecs_t readTime) override;
187 [[nodiscard]] std::list<NotifyArgs> timeoutExpired(nsecs_t when) override;
188 [[nodiscard]] std::list<NotifyArgs> updateExternalStylusState(
189 const StylusState& state) override;
Michael Wright227c5542020-07-02 18:30:52 +0100190 std::optional<int32_t> getAssociatedDisplayId() override;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700191
192protected:
193 CursorButtonAccumulator mCursorButtonAccumulator;
194 CursorScrollAccumulator mCursorScrollAccumulator;
195 TouchButtonAccumulator mTouchButtonAccumulator;
196
197 struct VirtualKey {
198 int32_t keyCode;
199 int32_t scanCode;
200 uint32_t flags;
201
202 // computed hit box, specified in touch screen coords based on known display size
203 int32_t hitLeft;
204 int32_t hitTop;
205 int32_t hitRight;
206 int32_t hitBottom;
207
208 inline bool isHit(int32_t x, int32_t y) const {
209 return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
210 }
211 };
212
213 // Input sources and device mode.
Arpit Singh403e53c2023-04-18 11:46:56 +0000214 uint32_t mSource{0};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700215
Michael Wright227c5542020-07-02 18:30:52 +0100216 enum class DeviceMode {
217 DISABLED, // input is disabled
218 DIRECT, // direct mapping (touchscreen)
Michael Wright227c5542020-07-02 18:30:52 +0100219 NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
Harry Cuttse3aaf392023-06-19 17:13:43 +0000220 POINTER, // pointer mapping (e.g. uncaptured touchpad, drawing tablet)
Dominik Laskowski75788452021-02-09 18:51:25 -0800221
222 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700223 };
Arpit Singh403e53c2023-04-18 11:46:56 +0000224 DeviceMode mDeviceMode{DeviceMode::DISABLED};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700225
226 // The reader's configuration.
227 InputReaderConfiguration mConfig;
228
229 // Immutable configuration parameters.
230 struct Parameters {
Michael Wright227c5542020-07-02 18:30:52 +0100231 enum class DeviceType {
232 TOUCH_SCREEN,
Michael Wright227c5542020-07-02 18:30:52 +0100233 TOUCH_NAVIGATION,
234 POINTER,
Dominik Laskowski75788452021-02-09 18:51:25 -0800235
236 ftl_last = POINTER
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700237 };
238
239 DeviceType deviceType;
240 bool hasAssociatedDisplay;
241 bool associatedDisplayIsExternal;
242 bool orientationAware;
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700243
Michael Wrighta9cf4192022-12-01 23:46:39 +0000244 ui::Rotation orientation;
Prabir Pradhanac1c74f2021-08-20 16:09:32 -0700245
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700246 bool hasButtonUnderPad;
247 std::string uniqueDisplayId;
248
Michael Wright227c5542020-07-02 18:30:52 +0100249 enum class GestureMode {
250 SINGLE_TOUCH,
251 MULTI_TOUCH,
Dominik Laskowski75788452021-02-09 18:51:25 -0800252
253 ftl_last = MULTI_TOUCH
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700254 };
255 GestureMode gestureMode;
256
257 bool wake;
Prabir Pradhan167c2702022-09-14 00:37:24 +0000258
Prabir Pradhane04ffaa2022-12-13 23:04:04 +0000259 // The Universal Stylus Initiative (USI) protocol version supported by this device.
260 std::optional<InputDeviceUsiVersion> usiVersion;
Yuncheol Heo50c19b12022-11-02 20:33:08 -0700261
262 // Allows touches while the display is off.
263 bool enableForInactiveViewport;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700264 } mParameters;
265
266 // Immutable calibration parameters in parsed form.
267 struct Calibration {
268 // Size
Michael Wright227c5542020-07-02 18:30:52 +0100269 enum class SizeCalibration {
270 DEFAULT,
271 NONE,
272 GEOMETRIC,
273 DIAMETER,
274 BOX,
275 AREA,
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800276 ftl_last = AREA
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700277 };
278
279 SizeCalibration sizeCalibration;
280
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700281 std::optional<float> sizeScale;
282 std::optional<float> sizeBias;
283 std::optional<bool> sizeIsSummed;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700284
285 // Pressure
Michael Wright227c5542020-07-02 18:30:52 +0100286 enum class PressureCalibration {
287 DEFAULT,
288 NONE,
289 PHYSICAL,
290 AMPLITUDE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700291 };
292
293 PressureCalibration pressureCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700294 std::optional<float> pressureScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700295
296 // Orientation
Michael Wright227c5542020-07-02 18:30:52 +0100297 enum class OrientationCalibration {
298 DEFAULT,
299 NONE,
300 INTERPOLATED,
301 VECTOR,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700302 };
303
304 OrientationCalibration orientationCalibration;
305
306 // Distance
Michael Wright227c5542020-07-02 18:30:52 +0100307 enum class DistanceCalibration {
308 DEFAULT,
309 NONE,
310 SCALED,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700311 };
312
313 DistanceCalibration distanceCalibration;
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700314 std::optional<float> distanceScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700315
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700316 inline void applySizeScaleAndBias(float& outSize) const {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700317 if (sizeScale) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700318 outSize *= *sizeScale;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700319 }
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700320 if (sizeBias) {
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700321 outSize += *sizeBias;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700322 }
Siarhei Vishniakou07247342022-07-15 14:27:37 -0700323 if (outSize < 0) {
324 outSize = 0;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700325 }
326 }
327 } mCalibration;
328
329 // Affine location transformation/calibration
330 struct TouchAffineTransformation mAffineTransform;
331
332 RawPointerAxes mRawPointerAxes;
333
334 struct RawState {
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +0000335 nsecs_t when{std::numeric_limits<nsecs_t>::min()};
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000336 nsecs_t readTime{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700337
338 // Raw pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000339 RawPointerData rawPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700340
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000341 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700342
343 // Scroll state.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000344 int32_t rawVScroll{};
345 int32_t rawHScroll{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700346
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000347 inline void clear() { *this = RawState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700348 };
349
350 struct CookedState {
351 // Cooked pointer sample data.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000352 CookedPointerData cookedPointerData{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700353
354 // Id bits used to differentiate fingers, stylus and mouse tools.
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000355 BitSet32 fingerIdBits{};
356 BitSet32 stylusIdBits{};
357 BitSet32 mouseIdBits{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700358
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000359 int32_t buttonState{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700360
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000361 inline void clear() { *this = CookedState(); }
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700362 };
363
364 std::vector<RawState> mRawStatesPending;
365 RawState mCurrentRawState;
366 CookedState mCurrentCookedState;
367 RawState mLastRawState;
368 CookedState mLastCookedState;
369
370 // State provided by an external stylus
371 StylusState mExternalStylusState;
Prabir Pradhan8d9ba912022-11-11 22:26:33 +0000372 // If an external stylus is capable of reporting pointer-specific data like pressure, we will
373 // attempt to fuse the pointer data reported by the stylus to the first touch pointer. This is
374 // the id of the pointer to which the external stylus data is fused.
375 std::optional<uint32_t> mFusedStylusPointerId;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700376 nsecs_t mExternalStylusFusionTimeout;
377 bool mExternalStylusDataPending;
Prabir Pradhan124ea442022-10-28 20:27:44 +0000378 // A subset of the buttons in mCurrentRawState that came from an external stylus.
Arpit Singha8c236b2023-04-25 13:56:05 +0000379 int32_t mExternalStylusButtonsApplied{0};
Prabir Pradhanb08a0e82023-09-14 22:28:32 +0000380 // True if the current cooked pointer data was modified due to the state of an external stylus.
381 bool mCurrentStreamModifiedByExternalStylus{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700382
383 // True if we sent a HOVER_ENTER event.
Arpit Singha8c236b2023-04-25 13:56:05 +0000384 bool mSentHoverEnter{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700385
386 // Have we assigned pointer IDs for this stream
Arpit Singha8c236b2023-04-25 13:56:05 +0000387 bool mHavePointerIds{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700388
389 // Is the current stream of direct touch events aborted
Arpit Singha8c236b2023-04-25 13:56:05 +0000390 bool mCurrentMotionAborted{false};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700391
392 // The time the primary pointer last went down.
Arpit Singha8c236b2023-04-25 13:56:05 +0000393 nsecs_t mDownTime{0};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700394
395 // The pointer controller, or null if the device is not a pointer.
Michael Wright17db18e2020-06-26 20:51:44 +0100396 std::shared_ptr<PointerControllerInterface> mPointerController;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700397
398 std::vector<VirtualKey> mVirtualKeys;
399
Arpit Singha8c236b2023-04-25 13:56:05 +0000400 explicit TouchInputMapper(InputDeviceContext& deviceContext,
401 const InputReaderConfiguration& readerConfig);
402
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700403 virtual void dumpParameters(std::string& dump);
404 virtual void configureRawPointerAxes();
405 virtual void dumpRawPointerAxes(std::string& dump);
Prabir Pradhan1728b212021-10-19 16:00:03 -0700406 virtual void configureInputDevice(nsecs_t when, bool* outResetNeeded);
407 virtual void dumpDisplay(std::string& dump);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700408 virtual void configureVirtualKeys();
409 virtual void dumpVirtualKeys(std::string& dump);
410 virtual void parseCalibration();
411 virtual void resolveCalibration();
412 virtual void dumpCalibration(std::string& dump);
413 virtual void updateAffineTransformation();
414 virtual void dumpAffineTransformation(std::string& dump);
415 virtual void resolveExternalStylusPresence();
416 virtual bool hasStylus() const = 0;
417 virtual bool hasExternalStylus() const;
418
419 virtual void syncTouch(nsecs_t when, RawState* outState) = 0;
420
421private:
422 // The current viewport.
423 // The components of the viewport are specified in the display's rotated orientation.
424 DisplayViewport mViewport;
425
Prabir Pradhan2d613f42022-11-10 20:22:06 +0000426 // We refer to the display as being in the "natural orientation" when there is no rotation
427 // applied. The display size obtained from the viewport in the natural orientation.
Prabir Pradhan7ddbc952022-11-09 22:03:40 +0000428 // Always starts at (0, 0).
429 ui::Size mDisplayBounds{ui::kInvalidSize};
Arthur Hung4197f6b2020-03-16 15:39:59 +0800430
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000431 // The physical frame is the rectangle in the rotated display's coordinate space that maps to
Prabir Pradhan1728b212021-10-19 16:00:03 -0700432 // the logical display frame.
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000433 Rect mPhysicalFrameInRotatedDisplay{Rect::INVALID_RECT};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700434
Prabir Pradhan1728b212021-10-19 16:00:03 -0700435 // The orientation of the input device relative to that of the display panel. It specifies
436 // the rotation of the input device coordinates required to produce the display panel
437 // orientation, so it will depend on whether the device is orientation aware.
Arpit Singh403e53c2023-04-18 11:46:56 +0000438 ui::Rotation mInputDeviceOrientation{ui::ROTATION_0};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700439
Prabir Pradhanea31d4f2022-11-10 20:48:01 +0000440 // The transform that maps the input device's raw coordinate space to the un-rotated display's
441 // coordinate space. InputReader generates events in the un-rotated display's coordinate space.
442 ui::Transform mRawToDisplay;
443
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000444 // The transform that maps the input device's raw coordinate space to the rotated display's
445 // coordinate space. This used to perform hit-testing of raw events with the physical frame in
446 // the rotated coordinate space. See mPhysicalFrameInRotatedDisplay.
447 ui::Transform mRawToRotatedDisplay;
448
Prabir Pradhane2e10b42022-11-17 20:59:36 +0000449 // The transform used for non-planar raw axes, such as orientation and tilt.
450 ui::Transform mRawRotation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700451
452 float mGeometricScale;
453
454 float mPressureScale;
455
456 float mSizeScale;
457
458 float mOrientationScale;
459
460 float mDistanceScale;
461
462 bool mHaveTilt;
463 float mTiltXCenter;
464 float mTiltXScale;
465 float mTiltYCenter;
466 float mTiltYScale;
467
468 bool mExternalStylusConnected;
469
470 // Oriented motion ranges for input device info.
471 struct OrientedRanges {
472 InputDeviceInfo::MotionRange x;
473 InputDeviceInfo::MotionRange y;
474 InputDeviceInfo::MotionRange pressure;
475
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700476 std::optional<InputDeviceInfo::MotionRange> size;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700477
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700478 std::optional<InputDeviceInfo::MotionRange> touchMajor;
479 std::optional<InputDeviceInfo::MotionRange> touchMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700480
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700481 std::optional<InputDeviceInfo::MotionRange> toolMajor;
482 std::optional<InputDeviceInfo::MotionRange> toolMinor;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700483
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700484 std::optional<InputDeviceInfo::MotionRange> orientation;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700485
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700486 std::optional<InputDeviceInfo::MotionRange> distance;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700487
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700488 std::optional<InputDeviceInfo::MotionRange> tilt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700489
490 void clear() {
Siarhei Vishniakou24210882022-07-15 09:42:04 -0700491 size = std::nullopt;
492 touchMajor = std::nullopt;
493 touchMinor = std::nullopt;
494 toolMajor = std::nullopt;
495 toolMinor = std::nullopt;
496 orientation = std::nullopt;
497 distance = std::nullopt;
498 tilt = std::nullopt;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700499 }
500 } mOrientedRanges;
501
502 // Oriented dimensions and precision.
503 float mOrientedXPrecision;
504 float mOrientedYPrecision;
505
506 struct CurrentVirtualKeyState {
507 bool down;
508 bool ignored;
509 nsecs_t downTime;
510 int32_t keyCode;
511 int32_t scanCode;
512 } mCurrentVirtualKey;
513
514 // Scale factor for gesture or mouse based pointer movements.
515 float mPointerXMovementScale;
516 float mPointerYMovementScale;
517
518 // Scale factor for gesture based zooming and other freeform motions.
519 float mPointerXZoomScale;
520 float mPointerYZoomScale;
521
HQ Liue6983c72022-04-19 22:14:56 +0000522 // The maximum swipe width between pointers to detect a swipe gesture
523 // in the number of pixels.Touches that are wider than this are translated
524 // into freeform gestures.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700525 float mPointerGestureMaxSwipeWidth;
526
527 struct PointerDistanceHeapElement {
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000528 uint32_t currentPointerIndex : 8 {};
529 uint32_t lastPointerIndex : 8 {};
530 uint64_t distance : 48 {}; // squared distance
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700531 };
532
Michael Wright227c5542020-07-02 18:30:52 +0100533 enum class PointerUsage {
534 NONE,
535 GESTURES,
536 STYLUS,
537 MOUSE,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700538 };
Arpit Singha8c236b2023-04-25 13:56:05 +0000539 PointerUsage mPointerUsage{PointerUsage::NONE};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700540
541 struct PointerGesture {
Michael Wright227c5542020-07-02 18:30:52 +0100542 enum class Mode {
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700543 // No fingers, button is not pressed.
544 // Nothing happening.
545 NEUTRAL,
546
547 // No fingers, button is not pressed.
548 // Tap detected.
549 // Emits DOWN and UP events at the pointer location.
550 TAP,
551
552 // Exactly one finger dragging following a tap.
553 // Pointer follows the active finger.
554 // Emits DOWN, MOVE and UP events at the pointer location.
555 //
556 // Detect double-taps when the finger goes up while in TAP_DRAG mode.
557 TAP_DRAG,
558
559 // Button is pressed.
560 // Pointer follows the active finger if there is one. Other fingers are ignored.
561 // Emits DOWN, MOVE and UP events at the pointer location.
562 BUTTON_CLICK_OR_DRAG,
563
564 // Exactly one finger, button is not pressed.
565 // Pointer follows the active finger.
566 // Emits HOVER_MOVE events at the pointer location.
567 //
568 // Detect taps when the finger goes up while in HOVER mode.
569 HOVER,
570
571 // Exactly two fingers but neither have moved enough to clearly indicate
572 // whether a swipe or freeform gesture was intended. We consider the
573 // pointer to be pressed so this enables clicking or long-pressing on buttons.
574 // Pointer does not move.
575 // Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
576 PRESS,
577
578 // Exactly two fingers moving in the same direction, button is not pressed.
579 // Pointer does not move.
580 // Emits DOWN, MOVE and UP events with a single pointer coordinate that
581 // follows the midpoint between both fingers.
582 SWIPE,
583
584 // Two or more fingers moving in arbitrary directions, button is not pressed.
585 // Pointer does not move.
586 // Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
587 // each finger individually relative to the initial centroid of the finger.
588 FREEFORM,
589
590 // Waiting for quiet time to end before starting the next gesture.
591 QUIET,
Harry Cuttsc57cd3c2024-04-24 13:52:55 +0000592
593 ftl_last = QUIET,
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700594 };
595
Prabir Pradhan47cf0a02021-03-11 20:30:57 -0800596 // When a gesture is sent to an unfocused window, return true if it can bring that window
597 // into focus, false otherwise.
598 static bool canGestureAffectWindowFocus(Mode mode) {
599 switch (mode) {
600 case Mode::TAP:
601 case Mode::TAP_DRAG:
602 case Mode::BUTTON_CLICK_OR_DRAG:
603 // Taps can affect window focus.
604 return true;
605 case Mode::FREEFORM:
606 case Mode::HOVER:
607 case Mode::NEUTRAL:
608 case Mode::PRESS:
609 case Mode::QUIET:
610 case Mode::SWIPE:
611 // Most gestures can be performed on an unfocused window, so they should not
612 // not affect window focus.
613 return false;
614 }
615 }
616
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700617 // Time the first finger went down.
618 nsecs_t firstTouchTime;
619
620 // The active pointer id from the raw touch data.
621 int32_t activeTouchId; // -1 if none
622
623 // The active pointer id from the gesture last delivered to the application.
624 int32_t activeGestureId; // -1 if none
625
626 // Pointer coords and ids for the current and previous pointer gesture.
627 Mode currentGestureMode;
628 BitSet32 currentGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000629 IdToIndexArray currentGestureIdToIndex{};
630 PropertiesArray currentGestureProperties{};
631 CoordsArray currentGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700632
633 Mode lastGestureMode;
634 BitSet32 lastGestureIdBits;
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000635 IdToIndexArray lastGestureIdToIndex{};
636 PropertiesArray lastGestureProperties{};
637 CoordsArray lastGestureCoords{};
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700638
639 // Time the pointer gesture last went down.
640 nsecs_t downTime;
641
642 // Time when the pointer went down for a TAP.
643 nsecs_t tapDownTime;
644
645 // Time when the pointer went up for a TAP.
646 nsecs_t tapUpTime;
647
648 // Location of initial tap.
649 float tapX, tapY;
650
651 // Time we started waiting for quiescence.
652 nsecs_t quietTime;
653
654 // Reference points for multitouch gestures.
655 float referenceTouchX; // reference touch X/Y coordinates in surface units
656 float referenceTouchY;
657 float referenceGestureX; // reference gesture X/Y coordinates in pixels
658 float referenceGestureY;
659
660 // Distance that each pointer has traveled which has not yet been
661 // subsumed into the reference gesture position.
662 BitSet32 referenceIdBits;
663 struct Delta {
664 float dx, dy;
665 };
666 Delta referenceDeltas[MAX_POINTER_ID + 1];
667
668 // Describes how touch ids are mapped to gesture ids for freeform gestures.
669 uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
670
671 // A velocity tracker for determining whether to switch active pointers during drags.
672 VelocityTracker velocityTracker;
673
674 void reset() {
675 firstTouchTime = LLONG_MIN;
676 activeTouchId = -1;
677 activeGestureId = -1;
Michael Wright227c5542020-07-02 18:30:52 +0100678 currentGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700679 currentGestureIdBits.clear();
Michael Wright227c5542020-07-02 18:30:52 +0100680 lastGestureMode = Mode::NEUTRAL;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700681 lastGestureIdBits.clear();
682 downTime = 0;
683 velocityTracker.clear();
684 resetTap();
685 resetQuietTime();
686 }
687
688 void resetTap() {
689 tapDownTime = LLONG_MIN;
690 tapUpTime = LLONG_MIN;
691 }
692
693 void resetQuietTime() { quietTime = LLONG_MIN; }
694 } mPointerGesture;
695
696 struct PointerSimple {
697 PointerCoords currentCoords;
698 PointerProperties currentProperties;
699 PointerCoords lastCoords;
700 PointerProperties lastProperties;
701
702 // True if the pointer is down.
703 bool down;
704
705 // True if the pointer is hovering.
706 bool hovering;
707
708 // Time the pointer last went down.
709 nsecs_t downTime;
710
Prabir Pradhanb80b6c02022-11-02 20:05:13 +0000711 // Values reported for the last pointer event.
712 uint32_t source;
713 int32_t displayId;
714 float lastCursorX;
715 float lastCursorY;
716
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700717 void reset() {
718 currentCoords.clear();
719 currentProperties.clear();
720 lastCoords.clear();
721 lastProperties.clear();
722 down = false;
723 hovering = false;
724 downTime = 0;
Prabir Pradhanb80b6c02022-11-02 20:05:13 +0000725 source = 0;
726 displayId = ADISPLAY_ID_NONE;
727 lastCursorX = 0.f;
728 lastCursorY = 0.f;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700729 }
730 } mPointerSimple;
731
732 // The pointer and scroll velocity controls.
Harry Cuttse78184b2024-01-08 15:54:58 +0000733 SimpleVelocityControl mPointerVelocityControl;
734 SimpleVelocityControl mWheelXVelocityControl;
735 SimpleVelocityControl mWheelYVelocityControl;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700736
737 std::optional<DisplayViewport> findViewport();
738
739 void resetExternalStylus();
740 void clearStylusDataPendingFlags();
741
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800742 int32_t clampResolution(const char* axisName, int32_t resolution) const;
Siarhei Vishniakou4e837cc2021-12-20 23:24:33 -0800743 void initializeOrientedRanges();
744 void initializeSizeRanges();
745
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700746 [[nodiscard]] std::list<NotifyArgs> sync(nsecs_t when, nsecs_t readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700747
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700748 [[nodiscard]] std::list<NotifyArgs> consumeRawTouches(nsecs_t when, nsecs_t readTime,
749 uint32_t policyFlags, bool& outConsumed);
750 [[nodiscard]] std::list<NotifyArgs> processRawTouches(bool timeout);
751 [[nodiscard]] std::list<NotifyArgs> cookAndDispatch(nsecs_t when, nsecs_t readTime);
752 [[nodiscard]] NotifyKeyArgs dispatchVirtualKey(nsecs_t when, nsecs_t readTime,
753 uint32_t policyFlags, int32_t keyEventAction,
754 int32_t keyEventFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700755
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700756 [[nodiscard]] std::list<NotifyArgs> dispatchTouches(nsecs_t when, nsecs_t readTime,
757 uint32_t policyFlags);
758 [[nodiscard]] std::list<NotifyArgs> dispatchHoverExit(nsecs_t when, nsecs_t readTime,
759 uint32_t policyFlags);
760 [[nodiscard]] std::list<NotifyArgs> dispatchHoverEnterAndMove(nsecs_t when, nsecs_t readTime,
761 uint32_t policyFlags);
762 [[nodiscard]] std::list<NotifyArgs> dispatchButtonRelease(nsecs_t when, nsecs_t readTime,
763 uint32_t policyFlags);
764 [[nodiscard]] std::list<NotifyArgs> dispatchButtonPress(nsecs_t when, nsecs_t readTime,
765 uint32_t policyFlags);
LiZhihong758eb562022-11-03 15:28:29 +0800766 [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonPress(nsecs_t when,
767 uint32_t policyFlags,
768 BitSet32 idBits,
769 nsecs_t readTime);
770 [[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonRelease(nsecs_t when,
771 uint32_t policyFlags,
772 BitSet32 idBits,
773 nsecs_t readTime);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700774 const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData);
775 void cookPointerData();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700776 [[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime,
777 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700778
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700779 [[nodiscard]] std::list<NotifyArgs> dispatchPointerUsage(nsecs_t when, nsecs_t readTime,
780 uint32_t policyFlags,
781 PointerUsage pointerUsage);
782 [[nodiscard]] std::list<NotifyArgs> abortPointerUsage(nsecs_t when, nsecs_t readTime,
783 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700784
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700785 [[nodiscard]] std::list<NotifyArgs> dispatchPointerGestures(nsecs_t when, nsecs_t readTime,
786 uint32_t policyFlags,
787 bool isTimeout);
788 [[nodiscard]] std::list<NotifyArgs> abortPointerGestures(nsecs_t when, nsecs_t readTime,
789 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700790 bool preparePointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
791 bool* outFinishPreviousGesture, bool isTimeout);
792
Harry Cuttsbea6ce52022-10-14 15:17:30 +0000793 // Returns true if we're in a period of "quiet time" when touchpad gestures should be ignored.
794 bool checkForTouchpadQuietTime(nsecs_t when);
795
796 std::pair<int32_t, float> getFastestFinger();
797
798 void prepareMultiFingerPointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
799 bool* outFinishPreviousGesture);
800
Harry Cutts714d1ad2022-08-24 16:36:43 +0000801 // Moves the on-screen mouse pointer based on the movement of the pointer of the given ID
802 // between the last and current events. Uses a relative motion.
803 void moveMousePointerFromPointerDelta(nsecs_t when, uint32_t pointerId);
804
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700805 [[nodiscard]] std::list<NotifyArgs> dispatchPointerStylus(nsecs_t when, nsecs_t readTime,
806 uint32_t policyFlags);
807 [[nodiscard]] std::list<NotifyArgs> abortPointerStylus(nsecs_t when, nsecs_t readTime,
808 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700809
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700810 [[nodiscard]] std::list<NotifyArgs> dispatchPointerMouse(nsecs_t when, nsecs_t readTime,
811 uint32_t policyFlags);
812 [[nodiscard]] std::list<NotifyArgs> abortPointerMouse(nsecs_t when, nsecs_t readTime,
813 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700814
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700815 [[nodiscard]] std::list<NotifyArgs> dispatchPointerSimple(nsecs_t when, nsecs_t readTime,
816 uint32_t policyFlags, bool down,
Prabir Pradhane71e5702023-03-29 14:51:38 +0000817 bool hovering, int32_t displayId);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700818 [[nodiscard]] std::list<NotifyArgs> abortPointerSimple(nsecs_t when, nsecs_t readTime,
819 uint32_t policyFlags);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700820
Prabir Pradhan3f7545f2022-10-19 16:56:39 +0000821 // Attempts to assign a pointer id to the external stylus. Returns true if the state should be
822 // withheld from further processing while waiting for data from the stylus.
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700823 bool assignExternalStylusId(const RawState& state, bool timeout);
824 void applyExternalStylusButtonState(nsecs_t when);
825 void applyExternalStylusTouchState(nsecs_t when);
826
827 // Dispatches a motion event.
828 // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
829 // method will take care of setting the index and transmuting the action to DOWN or UP
830 // it is the first / last pointer to go down / up.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700831 [[nodiscard]] NotifyMotionArgs dispatchMotion(
832 nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
833 int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
Prabir Pradhand6ccedb2022-09-27 21:04:06 +0000834 int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords,
835 const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700836 float yPrecision, nsecs_t downTime, MotionClassification classification);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700837
Garfield Tanc734e4f2021-01-15 20:01:39 -0800838 // Returns if this touch device is a touch screen with an associated display.
839 bool isTouchScreen();
840 // Updates touch spots if they are enabled. Should only be used when this device is a
841 // touchscreen.
842 void updateTouchSpots();
843
Prabir Pradhan1728b212021-10-19 16:00:03 -0700844 bool isPointInsidePhysicalFrame(int32_t x, int32_t y) const;
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700845 const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
846
Siarhei Vishniakou57479982021-03-03 01:32:21 +0000847 static void assignPointerIds(const RawState& last, RawState& current);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700848
Prabir Pradhan7d9cb5a2023-03-14 21:18:07 +0000849 // Compute input transforms for DIRECT and POINTER modes.
Prabir Pradhan675f25a2022-11-10 22:04:07 +0000850 void computeInputTransforms();
Arpit Singh403e53c2023-04-18 11:46:56 +0000851 static Parameters::DeviceType computeDeviceType(const InputDeviceContext& deviceContext);
852 static Parameters computeParameters(const InputDeviceContext& deviceContext);
Prabir Pradhanbaa5c822019-08-30 15:27:05 -0700853};
854
855} // namespace android