blob: 3e5674e4fbed0646e893376b4717bb3ac657ea55 [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,
Jeff Brown5912f952013-07-01 19:10:31 -070074 };
75
76 struct Header {
Siarhei Vishniakou52402772019-10-22 09:32:30 -070077 Type type; // 4 bytes
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -050078 uint32_t seq;
Jeff Brown5912f952013-07-01 19:10:31 -070079 } header;
80
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -060081 // For keys and motions, rely on the fact that std::array takes up exactly as much space
82 // as the underlying data. This is not guaranteed by C++, but it simplifies the conversions.
83 static_assert(sizeof(std::array<uint8_t, 32>) == 32);
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +000084
85 // For bool values, rely on the fact that they take up exactly one byte. This is not guaranteed
86 // by C++ and is implementation-dependent, but it simplifies the conversions.
87 static_assert(sizeof(bool) == 1);
88
89 // Body *must* be 8 byte aligned.
Jeff Brown5912f952013-07-01 19:10:31 -070090 union Body {
91 struct Key {
Garfield Tan1c7bc862020-01-28 13:24:04 -080092 int32_t eventId;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -050093 uint32_t empty1;
Fengwei Yin83e0e422014-05-24 05:32:09 +080094 nsecs_t eventTime __attribute__((aligned(8)));
Jeff Brown5912f952013-07-01 19:10:31 -070095 int32_t deviceId;
96 int32_t source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +010097 int32_t displayId;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -060098 std::array<uint8_t, 32> hmac;
Jeff Brown5912f952013-07-01 19:10:31 -070099 int32_t action;
100 int32_t flags;
101 int32_t keyCode;
102 int32_t scanCode;
103 int32_t metaState;
104 int32_t repeatCount;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800105 uint32_t empty2;
Fengwei Yin83e0e422014-05-24 05:32:09 +0800106 nsecs_t downTime __attribute__((aligned(8)));
Jeff Brown5912f952013-07-01 19:10:31 -0700107
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800108 inline size_t size() const { return sizeof(Key); }
Jeff Brown5912f952013-07-01 19:10:31 -0700109 } key;
110
111 struct Motion {
Garfield Tan1c7bc862020-01-28 13:24:04 -0800112 int32_t eventId;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500113 uint32_t empty1;
Fengwei Yin83e0e422014-05-24 05:32:09 +0800114 nsecs_t eventTime __attribute__((aligned(8)));
Jeff Brown5912f952013-07-01 19:10:31 -0700115 int32_t deviceId;
116 int32_t source;
Tarandeep Singh58641502017-07-31 10:51:54 -0700117 int32_t displayId;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600118 std::array<uint8_t, 32> hmac;
Jeff Brown5912f952013-07-01 19:10:31 -0700119 int32_t action;
Michael Wright7b159c92015-05-14 14:48:03 +0100120 int32_t actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700121 int32_t flags;
122 int32_t metaState;
123 int32_t buttonState;
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800124 MotionClassification classification; // base type: uint8_t
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800125 uint8_t empty2[3]; // 3 bytes to fill gap created by classification
Jeff Brown5912f952013-07-01 19:10:31 -0700126 int32_t edgeFlags;
Fengwei Yin83e0e422014-05-24 05:32:09 +0800127 nsecs_t downTime __attribute__((aligned(8)));
chaviw9eaa22c2020-07-01 16:21:27 -0700128 float dsdx;
129 float dtdx;
130 float dtdy;
131 float dsdy;
132 float tx;
133 float ty;
Jeff Brown5912f952013-07-01 19:10:31 -0700134 float xPrecision;
135 float yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700136 float xCursorPosition;
137 float yCursorPosition;
Narayan Kamathed5fd382014-05-02 17:53:33 +0100138 uint32_t pointerCount;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800139 uint32_t empty3;
Siarhei Vishniakou10fe6762019-11-25 11:44:11 -0800140 /**
141 * The "pointers" field must be the last field of the struct InputMessage.
142 * When we send the struct InputMessage across the socket, we are not
143 * writing the entire "pointers" array, but only the pointerCount portion
144 * of it as an optimization. Adding a field after "pointers" would break this.
145 */
Michael Wrightb03f1032015-05-14 16:29:13 +0100146 struct Pointer {
Jeff Brown5912f952013-07-01 19:10:31 -0700147 PointerProperties properties;
148 PointerCoords coords;
Siarhei Vishniakou10fe6762019-11-25 11:44:11 -0800149 } pointers[MAX_POINTERS] __attribute__((aligned(8)));
Jeff Brown5912f952013-07-01 19:10:31 -0700150
151 int32_t getActionId() const {
152 uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
153 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
154 return pointers[index].properties.id;
155 }
156
157 inline size_t size() const {
158 return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS
159 + sizeof(Pointer) * pointerCount;
160 }
161 } motion;
162
163 struct Finished {
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +0000164 bool handled;
165 uint8_t empty[7];
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -1000166 nsecs_t consumeTime; // The time when the event was consumed by the receiving end
Jeff Brown5912f952013-07-01 19:10:31 -0700167
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800168 inline size_t size() const { return sizeof(Finished); }
Jeff Brown5912f952013-07-01 19:10:31 -0700169 } finished;
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800170
171 struct Focus {
Garfield Tan1c7bc862020-01-28 13:24:04 -0800172 int32_t eventId;
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +0000173 // The following 3 fields take up 4 bytes total
174 bool hasFocus;
175 bool inTouchMode;
176 uint8_t empty[2];
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800177
178 inline size_t size() const { return sizeof(Focus); }
179 } focus;
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800180
181 struct Capture {
182 int32_t eventId;
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +0000183 bool pointerCaptureEnabled;
184 uint8_t empty[3];
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800185
186 inline size_t size() const { return sizeof(Capture); }
187 } capture;
arthurhung7632c332020-12-30 16:58:01 +0800188
189 struct Drag {
190 int32_t eventId;
191 float x;
192 float y;
193 bool isExiting;
194 uint8_t empty[3];
195
196 inline size_t size() const { return sizeof(Drag); }
197 } drag;
Fengwei Yin83e0e422014-05-24 05:32:09 +0800198 } __attribute__((aligned(8))) body;
Jeff Brown5912f952013-07-01 19:10:31 -0700199
200 bool isValid(size_t actualSize) const;
201 size_t size() const;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800202 void getSanitizedCopy(InputMessage* msg) const;
Jeff Brown5912f952013-07-01 19:10:31 -0700203};
204
205/*
206 * An input channel consists of a local unix domain socket used to send and receive
207 * input messages across processes. Each channel has a descriptive name for debugging purposes.
208 *
209 * Each endpoint has its own InputChannel object that specifies its file descriptor.
210 *
211 * The input channel is closed when all references to it are released.
212 */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500213class InputChannel : public Parcelable {
Chris Ye0783e992020-06-02 21:34:49 -0700214public:
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500215 static std::unique_ptr<InputChannel> create(const std::string& name,
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500216 android::base::unique_fd fd, sp<IBinder> token);
217 InputChannel() = default;
218 InputChannel(const InputChannel& other)
219 : mName(other.mName), mFd(::dup(other.mFd)), mToken(other.mToken){};
220 InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token);
Jeff Brown5912f952013-07-01 19:10:31 -0700221 virtual ~InputChannel();
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700222 /**
223 * Create a pair of input channels.
224 * The two returned input channels are equivalent, and are labeled as "server" and "client"
225 * for convenience. The two input channels share the same token.
Jeff Brown5912f952013-07-01 19:10:31 -0700226 *
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700227 * Return OK on success.
Jeff Brown5912f952013-07-01 19:10:31 -0700228 */
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800229 static status_t openInputChannelPair(const std::string& name,
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500230 std::unique_ptr<InputChannel>& outServerChannel,
231 std::unique_ptr<InputChannel>& outClientChannel);
Jeff Brown5912f952013-07-01 19:10:31 -0700232
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500233 inline std::string getName() const { return mName; }
234 inline const android::base::unique_fd& getFd() const { return mFd; }
235 inline sp<IBinder> getToken() const { return mToken; }
Jeff Brown5912f952013-07-01 19:10:31 -0700236
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700237 /* Send a message to the other endpoint.
Jeff Brown5912f952013-07-01 19:10:31 -0700238 *
239 * If the channel is full then the message is guaranteed not to have been sent at all.
240 * Try again after the consumer has sent a finished signal indicating that it has
241 * consumed some of the pending messages from the channel.
242 *
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700243 * Return OK on success.
244 * Return WOULD_BLOCK if the channel is full.
245 * Return DEAD_OBJECT if the channel's peer has been closed.
Jeff Brown5912f952013-07-01 19:10:31 -0700246 * Other errors probably indicate that the channel is broken.
247 */
248 status_t sendMessage(const InputMessage* msg);
249
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700250 /* Receive a message sent by the other endpoint.
Jeff Brown5912f952013-07-01 19:10:31 -0700251 *
252 * If there is no message present, try again after poll() indicates that the fd
253 * is readable.
254 *
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700255 * Return OK on success.
256 * Return WOULD_BLOCK if there is no message present.
257 * Return DEAD_OBJECT if the channel's peer has been closed.
Jeff Brown5912f952013-07-01 19:10:31 -0700258 * Other errors probably indicate that the channel is broken.
259 */
260 status_t receiveMessage(InputMessage* msg);
261
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700262 /* Return a new object that has a duplicate of this channel's fd. */
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500263 std::unique_ptr<InputChannel> dup() const;
Jeff Brown5912f952013-07-01 19:10:31 -0700264
Garfield Tan15601662020-09-22 15:32:38 -0700265 void copyTo(InputChannel& outChannel) const;
266
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500267 status_t readFromParcel(const android::Parcel* parcel) override;
268 status_t writeToParcel(android::Parcel* parcel) const override;
Robert Carr3720ed02018-08-08 16:08:27 -0700269
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700270 /**
271 * The connection token is used to identify the input connection, i.e.
272 * the pair of input channels that were created simultaneously. Input channels
273 * are always created in pairs, and the token can be used to find the server-side
274 * input channel from the client-side input channel, and vice versa.
275 *
276 * Do not use connection token to check equality of a specific input channel object
277 * to another, because two different (client and server) input channels will share the
278 * same connection token.
279 *
280 * Return the token that identifies this connection.
281 */
282 sp<IBinder> getConnectionToken() const;
Robert Carr803535b2018-08-02 16:38:15 -0700283
Chris Ye0783e992020-06-02 21:34:49 -0700284 bool operator==(const InputChannel& inputChannel) const {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500285 struct stat lhs, rhs;
286 if (fstat(mFd.get(), &lhs) != 0) {
Chris Ye0783e992020-06-02 21:34:49 -0700287 return false;
288 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500289 if (fstat(inputChannel.getFd(), &rhs) != 0) {
Chris Ye0783e992020-06-02 21:34:49 -0700290 return false;
291 }
292 // If file descriptors are pointing to same inode they are duplicated fds.
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500293 return inputChannel.getName() == getName() && inputChannel.getConnectionToken() == mToken &&
294 lhs.st_ino == rhs.st_ino;
Chris Ye0783e992020-06-02 21:34:49 -0700295 }
296
Jeff Brown5912f952013-07-01 19:10:31 -0700297private:
Garfield Tan15601662020-09-22 15:32:38 -0700298 base::unique_fd dupFd() const;
299
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500300 std::string mName;
301 android::base::unique_fd mFd;
302
303 sp<IBinder> mToken;
Jeff Brown5912f952013-07-01 19:10:31 -0700304};
305
306/*
307 * Publishes input events to an input channel.
308 */
309class InputPublisher {
310public:
311 /* Creates a publisher associated with an input channel. */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500312 explicit InputPublisher(const std::shared_ptr<InputChannel>& channel);
Jeff Brown5912f952013-07-01 19:10:31 -0700313
314 /* Destroys the publisher and releases its input channel. */
315 ~InputPublisher();
316
317 /* Gets the underlying input channel. */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500318 inline std::shared_ptr<InputChannel> getChannel() { return mChannel; }
Jeff Brown5912f952013-07-01 19:10:31 -0700319
320 /* Publishes a key event to the input channel.
321 *
322 * Returns OK on success.
323 * Returns WOULD_BLOCK if the channel is full.
324 * Returns DEAD_OBJECT if the channel's peer has been closed.
325 * Returns BAD_VALUE if seq is 0.
326 * Other errors probably indicate that the channel is broken.
327 */
Garfield Tan1c7bc862020-01-28 13:24:04 -0800328 status_t publishKeyEvent(uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source,
329 int32_t displayId, std::array<uint8_t, 32> hmac, int32_t action,
330 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600331 int32_t repeatCount, nsecs_t downTime, nsecs_t eventTime);
Jeff Brown5912f952013-07-01 19:10:31 -0700332
333 /* Publishes a motion event to the input channel.
334 *
335 * Returns OK on success.
336 * Returns WOULD_BLOCK if the channel is full.
337 * Returns DEAD_OBJECT if the channel's peer has been closed.
338 * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.
339 * Other errors probably indicate that the channel is broken.
340 */
Garfield Tan1c7bc862020-01-28 13:24:04 -0800341 status_t publishMotionEvent(uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source,
342 int32_t displayId, std::array<uint8_t, 32> hmac, int32_t action,
343 int32_t actionButton, int32_t flags, int32_t edgeFlags,
344 int32_t metaState, int32_t buttonState,
chaviw9eaa22c2020-07-01 16:21:27 -0700345 MotionClassification classification, const ui::Transform& transform,
346 float xPrecision, float yPrecision, float xCursorPosition,
347 float yCursorPosition, nsecs_t downTime, nsecs_t eventTime,
348 uint32_t pointerCount, const PointerProperties* pointerProperties,
Garfield Tan00f511d2019-06-12 16:55:40 -0700349 const PointerCoords* pointerCoords);
Jeff Brown5912f952013-07-01 19:10:31 -0700350
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800351 /* Publishes a focus event to the input channel.
352 *
353 * Returns OK on success.
354 * Returns WOULD_BLOCK if the channel is full.
355 * Returns DEAD_OBJECT if the channel's peer has been closed.
356 * Other errors probably indicate that the channel is broken.
357 */
Garfield Tan1c7bc862020-01-28 13:24:04 -0800358 status_t publishFocusEvent(uint32_t seq, int32_t eventId, bool hasFocus, bool inTouchMode);
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800359
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800360 /* Publishes a capture event to the input channel.
361 *
362 * Returns OK on success.
363 * Returns WOULD_BLOCK if the channel is full.
364 * Returns DEAD_OBJECT if the channel's peer has been closed.
365 * Other errors probably indicate that the channel is broken.
366 */
367 status_t publishCaptureEvent(uint32_t seq, int32_t eventId, bool pointerCaptureEnabled);
368
arthurhung7632c332020-12-30 16:58:01 +0800369 /* Publishes a drag event to the input channel.
370 *
371 * Returns OK on success.
372 * Returns WOULD_BLOCK if the channel is full.
373 * Returns DEAD_OBJECT if the channel's peer has been closed.
374 * Other errors probably indicate that the channel is broken.
375 */
376 status_t publishDragEvent(uint32_t seq, int32_t eventId, float x, float y, bool isExiting);
377
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +0000378 struct Finished {
379 uint32_t seq;
380 bool handled;
381 nsecs_t consumeTime;
382 };
383
Jeff Brown5912f952013-07-01 19:10:31 -0700384 /* Receives the finished signal from the consumer in reply to the original dispatch signal.
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +0000385 * If a signal was received, returns a Finished object.
Jeff Brown5912f952013-07-01 19:10:31 -0700386 *
387 * The returned sequence number is never 0 unless the operation failed.
388 *
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +0000389 * Returned error codes:
390 * OK on success.
391 * WOULD_BLOCK if there is no signal present.
392 * DEAD_OBJECT if the channel's peer has been closed.
393 * Other errors probably indicate that the channel is broken.
Jeff Brown5912f952013-07-01 19:10:31 -0700394 */
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +0000395 android::base::Result<Finished> receiveFinishedSignal();
Jeff Brown5912f952013-07-01 19:10:31 -0700396
397private:
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500398 std::shared_ptr<InputChannel> mChannel;
Jeff Brown5912f952013-07-01 19:10:31 -0700399};
400
401/*
402 * Consumes input events from an input channel.
403 */
404class InputConsumer {
405public:
406 /* Creates a consumer associated with an input channel. */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500407 explicit InputConsumer(const std::shared_ptr<InputChannel>& channel);
Jeff Brown5912f952013-07-01 19:10:31 -0700408
409 /* Destroys the consumer and releases its input channel. */
410 ~InputConsumer();
411
412 /* Gets the underlying input channel. */
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500413 inline std::shared_ptr<InputChannel> getChannel() { return mChannel; }
Jeff Brown5912f952013-07-01 19:10:31 -0700414
415 /* Consumes an input event from the input channel and copies its contents into
416 * an InputEvent object created using the specified factory.
417 *
418 * Tries to combine a series of move events into larger batches whenever possible.
419 *
420 * If consumeBatches is false, then defers consuming pending batched events if it
421 * is possible for additional samples to be added to them later. Call hasPendingBatch()
422 * to determine whether a pending batch is available to be consumed.
423 *
424 * If consumeBatches is true, then events are still batched but they are consumed
425 * immediately as soon as the input channel is exhausted.
426 *
427 * The frameTime parameter specifies the time when the current display frame started
428 * rendering in the CLOCK_MONOTONIC time base, or -1 if unknown.
429 *
430 * The returned sequence number is never 0 unless the operation failed.
431 *
432 * Returns OK on success.
433 * Returns WOULD_BLOCK if there is no event present.
434 * Returns DEAD_OBJECT if the channel's peer has been closed.
435 * Returns NO_MEMORY if the event could not be created.
436 * Other errors probably indicate that the channel is broken.
437 */
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800438 status_t consume(InputEventFactoryInterface* factory, bool consumeBatches, nsecs_t frameTime,
439 uint32_t* outSeq, InputEvent** outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700440
441 /* Sends a finished signal to the publisher to inform it that the message
442 * with the specified sequence number has finished being process and whether
443 * the message was handled by the consumer.
444 *
445 * Returns OK on success.
446 * Returns BAD_VALUE if seq is 0.
447 * Other errors probably indicate that the channel is broken.
448 */
449 status_t sendFinishedSignal(uint32_t seq, bool handled);
450
451 /* Returns true if there is a deferred event waiting.
452 *
453 * Should be called after calling consume() to determine whether the consumer
454 * has a deferred event to be processed. Deferred events are somewhat special in
455 * that they have already been removed from the input channel. If the input channel
456 * becomes empty, the client may need to do extra work to ensure that it processes
457 * the deferred event despite the fact that the input channel's file descriptor
458 * is not readable.
459 *
460 * One option is simply to call consume() in a loop until it returns WOULD_BLOCK.
461 * This guarantees that all deferred events will be processed.
462 *
463 * Alternately, the caller can call hasDeferredEvent() to determine whether there is
464 * a deferred event waiting and then ensure that its event loop wakes up at least
465 * one more time to consume the deferred event.
466 */
467 bool hasDeferredEvent() const;
468
469 /* Returns true if there is a pending batch.
470 *
471 * Should be called after calling consume() with consumeBatches == false to determine
472 * whether consume() should be called again later on with consumeBatches == true.
473 */
474 bool hasPendingBatch() const;
475
Arthur Hungc7812be2020-02-27 22:40:27 +0800476 /* Returns the source of first pending batch if exist.
477 *
478 * Should be called after calling consume() with consumeBatches == false to determine
479 * whether consume() should be called again later on with consumeBatches == true.
480 */
481 int32_t getPendingBatchSource() const;
482
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500483 std::string dump() const;
484
Jeff Brown5912f952013-07-01 19:10:31 -0700485private:
486 // True if touch resampling is enabled.
487 const bool mResampleTouch;
488
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500489 std::shared_ptr<InputChannel> mChannel;
Jeff Brown5912f952013-07-01 19:10:31 -0700490
491 // The current input message.
492 InputMessage mMsg;
493
494 // True if mMsg contains a valid input message that was deferred from the previous
495 // call to consume and that still needs to be handled.
496 bool mMsgDeferred;
497
498 // Batched motion events per device and source.
499 struct Batch {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500500 std::vector<InputMessage> samples;
Jeff Brown5912f952013-07-01 19:10:31 -0700501 };
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500502 std::vector<Batch> mBatches;
Jeff Brown5912f952013-07-01 19:10:31 -0700503
504 // Touch state per device and source, only for sources of class pointer.
505 struct History {
506 nsecs_t eventTime;
507 BitSet32 idBits;
508 int32_t idToIndex[MAX_POINTER_ID + 1];
509 PointerCoords pointers[MAX_POINTERS];
510
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100511 void initializeFrom(const InputMessage& msg) {
512 eventTime = msg.body.motion.eventTime;
Jeff Brown5912f952013-07-01 19:10:31 -0700513 idBits.clear();
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100514 for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
515 uint32_t id = msg.body.motion.pointers[i].properties.id;
Jeff Brown5912f952013-07-01 19:10:31 -0700516 idBits.markBit(id);
517 idToIndex[id] = i;
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100518 pointers[i].copyFrom(msg.body.motion.pointers[i].coords);
Jeff Brown5912f952013-07-01 19:10:31 -0700519 }
520 }
521
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800522 void initializeFrom(const History& other) {
523 eventTime = other.eventTime;
524 idBits = other.idBits; // temporary copy
525 for (size_t i = 0; i < other.idBits.count(); i++) {
526 uint32_t id = idBits.clearFirstMarkedBit();
527 int32_t index = other.idToIndex[id];
528 idToIndex[id] = index;
529 pointers[index].copyFrom(other.pointers[index]);
530 }
531 idBits = other.idBits; // final copy
532 }
533
Jeff Brown5912f952013-07-01 19:10:31 -0700534 const PointerCoords& getPointerById(uint32_t id) const {
535 return pointers[idToIndex[id]];
536 }
Siarhei Vishniakouc7dc3782017-08-24 20:36:28 -0700537
538 bool hasPointerId(uint32_t id) const {
539 return idBits.hasBit(id);
540 }
Jeff Brown5912f952013-07-01 19:10:31 -0700541 };
542 struct TouchState {
543 int32_t deviceId;
544 int32_t source;
545 size_t historyCurrent;
546 size_t historySize;
547 History history[2];
548 History lastResample;
549
550 void initialize(int32_t deviceId, int32_t source) {
551 this->deviceId = deviceId;
552 this->source = source;
553 historyCurrent = 0;
554 historySize = 0;
555 lastResample.eventTime = 0;
556 lastResample.idBits.clear();
557 }
558
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100559 void addHistory(const InputMessage& msg) {
Jeff Brown5912f952013-07-01 19:10:31 -0700560 historyCurrent ^= 1;
561 if (historySize < 2) {
562 historySize += 1;
563 }
564 history[historyCurrent].initializeFrom(msg);
565 }
566
567 const History* getHistory(size_t index) const {
568 return &history[(historyCurrent + index) & 1];
569 }
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100570
571 bool recentCoordinatesAreIdentical(uint32_t id) const {
572 // Return true if the two most recently received "raw" coordinates are identical
573 if (historySize < 2) {
574 return false;
575 }
Siarhei Vishniakouc7dc3782017-08-24 20:36:28 -0700576 if (!getHistory(0)->hasPointerId(id) || !getHistory(1)->hasPointerId(id)) {
577 return false;
578 }
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100579 float currentX = getHistory(0)->getPointerById(id).getX();
580 float currentY = getHistory(0)->getPointerById(id).getY();
581 float previousX = getHistory(1)->getPointerById(id).getX();
582 float previousY = getHistory(1)->getPointerById(id).getY();
583 if (currentX == previousX && currentY == previousY) {
584 return true;
585 }
586 return false;
587 }
Jeff Brown5912f952013-07-01 19:10:31 -0700588 };
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500589 std::vector<TouchState> mTouchStates;
Jeff Brown5912f952013-07-01 19:10:31 -0700590
591 // Chain of batched sequence numbers. When multiple input messages are combined into
592 // a batch, we append a record here that associates the last sequence number in the
593 // batch with the previous one. When the finished signal is sent, we traverse the
594 // chain to individually finish all input messages that were part of the batch.
595 struct SeqChain {
596 uint32_t seq; // sequence number of batched input message
597 uint32_t chain; // sequence number of previous batched input message
598 };
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500599 std::vector<SeqChain> mSeqChains;
Jeff Brown5912f952013-07-01 19:10:31 -0700600
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -1000601 // The time at which each event with the sequence number 'seq' was consumed.
602 // This data is provided in 'finishInputEvent' so that the receiving end can measure the latency
603 // This collection is populated when the event is received, and the entries are erased when the
604 // events are finished. It should not grow infinitely because if an event is not ack'd, ANR
605 // will be raised for that connection, and no further events will be posted to that channel.
606 std::unordered_map<uint32_t /*seq*/, nsecs_t /*consumeTime*/> mConsumeTimes;
607
Jeff Brown5912f952013-07-01 19:10:31 -0700608 status_t consumeBatch(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800609 nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700610 status_t consumeSamples(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800611 Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700612
Siarhei Vishniakou086a02a2017-06-12 15:01:41 +0100613 void updateTouchState(InputMessage& msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700614 void resampleTouchState(nsecs_t frameTime, MotionEvent* event,
615 const InputMessage *next);
616
617 ssize_t findBatch(int32_t deviceId, int32_t source) const;
618 ssize_t findTouchState(int32_t deviceId, int32_t source) const;
619
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -1000620 nsecs_t getConsumeTime(uint32_t seq) const;
621 void popConsumeTime(uint32_t seq);
Jeff Brown5912f952013-07-01 19:10:31 -0700622 status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled);
623
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800624 static void rewriteMessage(TouchState& state, InputMessage& msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700625 static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg);
626 static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg);
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800627 static void initializeFocusEvent(FocusEvent* event, const InputMessage* msg);
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800628 static void initializeCaptureEvent(CaptureEvent* event, const InputMessage* msg);
arthurhung7632c332020-12-30 16:58:01 +0800629 static void initializeDragEvent(DragEvent* event, const InputMessage* msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700630 static void addSample(MotionEvent* event, const InputMessage* msg);
631 static bool canAddSample(const Batch& batch, const InputMessage* msg);
632 static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
633 static bool shouldResampleTool(int32_t toolType);
634
635 static bool isTouchResamplingEnabled();
636};
637
638} // namespace android
639
640#endif // _LIBINPUT_INPUT_TRANSPORT_H