blob: eb8f820f085b3810e6af8ddc594dfa12cb7c7747 [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -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 _UI_INPUT_DISPATCHER_H
18#define _UI_INPUT_DISPATCHER_H
19
20#include <ui/Input.h>
Jeff Browne839a582010-04-22 18:58:52 -070021#include <ui/InputTransport.h>
22#include <utils/KeyedVector.h>
23#include <utils/Vector.h>
24#include <utils/threads.h>
25#include <utils/Timers.h>
26#include <utils/RefBase.h>
27#include <utils/String8.h>
28#include <utils/PollLoop.h>
29#include <utils/Pool.h>
30
31#include <stddef.h>
32#include <unistd.h>
33
34
35namespace android {
36
Jeff Brown54bc2812010-06-15 01:31:58 -070037/*
Jeff Brown51d45a72010-06-17 20:52:56 -070038 * Constants used to report the outcome of input event injection.
39 */
40enum {
41 /* (INTERNAL USE ONLY) Specifies that injection is pending and its outcome is unknown. */
42 INPUT_EVENT_INJECTION_PENDING = -1,
43
44 /* Injection succeeded. */
45 INPUT_EVENT_INJECTION_SUCCEEDED = 0,
46
47 /* Injection failed because the injector did not have permission to inject
48 * into the application with input focus. */
49 INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1,
50
51 /* Injection failed because there were no available input targets. */
52 INPUT_EVENT_INJECTION_FAILED = 2,
53
54 /* Injection failed due to a timeout. */
55 INPUT_EVENT_INJECTION_TIMED_OUT = 3
56};
57
58
59/*
Jeff Brown54bc2812010-06-15 01:31:58 -070060 * An input target specifies how an input event is to be dispatched to a particular window
61 * including the window's input channel, control flags, a timeout, and an X / Y offset to
62 * be added to input event coordinates to compensate for the absolute position of the
63 * window area.
64 */
65struct InputTarget {
66 enum {
67 /* This flag indicates that subsequent event delivery should be held until the
68 * current event is delivered to this target or a timeout occurs. */
69 FLAG_SYNC = 0x01,
70
71 /* This flag indicates that a MotionEvent with ACTION_DOWN falls outside of the area of
72 * this target and so should instead be delivered as an ACTION_OUTSIDE to this target. */
73 FLAG_OUTSIDE = 0x02,
74
75 /* This flag indicates that a KeyEvent or MotionEvent is being canceled.
76 * In the case of a key event, it should be delivered with KeyEvent.FLAG_CANCELED set.
77 * In the case of a motion event, it should be delivered as MotionEvent.ACTION_CANCEL. */
78 FLAG_CANCEL = 0x04
79 };
80
81 // The input channel to be targeted.
82 sp<InputChannel> inputChannel;
83
84 // Flags for the input target.
85 int32_t flags;
86
87 // The timeout for event delivery to this target in nanoseconds. Or -1 if none.
88 nsecs_t timeout;
89
90 // The x and y offset to add to a MotionEvent as it is delivered.
91 // (ignored for KeyEvents)
92 float xOffset, yOffset;
93};
94
Jeff Brown51d45a72010-06-17 20:52:56 -070095
Jeff Brown54bc2812010-06-15 01:31:58 -070096/*
97 * Input dispatcher policy interface.
98 *
99 * The input reader policy is used by the input reader to interact with the Window Manager
100 * and other system components.
101 *
102 * The actual implementation is partially supported by callbacks into the DVM
103 * via JNI. This interface is also mocked in the unit tests.
104 */
105class InputDispatcherPolicyInterface : public virtual RefBase {
106protected:
107 InputDispatcherPolicyInterface() { }
108 virtual ~InputDispatcherPolicyInterface() { }
109
110public:
111 /* Notifies the system that a configuration change has occurred. */
112 virtual void notifyConfigurationChanged(nsecs_t when) = 0;
113
114 /* Notifies the system that an input channel is unrecoverably broken. */
115 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) = 0;
116
Jeff Brown51d45a72010-06-17 20:52:56 -0700117 /* Notifies the system that an input channel is not responding.
118 * Returns true and a new timeout value if the dispatcher should keep waiting.
119 * Otherwise returns false. */
120 virtual bool notifyInputChannelANR(const sp<InputChannel>& inputChannel,
121 nsecs_t& outNewTimeout) = 0;
Jeff Brown54bc2812010-06-15 01:31:58 -0700122
123 /* Notifies the system that an input channel recovered from ANR. */
124 virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) = 0;
125
126 /* Gets the key repeat timeout or -1 if automatic key repeating is disabled. */
127 virtual nsecs_t getKeyRepeatTimeout() = 0;
128
Jeff Brown50de30a2010-06-22 01:27:15 -0700129 /* Waits for key event input targets to become available.
Jeff Brown51d45a72010-06-17 20:52:56 -0700130 * If the event is being injected, injectorPid and injectorUid should specify the
131 * process id and used id of the injecting application, otherwise they should both
132 * be -1.
133 * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
Jeff Brown50de30a2010-06-22 01:27:15 -0700134 virtual int32_t waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700135 int32_t injectorPid, int32_t injectorUid,
Jeff Brown54bc2812010-06-15 01:31:58 -0700136 Vector<InputTarget>& outTargets) = 0;
137
Jeff Brown50de30a2010-06-22 01:27:15 -0700138 /* Waits for motion event targets to become available.
Jeff Brown51d45a72010-06-17 20:52:56 -0700139 * If the event is being injected, injectorPid and injectorUid should specify the
140 * process id and used id of the injecting application, otherwise they should both
141 * be -1.
142 * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
Jeff Brown50de30a2010-06-22 01:27:15 -0700143 virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700144 int32_t injectorPid, int32_t injectorUid,
Jeff Brown54bc2812010-06-15 01:31:58 -0700145 Vector<InputTarget>& outTargets) = 0;
146};
147
148
Jeff Browne839a582010-04-22 18:58:52 -0700149/* Notifies the system about input events generated by the input reader.
150 * The dispatcher is expected to be mostly asynchronous. */
151class InputDispatcherInterface : public virtual RefBase {
152protected:
153 InputDispatcherInterface() { }
154 virtual ~InputDispatcherInterface() { }
155
156public:
157 /* Runs a single iteration of the dispatch loop.
158 * Nominally processes one queued event, a timeout, or a response from an input consumer.
159 *
160 * This method should only be called on the input dispatcher thread.
161 */
162 virtual void dispatchOnce() = 0;
163
164 /* Notifies the dispatcher about new events.
Jeff Browne839a582010-04-22 18:58:52 -0700165 *
166 * These methods should only be called on the input reader thread.
167 */
Jeff Brown54bc2812010-06-15 01:31:58 -0700168 virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
Jeff Browne839a582010-04-22 18:58:52 -0700169 virtual void notifyAppSwitchComing(nsecs_t eventTime) = 0;
170 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature,
171 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
172 int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
173 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature,
174 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
175 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
176 float xPrecision, float yPrecision, nsecs_t downTime) = 0;
177
Jeff Brown51d45a72010-06-17 20:52:56 -0700178 /* Injects an input event and optionally waits for sync.
179 * This method may block even if sync is false because it must wait for previous events
180 * to be dispatched before it can determine whether input event injection will be
181 * permitted based on the current input focus.
182 * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
183 *
184 * This method may be called on any thread (usually by the input manager).
185 */
186 virtual int32_t injectInputEvent(const InputEvent* event,
187 int32_t injectorPid, int32_t injectorUid, bool sync, int32_t timeoutMillis) = 0;
188
Jeff Brown50de30a2010-06-22 01:27:15 -0700189 /* Preempts input dispatch in progress by making pending synchronous
190 * dispatches asynchronous instead. This method is generally called during a focus
191 * transition from one application to the next so as to enable the new application
192 * to start receiving input as soon as possible without having to wait for the
193 * old application to finish up.
194 *
195 * This method may be called on any thread (usually by the input manager).
196 */
197 virtual void preemptInputDispatch() = 0;
198
Jeff Browne839a582010-04-22 18:58:52 -0700199 /* Registers or unregister input channels that may be used as targets for input events.
200 *
201 * These methods may be called on any thread (usually by the input manager).
202 */
203 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
204 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
205};
206
Jeff Brown54bc2812010-06-15 01:31:58 -0700207/* Dispatches events to input targets. Some functions of the input dispatcher, such as
208 * identifying input targets, are controlled by a separate policy object.
209 *
210 * IMPORTANT INVARIANT:
211 * Because the policy can potentially block or cause re-entrance into the input dispatcher,
212 * the input dispatcher never calls into the policy while holding its internal locks.
213 * The implementation is also carefully designed to recover from scenarios such as an
214 * input channel becoming unregistered while identifying input targets or processing timeouts.
215 *
216 * Methods marked 'Locked' must be called with the lock acquired.
217 *
218 * Methods marked 'LockedInterruptible' must be called with the lock acquired but
219 * may during the course of their execution release the lock, call into the policy, and
220 * then reacquire the lock. The caller is responsible for recovering gracefully.
221 *
222 * A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
223 */
Jeff Browne839a582010-04-22 18:58:52 -0700224class InputDispatcher : public InputDispatcherInterface {
225protected:
226 virtual ~InputDispatcher();
227
228public:
Jeff Brown54bc2812010-06-15 01:31:58 -0700229 explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
Jeff Browne839a582010-04-22 18:58:52 -0700230
231 virtual void dispatchOnce();
232
Jeff Brown54bc2812010-06-15 01:31:58 -0700233 virtual void notifyConfigurationChanged(nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700234 virtual void notifyAppSwitchComing(nsecs_t eventTime);
235 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature,
236 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
237 int32_t scanCode, int32_t metaState, nsecs_t downTime);
238 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature,
239 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
240 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
241 float xPrecision, float yPrecision, nsecs_t downTime);
242
Jeff Brown51d45a72010-06-17 20:52:56 -0700243 virtual int32_t injectInputEvent(const InputEvent* event,
244 int32_t injectorPid, int32_t injectorUid, bool sync, int32_t timeoutMillis);
245
Jeff Brown50de30a2010-06-22 01:27:15 -0700246 virtual void preemptInputDispatch();
247
Jeff Browne839a582010-04-22 18:58:52 -0700248 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
249 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
250
251private:
252 template <typename T>
253 struct Link {
254 T* next;
255 T* prev;
256 };
257
258 struct EventEntry : Link<EventEntry> {
259 enum {
260 TYPE_SENTINEL,
261 TYPE_CONFIGURATION_CHANGED,
262 TYPE_KEY,
263 TYPE_MOTION
264 };
265
266 int32_t refCount;
267 int32_t type;
268 nsecs_t eventTime;
Jeff Brown54bc2812010-06-15 01:31:58 -0700269
Jeff Brown51d45a72010-06-17 20:52:56 -0700270 int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
271 int32_t injectorPid; // -1 if not injected
272 int32_t injectorUid; // -1 if not injected
273
Jeff Brown54bc2812010-06-15 01:31:58 -0700274 bool dispatchInProgress; // initially false, set to true while dispatching
Jeff Brown51d45a72010-06-17 20:52:56 -0700275
276 inline bool isInjected() { return injectorPid >= 0; }
Jeff Browne839a582010-04-22 18:58:52 -0700277 };
278
279 struct ConfigurationChangedEntry : EventEntry {
Jeff Browne839a582010-04-22 18:58:52 -0700280 };
281
282 struct KeyEntry : EventEntry {
283 int32_t deviceId;
284 int32_t nature;
285 uint32_t policyFlags;
286 int32_t action;
287 int32_t flags;
288 int32_t keyCode;
289 int32_t scanCode;
290 int32_t metaState;
291 int32_t repeatCount;
292 nsecs_t downTime;
293 };
294
295 struct MotionSample {
296 MotionSample* next;
297
298 nsecs_t eventTime;
299 PointerCoords pointerCoords[MAX_POINTERS];
300 };
301
302 struct MotionEntry : EventEntry {
303 int32_t deviceId;
304 int32_t nature;
305 uint32_t policyFlags;
306 int32_t action;
307 int32_t metaState;
308 int32_t edgeFlags;
309 float xPrecision;
310 float yPrecision;
311 nsecs_t downTime;
312 uint32_t pointerCount;
313 int32_t pointerIds[MAX_POINTERS];
314
315 // Linked list of motion samples associated with this motion event.
316 MotionSample firstSample;
317 MotionSample* lastSample;
318 };
319
Jeff Brown54bc2812010-06-15 01:31:58 -0700320 // Tracks the progress of dispatching a particular event to a particular connection.
Jeff Browne839a582010-04-22 18:58:52 -0700321 struct DispatchEntry : Link<DispatchEntry> {
322 EventEntry* eventEntry; // the event to dispatch
323 int32_t targetFlags;
324 float xOffset;
325 float yOffset;
326 nsecs_t timeout;
327
328 // True if dispatch has started.
329 bool inProgress;
330
331 // For motion events:
332 // Pointer to the first motion sample to dispatch in this cycle.
333 // Usually NULL to indicate that the list of motion samples begins at
334 // MotionEntry::firstSample. Otherwise, some samples were dispatched in a previous
335 // cycle and this pointer indicates the location of the first remainining sample
336 // to dispatch during the current cycle.
337 MotionSample* headMotionSample;
338 // Pointer to a motion sample to dispatch in the next cycle if the dispatcher was
339 // unable to send all motion samples during this cycle. On the next cycle,
340 // headMotionSample will be initialized to tailMotionSample and tailMotionSample
341 // will be set to NULL.
342 MotionSample* tailMotionSample;
343 };
344
Jeff Brown54bc2812010-06-15 01:31:58 -0700345 // A command entry captures state and behavior for an action to be performed in the
346 // dispatch loop after the initial processing has taken place. It is essentially
347 // a kind of continuation used to postpone sensitive policy interactions to a point
348 // in the dispatch loop where it is safe to release the lock (generally after finishing
349 // the critical parts of the dispatch cycle).
350 //
351 // The special thing about commands is that they can voluntarily release and reacquire
352 // the dispatcher lock at will. Initially when the command starts running, the
353 // dispatcher lock is held. However, if the command needs to call into the policy to
354 // do some work, it can release the lock, do the work, then reacquire the lock again
355 // before returning.
356 //
357 // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
358 // never calls into the policy while holding its lock.
359 //
360 // Commands are implicitly 'LockedInterruptible'.
361 struct CommandEntry;
362 typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
363
Jeff Brown51d45a72010-06-17 20:52:56 -0700364 class Connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700365 struct CommandEntry : Link<CommandEntry> {
366 CommandEntry();
367 ~CommandEntry();
368
369 Command command;
370
371 // parameters for the command (usage varies by command)
Jeff Brown51d45a72010-06-17 20:52:56 -0700372 sp<Connection> connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700373 };
374
375 // Generic queue implementation.
Jeff Browne839a582010-04-22 18:58:52 -0700376 template <typename T>
377 struct Queue {
378 T head;
379 T tail;
380
381 inline Queue() {
382 head.prev = NULL;
383 head.next = & tail;
384 tail.prev = & head;
385 tail.next = NULL;
386 }
387
388 inline bool isEmpty() {
389 return head.next == & tail;
390 }
391
392 inline void enqueueAtTail(T* entry) {
393 T* last = tail.prev;
394 last->next = entry;
395 entry->prev = last;
396 entry->next = & tail;
397 tail.prev = entry;
398 }
399
400 inline void enqueueAtHead(T* entry) {
401 T* first = head.next;
402 head.next = entry;
403 entry->prev = & head;
404 entry->next = first;
405 first->prev = entry;
406 }
407
408 inline void dequeue(T* entry) {
409 entry->prev->next = entry->next;
410 entry->next->prev = entry->prev;
411 }
412
413 inline T* dequeueAtHead() {
414 T* first = head.next;
415 dequeue(first);
416 return first;
417 }
418 };
419
420 /* Allocates queue entries and performs reference counting as needed. */
421 class Allocator {
422 public:
423 Allocator();
424
Jeff Brown51d45a72010-06-17 20:52:56 -0700425 ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
426 KeyEntry* obtainKeyEntry(nsecs_t eventTime,
427 int32_t deviceId, int32_t nature, uint32_t policyFlags, int32_t action,
428 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
429 int32_t repeatCount, nsecs_t downTime);
430 MotionEntry* obtainMotionEntry(nsecs_t eventTime,
431 int32_t deviceId, int32_t nature, uint32_t policyFlags, int32_t action,
432 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
433 nsecs_t downTime, uint32_t pointerCount,
434 const int32_t* pointerIds, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700435 DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700436 CommandEntry* obtainCommandEntry(Command command);
Jeff Browne839a582010-04-22 18:58:52 -0700437
438 void releaseEventEntry(EventEntry* entry);
439 void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
440 void releaseKeyEntry(KeyEntry* entry);
441 void releaseMotionEntry(MotionEntry* entry);
442 void releaseDispatchEntry(DispatchEntry* entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700443 void releaseCommandEntry(CommandEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700444
445 void appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -0700446 nsecs_t eventTime, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700447
448 private:
449 Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
450 Pool<KeyEntry> mKeyEntryPool;
451 Pool<MotionEntry> mMotionEntryPool;
452 Pool<MotionSample> mMotionSamplePool;
453 Pool<DispatchEntry> mDispatchEntryPool;
Jeff Brown54bc2812010-06-15 01:31:58 -0700454 Pool<CommandEntry> mCommandEntryPool;
Jeff Brown51d45a72010-06-17 20:52:56 -0700455
456 void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700457 };
458
459 /* Manages the dispatch state associated with a single input channel. */
460 class Connection : public RefBase {
461 protected:
462 virtual ~Connection();
463
464 public:
465 enum Status {
466 // Everything is peachy.
467 STATUS_NORMAL,
468 // An unrecoverable communication error has occurred.
469 STATUS_BROKEN,
470 // The client is not responding.
471 STATUS_NOT_RESPONDING,
472 // The input channel has been unregistered.
473 STATUS_ZOMBIE
474 };
475
476 Status status;
477 sp<InputChannel> inputChannel;
478 InputPublisher inputPublisher;
479 Queue<DispatchEntry> outboundQueue;
480 nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
481
482 nsecs_t lastEventTime; // the time when the event was originally captured
483 nsecs_t lastDispatchTime; // the time when the last event was dispatched
484 nsecs_t lastANRTime; // the time when the last ANR was recorded
485
486 explicit Connection(const sp<InputChannel>& inputChannel);
487
Jeff Brown54bc2812010-06-15 01:31:58 -0700488 inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
489
490 const char* getStatusLabel() const;
Jeff Browne839a582010-04-22 18:58:52 -0700491
492 // Finds a DispatchEntry in the outbound queue associated with the specified event.
493 // Returns NULL if not found.
494 DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const;
495
496 // Determine whether this connection has a pending synchronous dispatch target.
497 // Since there can only ever be at most one such target at a time, if there is one,
498 // it must be at the tail because nothing else can be enqueued after it.
499 inline bool hasPendingSyncTarget() {
500 return ! outboundQueue.isEmpty()
501 && (outboundQueue.tail.prev->targetFlags & InputTarget::FLAG_SYNC);
502 }
503
504 // Gets the time since the current event was originally obtained from the input driver.
505 inline double getEventLatencyMillis(nsecs_t currentTime) {
506 return (currentTime - lastEventTime) / 1000000.0;
507 }
508
509 // Gets the time since the current event entered the outbound dispatch queue.
510 inline double getDispatchLatencyMillis(nsecs_t currentTime) {
511 return (currentTime - lastDispatchTime) / 1000000.0;
512 }
513
514 // Gets the time since the current event ANR was declared, if applicable.
515 inline double getANRLatencyMillis(nsecs_t currentTime) {
516 return (currentTime - lastANRTime) / 1000000.0;
517 }
518
519 status_t initialize();
Jeff Brown51d45a72010-06-17 20:52:56 -0700520
521 void setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout);
Jeff Browne839a582010-04-22 18:58:52 -0700522 };
523
Jeff Brown54bc2812010-06-15 01:31:58 -0700524 sp<InputDispatcherPolicyInterface> mPolicy;
Jeff Browne839a582010-04-22 18:58:52 -0700525
526 Mutex mLock;
527
Jeff Browne839a582010-04-22 18:58:52 -0700528 Allocator mAllocator;
Jeff Browne839a582010-04-22 18:58:52 -0700529 sp<PollLoop> mPollLoop;
530
Jeff Brown54bc2812010-06-15 01:31:58 -0700531 Queue<EventEntry> mInboundQueue;
532 Queue<CommandEntry> mCommandQueue;
533
Jeff Browne839a582010-04-22 18:58:52 -0700534 // All registered connections mapped by receive pipe file descriptor.
535 KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
536
537 // Active connections are connections that have a non-empty outbound queue.
Jeff Brown51d45a72010-06-17 20:52:56 -0700538 // We don't use a ref-counted pointer here because we explicitly abort connections
539 // during unregistration which causes the connection's outbound queue to be cleared
540 // and the connection itself to be deactivated.
Jeff Browne839a582010-04-22 18:58:52 -0700541 Vector<Connection*> mActiveConnections;
542
Jeff Brown51d45a72010-06-17 20:52:56 -0700543 // List of connections that have timed out. Only used by dispatchOnce()
544 // We don't use a ref-counted pointer here because it is not possible for a connection
545 // to be unregistered while processing timed out connections since we hold the lock for
546 // the duration.
547 Vector<Connection*> mTimedOutConnections;
548
Jeff Brown54bc2812010-06-15 01:31:58 -0700549 // Preallocated key and motion event objects used only to ask the input dispatcher policy
Jeff Browne839a582010-04-22 18:58:52 -0700550 // for the targets of an event that is to be dispatched.
551 KeyEvent mReusableKeyEvent;
552 MotionEvent mReusableMotionEvent;
553
554 // The input targets that were most recently identified for dispatch.
555 // If there is a synchronous event dispatch in progress, the current input targets will
556 // remain unchanged until the dispatch has completed or been aborted.
557 Vector<InputTarget> mCurrentInputTargets;
Jeff Brown54bc2812010-06-15 01:31:58 -0700558 bool mCurrentInputTargetsValid; // false while targets are being recomputed
Jeff Browne839a582010-04-22 18:58:52 -0700559
Jeff Brown51d45a72010-06-17 20:52:56 -0700560 // Event injection and synchronization.
561 Condition mInjectionResultAvailableCondition;
562 Condition mFullySynchronizedCondition;
563 bool isFullySynchronizedLocked();
564 EventEntry* createEntryFromInputEventLocked(const InputEvent* event);
565 void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
566
Jeff Browne839a582010-04-22 18:58:52 -0700567 // Key repeat tracking.
568 // XXX Move this up to the input reader instead.
569 struct KeyRepeatState {
570 KeyEntry* lastKeyEntry; // or null if no repeat
571 nsecs_t nextRepeatTime;
572 } mKeyRepeatState;
573
574 void resetKeyRepeatLocked();
575
Jeff Brown54bc2812010-06-15 01:31:58 -0700576 // Deferred command processing.
577 bool runCommandsLockedInterruptible();
578 CommandEntry* postCommandLocked(Command command);
579
Jeff Browne839a582010-04-22 18:58:52 -0700580 // Process events that have just been dequeued from the head of the input queue.
Jeff Brown54bc2812010-06-15 01:31:58 -0700581 void processConfigurationChangedLockedInterruptible(
582 nsecs_t currentTime, ConfigurationChangedEntry* entry);
583 void processKeyLockedInterruptible(
584 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout);
585 void processKeyRepeatLockedInterruptible(
586 nsecs_t currentTime, nsecs_t keyRepeatTimeout);
587 void processMotionLockedInterruptible(
588 nsecs_t currentTime, MotionEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700589
590 // Identify input targets for an event and dispatch to them.
Jeff Brown54bc2812010-06-15 01:31:58 -0700591 void identifyInputTargetsAndDispatchKeyLockedInterruptible(
592 nsecs_t currentTime, KeyEntry* entry);
593 void identifyInputTargetsAndDispatchMotionLockedInterruptible(
594 nsecs_t currentTime, MotionEntry* entry);
595 void dispatchEventToCurrentInputTargetsLocked(
596 nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
Jeff Browne839a582010-04-22 18:58:52 -0700597
598 // Manage the dispatch cycle for a single connection.
Jeff Brown51d45a72010-06-17 20:52:56 -0700599 // These methods are deliberately not Interruptible because doing all of the work
600 // with the mutex held makes it easier to ensure that connection invariants are maintained.
601 // If needed, the methods post commands to run later once the critical bits are done.
602 void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700603 EventEntry* eventEntry, const InputTarget* inputTarget,
604 bool resumeWithAppendedMotionSample);
Jeff Brown51d45a72010-06-17 20:52:56 -0700605 void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
606 void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
607 void timeoutDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
608 void resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
609 const sp<Connection>& connection, nsecs_t newTimeout);
610 void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700611 bool broken);
612 static bool handleReceiveCallback(int receiveFd, int events, void* data);
613
614 // Add or remove a connection to the mActiveConnections vector.
615 void activateConnectionLocked(Connection* connection);
616 void deactivateConnectionLocked(Connection* connection);
617
618 // Interesting events that we might like to log or tell the framework about.
Jeff Brown54bc2812010-06-15 01:31:58 -0700619 void onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700620 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700621 void onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700622 nsecs_t currentTime, const sp<Connection>& connection, bool recoveredFromANR);
Jeff Brown54bc2812010-06-15 01:31:58 -0700623 void onDispatchCycleANRLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700624 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700625 void onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700626 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700627
Jeff Brown51d45a72010-06-17 20:52:56 -0700628 // Outbound policy interactions.
Jeff Brown54bc2812010-06-15 01:31:58 -0700629 void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
630 void doNotifyInputChannelANRLockedInterruptible(CommandEntry* commandEntry);
631 void doNotifyInputChannelRecoveredFromANRLockedInterruptible(CommandEntry* commandEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700632};
633
634/* Enqueues and dispatches input events, endlessly. */
635class InputDispatcherThread : public Thread {
636public:
637 explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
638 ~InputDispatcherThread();
639
640private:
641 virtual bool threadLoop();
642
643 sp<InputDispatcherInterface> mDispatcher;
644};
645
646} // namespace android
647
648#endif // _UI_INPUT_DISPATCHER_PRIV_H