blob: 358a19158ee9a0e5c2518f4d613425fdd871afda [file] [log] [blame]
Siarhei Vishniakou2b920272024-02-27 19:49:51 -08001/**
2 * Copyright 2024 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#pragma once
18
Paul Ramirezb41d38e2024-07-16 17:44:20 +000019#include <input/InputTransport.h>
Paul Ramireze2bb1872024-08-12 20:21:13 +000020#include <input/LooperInterface.h>
Paul Ramirezbe9c5442024-07-10 00:12:41 +000021#include <input/Resampler.h>
Siarhei Vishniakou2b920272024-02-27 19:49:51 -080022#include <utils/Looper.h>
Siarhei Vishniakou2b920272024-02-27 19:49:51 -080023
24namespace android {
25
26/**
27 * An interface to receive batched input events. Even if you don't want batching, you still have to
28 * use this interface, and some of the events will be batched if your implementation is slow to
Paul Ramirez79655f22024-07-01 21:55:48 +000029 * handle the incoming input. The events received by these callbacks are never null.
Siarhei Vishniakou2b920272024-02-27 19:49:51 -080030 */
31class InputConsumerCallbacks {
32public:
33 virtual ~InputConsumerCallbacks(){};
Siarhei Vishniakou3891ec92024-03-15 13:29:57 -070034 virtual void onKeyEvent(std::unique_ptr<KeyEvent> event, uint32_t seq) = 0;
35 virtual void onMotionEvent(std::unique_ptr<MotionEvent> event, uint32_t seq) = 0;
Siarhei Vishniakou2b920272024-02-27 19:49:51 -080036 /**
37 * When you receive this callback, you must (eventually) call "consumeBatchedInputEvents".
38 * If you don't want batching, then call "consumeBatchedInputEvents" immediately with
39 * std::nullopt frameTime to receive the pending motion event(s).
40 * @param pendingBatchSource the source of the pending batch.
41 */
42 virtual void onBatchedInputEventPending(int32_t pendingBatchSource) = 0;
Siarhei Vishniakou3891ec92024-03-15 13:29:57 -070043 virtual void onFocusEvent(std::unique_ptr<FocusEvent> event, uint32_t seq) = 0;
44 virtual void onCaptureEvent(std::unique_ptr<CaptureEvent> event, uint32_t seq) = 0;
45 virtual void onDragEvent(std::unique_ptr<DragEvent> event, uint32_t seq) = 0;
46 virtual void onTouchModeEvent(std::unique_ptr<TouchModeEvent> event, uint32_t seq) = 0;
Siarhei Vishniakou2b920272024-02-27 19:49:51 -080047};
48
49/**
50 * Consumes input events from an input channel.
51 *
Paul Ramirezbe9c5442024-07-10 00:12:41 +000052 * This is a re-implementation of InputConsumer. At the moment it only supports resampling for
53 * single pointer events. A lot of the higher-level logic has been folded into this class, to make
54 * it easier to use. In the legacy class, InputConsumer, the consumption logic was partially handled
55 * in the jni layer, as well as various actions like adding the fd to the Choreographer.
Siarhei Vishniakou2b920272024-02-27 19:49:51 -080056 *
57 * TODO(b/297226446): use this instead of "InputConsumer":
Paul Ramirezbe9c5442024-07-10 00:12:41 +000058 * - Add resampling for multiple pointer events.
Siarhei Vishniakou2b920272024-02-27 19:49:51 -080059 * - Allow various resampling strategies to be specified
60 * - Delete the old "InputConsumer" and use this class instead, renaming it to "InputConsumer".
61 * - Add tracing
62 * - Update all tests to use the new InputConsumer
63 *
64 * This class is not thread-safe. We are currently allowing the constructor to run on any thread,
65 * but all of the remaining APIs should be invoked on the looper thread only.
66 */
67class InputConsumerNoResampling final {
68public:
Paul Ramirezbe9c5442024-07-10 00:12:41 +000069 /**
Paul Ramireze2bb1872024-08-12 20:21:13 +000070 * This constructor is exclusively for test code. Any real use of InputConsumerNoResampling must
71 * use the constructor that takes an sp<Looper> parameter instead of
72 * std::shared_ptr<LooperInterface>.
73 */
74 explicit InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel,
75 std::shared_ptr<LooperInterface> looper,
76 InputConsumerCallbacks& callbacks,
77 std::unique_ptr<Resampler> resampler);
78
79 /**
Paul Ramirezbe9c5442024-07-10 00:12:41 +000080 * @param callbacks are used to interact with InputConsumerNoResampling. They're called whenever
81 * the event is ready to consume.
82 * @param looper needs to be sp and not shared_ptr because it inherits from
83 * RefBase
84 * @param resampler the resampling strategy to use. If null, no resampling will be
85 * performed.
86 */
Siarhei Vishniakou2b920272024-02-27 19:49:51 -080087 explicit InputConsumerNoResampling(const std::shared_ptr<InputChannel>& channel,
Paul Ramirezbe9c5442024-07-10 00:12:41 +000088 sp<Looper> looper, InputConsumerCallbacks& callbacks,
89 std::unique_ptr<Resampler> resampler);
90
Siarhei Vishniakou2b920272024-02-27 19:49:51 -080091 ~InputConsumerNoResampling();
92
93 /**
94 * Must be called exactly once for each event received through the callbacks.
95 */
96 void finishInputEvent(uint32_t seq, bool handled);
97 void reportTimeline(int32_t inputEventId, nsecs_t gpuCompletedTime, nsecs_t presentTime);
98 /**
99 * If you want to consume all events immediately (disable batching), the you still must call
100 * this. For frameTime, use a std::nullopt.
101 * @param frameTime the time up to which consume the events. When there's double (or triple)
102 * buffering, you may want to not consume all events currently available, because you could be
103 * still working on an older frame, but there could already have been events that arrived that
104 * are more recent.
105 * @return whether any events were actually consumed
106 */
107 bool consumeBatchedInputEvents(std::optional<nsecs_t> frameTime);
108 /**
109 * Returns true when there is *likely* a pending batch or a pending event in the channel.
110 *
111 * This is only a performance hint and may return false negative results. Clients should not
112 * rely on availability of the message based on the return value.
113 */
114 bool probablyHasInput() const;
115
116 std::string getName() { return mChannel->getName(); }
117
118 std::string dump() const;
119
120private:
121 std::shared_ptr<InputChannel> mChannel;
Paul Ramireze2bb1872024-08-12 20:21:13 +0000122 std::shared_ptr<LooperInterface> mLooper;
Siarhei Vishniakou2b920272024-02-27 19:49:51 -0800123 InputConsumerCallbacks& mCallbacks;
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000124 std::unique_ptr<Resampler> mResampler;
Siarhei Vishniakou2b920272024-02-27 19:49:51 -0800125
126 // Looper-related infrastructure
127 /**
128 * This class is needed to associate the function "handleReceiveCallback" with the provided
129 * looper. The callback sent to the looper is RefBase - based, so we can't just send a reference
130 * of this class directly to the looper.
131 */
132 class LooperEventCallback : public LooperCallback {
133 public:
134 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
135 int handleEvent(int /*fd*/, int events, void* /*data*/) override {
136 return mCallback(events);
137 }
138
139 private:
140 std::function<int(int events)> mCallback;
141 };
142 sp<LooperEventCallback> mCallback;
143 /**
144 * The actual code that executes when the looper encounters available data on the InputChannel.
145 */
146 int handleReceiveCallback(int events);
147 int mFdEvents;
148 void setFdEvents(int events);
149
150 void ensureCalledOnLooperThread(const char* func) const;
151
152 // Event-reading infrastructure
153 /**
154 * A fifo queue of events to be sent to the InputChannel. We can't send all InputMessages to
155 * the channel immediately when they are produced, because it's possible that the InputChannel
156 * is blocked (if the channel buffer is full). When that happens, we don't want to drop the
157 * events. Therefore, events should only be erased from the queue after they've been
158 * successfully written to the InputChannel.
159 */
160 std::queue<InputMessage> mOutboundQueue;
161 /**
162 * Try to send all of the events in mOutboundQueue over the InputChannel. Not all events might
163 * actually get sent, because it's possible that the channel is blocked.
164 */
165 void processOutboundEvents();
166
167 /**
168 * The time at which each event with the sequence number 'seq' was consumed.
169 * This data is provided in 'finishInputEvent' so that the receiving end can measure the latency
170 * This collection is populated when the event is received, and the entries are erased when the
171 * events are finished. It should not grow infinitely because if an event is not ack'd, ANR
172 * will be raised for that connection, and no further events will be posted to that channel.
173 */
174 std::unordered_map<uint32_t /*seq*/, nsecs_t /*consumeTime*/> mConsumeTimes;
175 /**
176 * Find and return the consumeTime associated with the provided sequence number. Crashes if
177 * the provided seq number is not found.
178 */
179 nsecs_t popConsumeTime(uint32_t seq);
180
181 // Event reading and processing
182 /**
183 * Read all of the available events from the InputChannel
184 */
185 std::vector<InputMessage> readAllMessages();
186
187 /**
188 * Send InputMessage to the corresponding InputConsumerCallbacks function.
189 * @param msg
190 */
191 void handleMessage(const InputMessage& msg) const;
192
193 // Batching
194 /**
195 * Batch messages that can be batched. When an unbatchable message is encountered, send it
196 * to the InputConsumerCallbacks immediately. If there are batches remaining,
197 * notify InputConsumerCallbacks.
198 */
199 void handleMessages(std::vector<InputMessage>&& messages);
200 /**
201 * Batched InputMessages, per deviceId.
202 * For each device, we are storing a queue of batched messages. These will all be collapsed into
203 * a single MotionEvent (up to a specific frameTime) when the consumer calls
204 * `consumeBatchedInputEvents`.
205 */
206 std::map<DeviceId, std::queue<InputMessage>> mBatches;
207 /**
Paul Ramirezb41d38e2024-07-16 17:44:20 +0000208 * Creates a MotionEvent by consuming samples from the provided queue. If one message has
209 * eventTime > frameTime, all subsequent messages in the queue will be skipped. It is assumed
210 * that messages are queued in chronological order. In other words, only events that occurred
211 * prior to the requested frameTime will be consumed.
212 * @param frameTime the time up to which to consume events
213 * @param messages the queue of messages to consume from
214 */
215 std::pair<std::unique_ptr<MotionEvent>, std::optional<uint32_t>> createBatchedMotionEvent(
216 const nsecs_t frameTime, std::queue<InputMessage>& messages);
217 /**
Siarhei Vishniakou2b920272024-02-27 19:49:51 -0800218 * A map from a single sequence number to several sequence numbers. This is needed because of
219 * batching. When batching is enabled, a single MotionEvent will contain several samples. Each
220 * sample came from an individual InputMessage of Type::Motion, and therefore will have to be
221 * finished individually. Therefore, when the app calls "finish" on a (possibly batched)
222 * MotionEvent, we will need to check this map in case there are multiple sequence numbers
223 * associated with a single number that the app provided.
224 *
225 * For example:
226 * Suppose we received 4 InputMessage's of type Motion, with action MOVE:
227 * InputMessage(MOVE) InputMessage(MOVE) InputMessage(MOVE) InputMessage(MOVE)
228 * seq=10 seq=11 seq=12 seq=13
229 * The app consumed them all as a batch, which means that the app received a single MotionEvent
230 * with historySize=3 and seq = 10.
231 *
232 * This map will look like:
233 * {
234 * 10: [11, 12, 13],
235 * }
236 * So the sequence number 10 will have 3 other sequence numbers associated with it.
237 * When the app calls 'finish' for seq=10, we need to call 'finish' 4 times total, for sequence
238 * numbers 10, 11, 12, 13. The app is not aware of the sequence numbers of each sample inside
239 * the batched MotionEvent that it received.
240 */
241 std::map<uint32_t, std::vector<uint32_t>> mBatchedSequenceNumbers;
242};
243
244} // namespace android