blob: d3495fee5dcbdf2545402aa8df330f64ccb8cd69 [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
Jeff Brownf67c53e2010-07-28 15:48:59 -070058/*
59 * Constants used to determine the input event injection synchronization mode.
60 */
61enum {
62 /* Injection is asynchronous and is assumed always to be successful. */
63 INPUT_EVENT_INJECTION_SYNC_NONE = 0,
64
65 /* Waits for previous events to be dispatched so that the input dispatcher can determine
66 * whether input event injection willbe permitted based on the current input focus.
67 * Does not wait for the input event to finish processing. */
68 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1,
69
70 /* Waits for the input event to be completely processed. */
71 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED = 2,
72};
73
Jeff Brown51d45a72010-06-17 20:52:56 -070074
75/*
Jeff Brown54bc2812010-06-15 01:31:58 -070076 * An input target specifies how an input event is to be dispatched to a particular window
77 * including the window's input channel, control flags, a timeout, and an X / Y offset to
78 * be added to input event coordinates to compensate for the absolute position of the
79 * window area.
80 */
81struct InputTarget {
82 enum {
83 /* This flag indicates that subsequent event delivery should be held until the
84 * current event is delivered to this target or a timeout occurs. */
85 FLAG_SYNC = 0x01,
86
87 /* This flag indicates that a MotionEvent with ACTION_DOWN falls outside of the area of
88 * this target and so should instead be delivered as an ACTION_OUTSIDE to this target. */
89 FLAG_OUTSIDE = 0x02,
90
91 /* This flag indicates that a KeyEvent or MotionEvent is being canceled.
92 * In the case of a key event, it should be delivered with KeyEvent.FLAG_CANCELED set.
93 * In the case of a motion event, it should be delivered as MotionEvent.ACTION_CANCEL. */
94 FLAG_CANCEL = 0x04
95 };
96
97 // The input channel to be targeted.
98 sp<InputChannel> inputChannel;
99
100 // Flags for the input target.
101 int32_t flags;
102
103 // The timeout for event delivery to this target in nanoseconds. Or -1 if none.
104 nsecs_t timeout;
105
106 // The x and y offset to add to a MotionEvent as it is delivered.
107 // (ignored for KeyEvents)
108 float xOffset, yOffset;
109};
110
Jeff Brown51d45a72010-06-17 20:52:56 -0700111
Jeff Brown54bc2812010-06-15 01:31:58 -0700112/*
113 * Input dispatcher policy interface.
114 *
115 * The input reader policy is used by the input reader to interact with the Window Manager
116 * and other system components.
117 *
118 * The actual implementation is partially supported by callbacks into the DVM
119 * via JNI. This interface is also mocked in the unit tests.
120 */
121class InputDispatcherPolicyInterface : public virtual RefBase {
122protected:
123 InputDispatcherPolicyInterface() { }
124 virtual ~InputDispatcherPolicyInterface() { }
125
126public:
127 /* Notifies the system that a configuration change has occurred. */
128 virtual void notifyConfigurationChanged(nsecs_t when) = 0;
129
130 /* Notifies the system that an input channel is unrecoverably broken. */
131 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) = 0;
132
Jeff Brown51d45a72010-06-17 20:52:56 -0700133 /* Notifies the system that an input channel is not responding.
134 * Returns true and a new timeout value if the dispatcher should keep waiting.
135 * Otherwise returns false. */
136 virtual bool notifyInputChannelANR(const sp<InputChannel>& inputChannel,
137 nsecs_t& outNewTimeout) = 0;
Jeff Brown54bc2812010-06-15 01:31:58 -0700138
139 /* Notifies the system that an input channel recovered from ANR. */
140 virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) = 0;
141
142 /* Gets the key repeat timeout or -1 if automatic key repeating is disabled. */
143 virtual nsecs_t getKeyRepeatTimeout() = 0;
144
Jeff Brown50de30a2010-06-22 01:27:15 -0700145 /* Waits for key event input targets to become available.
Jeff Brown51d45a72010-06-17 20:52:56 -0700146 * If the event is being injected, injectorPid and injectorUid should specify the
147 * process id and used id of the injecting application, otherwise they should both
148 * be -1.
149 * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
Jeff Brown50de30a2010-06-22 01:27:15 -0700150 virtual int32_t waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700151 int32_t injectorPid, int32_t injectorUid,
Jeff Brown54bc2812010-06-15 01:31:58 -0700152 Vector<InputTarget>& outTargets) = 0;
153
Jeff Brown50de30a2010-06-22 01:27:15 -0700154 /* Waits for motion event targets to become available.
Jeff Brown51d45a72010-06-17 20:52:56 -0700155 * If the event is being injected, injectorPid and injectorUid should specify the
156 * process id and used id of the injecting application, otherwise they should both
157 * be -1.
158 * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
Jeff Brown50de30a2010-06-22 01:27:15 -0700159 virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700160 int32_t injectorPid, int32_t injectorUid,
Jeff Brown54bc2812010-06-15 01:31:58 -0700161 Vector<InputTarget>& outTargets) = 0;
162};
163
164
Jeff Browne839a582010-04-22 18:58:52 -0700165/* Notifies the system about input events generated by the input reader.
166 * The dispatcher is expected to be mostly asynchronous. */
167class InputDispatcherInterface : public virtual RefBase {
168protected:
169 InputDispatcherInterface() { }
170 virtual ~InputDispatcherInterface() { }
171
172public:
173 /* Runs a single iteration of the dispatch loop.
174 * Nominally processes one queued event, a timeout, or a response from an input consumer.
175 *
176 * This method should only be called on the input dispatcher thread.
177 */
178 virtual void dispatchOnce() = 0;
179
180 /* Notifies the dispatcher about new events.
Jeff Browne839a582010-04-22 18:58:52 -0700181 *
182 * These methods should only be called on the input reader thread.
183 */
Jeff Brown54bc2812010-06-15 01:31:58 -0700184 virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
Jeff Browne839a582010-04-22 18:58:52 -0700185 virtual void notifyAppSwitchComing(nsecs_t eventTime) = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700186 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700187 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
188 int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700189 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700190 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
191 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
192 float xPrecision, float yPrecision, nsecs_t downTime) = 0;
193
Jeff Brown51d45a72010-06-17 20:52:56 -0700194 /* Injects an input event and optionally waits for sync.
Jeff Brownf67c53e2010-07-28 15:48:59 -0700195 * The synchronization mode determines whether the method blocks while waiting for
196 * input injection to proceed.
Jeff Brown51d45a72010-06-17 20:52:56 -0700197 * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
198 *
199 * This method may be called on any thread (usually by the input manager).
200 */
201 virtual int32_t injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -0700202 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
Jeff Brown51d45a72010-06-17 20:52:56 -0700203
Jeff Brown50de30a2010-06-22 01:27:15 -0700204 /* Preempts input dispatch in progress by making pending synchronous
205 * dispatches asynchronous instead. This method is generally called during a focus
206 * transition from one application to the next so as to enable the new application
207 * to start receiving input as soon as possible without having to wait for the
208 * old application to finish up.
209 *
210 * This method may be called on any thread (usually by the input manager).
211 */
212 virtual void preemptInputDispatch() = 0;
213
Jeff Browne839a582010-04-22 18:58:52 -0700214 /* Registers or unregister input channels that may be used as targets for input events.
215 *
216 * These methods may be called on any thread (usually by the input manager).
217 */
218 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
219 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
220};
221
Jeff Brown54bc2812010-06-15 01:31:58 -0700222/* Dispatches events to input targets. Some functions of the input dispatcher, such as
223 * identifying input targets, are controlled by a separate policy object.
224 *
225 * IMPORTANT INVARIANT:
226 * Because the policy can potentially block or cause re-entrance into the input dispatcher,
227 * the input dispatcher never calls into the policy while holding its internal locks.
228 * The implementation is also carefully designed to recover from scenarios such as an
229 * input channel becoming unregistered while identifying input targets or processing timeouts.
230 *
231 * Methods marked 'Locked' must be called with the lock acquired.
232 *
233 * Methods marked 'LockedInterruptible' must be called with the lock acquired but
234 * may during the course of their execution release the lock, call into the policy, and
235 * then reacquire the lock. The caller is responsible for recovering gracefully.
236 *
237 * A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
238 */
Jeff Browne839a582010-04-22 18:58:52 -0700239class InputDispatcher : public InputDispatcherInterface {
240protected:
241 virtual ~InputDispatcher();
242
243public:
Jeff Brown54bc2812010-06-15 01:31:58 -0700244 explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
Jeff Browne839a582010-04-22 18:58:52 -0700245
246 virtual void dispatchOnce();
247
Jeff Brown54bc2812010-06-15 01:31:58 -0700248 virtual void notifyConfigurationChanged(nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700249 virtual void notifyAppSwitchComing(nsecs_t eventTime);
Jeff Brown5c1ed842010-07-14 18:48:53 -0700250 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700251 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
252 int32_t scanCode, int32_t metaState, nsecs_t downTime);
Jeff Brown5c1ed842010-07-14 18:48:53 -0700253 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700254 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
255 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
256 float xPrecision, float yPrecision, nsecs_t downTime);
257
Jeff Brown51d45a72010-06-17 20:52:56 -0700258 virtual int32_t injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -0700259 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -0700260
Jeff Brown50de30a2010-06-22 01:27:15 -0700261 virtual void preemptInputDispatch();
262
Jeff Browne839a582010-04-22 18:58:52 -0700263 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
264 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
265
266private:
267 template <typename T>
268 struct Link {
269 T* next;
270 T* prev;
271 };
272
273 struct EventEntry : Link<EventEntry> {
274 enum {
275 TYPE_SENTINEL,
276 TYPE_CONFIGURATION_CHANGED,
277 TYPE_KEY,
278 TYPE_MOTION
279 };
280
281 int32_t refCount;
282 int32_t type;
283 nsecs_t eventTime;
Jeff Brown54bc2812010-06-15 01:31:58 -0700284
Jeff Brownf67c53e2010-07-28 15:48:59 -0700285 int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
286 bool injectionIsAsync; // set to true if injection is not waiting for the result
287 int32_t injectorPid; // -1 if not injected
288 int32_t injectorUid; // -1 if not injected
Jeff Brown51d45a72010-06-17 20:52:56 -0700289
Jeff Brown54bc2812010-06-15 01:31:58 -0700290 bool dispatchInProgress; // initially false, set to true while dispatching
Jeff Brownf67c53e2010-07-28 15:48:59 -0700291 int32_t pendingSyncDispatches; // the number of synchronous dispatches in progress
Jeff Brown51d45a72010-06-17 20:52:56 -0700292
293 inline bool isInjected() { return injectorPid >= 0; }
Jeff Browne839a582010-04-22 18:58:52 -0700294 };
295
296 struct ConfigurationChangedEntry : EventEntry {
Jeff Browne839a582010-04-22 18:58:52 -0700297 };
298
299 struct KeyEntry : EventEntry {
300 int32_t deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700301 int32_t source;
Jeff Browne839a582010-04-22 18:58:52 -0700302 uint32_t policyFlags;
303 int32_t action;
304 int32_t flags;
305 int32_t keyCode;
306 int32_t scanCode;
307 int32_t metaState;
308 int32_t repeatCount;
309 nsecs_t downTime;
310 };
311
312 struct MotionSample {
313 MotionSample* next;
314
315 nsecs_t eventTime;
316 PointerCoords pointerCoords[MAX_POINTERS];
317 };
318
319 struct MotionEntry : EventEntry {
320 int32_t deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700321 int32_t source;
Jeff Browne839a582010-04-22 18:58:52 -0700322 uint32_t policyFlags;
323 int32_t action;
324 int32_t metaState;
325 int32_t edgeFlags;
326 float xPrecision;
327 float yPrecision;
328 nsecs_t downTime;
329 uint32_t pointerCount;
330 int32_t pointerIds[MAX_POINTERS];
331
332 // Linked list of motion samples associated with this motion event.
333 MotionSample firstSample;
334 MotionSample* lastSample;
335 };
336
Jeff Brown54bc2812010-06-15 01:31:58 -0700337 // Tracks the progress of dispatching a particular event to a particular connection.
Jeff Browne839a582010-04-22 18:58:52 -0700338 struct DispatchEntry : Link<DispatchEntry> {
339 EventEntry* eventEntry; // the event to dispatch
340 int32_t targetFlags;
341 float xOffset;
342 float yOffset;
343 nsecs_t timeout;
344
345 // True if dispatch has started.
346 bool inProgress;
347
348 // For motion events:
349 // Pointer to the first motion sample to dispatch in this cycle.
350 // Usually NULL to indicate that the list of motion samples begins at
351 // MotionEntry::firstSample. Otherwise, some samples were dispatched in a previous
352 // cycle and this pointer indicates the location of the first remainining sample
353 // to dispatch during the current cycle.
354 MotionSample* headMotionSample;
355 // Pointer to a motion sample to dispatch in the next cycle if the dispatcher was
356 // unable to send all motion samples during this cycle. On the next cycle,
357 // headMotionSample will be initialized to tailMotionSample and tailMotionSample
358 // will be set to NULL.
359 MotionSample* tailMotionSample;
Jeff Brownf67c53e2010-07-28 15:48:59 -0700360
361 inline bool isSyncTarget() {
362 return targetFlags & InputTarget::FLAG_SYNC;
363 }
Jeff Browne839a582010-04-22 18:58:52 -0700364 };
365
Jeff Brown54bc2812010-06-15 01:31:58 -0700366 // A command entry captures state and behavior for an action to be performed in the
367 // dispatch loop after the initial processing has taken place. It is essentially
368 // a kind of continuation used to postpone sensitive policy interactions to a point
369 // in the dispatch loop where it is safe to release the lock (generally after finishing
370 // the critical parts of the dispatch cycle).
371 //
372 // The special thing about commands is that they can voluntarily release and reacquire
373 // the dispatcher lock at will. Initially when the command starts running, the
374 // dispatcher lock is held. However, if the command needs to call into the policy to
375 // do some work, it can release the lock, do the work, then reacquire the lock again
376 // before returning.
377 //
378 // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
379 // never calls into the policy while holding its lock.
380 //
381 // Commands are implicitly 'LockedInterruptible'.
382 struct CommandEntry;
383 typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
384
Jeff Brown51d45a72010-06-17 20:52:56 -0700385 class Connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700386 struct CommandEntry : Link<CommandEntry> {
387 CommandEntry();
388 ~CommandEntry();
389
390 Command command;
391
392 // parameters for the command (usage varies by command)
Jeff Brown51d45a72010-06-17 20:52:56 -0700393 sp<Connection> connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700394 };
395
396 // Generic queue implementation.
Jeff Browne839a582010-04-22 18:58:52 -0700397 template <typename T>
398 struct Queue {
399 T head;
400 T tail;
401
402 inline Queue() {
403 head.prev = NULL;
404 head.next = & tail;
405 tail.prev = & head;
406 tail.next = NULL;
407 }
408
409 inline bool isEmpty() {
410 return head.next == & tail;
411 }
412
413 inline void enqueueAtTail(T* entry) {
414 T* last = tail.prev;
415 last->next = entry;
416 entry->prev = last;
417 entry->next = & tail;
418 tail.prev = entry;
419 }
420
421 inline void enqueueAtHead(T* entry) {
422 T* first = head.next;
423 head.next = entry;
424 entry->prev = & head;
425 entry->next = first;
426 first->prev = entry;
427 }
428
429 inline void dequeue(T* entry) {
430 entry->prev->next = entry->next;
431 entry->next->prev = entry->prev;
432 }
433
434 inline T* dequeueAtHead() {
435 T* first = head.next;
436 dequeue(first);
437 return first;
438 }
439 };
440
441 /* Allocates queue entries and performs reference counting as needed. */
442 class Allocator {
443 public:
444 Allocator();
445
Jeff Brown51d45a72010-06-17 20:52:56 -0700446 ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
447 KeyEntry* obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700448 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -0700449 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
450 int32_t repeatCount, nsecs_t downTime);
451 MotionEntry* obtainMotionEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700452 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -0700453 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
454 nsecs_t downTime, uint32_t pointerCount,
455 const int32_t* pointerIds, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700456 DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700457 CommandEntry* obtainCommandEntry(Command command);
Jeff Browne839a582010-04-22 18:58:52 -0700458
459 void releaseEventEntry(EventEntry* entry);
460 void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
461 void releaseKeyEntry(KeyEntry* entry);
462 void releaseMotionEntry(MotionEntry* entry);
463 void releaseDispatchEntry(DispatchEntry* entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700464 void releaseCommandEntry(CommandEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700465
466 void appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -0700467 nsecs_t eventTime, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700468
469 private:
470 Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
471 Pool<KeyEntry> mKeyEntryPool;
472 Pool<MotionEntry> mMotionEntryPool;
473 Pool<MotionSample> mMotionSamplePool;
474 Pool<DispatchEntry> mDispatchEntryPool;
Jeff Brown54bc2812010-06-15 01:31:58 -0700475 Pool<CommandEntry> mCommandEntryPool;
Jeff Brown51d45a72010-06-17 20:52:56 -0700476
477 void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700478 };
479
480 /* Manages the dispatch state associated with a single input channel. */
481 class Connection : public RefBase {
482 protected:
483 virtual ~Connection();
484
485 public:
486 enum Status {
487 // Everything is peachy.
488 STATUS_NORMAL,
489 // An unrecoverable communication error has occurred.
490 STATUS_BROKEN,
491 // The client is not responding.
492 STATUS_NOT_RESPONDING,
493 // The input channel has been unregistered.
494 STATUS_ZOMBIE
495 };
496
497 Status status;
498 sp<InputChannel> inputChannel;
499 InputPublisher inputPublisher;
500 Queue<DispatchEntry> outboundQueue;
501 nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
502
503 nsecs_t lastEventTime; // the time when the event was originally captured
504 nsecs_t lastDispatchTime; // the time when the last event was dispatched
505 nsecs_t lastANRTime; // the time when the last ANR was recorded
506
507 explicit Connection(const sp<InputChannel>& inputChannel);
508
Jeff Brown54bc2812010-06-15 01:31:58 -0700509 inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
510
511 const char* getStatusLabel() const;
Jeff Browne839a582010-04-22 18:58:52 -0700512
513 // Finds a DispatchEntry in the outbound queue associated with the specified event.
514 // Returns NULL if not found.
515 DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const;
516
517 // Determine whether this connection has a pending synchronous dispatch target.
518 // Since there can only ever be at most one such target at a time, if there is one,
519 // it must be at the tail because nothing else can be enqueued after it.
520 inline bool hasPendingSyncTarget() {
Jeff Brownf67c53e2010-07-28 15:48:59 -0700521 return ! outboundQueue.isEmpty() && outboundQueue.tail.prev->isSyncTarget();
Jeff Browne839a582010-04-22 18:58:52 -0700522 }
523
524 // Gets the time since the current event was originally obtained from the input driver.
525 inline double getEventLatencyMillis(nsecs_t currentTime) {
526 return (currentTime - lastEventTime) / 1000000.0;
527 }
528
529 // Gets the time since the current event entered the outbound dispatch queue.
530 inline double getDispatchLatencyMillis(nsecs_t currentTime) {
531 return (currentTime - lastDispatchTime) / 1000000.0;
532 }
533
534 // Gets the time since the current event ANR was declared, if applicable.
535 inline double getANRLatencyMillis(nsecs_t currentTime) {
536 return (currentTime - lastANRTime) / 1000000.0;
537 }
538
539 status_t initialize();
Jeff Brown51d45a72010-06-17 20:52:56 -0700540
541 void setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout);
Jeff Browne839a582010-04-22 18:58:52 -0700542 };
543
Jeff Brown54bc2812010-06-15 01:31:58 -0700544 sp<InputDispatcherPolicyInterface> mPolicy;
Jeff Browne839a582010-04-22 18:58:52 -0700545
546 Mutex mLock;
547
Jeff Browne839a582010-04-22 18:58:52 -0700548 Allocator mAllocator;
Jeff Browne839a582010-04-22 18:58:52 -0700549 sp<PollLoop> mPollLoop;
550
Jeff Brown54bc2812010-06-15 01:31:58 -0700551 Queue<EventEntry> mInboundQueue;
552 Queue<CommandEntry> mCommandQueue;
553
Jeff Browne839a582010-04-22 18:58:52 -0700554 // All registered connections mapped by receive pipe file descriptor.
555 KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
556
557 // Active connections are connections that have a non-empty outbound queue.
Jeff Brown51d45a72010-06-17 20:52:56 -0700558 // We don't use a ref-counted pointer here because we explicitly abort connections
559 // during unregistration which causes the connection's outbound queue to be cleared
560 // and the connection itself to be deactivated.
Jeff Browne839a582010-04-22 18:58:52 -0700561 Vector<Connection*> mActiveConnections;
562
Jeff Brown51d45a72010-06-17 20:52:56 -0700563 // List of connections that have timed out. Only used by dispatchOnce()
564 // We don't use a ref-counted pointer here because it is not possible for a connection
565 // to be unregistered while processing timed out connections since we hold the lock for
566 // the duration.
567 Vector<Connection*> mTimedOutConnections;
568
Jeff Brown54bc2812010-06-15 01:31:58 -0700569 // Preallocated key and motion event objects used only to ask the input dispatcher policy
Jeff Browne839a582010-04-22 18:58:52 -0700570 // for the targets of an event that is to be dispatched.
571 KeyEvent mReusableKeyEvent;
572 MotionEvent mReusableMotionEvent;
573
574 // The input targets that were most recently identified for dispatch.
575 // If there is a synchronous event dispatch in progress, the current input targets will
576 // remain unchanged until the dispatch has completed or been aborted.
577 Vector<InputTarget> mCurrentInputTargets;
Jeff Brown54bc2812010-06-15 01:31:58 -0700578 bool mCurrentInputTargetsValid; // false while targets are being recomputed
Jeff Browne839a582010-04-22 18:58:52 -0700579
Jeff Brown51d45a72010-06-17 20:52:56 -0700580 // Event injection and synchronization.
581 Condition mInjectionResultAvailableCondition;
Jeff Brown51d45a72010-06-17 20:52:56 -0700582 EventEntry* createEntryFromInputEventLocked(const InputEvent* event);
583 void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
584
Jeff Brownf67c53e2010-07-28 15:48:59 -0700585 Condition mInjectionSyncFinishedCondition;
586 void decrementPendingSyncDispatchesLocked(EventEntry* entry);
587
Jeff Browne839a582010-04-22 18:58:52 -0700588 // Key repeat tracking.
589 // XXX Move this up to the input reader instead.
590 struct KeyRepeatState {
591 KeyEntry* lastKeyEntry; // or null if no repeat
592 nsecs_t nextRepeatTime;
593 } mKeyRepeatState;
594
595 void resetKeyRepeatLocked();
596
Jeff Brown54bc2812010-06-15 01:31:58 -0700597 // Deferred command processing.
598 bool runCommandsLockedInterruptible();
599 CommandEntry* postCommandLocked(Command command);
600
Jeff Browne839a582010-04-22 18:58:52 -0700601 // Process events that have just been dequeued from the head of the input queue.
Jeff Brown54bc2812010-06-15 01:31:58 -0700602 void processConfigurationChangedLockedInterruptible(
603 nsecs_t currentTime, ConfigurationChangedEntry* entry);
604 void processKeyLockedInterruptible(
605 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout);
606 void processKeyRepeatLockedInterruptible(
607 nsecs_t currentTime, nsecs_t keyRepeatTimeout);
608 void processMotionLockedInterruptible(
609 nsecs_t currentTime, MotionEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700610
611 // Identify input targets for an event and dispatch to them.
Jeff Brown54bc2812010-06-15 01:31:58 -0700612 void identifyInputTargetsAndDispatchKeyLockedInterruptible(
613 nsecs_t currentTime, KeyEntry* entry);
614 void identifyInputTargetsAndDispatchMotionLockedInterruptible(
615 nsecs_t currentTime, MotionEntry* entry);
616 void dispatchEventToCurrentInputTargetsLocked(
617 nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
Jeff Browne839a582010-04-22 18:58:52 -0700618
619 // Manage the dispatch cycle for a single connection.
Jeff Brown51d45a72010-06-17 20:52:56 -0700620 // These methods are deliberately not Interruptible because doing all of the work
621 // with the mutex held makes it easier to ensure that connection invariants are maintained.
622 // If needed, the methods post commands to run later once the critical bits are done.
623 void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700624 EventEntry* eventEntry, const InputTarget* inputTarget,
625 bool resumeWithAppendedMotionSample);
Jeff Brown51d45a72010-06-17 20:52:56 -0700626 void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
627 void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
628 void timeoutDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
629 void resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
630 const sp<Connection>& connection, nsecs_t newTimeout);
631 void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700632 bool broken);
633 static bool handleReceiveCallback(int receiveFd, int events, void* data);
634
635 // Add or remove a connection to the mActiveConnections vector.
636 void activateConnectionLocked(Connection* connection);
637 void deactivateConnectionLocked(Connection* connection);
638
639 // Interesting events that we might like to log or tell the framework about.
Jeff Brown54bc2812010-06-15 01:31:58 -0700640 void onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700641 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700642 void onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700643 nsecs_t currentTime, const sp<Connection>& connection, bool recoveredFromANR);
Jeff Brown54bc2812010-06-15 01:31:58 -0700644 void onDispatchCycleANRLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700645 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700646 void onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700647 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700648
Jeff Brown51d45a72010-06-17 20:52:56 -0700649 // Outbound policy interactions.
Jeff Brown54bc2812010-06-15 01:31:58 -0700650 void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
651 void doNotifyInputChannelANRLockedInterruptible(CommandEntry* commandEntry);
652 void doNotifyInputChannelRecoveredFromANRLockedInterruptible(CommandEntry* commandEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700653};
654
655/* Enqueues and dispatches input events, endlessly. */
656class InputDispatcherThread : public Thread {
657public:
658 explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
659 ~InputDispatcherThread();
660
661private:
662 virtual bool threadLoop();
663
664 sp<InputDispatcherInterface> mDispatcher;
665};
666
667} // namespace android
668
669#endif // _UI_INPUT_DISPATCHER_PRIV_H