blob: 62cf67ea88763bb64f25ead9d96e6afcda44189b [file] [log] [blame]
Jeff Brown5912f952013-07-01 19:10:31 -07001/*
2 * Copyright (C) 2010 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
17#ifndef _LIBINPUT_INPUT_TRANSPORT_H
18#define _LIBINPUT_INPUT_TRANSPORT_H
19
Robert Carr2c358bf2018-08-08 15:58:15 -070020#pragma GCC system_header
21
Jeff Brown5912f952013-07-01 19:10:31 -070022/**
23 * Native input transport.
24 *
25 * The InputChannel provides a mechanism for exchanging InputMessage structures across processes.
26 *
27 * The InputPublisher and InputConsumer each handle one end-point of an input channel.
28 * The InputPublisher is used by the input dispatcher to send events to the application.
29 * The InputConsumer is used by the application to receive events from the input dispatcher.
30 */
31
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +010032#include <string>
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -100033#include <unordered_map>
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +010034
Atif Niyaz3d3fa522019-07-25 11:12:39 -070035#include <android-base/chrono_utils.h>
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000036#include <android-base/result.h>
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +000037#include <android-base/unique_fd.h>
Atif Niyaz3d3fa522019-07-25 11:12:39 -070038
Robert Carr803535b2018-08-02 16:38:15 -070039#include <binder/IBinder.h>
Chris Ye0783e992020-06-02 21:34:49 -070040#include <binder/Parcelable.h>
Jeff Brown5912f952013-07-01 19:10:31 -070041#include <input/Input.h>
Chris Ye0783e992020-06-02 21:34:49 -070042#include <sys/stat.h>
chaviw9eaa22c2020-07-01 16:21:27 -070043#include <ui/Transform.h>
Jeff Brown5912f952013-07-01 19:10:31 -070044#include <utils/BitSet.h>
Atif Niyaz3d3fa522019-07-25 11:12:39 -070045#include <utils/Errors.h>
46#include <utils/RefBase.h>
47#include <utils/Timers.h>
Jeff Brown5912f952013-07-01 19:10:31 -070048
Josh Gao2ccbe3a2019-08-09 14:35:36 -070049
Jeff Brown5912f952013-07-01 19:10:31 -070050namespace android {
Robert Carr3720ed02018-08-08 16:08:27 -070051class Parcel;
Jeff Brown5912f952013-07-01 19:10:31 -070052
53/*
54 * Intermediate representation used to send input events and related signals.
Fengwei Yin83e0e422014-05-24 05:32:09 +080055 *
56 * Note that this structure is used for IPCs so its layout must be identical
57 * on 64 and 32 bit processes. This is tested in StructLayout_test.cpp.
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -080058 *
59 * Since the struct must be aligned to an 8-byte boundary, there could be uninitialized bytes
60 * in-between the defined fields. This padding data should be explicitly accounted for by adding
61 * "empty" fields into the struct. This data is memset to zero before sending the struct across
62 * the socket. Adding the explicit fields ensures that the memset is not optimized away by the
63 * compiler. When a new field is added to the struct, the corresponding change
64 * in StructLayout_test should be made.
Jeff Brown5912f952013-07-01 19:10:31 -070065 */
66struct InputMessage {
Siarhei Vishniakou52402772019-10-22 09:32:30 -070067 enum class Type : uint32_t {
68 KEY,
69 MOTION,
70 FINISHED,
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080071 FOCUS,
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -080072 CAPTURE,
arthurhung7632c332020-12-30 16:58:01 +080073 DRAG,
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +000074 TIMELINE,
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -070075 TOUCH_MODE,
Jeff Brown5912f952013-07-01 19:10:31 -070076 };
77
78 struct Header {
Siarhei Vishniakou52402772019-10-22 09:32:30 -070079 Type type; // 4 bytes
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -050080 uint32_t seq;
Jeff Brown5912f952013-07-01 19:10:31 -070081 } header;
82
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -060083 // For keys and motions, rely on the fact that std::array takes up exactly as much space
84 // as the underlying data. This is not guaranteed by C++, but it simplifies the conversions.
85 static_assert(sizeof(std::array<uint8_t, 32>) == 32);
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +000086
87 // For bool values, rely on the fact that they take up exactly one byte. This is not guaranteed
88 // by C++ and is implementation-dependent, but it simplifies the conversions.
89 static_assert(sizeof(bool) == 1);
90
91 // Body *must* be 8 byte aligned.
Jeff Brown5912f952013-07-01 19:10:31 -070092 union Body {
93 struct Key {
Garfield Tan1c7bc862020-01-28 13:24:04 -080094 int32_t eventId;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -050095 uint32_t empty1;
Fengwei Yin83e0e422014-05-24 05:32:09 +080096 nsecs_t eventTime __attribute__((aligned(8)));
Jeff Brown5912f952013-07-01 19:10:31 -070097 int32_t deviceId;
98 int32_t source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010099 int32_t displayId;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600100 std::array<uint8_t, 32> hmac;
Jeff Brown5912f952013-07-01 19:10:31 -0700101 int32_t action;
102 int32_t flags;
103 int32_t keyCode;
104 int32_t scanCode;
105 int32_t metaState;
106 int32_t repeatCount;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800107 uint32_t empty2;
Fengwei Yin83e0e422014-05-24 05:32:09 +0800108 nsecs_t downTime __attribute__((aligned(8)));
Jeff Brown5912f952013-07-01 19:10:31 -0700109
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800110 inline size_t size() const { return sizeof(Key); }
Jeff Brown5912f952013-07-01 19:10:31 -0700111 } key;
112
113 struct Motion {
Garfield Tan1c7bc862020-01-28 13:24:04 -0800114 int32_t eventId;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500115 uint32_t empty1;
Fengwei Yin83e0e422014-05-24 05:32:09 +0800116 nsecs_t eventTime __attribute__((aligned(8)));
Jeff Brown5912f952013-07-01 19:10:31 -0700117 int32_t deviceId;
118 int32_t source;
Tarandeep Singh58641502017-07-31 10:51:54 -0700119 int32_t displayId;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600120 std::array<uint8_t, 32> hmac;
Jeff Brown5912f952013-07-01 19:10:31 -0700121 int32_t action;
Michael Wright7b159c92015-05-14 14:48:03 +0100122 int32_t actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700123 int32_t flags;
124 int32_t metaState;
125 int32_t buttonState;
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800126 MotionClassification classification; // base type: uint8_t
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800127 uint8_t empty2[3]; // 3 bytes to fill gap created by classification
Jeff Brown5912f952013-07-01 19:10:31 -0700128 int32_t edgeFlags;
Fengwei Yin83e0e422014-05-24 05:32:09 +0800129 nsecs_t downTime __attribute__((aligned(8)));
chaviw9eaa22c2020-07-01 16:21:27 -0700130 float dsdx;
131 float dtdx;
132 float dtdy;
133 float dsdy;
134 float tx;
135 float ty;
Jeff Brown5912f952013-07-01 19:10:31 -0700136 float xPrecision;
137 float yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700138 float xCursorPosition;
139 float yCursorPosition;
Evan Rosky84f07f02021-04-16 10:42:42 -0700140 int32_t displayWidth;
141 int32_t displayHeight;
Narayan Kamathed5fd382014-05-02 17:53:33 +0100142 uint32_t pointerCount;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800143 uint32_t empty3;
Siarhei Vishniakou10fe6762019-11-25 11:44:11 -0800144 /**
145 * The "pointers" field must be the last field of the struct InputMessage.
146 * When we send the struct InputMessage across the socket, we are not
147 * writing the entire "pointers" array, but only the pointerCount portion
148 * of it as an optimization. Adding a field after "pointers" would break this.
149 */
Michael Wrightb03f1032015-05-14 16:29:13 +0100150 struct Pointer {
Jeff Brown5912f952013-07-01 19:10:31 -0700151 PointerProperties properties;
152 PointerCoords coords;
Siarhei Vishniakou10fe6762019-11-25 11:44:11 -0800153 } pointers[MAX_POINTERS] __attribute__((aligned(8)));
Jeff Brown5912f952013-07-01 19:10:31 -0700154
155 int32_t getActionId() const {
156 uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
157 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
158 return pointers[index].properties.id;
159 }
160
161 inline size_t size() const {
162 return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS
163 + sizeof(Pointer) * pointerCount;
164 }
165 } motion;
166
167 struct Finished {
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +0000168 bool handled;
169 uint8_t empty[7];
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -1000170 nsecs_t consumeTime; // The time when the event was consumed by the receiving end
Jeff Brown5912f952013-07-01 19:10:31 -0700171
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800172 inline size_t size() const { return sizeof(Finished); }
Jeff Brown5912f952013-07-01 19:10:31 -0700173 } finished;
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800174
175 struct Focus {
Garfield Tan1c7bc862020-01-28 13:24:04 -0800176 int32_t eventId;
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +0000177 // The following 3 fields take up 4 bytes total
178 bool hasFocus;
179 bool inTouchMode;
180 uint8_t empty[2];
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800181
182 inline size_t size() const { return sizeof(Focus); }
183 } focus;
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800184
185 struct Capture {
186 int32_t eventId;
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +0000187 bool pointerCaptureEnabled;
188 uint8_t empty[3];
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800189
190 inline size_t size() const { return sizeof(Capture); }
191 } capture;
arthurhung7632c332020-12-30 16:58:01 +0800192
193 struct Drag {
194 int32_t eventId;
195 float x;
196 float y;
197 bool isExiting;
198 uint8_t empty[3];
199
200 inline size_t size() const { return sizeof(Drag); }
201 } drag;
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000202
203 struct Timeline {
204 int32_t eventId;
205 uint32_t empty;
206 std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
207
208 inline size_t size() const { return sizeof(Timeline); }
209 } timeline;
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -0700210
211 struct TouchMode {
212 int32_t eventId;
213 // The following 2 fields take up 4 bytes total
214 bool isInTouchMode;
215 uint8_t empty[3];
216
217 inline size_t size() const { return sizeof(TouchMode); }
218 } touchMode;
Fengwei Yin83e0e422014-05-24 05:32:09 +0800219 } __attribute__((aligned(8))) body;
Jeff Brown5912f952013-07-01 19:10:31 -0700220
221 bool isValid(size_t actualSize) const;
222 size_t size() const;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800223 void getSanitizedCopy(InputMessage* msg) const;
Jeff Brown5912f952013-07-01 19:10:31 -0700224};
225
226/*
227 * An input channel consists of a local unix domain socket used to send and receive
228 * input messages across processes. Each channel has a descriptive name for debugging purposes.
229 *
230 * Each endpoint has its own InputChannel object that specifies its file descriptor.
231 *
232 * The input channel is closed when all references to it are released.
233 */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500234class InputChannel : public Parcelable {
Chris Ye0783e992020-06-02 21:34:49 -0700235public:
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500236 static std::unique_ptr<InputChannel> create(const std::string& name,
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500237 android::base::unique_fd fd, sp<IBinder> token);
238 InputChannel() = default;
239 InputChannel(const InputChannel& other)
240 : mName(other.mName), mFd(::dup(other.mFd)), mToken(other.mToken){};
241 InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000242 ~InputChannel() override;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700243 /**
244 * Create a pair of input channels.
245 * The two returned input channels are equivalent, and are labeled as "server" and "client"
246 * for convenience. The two input channels share the same token.
Jeff Brown5912f952013-07-01 19:10:31 -0700247 *
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700248 * Return OK on success.
Jeff Brown5912f952013-07-01 19:10:31 -0700249 */
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800250 static status_t openInputChannelPair(const std::string& name,
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500251 std::unique_ptr<InputChannel>& outServerChannel,
252 std::unique_ptr<InputChannel>& outClientChannel);
Jeff Brown5912f952013-07-01 19:10:31 -0700253
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500254 inline std::string getName() const { return mName; }
255 inline const android::base::unique_fd& getFd() const { return mFd; }
256 inline sp<IBinder> getToken() const { return mToken; }
Jeff Brown5912f952013-07-01 19:10:31 -0700257
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700258 /* Send a message to the other endpoint.
Jeff Brown5912f952013-07-01 19:10:31 -0700259 *
260 * If the channel is full then the message is guaranteed not to have been sent at all.
261 * Try again after the consumer has sent a finished signal indicating that it has
262 * consumed some of the pending messages from the channel.
263 *
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700264 * Return OK on success.
265 * Return WOULD_BLOCK if the channel is full.
266 * Return DEAD_OBJECT if the channel's peer has been closed.
Jeff Brown5912f952013-07-01 19:10:31 -0700267 * Other errors probably indicate that the channel is broken.
268 */
269 status_t sendMessage(const InputMessage* msg);
270
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700271 /* Receive a message sent by the other endpoint.
Jeff Brown5912f952013-07-01 19:10:31 -0700272 *
273 * If there is no message present, try again after poll() indicates that the fd
274 * is readable.
275 *
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700276 * Return OK on success.
277 * Return WOULD_BLOCK if there is no message present.
278 * Return DEAD_OBJECT if the channel's peer has been closed.
Jeff Brown5912f952013-07-01 19:10:31 -0700279 * Other errors probably indicate that the channel is broken.
280 */
281 status_t receiveMessage(InputMessage* msg);
282
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700283 /* Return a new object that has a duplicate of this channel's fd. */
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500284 std::unique_ptr<InputChannel> dup() const;
Jeff Brown5912f952013-07-01 19:10:31 -0700285
Garfield Tan15601662020-09-22 15:32:38 -0700286 void copyTo(InputChannel& outChannel) const;
287
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500288 status_t readFromParcel(const android::Parcel* parcel) override;
289 status_t writeToParcel(android::Parcel* parcel) const override;
Robert Carr3720ed02018-08-08 16:08:27 -0700290
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700291 /**
292 * The connection token is used to identify the input connection, i.e.
293 * the pair of input channels that were created simultaneously. Input channels
294 * are always created in pairs, and the token can be used to find the server-side
295 * input channel from the client-side input channel, and vice versa.
296 *
297 * Do not use connection token to check equality of a specific input channel object
298 * to another, because two different (client and server) input channels will share the
299 * same connection token.
300 *
301 * Return the token that identifies this connection.
302 */
303 sp<IBinder> getConnectionToken() const;
Robert Carr803535b2018-08-02 16:38:15 -0700304
Chris Ye0783e992020-06-02 21:34:49 -0700305 bool operator==(const InputChannel& inputChannel) const {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500306 struct stat lhs, rhs;
307 if (fstat(mFd.get(), &lhs) != 0) {
Chris Ye0783e992020-06-02 21:34:49 -0700308 return false;
309 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500310 if (fstat(inputChannel.getFd(), &rhs) != 0) {
Chris Ye0783e992020-06-02 21:34:49 -0700311 return false;
312 }
313 // If file descriptors are pointing to same inode they are duplicated fds.
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500314 return inputChannel.getName() == getName() && inputChannel.getConnectionToken() == mToken &&
315 lhs.st_ino == rhs.st_ino;
Chris Ye0783e992020-06-02 21:34:49 -0700316 }
317
Jeff Brown5912f952013-07-01 19:10:31 -0700318private:
Garfield Tan15601662020-09-22 15:32:38 -0700319 base::unique_fd dupFd() const;
320
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500321 std::string mName;
322 android::base::unique_fd mFd;
323
324 sp<IBinder> mToken;
Jeff Brown5912f952013-07-01 19:10:31 -0700325};
326
327/*
328 * Publishes input events to an input channel.
329 */
330class InputPublisher {
331public:
332 /* Creates a publisher associated with an input channel. */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500333 explicit InputPublisher(const std::shared_ptr<InputChannel>& channel);
Jeff Brown5912f952013-07-01 19:10:31 -0700334
335 /* Destroys the publisher and releases its input channel. */
336 ~InputPublisher();
337
338 /* Gets the underlying input channel. */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500339 inline std::shared_ptr<InputChannel> getChannel() { return mChannel; }
Jeff Brown5912f952013-07-01 19:10:31 -0700340
341 /* Publishes a key event to the input channel.
342 *
343 * Returns OK on success.
344 * Returns WOULD_BLOCK if the channel is full.
345 * Returns DEAD_OBJECT if the channel's peer has been closed.
346 * Returns BAD_VALUE if seq is 0.
347 * Other errors probably indicate that the channel is broken.
348 */
Garfield Tan1c7bc862020-01-28 13:24:04 -0800349 status_t publishKeyEvent(uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source,
350 int32_t displayId, std::array<uint8_t, 32> hmac, int32_t action,
351 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600352 int32_t repeatCount, nsecs_t downTime, nsecs_t eventTime);
Jeff Brown5912f952013-07-01 19:10:31 -0700353
354 /* Publishes a motion event to the input channel.
355 *
356 * Returns OK on success.
357 * Returns WOULD_BLOCK if the channel is full.
358 * Returns DEAD_OBJECT if the channel's peer has been closed.
359 * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.
360 * Other errors probably indicate that the channel is broken.
361 */
Garfield Tan1c7bc862020-01-28 13:24:04 -0800362 status_t publishMotionEvent(uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source,
363 int32_t displayId, std::array<uint8_t, 32> hmac, int32_t action,
364 int32_t actionButton, int32_t flags, int32_t edgeFlags,
365 int32_t metaState, int32_t buttonState,
chaviw9eaa22c2020-07-01 16:21:27 -0700366 MotionClassification classification, const ui::Transform& transform,
367 float xPrecision, float yPrecision, float xCursorPosition,
Evan Rosky84f07f02021-04-16 10:42:42 -0700368 float yCursorPosition, int32_t displayWidth, int32_t displayHeight,
369 nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
370 const PointerProperties* pointerProperties,
Garfield Tan00f511d2019-06-12 16:55:40 -0700371 const PointerCoords* pointerCoords);
Jeff Brown5912f952013-07-01 19:10:31 -0700372
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800373 /* Publishes a focus event to the input channel.
374 *
375 * Returns OK on success.
376 * Returns WOULD_BLOCK if the channel is full.
377 * Returns DEAD_OBJECT if the channel's peer has been closed.
378 * Other errors probably indicate that the channel is broken.
379 */
Garfield Tan1c7bc862020-01-28 13:24:04 -0800380 status_t publishFocusEvent(uint32_t seq, int32_t eventId, bool hasFocus, bool inTouchMode);
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800381
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800382 /* Publishes a capture event to the input channel.
383 *
384 * Returns OK on success.
385 * Returns WOULD_BLOCK if the channel is full.
386 * Returns DEAD_OBJECT if the channel's peer has been closed.
387 * Other errors probably indicate that the channel is broken.
388 */
389 status_t publishCaptureEvent(uint32_t seq, int32_t eventId, bool pointerCaptureEnabled);
390
arthurhung7632c332020-12-30 16:58:01 +0800391 /* Publishes a drag event to the input channel.
392 *
393 * Returns OK on success.
394 * Returns WOULD_BLOCK if the channel is full.
395 * Returns DEAD_OBJECT if the channel's peer has been closed.
396 * Other errors probably indicate that the channel is broken.
397 */
398 status_t publishDragEvent(uint32_t seq, int32_t eventId, float x, float y, bool isExiting);
399
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -0700400 /* Publishes a touch mode event to the input channel.
401 *
402 * Returns OK on success.
403 * Returns WOULD_BLOCK if the channel is full.
404 * Returns DEAD_OBJECT if the channel's peer has been closed.
405 * Other errors probably indicate that the channel is broken.
406 */
407 status_t publishTouchModeEvent(uint32_t seq, int32_t eventId, bool isInTouchMode);
408
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +0000409 struct Finished {
410 uint32_t seq;
411 bool handled;
412 nsecs_t consumeTime;
413 };
414
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000415 struct Timeline {
416 int32_t inputEventId;
417 std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
418 };
419
420 typedef std::variant<Finished, Timeline> ConsumerResponse;
421 /* Receive a signal from the consumer in reply to the original dispatch signal.
422 * If a signal was received, returns a Finished or a Timeline object.
423 * The InputConsumer should return a Finished object for every InputMessage that it is sent
424 * to confirm that it has been processed and that the InputConsumer is responsive.
425 * If several InputMessages are sent to InputConsumer, it's possible to receive Finished
426 * events out of order for those messages.
Jeff Brown5912f952013-07-01 19:10:31 -0700427 *
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000428 * The Timeline object is returned whenever the receiving end has processed a graphical frame
429 * and is returning the timeline of the frame. Not all input events will cause a Timeline
430 * object to be returned, and there is not guarantee about when it will arrive.
431 *
432 * If an object of Finished is returned, the returned sequence number is never 0 unless the
433 * operation failed.
Jeff Brown5912f952013-07-01 19:10:31 -0700434 *
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +0000435 * Returned error codes:
436 * OK on success.
437 * WOULD_BLOCK if there is no signal present.
438 * DEAD_OBJECT if the channel's peer has been closed.
439 * Other errors probably indicate that the channel is broken.
Jeff Brown5912f952013-07-01 19:10:31 -0700440 */
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000441 android::base::Result<ConsumerResponse> receiveConsumerResponse();
Jeff Brown5912f952013-07-01 19:10:31 -0700442
443private:
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500444 std::shared_ptr<InputChannel> mChannel;
Jeff Brown5912f952013-07-01 19:10:31 -0700445};
446
447/*
448 * Consumes input events from an input channel.
449 */
450class InputConsumer {
451public:
452 /* Creates a consumer associated with an input channel. */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500453 explicit InputConsumer(const std::shared_ptr<InputChannel>& channel);
Jeff Brown5912f952013-07-01 19:10:31 -0700454
455 /* Destroys the consumer and releases its input channel. */
456 ~InputConsumer();
457
458 /* Gets the underlying input channel. */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500459 inline std::shared_ptr<InputChannel> getChannel() { return mChannel; }
Jeff Brown5912f952013-07-01 19:10:31 -0700460
461 /* Consumes an input event from the input channel and copies its contents into
462 * an InputEvent object created using the specified factory.
463 *
464 * Tries to combine a series of move events into larger batches whenever possible.
465 *
466 * If consumeBatches is false, then defers consuming pending batched events if it
467 * is possible for additional samples to be added to them later. Call hasPendingBatch()
468 * to determine whether a pending batch is available to be consumed.
469 *
470 * If consumeBatches is true, then events are still batched but they are consumed
471 * immediately as soon as the input channel is exhausted.
472 *
473 * The frameTime parameter specifies the time when the current display frame started
474 * rendering in the CLOCK_MONOTONIC time base, or -1 if unknown.
475 *
476 * The returned sequence number is never 0 unless the operation failed.
477 *
478 * Returns OK on success.
479 * Returns WOULD_BLOCK if there is no event present.
480 * Returns DEAD_OBJECT if the channel's peer has been closed.
481 * Returns NO_MEMORY if the event could not be created.
482 * Other errors probably indicate that the channel is broken.
483 */
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800484 status_t consume(InputEventFactoryInterface* factory, bool consumeBatches, nsecs_t frameTime,
485 uint32_t* outSeq, InputEvent** outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700486
487 /* Sends a finished signal to the publisher to inform it that the message
488 * with the specified sequence number has finished being process and whether
489 * the message was handled by the consumer.
490 *
491 * Returns OK on success.
492 * Returns BAD_VALUE if seq is 0.
493 * Other errors probably indicate that the channel is broken.
494 */
495 status_t sendFinishedSignal(uint32_t seq, bool handled);
496
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000497 status_t sendTimeline(int32_t inputEventId,
498 std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);
499
Jeff Brown5912f952013-07-01 19:10:31 -0700500 /* Returns true if there is a deferred event waiting.
501 *
502 * Should be called after calling consume() to determine whether the consumer
503 * has a deferred event to be processed. Deferred events are somewhat special in
504 * that they have already been removed from the input channel. If the input channel
505 * becomes empty, the client may need to do extra work to ensure that it processes
506 * the deferred event despite the fact that the input channel's file descriptor
507 * is not readable.
508 *
509 * One option is simply to call consume() in a loop until it returns WOULD_BLOCK.
510 * This guarantees that all deferred events will be processed.
511 *
512 * Alternately, the caller can call hasDeferredEvent() to determine whether there is
513 * a deferred event waiting and then ensure that its event loop wakes up at least
514 * one more time to consume the deferred event.
515 */
516 bool hasDeferredEvent() const;
517
518 /* Returns true if there is a pending batch.
519 *
520 * Should be called after calling consume() with consumeBatches == false to determine
521 * whether consume() should be called again later on with consumeBatches == true.
522 */
523 bool hasPendingBatch() const;
524
Arthur Hungc7812be2020-02-27 22:40:27 +0800525 /* Returns the source of first pending batch if exist.
526 *
527 * Should be called after calling consume() with consumeBatches == false to determine
528 * whether consume() should be called again later on with consumeBatches == true.
529 */
530 int32_t getPendingBatchSource() const;
531
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500532 std::string dump() const;
533
Jeff Brown5912f952013-07-01 19:10:31 -0700534private:
535 // True if touch resampling is enabled.
536 const bool mResampleTouch;
537
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500538 std::shared_ptr<InputChannel> mChannel;
Jeff Brown5912f952013-07-01 19:10:31 -0700539
540 // The current input message.
541 InputMessage mMsg;
542
543 // True if mMsg contains a valid input message that was deferred from the previous
544 // call to consume and that still needs to be handled.
545 bool mMsgDeferred;
546
547 // Batched motion events per device and source.
548 struct Batch {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500549 std::vector<InputMessage> samples;
Jeff Brown5912f952013-07-01 19:10:31 -0700550 };
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500551 std::vector<Batch> mBatches;
Jeff Brown5912f952013-07-01 19:10:31 -0700552
553 // Touch state per device and source, only for sources of class pointer.
554 struct History {
555 nsecs_t eventTime;
556 BitSet32 idBits;
557 int32_t idToIndex[MAX_POINTER_ID + 1];
558 PointerCoords pointers[MAX_POINTERS];
559
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100560 void initializeFrom(const InputMessage& msg) {
561 eventTime = msg.body.motion.eventTime;
Jeff Brown5912f952013-07-01 19:10:31 -0700562 idBits.clear();
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100563 for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
564 uint32_t id = msg.body.motion.pointers[i].properties.id;
Jeff Brown5912f952013-07-01 19:10:31 -0700565 idBits.markBit(id);
566 idToIndex[id] = i;
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100567 pointers[i].copyFrom(msg.body.motion.pointers[i].coords);
Jeff Brown5912f952013-07-01 19:10:31 -0700568 }
569 }
570
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800571 void initializeFrom(const History& other) {
572 eventTime = other.eventTime;
573 idBits = other.idBits; // temporary copy
574 for (size_t i = 0; i < other.idBits.count(); i++) {
575 uint32_t id = idBits.clearFirstMarkedBit();
576 int32_t index = other.idToIndex[id];
577 idToIndex[id] = index;
578 pointers[index].copyFrom(other.pointers[index]);
579 }
580 idBits = other.idBits; // final copy
581 }
582
Jeff Brown5912f952013-07-01 19:10:31 -0700583 const PointerCoords& getPointerById(uint32_t id) const {
584 return pointers[idToIndex[id]];
585 }
Siarhei Vishniakouc7dc3782017-08-24 20:36:28 -0700586
587 bool hasPointerId(uint32_t id) const {
588 return idBits.hasBit(id);
589 }
Jeff Brown5912f952013-07-01 19:10:31 -0700590 };
591 struct TouchState {
592 int32_t deviceId;
593 int32_t source;
594 size_t historyCurrent;
595 size_t historySize;
596 History history[2];
597 History lastResample;
598
599 void initialize(int32_t deviceId, int32_t source) {
600 this->deviceId = deviceId;
601 this->source = source;
602 historyCurrent = 0;
603 historySize = 0;
604 lastResample.eventTime = 0;
605 lastResample.idBits.clear();
606 }
607
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100608 void addHistory(const InputMessage& msg) {
Jeff Brown5912f952013-07-01 19:10:31 -0700609 historyCurrent ^= 1;
610 if (historySize < 2) {
611 historySize += 1;
612 }
613 history[historyCurrent].initializeFrom(msg);
614 }
615
616 const History* getHistory(size_t index) const {
617 return &history[(historyCurrent + index) & 1];
618 }
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100619
620 bool recentCoordinatesAreIdentical(uint32_t id) const {
621 // Return true if the two most recently received "raw" coordinates are identical
622 if (historySize < 2) {
623 return false;
624 }
Siarhei Vishniakouc7dc3782017-08-24 20:36:28 -0700625 if (!getHistory(0)->hasPointerId(id) || !getHistory(1)->hasPointerId(id)) {
626 return false;
627 }
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100628 float currentX = getHistory(0)->getPointerById(id).getX();
629 float currentY = getHistory(0)->getPointerById(id).getY();
630 float previousX = getHistory(1)->getPointerById(id).getX();
631 float previousY = getHistory(1)->getPointerById(id).getY();
632 if (currentX == previousX && currentY == previousY) {
633 return true;
634 }
635 return false;
636 }
Jeff Brown5912f952013-07-01 19:10:31 -0700637 };
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500638 std::vector<TouchState> mTouchStates;
Jeff Brown5912f952013-07-01 19:10:31 -0700639
640 // Chain of batched sequence numbers. When multiple input messages are combined into
641 // a batch, we append a record here that associates the last sequence number in the
642 // batch with the previous one. When the finished signal is sent, we traverse the
643 // chain to individually finish all input messages that were part of the batch.
644 struct SeqChain {
645 uint32_t seq; // sequence number of batched input message
646 uint32_t chain; // sequence number of previous batched input message
647 };
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500648 std::vector<SeqChain> mSeqChains;
Jeff Brown5912f952013-07-01 19:10:31 -0700649
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -1000650 // The time at which each event with the sequence number 'seq' was consumed.
651 // This data is provided in 'finishInputEvent' so that the receiving end can measure the latency
652 // This collection is populated when the event is received, and the entries are erased when the
653 // events are finished. It should not grow infinitely because if an event is not ack'd, ANR
654 // will be raised for that connection, and no further events will be posted to that channel.
655 std::unordered_map<uint32_t /*seq*/, nsecs_t /*consumeTime*/> mConsumeTimes;
656
Jeff Brown5912f952013-07-01 19:10:31 -0700657 status_t consumeBatch(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800658 nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700659 status_t consumeSamples(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800660 Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700661
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100662 void updateTouchState(InputMessage& msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700663 void resampleTouchState(nsecs_t frameTime, MotionEvent* event,
664 const InputMessage *next);
665
666 ssize_t findBatch(int32_t deviceId, int32_t source) const;
667 ssize_t findTouchState(int32_t deviceId, int32_t source) const;
668
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -1000669 nsecs_t getConsumeTime(uint32_t seq) const;
670 void popConsumeTime(uint32_t seq);
Jeff Brown5912f952013-07-01 19:10:31 -0700671 status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled);
672
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800673 static void rewriteMessage(TouchState& state, InputMessage& msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700674 static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg);
675 static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg);
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800676 static void initializeFocusEvent(FocusEvent* event, const InputMessage* msg);
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800677 static void initializeCaptureEvent(CaptureEvent* event, const InputMessage* msg);
arthurhung7632c332020-12-30 16:58:01 +0800678 static void initializeDragEvent(DragEvent* event, const InputMessage* msg);
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -0700679 static void initializeTouchModeEvent(TouchModeEvent* event, const InputMessage* msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700680 static void addSample(MotionEvent* event, const InputMessage* msg);
681 static bool canAddSample(const Batch& batch, const InputMessage* msg);
682 static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
683 static bool shouldResampleTool(int32_t toolType);
684
685 static bool isTouchResamplingEnabled();
686};
687
688} // namespace android
689
690#endif // _LIBINPUT_INPUT_TRANSPORT_H