blob: 511ad20cfbed2902884d598499cc671b44fc071e [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 Brown51d45a72010-06-17 20:52:56 -0700129 /* Gets the input targets for a key event.
130 * 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. */
134 virtual int32_t getKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
135 int32_t injectorPid, int32_t injectorUid,
Jeff Brown54bc2812010-06-15 01:31:58 -0700136 Vector<InputTarget>& outTargets) = 0;
137
Jeff Brown51d45a72010-06-17 20:52:56 -0700138 /* Gets the input targets for a motion event.
139 * 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. */
143 virtual int32_t getMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
144 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 Browne839a582010-04-22 18:58:52 -0700189 /* Registers or unregister input channels that may be used as targets for input events.
190 *
191 * These methods may be called on any thread (usually by the input manager).
192 */
193 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
194 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
195};
196
Jeff Brown54bc2812010-06-15 01:31:58 -0700197/* Dispatches events to input targets. Some functions of the input dispatcher, such as
198 * identifying input targets, are controlled by a separate policy object.
199 *
200 * IMPORTANT INVARIANT:
201 * Because the policy can potentially block or cause re-entrance into the input dispatcher,
202 * the input dispatcher never calls into the policy while holding its internal locks.
203 * The implementation is also carefully designed to recover from scenarios such as an
204 * input channel becoming unregistered while identifying input targets or processing timeouts.
205 *
206 * Methods marked 'Locked' must be called with the lock acquired.
207 *
208 * Methods marked 'LockedInterruptible' must be called with the lock acquired but
209 * may during the course of their execution release the lock, call into the policy, and
210 * then reacquire the lock. The caller is responsible for recovering gracefully.
211 *
212 * A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
213 */
Jeff Browne839a582010-04-22 18:58:52 -0700214class InputDispatcher : public InputDispatcherInterface {
215protected:
216 virtual ~InputDispatcher();
217
218public:
Jeff Brown54bc2812010-06-15 01:31:58 -0700219 explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
Jeff Browne839a582010-04-22 18:58:52 -0700220
221 virtual void dispatchOnce();
222
Jeff Brown54bc2812010-06-15 01:31:58 -0700223 virtual void notifyConfigurationChanged(nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700224 virtual void notifyAppSwitchComing(nsecs_t eventTime);
225 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature,
226 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
227 int32_t scanCode, int32_t metaState, nsecs_t downTime);
228 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature,
229 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
230 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
231 float xPrecision, float yPrecision, nsecs_t downTime);
232
Jeff Brown51d45a72010-06-17 20:52:56 -0700233 virtual int32_t injectInputEvent(const InputEvent* event,
234 int32_t injectorPid, int32_t injectorUid, bool sync, int32_t timeoutMillis);
235
Jeff Browne839a582010-04-22 18:58:52 -0700236 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
237 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
238
239private:
240 template <typename T>
241 struct Link {
242 T* next;
243 T* prev;
244 };
245
246 struct EventEntry : Link<EventEntry> {
247 enum {
248 TYPE_SENTINEL,
249 TYPE_CONFIGURATION_CHANGED,
250 TYPE_KEY,
251 TYPE_MOTION
252 };
253
254 int32_t refCount;
255 int32_t type;
256 nsecs_t eventTime;
Jeff Brown54bc2812010-06-15 01:31:58 -0700257
Jeff Brown51d45a72010-06-17 20:52:56 -0700258 int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
259 int32_t injectorPid; // -1 if not injected
260 int32_t injectorUid; // -1 if not injected
261
Jeff Brown54bc2812010-06-15 01:31:58 -0700262 bool dispatchInProgress; // initially false, set to true while dispatching
Jeff Brown51d45a72010-06-17 20:52:56 -0700263
264 inline bool isInjected() { return injectorPid >= 0; }
Jeff Browne839a582010-04-22 18:58:52 -0700265 };
266
267 struct ConfigurationChangedEntry : EventEntry {
Jeff Browne839a582010-04-22 18:58:52 -0700268 };
269
270 struct KeyEntry : EventEntry {
271 int32_t deviceId;
272 int32_t nature;
273 uint32_t policyFlags;
274 int32_t action;
275 int32_t flags;
276 int32_t keyCode;
277 int32_t scanCode;
278 int32_t metaState;
279 int32_t repeatCount;
280 nsecs_t downTime;
281 };
282
283 struct MotionSample {
284 MotionSample* next;
285
286 nsecs_t eventTime;
287 PointerCoords pointerCoords[MAX_POINTERS];
288 };
289
290 struct MotionEntry : EventEntry {
291 int32_t deviceId;
292 int32_t nature;
293 uint32_t policyFlags;
294 int32_t action;
295 int32_t metaState;
296 int32_t edgeFlags;
297 float xPrecision;
298 float yPrecision;
299 nsecs_t downTime;
300 uint32_t pointerCount;
301 int32_t pointerIds[MAX_POINTERS];
302
303 // Linked list of motion samples associated with this motion event.
304 MotionSample firstSample;
305 MotionSample* lastSample;
306 };
307
Jeff Brown54bc2812010-06-15 01:31:58 -0700308 // Tracks the progress of dispatching a particular event to a particular connection.
Jeff Browne839a582010-04-22 18:58:52 -0700309 struct DispatchEntry : Link<DispatchEntry> {
310 EventEntry* eventEntry; // the event to dispatch
311 int32_t targetFlags;
312 float xOffset;
313 float yOffset;
314 nsecs_t timeout;
315
316 // True if dispatch has started.
317 bool inProgress;
318
319 // For motion events:
320 // Pointer to the first motion sample to dispatch in this cycle.
321 // Usually NULL to indicate that the list of motion samples begins at
322 // MotionEntry::firstSample. Otherwise, some samples were dispatched in a previous
323 // cycle and this pointer indicates the location of the first remainining sample
324 // to dispatch during the current cycle.
325 MotionSample* headMotionSample;
326 // Pointer to a motion sample to dispatch in the next cycle if the dispatcher was
327 // unable to send all motion samples during this cycle. On the next cycle,
328 // headMotionSample will be initialized to tailMotionSample and tailMotionSample
329 // will be set to NULL.
330 MotionSample* tailMotionSample;
331 };
332
Jeff Brown54bc2812010-06-15 01:31:58 -0700333 // A command entry captures state and behavior for an action to be performed in the
334 // dispatch loop after the initial processing has taken place. It is essentially
335 // a kind of continuation used to postpone sensitive policy interactions to a point
336 // in the dispatch loop where it is safe to release the lock (generally after finishing
337 // the critical parts of the dispatch cycle).
338 //
339 // The special thing about commands is that they can voluntarily release and reacquire
340 // the dispatcher lock at will. Initially when the command starts running, the
341 // dispatcher lock is held. However, if the command needs to call into the policy to
342 // do some work, it can release the lock, do the work, then reacquire the lock again
343 // before returning.
344 //
345 // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
346 // never calls into the policy while holding its lock.
347 //
348 // Commands are implicitly 'LockedInterruptible'.
349 struct CommandEntry;
350 typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
351
Jeff Brown51d45a72010-06-17 20:52:56 -0700352 class Connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700353 struct CommandEntry : Link<CommandEntry> {
354 CommandEntry();
355 ~CommandEntry();
356
357 Command command;
358
359 // parameters for the command (usage varies by command)
Jeff Brown51d45a72010-06-17 20:52:56 -0700360 sp<Connection> connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700361 };
362
363 // Generic queue implementation.
Jeff Browne839a582010-04-22 18:58:52 -0700364 template <typename T>
365 struct Queue {
366 T head;
367 T tail;
368
369 inline Queue() {
370 head.prev = NULL;
371 head.next = & tail;
372 tail.prev = & head;
373 tail.next = NULL;
374 }
375
376 inline bool isEmpty() {
377 return head.next == & tail;
378 }
379
380 inline void enqueueAtTail(T* entry) {
381 T* last = tail.prev;
382 last->next = entry;
383 entry->prev = last;
384 entry->next = & tail;
385 tail.prev = entry;
386 }
387
388 inline void enqueueAtHead(T* entry) {
389 T* first = head.next;
390 head.next = entry;
391 entry->prev = & head;
392 entry->next = first;
393 first->prev = entry;
394 }
395
396 inline void dequeue(T* entry) {
397 entry->prev->next = entry->next;
398 entry->next->prev = entry->prev;
399 }
400
401 inline T* dequeueAtHead() {
402 T* first = head.next;
403 dequeue(first);
404 return first;
405 }
406 };
407
408 /* Allocates queue entries and performs reference counting as needed. */
409 class Allocator {
410 public:
411 Allocator();
412
Jeff Brown51d45a72010-06-17 20:52:56 -0700413 ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
414 KeyEntry* obtainKeyEntry(nsecs_t eventTime,
415 int32_t deviceId, int32_t nature, uint32_t policyFlags, int32_t action,
416 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
417 int32_t repeatCount, nsecs_t downTime);
418 MotionEntry* obtainMotionEntry(nsecs_t eventTime,
419 int32_t deviceId, int32_t nature, uint32_t policyFlags, int32_t action,
420 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
421 nsecs_t downTime, uint32_t pointerCount,
422 const int32_t* pointerIds, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700423 DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700424 CommandEntry* obtainCommandEntry(Command command);
Jeff Browne839a582010-04-22 18:58:52 -0700425
426 void releaseEventEntry(EventEntry* entry);
427 void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
428 void releaseKeyEntry(KeyEntry* entry);
429 void releaseMotionEntry(MotionEntry* entry);
430 void releaseDispatchEntry(DispatchEntry* entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700431 void releaseCommandEntry(CommandEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700432
433 void appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -0700434 nsecs_t eventTime, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700435
436 private:
437 Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
438 Pool<KeyEntry> mKeyEntryPool;
439 Pool<MotionEntry> mMotionEntryPool;
440 Pool<MotionSample> mMotionSamplePool;
441 Pool<DispatchEntry> mDispatchEntryPool;
Jeff Brown54bc2812010-06-15 01:31:58 -0700442 Pool<CommandEntry> mCommandEntryPool;
Jeff Brown51d45a72010-06-17 20:52:56 -0700443
444 void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700445 };
446
447 /* Manages the dispatch state associated with a single input channel. */
448 class Connection : public RefBase {
449 protected:
450 virtual ~Connection();
451
452 public:
453 enum Status {
454 // Everything is peachy.
455 STATUS_NORMAL,
456 // An unrecoverable communication error has occurred.
457 STATUS_BROKEN,
458 // The client is not responding.
459 STATUS_NOT_RESPONDING,
460 // The input channel has been unregistered.
461 STATUS_ZOMBIE
462 };
463
464 Status status;
465 sp<InputChannel> inputChannel;
466 InputPublisher inputPublisher;
467 Queue<DispatchEntry> outboundQueue;
468 nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
469
470 nsecs_t lastEventTime; // the time when the event was originally captured
471 nsecs_t lastDispatchTime; // the time when the last event was dispatched
472 nsecs_t lastANRTime; // the time when the last ANR was recorded
473
474 explicit Connection(const sp<InputChannel>& inputChannel);
475
Jeff Brown54bc2812010-06-15 01:31:58 -0700476 inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
477
478 const char* getStatusLabel() const;
Jeff Browne839a582010-04-22 18:58:52 -0700479
480 // Finds a DispatchEntry in the outbound queue associated with the specified event.
481 // Returns NULL if not found.
482 DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const;
483
484 // Determine whether this connection has a pending synchronous dispatch target.
485 // Since there can only ever be at most one such target at a time, if there is one,
486 // it must be at the tail because nothing else can be enqueued after it.
487 inline bool hasPendingSyncTarget() {
488 return ! outboundQueue.isEmpty()
489 && (outboundQueue.tail.prev->targetFlags & InputTarget::FLAG_SYNC);
490 }
491
492 // Gets the time since the current event was originally obtained from the input driver.
493 inline double getEventLatencyMillis(nsecs_t currentTime) {
494 return (currentTime - lastEventTime) / 1000000.0;
495 }
496
497 // Gets the time since the current event entered the outbound dispatch queue.
498 inline double getDispatchLatencyMillis(nsecs_t currentTime) {
499 return (currentTime - lastDispatchTime) / 1000000.0;
500 }
501
502 // Gets the time since the current event ANR was declared, if applicable.
503 inline double getANRLatencyMillis(nsecs_t currentTime) {
504 return (currentTime - lastANRTime) / 1000000.0;
505 }
506
507 status_t initialize();
Jeff Brown51d45a72010-06-17 20:52:56 -0700508
509 void setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout);
Jeff Browne839a582010-04-22 18:58:52 -0700510 };
511
Jeff Brown54bc2812010-06-15 01:31:58 -0700512 sp<InputDispatcherPolicyInterface> mPolicy;
Jeff Browne839a582010-04-22 18:58:52 -0700513
514 Mutex mLock;
515
Jeff Browne839a582010-04-22 18:58:52 -0700516 Allocator mAllocator;
Jeff Browne839a582010-04-22 18:58:52 -0700517 sp<PollLoop> mPollLoop;
518
Jeff Brown54bc2812010-06-15 01:31:58 -0700519 Queue<EventEntry> mInboundQueue;
520 Queue<CommandEntry> mCommandQueue;
521
Jeff Browne839a582010-04-22 18:58:52 -0700522 // All registered connections mapped by receive pipe file descriptor.
523 KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
524
525 // Active connections are connections that have a non-empty outbound queue.
Jeff Brown51d45a72010-06-17 20:52:56 -0700526 // We don't use a ref-counted pointer here because we explicitly abort connections
527 // during unregistration which causes the connection's outbound queue to be cleared
528 // and the connection itself to be deactivated.
Jeff Browne839a582010-04-22 18:58:52 -0700529 Vector<Connection*> mActiveConnections;
530
Jeff Brown51d45a72010-06-17 20:52:56 -0700531 // List of connections that have timed out. Only used by dispatchOnce()
532 // We don't use a ref-counted pointer here because it is not possible for a connection
533 // to be unregistered while processing timed out connections since we hold the lock for
534 // the duration.
535 Vector<Connection*> mTimedOutConnections;
536
Jeff Brown54bc2812010-06-15 01:31:58 -0700537 // Preallocated key and motion event objects used only to ask the input dispatcher policy
Jeff Browne839a582010-04-22 18:58:52 -0700538 // for the targets of an event that is to be dispatched.
539 KeyEvent mReusableKeyEvent;
540 MotionEvent mReusableMotionEvent;
541
542 // The input targets that were most recently identified for dispatch.
543 // If there is a synchronous event dispatch in progress, the current input targets will
544 // remain unchanged until the dispatch has completed or been aborted.
545 Vector<InputTarget> mCurrentInputTargets;
Jeff Brown54bc2812010-06-15 01:31:58 -0700546 bool mCurrentInputTargetsValid; // false while targets are being recomputed
Jeff Browne839a582010-04-22 18:58:52 -0700547
Jeff Brown51d45a72010-06-17 20:52:56 -0700548 // Event injection and synchronization.
549 Condition mInjectionResultAvailableCondition;
550 Condition mFullySynchronizedCondition;
551 bool isFullySynchronizedLocked();
552 EventEntry* createEntryFromInputEventLocked(const InputEvent* event);
553 void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
554
Jeff Browne839a582010-04-22 18:58:52 -0700555 // Key repeat tracking.
556 // XXX Move this up to the input reader instead.
557 struct KeyRepeatState {
558 KeyEntry* lastKeyEntry; // or null if no repeat
559 nsecs_t nextRepeatTime;
560 } mKeyRepeatState;
561
562 void resetKeyRepeatLocked();
563
Jeff Brown54bc2812010-06-15 01:31:58 -0700564 // Deferred command processing.
565 bool runCommandsLockedInterruptible();
566 CommandEntry* postCommandLocked(Command command);
567
Jeff Browne839a582010-04-22 18:58:52 -0700568 // Process events that have just been dequeued from the head of the input queue.
Jeff Brown54bc2812010-06-15 01:31:58 -0700569 void processConfigurationChangedLockedInterruptible(
570 nsecs_t currentTime, ConfigurationChangedEntry* entry);
571 void processKeyLockedInterruptible(
572 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout);
573 void processKeyRepeatLockedInterruptible(
574 nsecs_t currentTime, nsecs_t keyRepeatTimeout);
575 void processMotionLockedInterruptible(
576 nsecs_t currentTime, MotionEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700577
578 // Identify input targets for an event and dispatch to them.
Jeff Brown54bc2812010-06-15 01:31:58 -0700579 void identifyInputTargetsAndDispatchKeyLockedInterruptible(
580 nsecs_t currentTime, KeyEntry* entry);
581 void identifyInputTargetsAndDispatchMotionLockedInterruptible(
582 nsecs_t currentTime, MotionEntry* entry);
583 void dispatchEventToCurrentInputTargetsLocked(
584 nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
Jeff Browne839a582010-04-22 18:58:52 -0700585
586 // Manage the dispatch cycle for a single connection.
Jeff Brown51d45a72010-06-17 20:52:56 -0700587 // These methods are deliberately not Interruptible because doing all of the work
588 // with the mutex held makes it easier to ensure that connection invariants are maintained.
589 // If needed, the methods post commands to run later once the critical bits are done.
590 void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700591 EventEntry* eventEntry, const InputTarget* inputTarget,
592 bool resumeWithAppendedMotionSample);
Jeff Brown51d45a72010-06-17 20:52:56 -0700593 void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
594 void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
595 void timeoutDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
596 void resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
597 const sp<Connection>& connection, nsecs_t newTimeout);
598 void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700599 bool broken);
600 static bool handleReceiveCallback(int receiveFd, int events, void* data);
601
602 // Add or remove a connection to the mActiveConnections vector.
603 void activateConnectionLocked(Connection* connection);
604 void deactivateConnectionLocked(Connection* connection);
605
606 // Interesting events that we might like to log or tell the framework about.
Jeff Brown54bc2812010-06-15 01:31:58 -0700607 void onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700608 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700609 void onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700610 nsecs_t currentTime, const sp<Connection>& connection, bool recoveredFromANR);
Jeff Brown54bc2812010-06-15 01:31:58 -0700611 void onDispatchCycleANRLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700612 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700613 void onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700614 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700615
Jeff Brown51d45a72010-06-17 20:52:56 -0700616 // Outbound policy interactions.
Jeff Brown54bc2812010-06-15 01:31:58 -0700617 void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
618 void doNotifyInputChannelANRLockedInterruptible(CommandEntry* commandEntry);
619 void doNotifyInputChannelRecoveredFromANRLockedInterruptible(CommandEntry* commandEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700620};
621
622/* Enqueues and dispatches input events, endlessly. */
623class InputDispatcherThread : public Thread {
624public:
625 explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
626 ~InputDispatcherThread();
627
628private:
629 virtual bool threadLoop();
630
631 sp<InputDispatcherInterface> mDispatcher;
632};
633
634} // namespace android
635
636#endif // _UI_INPUT_DISPATCHER_PRIV_H