xref: /aosp_15_r20/frameworks/native/include/input/InputConsumerNoResampling.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /**
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2024 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <functional>
20*38e8c45fSAndroid Build Coastguard Worker #include <map>
21*38e8c45fSAndroid Build Coastguard Worker #include <memory>
22*38e8c45fSAndroid Build Coastguard Worker #include <optional>
23*38e8c45fSAndroid Build Coastguard Worker 
24*38e8c45fSAndroid Build Coastguard Worker #include <input/Input.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <input/InputTransport.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <input/Resampler.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <utils/Looper.h>
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker namespace android {
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker /**
32*38e8c45fSAndroid Build Coastguard Worker  * An interface to receive batched input events. Even if you don't want batching, you still have to
33*38e8c45fSAndroid Build Coastguard Worker  * use this interface, and some of the events will be batched if your implementation is slow to
34*38e8c45fSAndroid Build Coastguard Worker  * handle the incoming input. The events received by these callbacks are never null.
35*38e8c45fSAndroid Build Coastguard Worker  */
36*38e8c45fSAndroid Build Coastguard Worker class InputConsumerCallbacks {
37*38e8c45fSAndroid Build Coastguard Worker public:
~InputConsumerCallbacks()38*38e8c45fSAndroid Build Coastguard Worker     virtual ~InputConsumerCallbacks(){};
39*38e8c45fSAndroid Build Coastguard Worker     virtual void onKeyEvent(std::unique_ptr<KeyEvent> event, uint32_t seq) = 0;
40*38e8c45fSAndroid Build Coastguard Worker     virtual void onMotionEvent(std::unique_ptr<MotionEvent> event, uint32_t seq) = 0;
41*38e8c45fSAndroid Build Coastguard Worker     /**
42*38e8c45fSAndroid Build Coastguard Worker      * When you receive this callback, you must (eventually) call "consumeBatchedInputEvents".
43*38e8c45fSAndroid Build Coastguard Worker      * If you don't want batching, then call "consumeBatchedInputEvents" immediately with
44*38e8c45fSAndroid Build Coastguard Worker      * std::nullopt requestedFrameTime to receive the pending motion event(s).
45*38e8c45fSAndroid Build Coastguard Worker      * @param pendingBatchSource the source of the pending batch.
46*38e8c45fSAndroid Build Coastguard Worker      */
47*38e8c45fSAndroid Build Coastguard Worker     virtual void onBatchedInputEventPending(int32_t pendingBatchSource) = 0;
48*38e8c45fSAndroid Build Coastguard Worker     virtual void onFocusEvent(std::unique_ptr<FocusEvent> event, uint32_t seq) = 0;
49*38e8c45fSAndroid Build Coastguard Worker     virtual void onCaptureEvent(std::unique_ptr<CaptureEvent> event, uint32_t seq) = 0;
50*38e8c45fSAndroid Build Coastguard Worker     virtual void onDragEvent(std::unique_ptr<DragEvent> event, uint32_t seq) = 0;
51*38e8c45fSAndroid Build Coastguard Worker     virtual void onTouchModeEvent(std::unique_ptr<TouchModeEvent> event, uint32_t seq) = 0;
52*38e8c45fSAndroid Build Coastguard Worker };
53*38e8c45fSAndroid Build Coastguard Worker 
54*38e8c45fSAndroid Build Coastguard Worker /**
55*38e8c45fSAndroid Build Coastguard Worker  * Consumes input events from an input channel.
56*38e8c45fSAndroid Build Coastguard Worker  *
57*38e8c45fSAndroid Build Coastguard Worker  * This is a re-implementation of InputConsumer. At the moment it only supports resampling for
58*38e8c45fSAndroid Build Coastguard Worker  * single pointer events. A lot of the higher-level logic has been folded into this class, to make
59*38e8c45fSAndroid Build Coastguard Worker  * it easier to use. In the legacy class, InputConsumer, the consumption logic was partially handled
60*38e8c45fSAndroid Build Coastguard Worker  * in the jni layer, as well as various actions like adding the fd to the Choreographer.
61*38e8c45fSAndroid Build Coastguard Worker  *
62*38e8c45fSAndroid Build Coastguard Worker  * TODO(b/297226446): use this instead of "InputConsumer":
63*38e8c45fSAndroid Build Coastguard Worker  * - Add resampling for multiple pointer events.
64*38e8c45fSAndroid Build Coastguard Worker  * - Allow various resampling strategies to be specified
65*38e8c45fSAndroid Build Coastguard Worker  * - Delete the old "InputConsumer" and use this class instead, renaming it to "InputConsumer".
66*38e8c45fSAndroid Build Coastguard Worker  * - Add tracing
67*38e8c45fSAndroid Build Coastguard Worker  * - Update all tests to use the new InputConsumer
68*38e8c45fSAndroid Build Coastguard Worker  *
69*38e8c45fSAndroid Build Coastguard Worker  * This class is not thread-safe. We are currently allowing the constructor to run on any thread,
70*38e8c45fSAndroid Build Coastguard Worker  * but all of the remaining APIs should be invoked on the looper thread only.
71*38e8c45fSAndroid Build Coastguard Worker  */
72*38e8c45fSAndroid Build Coastguard Worker class InputConsumerNoResampling final {
73*38e8c45fSAndroid Build Coastguard Worker public:
74*38e8c45fSAndroid Build Coastguard Worker     /**
75*38e8c45fSAndroid Build Coastguard Worker      * @param callbacks are used to interact with InputConsumerNoResampling. They're called whenever
76*38e8c45fSAndroid Build Coastguard Worker      * the event is ready to consume.
77*38e8c45fSAndroid Build Coastguard Worker      * @param looper needs to be sp and not shared_ptr because it inherits from
78*38e8c45fSAndroid Build Coastguard Worker      * RefBase
79*38e8c45fSAndroid Build Coastguard Worker      * @param resamplerCreator callable that returns the resampling strategy to be used. If null, no
80*38e8c45fSAndroid Build Coastguard Worker      * resampling will be performed. resamplerCreator must never return nullptr.
81*38e8c45fSAndroid Build Coastguard Worker      */
82*38e8c45fSAndroid Build Coastguard Worker     explicit InputConsumerNoResampling(
83*38e8c45fSAndroid Build Coastguard Worker             const std::shared_ptr<InputChannel>& channel, sp<Looper> looper,
84*38e8c45fSAndroid Build Coastguard Worker             InputConsumerCallbacks& callbacks,
85*38e8c45fSAndroid Build Coastguard Worker             std::function<std::unique_ptr<Resampler>()> resamplerCreator);
86*38e8c45fSAndroid Build Coastguard Worker 
87*38e8c45fSAndroid Build Coastguard Worker     ~InputConsumerNoResampling();
88*38e8c45fSAndroid Build Coastguard Worker 
89*38e8c45fSAndroid Build Coastguard Worker     /**
90*38e8c45fSAndroid Build Coastguard Worker      * Must be called exactly once for each event received through the callbacks.
91*38e8c45fSAndroid Build Coastguard Worker      */
92*38e8c45fSAndroid Build Coastguard Worker     void finishInputEvent(uint32_t seq, bool handled);
93*38e8c45fSAndroid Build Coastguard Worker     void reportTimeline(int32_t inputEventId, nsecs_t gpuCompletedTime, nsecs_t presentTime);
94*38e8c45fSAndroid Build Coastguard Worker     /**
95*38e8c45fSAndroid Build Coastguard Worker      * If you want to consume all events immediately (disable batching), then you still must call
96*38e8c45fSAndroid Build Coastguard Worker      * this. For requestedFrameTime, use a std::nullopt. It is not guaranteed that the consumption
97*38e8c45fSAndroid Build Coastguard Worker      * will occur at requestedFrameTime. The resampling strategy may modify it.
98*38e8c45fSAndroid Build Coastguard Worker      * @param requestedFrameTime the time up to which consume the events. When there's double (or
99*38e8c45fSAndroid Build Coastguard Worker      * triple) buffering, you may want to not consume all events currently available, because you
100*38e8c45fSAndroid Build Coastguard Worker      * could be still working on an older frame, but there could already have been events that
101*38e8c45fSAndroid Build Coastguard Worker      * arrived that are more recent.
102*38e8c45fSAndroid Build Coastguard Worker      * @return whether any events were actually consumed
103*38e8c45fSAndroid Build Coastguard Worker      */
104*38e8c45fSAndroid Build Coastguard Worker     bool consumeBatchedInputEvents(std::optional<nsecs_t> requestedFrameTime);
105*38e8c45fSAndroid Build Coastguard Worker 
106*38e8c45fSAndroid Build Coastguard Worker     /**
107*38e8c45fSAndroid Build Coastguard Worker      * Returns true when there is *likely* a pending batch or a pending event in the channel.
108*38e8c45fSAndroid Build Coastguard Worker      *
109*38e8c45fSAndroid Build Coastguard Worker      * This is only a performance hint and may return false negative results. Clients should not
110*38e8c45fSAndroid Build Coastguard Worker      * rely on availability of the message based on the return value.
111*38e8c45fSAndroid Build Coastguard Worker      */
112*38e8c45fSAndroid Build Coastguard Worker     bool probablyHasInput() const;
113*38e8c45fSAndroid Build Coastguard Worker 
getName()114*38e8c45fSAndroid Build Coastguard Worker     std::string getName() { return mChannel->getName(); }
115*38e8c45fSAndroid Build Coastguard Worker 
116*38e8c45fSAndroid Build Coastguard Worker     std::string dump() const;
117*38e8c45fSAndroid Build Coastguard Worker 
118*38e8c45fSAndroid Build Coastguard Worker private:
119*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<InputChannel> mChannel;
120*38e8c45fSAndroid Build Coastguard Worker     sp<Looper> mLooper;
121*38e8c45fSAndroid Build Coastguard Worker     InputConsumerCallbacks& mCallbacks;
122*38e8c45fSAndroid Build Coastguard Worker     const std::function<std::unique_ptr<Resampler>()> mResamplerCreator;
123*38e8c45fSAndroid Build Coastguard Worker 
124*38e8c45fSAndroid Build Coastguard Worker     /**
125*38e8c45fSAndroid Build Coastguard Worker      * A map to manage multidevice resampling. Each contained resampler is never null. This map is
126*38e8c45fSAndroid Build Coastguard Worker      * only modified by handleMessages.
127*38e8c45fSAndroid Build Coastguard Worker      */
128*38e8c45fSAndroid Build Coastguard Worker     std::map<DeviceId, std::unique_ptr<Resampler>> mResamplers;
129*38e8c45fSAndroid Build Coastguard Worker 
130*38e8c45fSAndroid Build Coastguard Worker     // Looper-related infrastructure
131*38e8c45fSAndroid Build Coastguard Worker     /**
132*38e8c45fSAndroid Build Coastguard Worker      * This class is needed to associate the function "handleReceiveCallback" with the provided
133*38e8c45fSAndroid Build Coastguard Worker      * looper. The callback sent to the looper is RefBase - based, so we can't just send a reference
134*38e8c45fSAndroid Build Coastguard Worker      * of this class directly to the looper.
135*38e8c45fSAndroid Build Coastguard Worker      */
136*38e8c45fSAndroid Build Coastguard Worker     class LooperEventCallback : public LooperCallback {
137*38e8c45fSAndroid Build Coastguard Worker     public:
LooperEventCallback(std::function<int (int events)> callback)138*38e8c45fSAndroid Build Coastguard Worker         LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
handleEvent(int,int events,void *)139*38e8c45fSAndroid Build Coastguard Worker         int handleEvent(int /*fd*/, int events, void* /*data*/) override {
140*38e8c45fSAndroid Build Coastguard Worker             return mCallback(events);
141*38e8c45fSAndroid Build Coastguard Worker         }
142*38e8c45fSAndroid Build Coastguard Worker 
143*38e8c45fSAndroid Build Coastguard Worker     private:
144*38e8c45fSAndroid Build Coastguard Worker         const std::function<int(int events)> mCallback;
145*38e8c45fSAndroid Build Coastguard Worker     };
146*38e8c45fSAndroid Build Coastguard Worker     sp<LooperEventCallback> mCallback;
147*38e8c45fSAndroid Build Coastguard Worker     /**
148*38e8c45fSAndroid Build Coastguard Worker      * The actual code that executes when the looper encounters available data on the InputChannel.
149*38e8c45fSAndroid Build Coastguard Worker      */
150*38e8c45fSAndroid Build Coastguard Worker     int handleReceiveCallback(int events);
151*38e8c45fSAndroid Build Coastguard Worker     int mFdEvents;
152*38e8c45fSAndroid Build Coastguard Worker     void setFdEvents(int events);
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker     void ensureCalledOnLooperThread(const char* func) const;
155*38e8c45fSAndroid Build Coastguard Worker 
156*38e8c45fSAndroid Build Coastguard Worker     // Event-reading infrastructure
157*38e8c45fSAndroid Build Coastguard Worker     /**
158*38e8c45fSAndroid Build Coastguard Worker      * A fifo queue of events to be sent to the InputChannel. We can't send all InputMessages to
159*38e8c45fSAndroid Build Coastguard Worker      * the channel immediately when they are produced, because it's possible that the InputChannel
160*38e8c45fSAndroid Build Coastguard Worker      * is blocked (if the channel buffer is full). When that happens, we don't want to drop the
161*38e8c45fSAndroid Build Coastguard Worker      * events. Therefore, events should only be erased from the queue after they've been
162*38e8c45fSAndroid Build Coastguard Worker      * successfully written to the InputChannel.
163*38e8c45fSAndroid Build Coastguard Worker      */
164*38e8c45fSAndroid Build Coastguard Worker     std::queue<InputMessage> mOutboundQueue;
165*38e8c45fSAndroid Build Coastguard Worker     /**
166*38e8c45fSAndroid Build Coastguard Worker      * Try to send all of the events in mOutboundQueue over the InputChannel. Not all events might
167*38e8c45fSAndroid Build Coastguard Worker      * actually get sent, because it's possible that the channel is blocked.
168*38e8c45fSAndroid Build Coastguard Worker      */
169*38e8c45fSAndroid Build Coastguard Worker     void processOutboundEvents();
170*38e8c45fSAndroid Build Coastguard Worker 
171*38e8c45fSAndroid Build Coastguard Worker     /**
172*38e8c45fSAndroid Build Coastguard Worker      * The time at which each event with the sequence number 'seq' was consumed.
173*38e8c45fSAndroid Build Coastguard Worker      * This data is provided in 'finishInputEvent' so that the receiving end can measure the latency
174*38e8c45fSAndroid Build Coastguard Worker      * This collection is populated when the event is received, and the entries are erased when the
175*38e8c45fSAndroid Build Coastguard Worker      * events are finished. It should not grow infinitely because if an event is not ack'd, ANR
176*38e8c45fSAndroid Build Coastguard Worker      * will be raised for that connection, and no further events will be posted to that channel.
177*38e8c45fSAndroid Build Coastguard Worker      */
178*38e8c45fSAndroid Build Coastguard Worker     std::unordered_map<uint32_t /*seq*/, nsecs_t /*consumeTime*/> mConsumeTimes;
179*38e8c45fSAndroid Build Coastguard Worker     /**
180*38e8c45fSAndroid Build Coastguard Worker      * Find and return the consumeTime associated with the provided sequence number. Crashes if
181*38e8c45fSAndroid Build Coastguard Worker      * the provided seq number is not found.
182*38e8c45fSAndroid Build Coastguard Worker      */
183*38e8c45fSAndroid Build Coastguard Worker     nsecs_t popConsumeTime(uint32_t seq);
184*38e8c45fSAndroid Build Coastguard Worker 
185*38e8c45fSAndroid Build Coastguard Worker     // Event reading and processing
186*38e8c45fSAndroid Build Coastguard Worker     /**
187*38e8c45fSAndroid Build Coastguard Worker      * Read all of the available events from the InputChannel
188*38e8c45fSAndroid Build Coastguard Worker      */
189*38e8c45fSAndroid Build Coastguard Worker     std::vector<InputMessage> readAllMessages();
190*38e8c45fSAndroid Build Coastguard Worker 
191*38e8c45fSAndroid Build Coastguard Worker     /**
192*38e8c45fSAndroid Build Coastguard Worker      * Send InputMessage to the corresponding InputConsumerCallbacks function.
193*38e8c45fSAndroid Build Coastguard Worker      * @param msg
194*38e8c45fSAndroid Build Coastguard Worker      */
195*38e8c45fSAndroid Build Coastguard Worker     void handleMessage(const InputMessage& msg) const;
196*38e8c45fSAndroid Build Coastguard Worker 
197*38e8c45fSAndroid Build Coastguard Worker     // Batching
198*38e8c45fSAndroid Build Coastguard Worker     /**
199*38e8c45fSAndroid Build Coastguard Worker      * Batch messages that can be batched. When an unbatchable message is encountered, send it
200*38e8c45fSAndroid Build Coastguard Worker      * to the InputConsumerCallbacks immediately. If there are batches remaining,
201*38e8c45fSAndroid Build Coastguard Worker      * notify InputConsumerCallbacks. If a resampleable ACTION_DOWN message is received, then a
202*38e8c45fSAndroid Build Coastguard Worker      * resampler is inserted for that deviceId in mResamplers. If a resampleable ACTION_UP or
203*38e8c45fSAndroid Build Coastguard Worker      * ACTION_CANCEL message is received then the resampler associated to that deviceId is erased
204*38e8c45fSAndroid Build Coastguard Worker      * from mResamplers.
205*38e8c45fSAndroid Build Coastguard Worker      */
206*38e8c45fSAndroid Build Coastguard Worker     void handleMessages(std::vector<InputMessage>&& messages);
207*38e8c45fSAndroid Build Coastguard Worker     /**
208*38e8c45fSAndroid Build Coastguard Worker      * Batched InputMessages, per deviceId.
209*38e8c45fSAndroid Build Coastguard Worker      * For each device, we are storing a queue of batched messages. These will all be collapsed into
210*38e8c45fSAndroid Build Coastguard Worker      * a single MotionEvent (up to a specific requestedFrameTime) when the consumer calls
211*38e8c45fSAndroid Build Coastguard Worker      * `consumeBatchedInputEvents`.
212*38e8c45fSAndroid Build Coastguard Worker      */
213*38e8c45fSAndroid Build Coastguard Worker     std::map<DeviceId, std::queue<InputMessage>> mBatches;
214*38e8c45fSAndroid Build Coastguard Worker 
215*38e8c45fSAndroid Build Coastguard Worker     /**
216*38e8c45fSAndroid Build Coastguard Worker      * Creates a MotionEvent by consuming samples from the provided queue. Consumes all messages
217*38e8c45fSAndroid Build Coastguard Worker      * with eventTime <= requestedFrameTime - resampleLatency, where `resampleLatency` is latency
218*38e8c45fSAndroid Build Coastguard Worker      * introduced by the resampler. Assumes that messages are queued in chronological order.
219*38e8c45fSAndroid Build Coastguard Worker      * @param requestedFrameTime The time up to which consume messages, as given by the inequality
220*38e8c45fSAndroid Build Coastguard Worker      * above. If std::nullopt, everything in messages will be consumed.
221*38e8c45fSAndroid Build Coastguard Worker      * @param messages the queue of messages to consume from.
222*38e8c45fSAndroid Build Coastguard Worker      */
223*38e8c45fSAndroid Build Coastguard Worker     std::pair<std::unique_ptr<MotionEvent>, std::optional<uint32_t>> createBatchedMotionEvent(
224*38e8c45fSAndroid Build Coastguard Worker             const std::optional<nsecs_t> requestedFrameTime, std::queue<InputMessage>& messages);
225*38e8c45fSAndroid Build Coastguard Worker 
226*38e8c45fSAndroid Build Coastguard Worker     /**
227*38e8c45fSAndroid Build Coastguard Worker      * Consumes the batched input events, optionally allowing the caller to specify a device id
228*38e8c45fSAndroid Build Coastguard Worker      * and/or requestedFrameTime threshold. It is not guaranteed that consumption will occur at
229*38e8c45fSAndroid Build Coastguard Worker      * requestedFrameTime.
230*38e8c45fSAndroid Build Coastguard Worker      * @param deviceId The device id from which to consume events. If std::nullopt, consumes events
231*38e8c45fSAndroid Build Coastguard Worker      * from any device id.
232*38e8c45fSAndroid Build Coastguard Worker      * @param requestedFrameTime The time up to which consume the events. If std::nullopt, consumes
233*38e8c45fSAndroid Build Coastguard Worker      * input events with any timestamp.
234*38e8c45fSAndroid Build Coastguard Worker      * @return Whether or not any events were consumed.
235*38e8c45fSAndroid Build Coastguard Worker      */
236*38e8c45fSAndroid Build Coastguard Worker     bool consumeBatchedInputEvents(std::optional<DeviceId> deviceId,
237*38e8c45fSAndroid Build Coastguard Worker                                    std::optional<nsecs_t> requestedFrameTime);
238*38e8c45fSAndroid Build Coastguard Worker     /**
239*38e8c45fSAndroid Build Coastguard Worker      * A map from a single sequence number to several sequence numbers. This is needed because of
240*38e8c45fSAndroid Build Coastguard Worker      * batching. When batching is enabled, a single MotionEvent will contain several samples. Each
241*38e8c45fSAndroid Build Coastguard Worker      * sample came from an individual InputMessage of Type::Motion, and therefore will have to be
242*38e8c45fSAndroid Build Coastguard Worker      * finished individually. Therefore, when the app calls "finish" on a (possibly batched)
243*38e8c45fSAndroid Build Coastguard Worker      * MotionEvent, we will need to check this map in case there are multiple sequence numbers
244*38e8c45fSAndroid Build Coastguard Worker      * associated with a single number that the app provided.
245*38e8c45fSAndroid Build Coastguard Worker      *
246*38e8c45fSAndroid Build Coastguard Worker      * For example:
247*38e8c45fSAndroid Build Coastguard Worker      * Suppose we received 4 InputMessage's of type Motion, with action MOVE:
248*38e8c45fSAndroid Build Coastguard Worker      * InputMessage(MOVE)   InputMessage(MOVE)   InputMessage(MOVE)   InputMessage(MOVE)
249*38e8c45fSAndroid Build Coastguard Worker      *    seq=10               seq=11               seq=12               seq=13
250*38e8c45fSAndroid Build Coastguard Worker      * The app consumed them all as a batch, which means that the app received a single MotionEvent
251*38e8c45fSAndroid Build Coastguard Worker      * with historySize=3 and seq = 10.
252*38e8c45fSAndroid Build Coastguard Worker      *
253*38e8c45fSAndroid Build Coastguard Worker      * This map will look like:
254*38e8c45fSAndroid Build Coastguard Worker      * {
255*38e8c45fSAndroid Build Coastguard Worker      *   10: [11, 12, 13],
256*38e8c45fSAndroid Build Coastguard Worker      * }
257*38e8c45fSAndroid Build Coastguard Worker      * So the sequence number 10 will have 3 other sequence numbers associated with it.
258*38e8c45fSAndroid Build Coastguard Worker      * When the app calls 'finish' for seq=10, we need to call 'finish' 4 times total, for sequence
259*38e8c45fSAndroid Build Coastguard Worker      * numbers 10, 11, 12, 13. The app is not aware of the sequence numbers of each sample inside
260*38e8c45fSAndroid Build Coastguard Worker      * the batched MotionEvent that it received.
261*38e8c45fSAndroid Build Coastguard Worker      */
262*38e8c45fSAndroid Build Coastguard Worker     std::map<uint32_t, std::vector<uint32_t>> mBatchedSequenceNumbers;
263*38e8c45fSAndroid Build Coastguard Worker };
264*38e8c45fSAndroid Build Coastguard Worker 
265*38e8c45fSAndroid Build Coastguard Worker } // namespace android
266