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