blob: f00f2dbce3ff2aeb840608d08fb5cafe89d96509 [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
Jeff Brownaf30ff62010-09-01 17:01:00 -070087 /* This flag indicates that a MotionEvent with AMOTION_EVENT_ACTION_DOWN falls outside
88 * of the area of this target and so should instead be delivered as an
89 * AMOTION_EVENT_ACTION_OUTSIDE to this target. */
Jeff Brown54bc2812010-06-15 01:31:58 -070090 FLAG_OUTSIDE = 0x02,
91
92 /* This flag indicates that a KeyEvent or MotionEvent is being canceled.
Jeff Brownaf30ff62010-09-01 17:01:00 -070093 * In the case of a key event, it should be delivered with flag
94 * AKEY_EVENT_FLAG_CANCELED set.
95 * In the case of a motion event, it should be delivered with action
96 * AMOTION_EVENT_ACTION_CANCEL instead. */
97 FLAG_CANCEL = 0x04,
98
99 /* This flag indicates that the target of a MotionEvent is partly or wholly
100 * obscured by another visible window above it. The motion event should be
101 * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */
102 FLAG_WINDOW_IS_OBSCURED = 0x08,
Jeff Brown54bc2812010-06-15 01:31:58 -0700103 };
104
105 // The input channel to be targeted.
106 sp<InputChannel> inputChannel;
107
108 // Flags for the input target.
109 int32_t flags;
110
111 // The timeout for event delivery to this target in nanoseconds. Or -1 if none.
112 nsecs_t timeout;
113
114 // The x and y offset to add to a MotionEvent as it is delivered.
115 // (ignored for KeyEvents)
116 float xOffset, yOffset;
117};
118
Jeff Brown51d45a72010-06-17 20:52:56 -0700119
Jeff Brown54bc2812010-06-15 01:31:58 -0700120/*
121 * Input dispatcher policy interface.
122 *
123 * The input reader policy is used by the input reader to interact with the Window Manager
124 * and other system components.
125 *
126 * The actual implementation is partially supported by callbacks into the DVM
127 * via JNI. This interface is also mocked in the unit tests.
128 */
129class InputDispatcherPolicyInterface : public virtual RefBase {
130protected:
131 InputDispatcherPolicyInterface() { }
132 virtual ~InputDispatcherPolicyInterface() { }
133
134public:
135 /* Notifies the system that a configuration change has occurred. */
136 virtual void notifyConfigurationChanged(nsecs_t when) = 0;
137
138 /* Notifies the system that an input channel is unrecoverably broken. */
139 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) = 0;
140
Jeff Brown51d45a72010-06-17 20:52:56 -0700141 /* Notifies the system that an input channel is not responding.
142 * Returns true and a new timeout value if the dispatcher should keep waiting.
143 * Otherwise returns false. */
144 virtual bool notifyInputChannelANR(const sp<InputChannel>& inputChannel,
145 nsecs_t& outNewTimeout) = 0;
Jeff Brown54bc2812010-06-15 01:31:58 -0700146
147 /* Notifies the system that an input channel recovered from ANR. */
148 virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) = 0;
149
Jeff Brown61ce3982010-09-07 10:44:57 -0700150 /* Gets the key repeat initial timeout or -1 if automatic key repeating is disabled. */
Jeff Brown54bc2812010-06-15 01:31:58 -0700151 virtual nsecs_t getKeyRepeatTimeout() = 0;
152
Jeff Brown61ce3982010-09-07 10:44:57 -0700153 /* Gets the key repeat inter-key delay. */
154 virtual nsecs_t getKeyRepeatDelay() = 0;
155
Jeff Brown50de30a2010-06-22 01:27:15 -0700156 /* Waits for key event input targets to become available.
Jeff Brown51d45a72010-06-17 20:52:56 -0700157 * If the event is being injected, injectorPid and injectorUid should specify the
158 * process id and used id of the injecting application, otherwise they should both
159 * be -1.
160 * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
Jeff Brown50de30a2010-06-22 01:27:15 -0700161 virtual int32_t waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700162 int32_t injectorPid, int32_t injectorUid,
Jeff Brown54bc2812010-06-15 01:31:58 -0700163 Vector<InputTarget>& outTargets) = 0;
164
Jeff Brown50de30a2010-06-22 01:27:15 -0700165 /* Waits for motion event targets to become available.
Jeff Brown51d45a72010-06-17 20:52:56 -0700166 * If the event is being injected, injectorPid and injectorUid should specify the
167 * process id and used id of the injecting application, otherwise they should both
168 * be -1.
169 * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
Jeff Brown50de30a2010-06-22 01:27:15 -0700170 virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700171 int32_t injectorPid, int32_t injectorUid,
Jeff Brown54bc2812010-06-15 01:31:58 -0700172 Vector<InputTarget>& outTargets) = 0;
Jeff Brown542412c2010-08-18 15:51:08 -0700173
174 /* Gets the maximum suggested event delivery rate per second.
175 * This value is used to throttle motion event movement actions on a per-device
176 * basis. It is not intended to be a hard limit.
177 */
178 virtual int32_t getMaxEventsPerSecond() = 0;
Jeff Brown54bc2812010-06-15 01:31:58 -0700179};
180
181
Jeff Browne839a582010-04-22 18:58:52 -0700182/* Notifies the system about input events generated by the input reader.
183 * The dispatcher is expected to be mostly asynchronous. */
184class InputDispatcherInterface : public virtual RefBase {
185protected:
186 InputDispatcherInterface() { }
187 virtual ~InputDispatcherInterface() { }
188
189public:
190 /* Runs a single iteration of the dispatch loop.
191 * Nominally processes one queued event, a timeout, or a response from an input consumer.
192 *
193 * This method should only be called on the input dispatcher thread.
194 */
195 virtual void dispatchOnce() = 0;
196
197 /* Notifies the dispatcher about new events.
Jeff Browne839a582010-04-22 18:58:52 -0700198 *
199 * These methods should only be called on the input reader thread.
200 */
Jeff Brown54bc2812010-06-15 01:31:58 -0700201 virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
Jeff Browne839a582010-04-22 18:58:52 -0700202 virtual void notifyAppSwitchComing(nsecs_t eventTime) = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700203 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700204 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
205 int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700206 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700207 uint32_t policyFlags, int32_t action, int32_t flags,
208 int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -0700209 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
210 float xPrecision, float yPrecision, nsecs_t downTime) = 0;
211
Jeff Brown51d45a72010-06-17 20:52:56 -0700212 /* Injects an input event and optionally waits for sync.
Jeff Brownf67c53e2010-07-28 15:48:59 -0700213 * The synchronization mode determines whether the method blocks while waiting for
214 * input injection to proceed.
Jeff Brown51d45a72010-06-17 20:52:56 -0700215 * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
216 *
217 * This method may be called on any thread (usually by the input manager).
218 */
219 virtual int32_t injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -0700220 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
Jeff Brown51d45a72010-06-17 20:52:56 -0700221
Jeff Brown50de30a2010-06-22 01:27:15 -0700222 /* Preempts input dispatch in progress by making pending synchronous
223 * dispatches asynchronous instead. This method is generally called during a focus
224 * transition from one application to the next so as to enable the new application
225 * to start receiving input as soon as possible without having to wait for the
226 * old application to finish up.
227 *
228 * This method may be called on any thread (usually by the input manager).
229 */
230 virtual void preemptInputDispatch() = 0;
231
Jeff Browne839a582010-04-22 18:58:52 -0700232 /* Registers or unregister input channels that may be used as targets for input events.
233 *
234 * These methods may be called on any thread (usually by the input manager).
235 */
236 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
237 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
238};
239
Jeff Brown54bc2812010-06-15 01:31:58 -0700240/* Dispatches events to input targets. Some functions of the input dispatcher, such as
241 * identifying input targets, are controlled by a separate policy object.
242 *
243 * IMPORTANT INVARIANT:
244 * Because the policy can potentially block or cause re-entrance into the input dispatcher,
245 * the input dispatcher never calls into the policy while holding its internal locks.
246 * The implementation is also carefully designed to recover from scenarios such as an
247 * input channel becoming unregistered while identifying input targets or processing timeouts.
248 *
249 * Methods marked 'Locked' must be called with the lock acquired.
250 *
251 * Methods marked 'LockedInterruptible' must be called with the lock acquired but
252 * may during the course of their execution release the lock, call into the policy, and
253 * then reacquire the lock. The caller is responsible for recovering gracefully.
254 *
255 * A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
256 */
Jeff Browne839a582010-04-22 18:58:52 -0700257class InputDispatcher : public InputDispatcherInterface {
258protected:
259 virtual ~InputDispatcher();
260
261public:
Jeff Brown54bc2812010-06-15 01:31:58 -0700262 explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
Jeff Browne839a582010-04-22 18:58:52 -0700263
264 virtual void dispatchOnce();
265
Jeff Brown54bc2812010-06-15 01:31:58 -0700266 virtual void notifyConfigurationChanged(nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700267 virtual void notifyAppSwitchComing(nsecs_t eventTime);
Jeff Brown5c1ed842010-07-14 18:48:53 -0700268 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700269 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
270 int32_t scanCode, int32_t metaState, nsecs_t downTime);
Jeff Brown5c1ed842010-07-14 18:48:53 -0700271 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700272 uint32_t policyFlags, int32_t action, int32_t flags,
273 int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -0700274 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
275 float xPrecision, float yPrecision, nsecs_t downTime);
276
Jeff Brown51d45a72010-06-17 20:52:56 -0700277 virtual int32_t injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -0700278 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -0700279
Jeff Brown50de30a2010-06-22 01:27:15 -0700280 virtual void preemptInputDispatch();
281
Jeff Browne839a582010-04-22 18:58:52 -0700282 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
283 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
284
285private:
286 template <typename T>
287 struct Link {
288 T* next;
289 T* prev;
290 };
291
292 struct EventEntry : Link<EventEntry> {
293 enum {
294 TYPE_SENTINEL,
295 TYPE_CONFIGURATION_CHANGED,
296 TYPE_KEY,
297 TYPE_MOTION
298 };
299
300 int32_t refCount;
301 int32_t type;
302 nsecs_t eventTime;
Jeff Brown54bc2812010-06-15 01:31:58 -0700303
Jeff Brownf67c53e2010-07-28 15:48:59 -0700304 int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
305 bool injectionIsAsync; // set to true if injection is not waiting for the result
306 int32_t injectorPid; // -1 if not injected
307 int32_t injectorUid; // -1 if not injected
Jeff Brown51d45a72010-06-17 20:52:56 -0700308
Jeff Brown54bc2812010-06-15 01:31:58 -0700309 bool dispatchInProgress; // initially false, set to true while dispatching
Jeff Brownf67c53e2010-07-28 15:48:59 -0700310 int32_t pendingSyncDispatches; // the number of synchronous dispatches in progress
Jeff Brown51d45a72010-06-17 20:52:56 -0700311
312 inline bool isInjected() { return injectorPid >= 0; }
Jeff Browne839a582010-04-22 18:58:52 -0700313 };
314
315 struct ConfigurationChangedEntry : EventEntry {
Jeff Browne839a582010-04-22 18:58:52 -0700316 };
317
318 struct KeyEntry : EventEntry {
319 int32_t deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700320 int32_t source;
Jeff Browne839a582010-04-22 18:58:52 -0700321 uint32_t policyFlags;
322 int32_t action;
323 int32_t flags;
324 int32_t keyCode;
325 int32_t scanCode;
326 int32_t metaState;
327 int32_t repeatCount;
328 nsecs_t downTime;
329 };
330
331 struct MotionSample {
332 MotionSample* next;
333
334 nsecs_t eventTime;
335 PointerCoords pointerCoords[MAX_POINTERS];
336 };
337
338 struct MotionEntry : EventEntry {
339 int32_t deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700340 int32_t source;
Jeff Browne839a582010-04-22 18:58:52 -0700341 uint32_t policyFlags;
342 int32_t action;
Jeff Brownaf30ff62010-09-01 17:01:00 -0700343 int32_t flags;
Jeff Browne839a582010-04-22 18:58:52 -0700344 int32_t metaState;
345 int32_t edgeFlags;
346 float xPrecision;
347 float yPrecision;
348 nsecs_t downTime;
349 uint32_t pointerCount;
350 int32_t pointerIds[MAX_POINTERS];
351
352 // Linked list of motion samples associated with this motion event.
353 MotionSample firstSample;
354 MotionSample* lastSample;
Jeff Brown542412c2010-08-18 15:51:08 -0700355
356 uint32_t countSamples() const;
Jeff Browne839a582010-04-22 18:58:52 -0700357 };
358
Jeff Brown54bc2812010-06-15 01:31:58 -0700359 // Tracks the progress of dispatching a particular event to a particular connection.
Jeff Browne839a582010-04-22 18:58:52 -0700360 struct DispatchEntry : Link<DispatchEntry> {
361 EventEntry* eventEntry; // the event to dispatch
362 int32_t targetFlags;
363 float xOffset;
364 float yOffset;
365 nsecs_t timeout;
366
367 // True if dispatch has started.
368 bool inProgress;
369
370 // For motion events:
371 // Pointer to the first motion sample to dispatch in this cycle.
372 // Usually NULL to indicate that the list of motion samples begins at
373 // MotionEntry::firstSample. Otherwise, some samples were dispatched in a previous
374 // cycle and this pointer indicates the location of the first remainining sample
375 // to dispatch during the current cycle.
376 MotionSample* headMotionSample;
377 // Pointer to a motion sample to dispatch in the next cycle if the dispatcher was
378 // unable to send all motion samples during this cycle. On the next cycle,
379 // headMotionSample will be initialized to tailMotionSample and tailMotionSample
380 // will be set to NULL.
381 MotionSample* tailMotionSample;
Jeff Brownf67c53e2010-07-28 15:48:59 -0700382
383 inline bool isSyncTarget() {
384 return targetFlags & InputTarget::FLAG_SYNC;
385 }
Jeff Browne839a582010-04-22 18:58:52 -0700386 };
387
Jeff Brown54bc2812010-06-15 01:31:58 -0700388 // A command entry captures state and behavior for an action to be performed in the
389 // dispatch loop after the initial processing has taken place. It is essentially
390 // a kind of continuation used to postpone sensitive policy interactions to a point
391 // in the dispatch loop where it is safe to release the lock (generally after finishing
392 // the critical parts of the dispatch cycle).
393 //
394 // The special thing about commands is that they can voluntarily release and reacquire
395 // the dispatcher lock at will. Initially when the command starts running, the
396 // dispatcher lock is held. However, if the command needs to call into the policy to
397 // do some work, it can release the lock, do the work, then reacquire the lock again
398 // before returning.
399 //
400 // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
401 // never calls into the policy while holding its lock.
402 //
403 // Commands are implicitly 'LockedInterruptible'.
404 struct CommandEntry;
405 typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
406
Jeff Brown51d45a72010-06-17 20:52:56 -0700407 class Connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700408 struct CommandEntry : Link<CommandEntry> {
409 CommandEntry();
410 ~CommandEntry();
411
412 Command command;
413
414 // parameters for the command (usage varies by command)
Jeff Brown51d45a72010-06-17 20:52:56 -0700415 sp<Connection> connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700416 };
417
418 // Generic queue implementation.
Jeff Browne839a582010-04-22 18:58:52 -0700419 template <typename T>
420 struct Queue {
421 T head;
422 T tail;
423
424 inline Queue() {
425 head.prev = NULL;
426 head.next = & tail;
427 tail.prev = & head;
428 tail.next = NULL;
429 }
430
431 inline bool isEmpty() {
432 return head.next == & tail;
433 }
434
435 inline void enqueueAtTail(T* entry) {
436 T* last = tail.prev;
437 last->next = entry;
438 entry->prev = last;
439 entry->next = & tail;
440 tail.prev = entry;
441 }
442
443 inline void enqueueAtHead(T* entry) {
444 T* first = head.next;
445 head.next = entry;
446 entry->prev = & head;
447 entry->next = first;
448 first->prev = entry;
449 }
450
451 inline void dequeue(T* entry) {
452 entry->prev->next = entry->next;
453 entry->next->prev = entry->prev;
454 }
455
456 inline T* dequeueAtHead() {
457 T* first = head.next;
458 dequeue(first);
459 return first;
460 }
461 };
462
463 /* Allocates queue entries and performs reference counting as needed. */
464 class Allocator {
465 public:
466 Allocator();
467
Jeff Brown51d45a72010-06-17 20:52:56 -0700468 ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
469 KeyEntry* obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700470 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -0700471 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
472 int32_t repeatCount, nsecs_t downTime);
473 MotionEntry* obtainMotionEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700474 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700475 int32_t flags, int32_t metaState, int32_t edgeFlags,
476 float xPrecision, float yPrecision,
Jeff Brown51d45a72010-06-17 20:52:56 -0700477 nsecs_t downTime, uint32_t pointerCount,
478 const int32_t* pointerIds, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700479 DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700480 CommandEntry* obtainCommandEntry(Command command);
Jeff Browne839a582010-04-22 18:58:52 -0700481
482 void releaseEventEntry(EventEntry* entry);
483 void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
484 void releaseKeyEntry(KeyEntry* entry);
485 void releaseMotionEntry(MotionEntry* entry);
486 void releaseDispatchEntry(DispatchEntry* entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700487 void releaseCommandEntry(CommandEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700488
489 void appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -0700490 nsecs_t eventTime, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700491
492 private:
493 Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
494 Pool<KeyEntry> mKeyEntryPool;
495 Pool<MotionEntry> mMotionEntryPool;
496 Pool<MotionSample> mMotionSamplePool;
497 Pool<DispatchEntry> mDispatchEntryPool;
Jeff Brown54bc2812010-06-15 01:31:58 -0700498 Pool<CommandEntry> mCommandEntryPool;
Jeff Brown51d45a72010-06-17 20:52:56 -0700499
500 void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700501 };
502
503 /* Manages the dispatch state associated with a single input channel. */
504 class Connection : public RefBase {
505 protected:
506 virtual ~Connection();
507
508 public:
509 enum Status {
510 // Everything is peachy.
511 STATUS_NORMAL,
512 // An unrecoverable communication error has occurred.
513 STATUS_BROKEN,
514 // The client is not responding.
515 STATUS_NOT_RESPONDING,
516 // The input channel has been unregistered.
517 STATUS_ZOMBIE
518 };
519
520 Status status;
521 sp<InputChannel> inputChannel;
522 InputPublisher inputPublisher;
523 Queue<DispatchEntry> outboundQueue;
524 nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
525
526 nsecs_t lastEventTime; // the time when the event was originally captured
527 nsecs_t lastDispatchTime; // the time when the last event was dispatched
528 nsecs_t lastANRTime; // the time when the last ANR was recorded
529
530 explicit Connection(const sp<InputChannel>& inputChannel);
531
Jeff Brown54bc2812010-06-15 01:31:58 -0700532 inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
533
534 const char* getStatusLabel() const;
Jeff Browne839a582010-04-22 18:58:52 -0700535
536 // Finds a DispatchEntry in the outbound queue associated with the specified event.
537 // Returns NULL if not found.
538 DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const;
539
540 // Determine whether this connection has a pending synchronous dispatch target.
541 // Since there can only ever be at most one such target at a time, if there is one,
542 // it must be at the tail because nothing else can be enqueued after it.
543 inline bool hasPendingSyncTarget() {
Jeff Brownf67c53e2010-07-28 15:48:59 -0700544 return ! outboundQueue.isEmpty() && outboundQueue.tail.prev->isSyncTarget();
Jeff Browne839a582010-04-22 18:58:52 -0700545 }
546
547 // Gets the time since the current event was originally obtained from the input driver.
548 inline double getEventLatencyMillis(nsecs_t currentTime) {
549 return (currentTime - lastEventTime) / 1000000.0;
550 }
551
552 // Gets the time since the current event entered the outbound dispatch queue.
553 inline double getDispatchLatencyMillis(nsecs_t currentTime) {
554 return (currentTime - lastDispatchTime) / 1000000.0;
555 }
556
557 // Gets the time since the current event ANR was declared, if applicable.
558 inline double getANRLatencyMillis(nsecs_t currentTime) {
559 return (currentTime - lastANRTime) / 1000000.0;
560 }
561
562 status_t initialize();
Jeff Brown51d45a72010-06-17 20:52:56 -0700563
564 void setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout);
Jeff Browne839a582010-04-22 18:58:52 -0700565 };
566
Jeff Brown54bc2812010-06-15 01:31:58 -0700567 sp<InputDispatcherPolicyInterface> mPolicy;
Jeff Browne839a582010-04-22 18:58:52 -0700568
569 Mutex mLock;
570
Jeff Browne839a582010-04-22 18:58:52 -0700571 Allocator mAllocator;
Jeff Browne839a582010-04-22 18:58:52 -0700572 sp<PollLoop> mPollLoop;
573
Jeff Brown54bc2812010-06-15 01:31:58 -0700574 Queue<EventEntry> mInboundQueue;
575 Queue<CommandEntry> mCommandQueue;
576
Jeff Browne839a582010-04-22 18:58:52 -0700577 // All registered connections mapped by receive pipe file descriptor.
578 KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
579
Jeff Brown0cacb872010-08-17 15:59:26 -0700580 ssize_t getConnectionIndex(const sp<InputChannel>& inputChannel);
581
Jeff Browne839a582010-04-22 18:58:52 -0700582 // Active connections are connections that have a non-empty outbound queue.
Jeff Brown51d45a72010-06-17 20:52:56 -0700583 // We don't use a ref-counted pointer here because we explicitly abort connections
584 // during unregistration which causes the connection's outbound queue to be cleared
585 // and the connection itself to be deactivated.
Jeff Browne839a582010-04-22 18:58:52 -0700586 Vector<Connection*> mActiveConnections;
587
Jeff Brown51d45a72010-06-17 20:52:56 -0700588 // List of connections that have timed out. Only used by dispatchOnce()
589 // We don't use a ref-counted pointer here because it is not possible for a connection
590 // to be unregistered while processing timed out connections since we hold the lock for
591 // the duration.
592 Vector<Connection*> mTimedOutConnections;
593
Jeff Brown54bc2812010-06-15 01:31:58 -0700594 // Preallocated key and motion event objects used only to ask the input dispatcher policy
Jeff Browne839a582010-04-22 18:58:52 -0700595 // for the targets of an event that is to be dispatched.
596 KeyEvent mReusableKeyEvent;
597 MotionEvent mReusableMotionEvent;
598
599 // The input targets that were most recently identified for dispatch.
600 // If there is a synchronous event dispatch in progress, the current input targets will
601 // remain unchanged until the dispatch has completed or been aborted.
602 Vector<InputTarget> mCurrentInputTargets;
Jeff Brown54bc2812010-06-15 01:31:58 -0700603 bool mCurrentInputTargetsValid; // false while targets are being recomputed
Jeff Browne839a582010-04-22 18:58:52 -0700604
Jeff Brown51d45a72010-06-17 20:52:56 -0700605 // Event injection and synchronization.
606 Condition mInjectionResultAvailableCondition;
Jeff Brown51d45a72010-06-17 20:52:56 -0700607 EventEntry* createEntryFromInputEventLocked(const InputEvent* event);
608 void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
609
Jeff Brownf67c53e2010-07-28 15:48:59 -0700610 Condition mInjectionSyncFinishedCondition;
611 void decrementPendingSyncDispatchesLocked(EventEntry* entry);
612
Jeff Brown542412c2010-08-18 15:51:08 -0700613 // Throttling state.
614 struct ThrottleState {
615 nsecs_t minTimeBetweenEvents;
616
617 nsecs_t lastEventTime;
618 int32_t lastDeviceId;
619 uint32_t lastSource;
620
621 uint32_t originalSampleCount; // only collected during debugging
622 } mThrottleState;
623
Jeff Browne839a582010-04-22 18:58:52 -0700624 // Key repeat tracking.
625 // XXX Move this up to the input reader instead.
626 struct KeyRepeatState {
627 KeyEntry* lastKeyEntry; // or null if no repeat
628 nsecs_t nextRepeatTime;
629 } mKeyRepeatState;
630
631 void resetKeyRepeatLocked();
632
Jeff Brown54bc2812010-06-15 01:31:58 -0700633 // Deferred command processing.
634 bool runCommandsLockedInterruptible();
635 CommandEntry* postCommandLocked(Command command);
636
Jeff Browne839a582010-04-22 18:58:52 -0700637 // Process events that have just been dequeued from the head of the input queue.
Jeff Brown54bc2812010-06-15 01:31:58 -0700638 void processConfigurationChangedLockedInterruptible(
639 nsecs_t currentTime, ConfigurationChangedEntry* entry);
640 void processKeyLockedInterruptible(
641 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout);
642 void processKeyRepeatLockedInterruptible(
643 nsecs_t currentTime, nsecs_t keyRepeatTimeout);
644 void processMotionLockedInterruptible(
645 nsecs_t currentTime, MotionEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700646
647 // Identify input targets for an event and dispatch to them.
Jeff Brown54bc2812010-06-15 01:31:58 -0700648 void identifyInputTargetsAndDispatchKeyLockedInterruptible(
649 nsecs_t currentTime, KeyEntry* entry);
650 void identifyInputTargetsAndDispatchMotionLockedInterruptible(
651 nsecs_t currentTime, MotionEntry* entry);
652 void dispatchEventToCurrentInputTargetsLocked(
653 nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
Jeff Browne839a582010-04-22 18:58:52 -0700654
655 // Manage the dispatch cycle for a single connection.
Jeff Brown51d45a72010-06-17 20:52:56 -0700656 // These methods are deliberately not Interruptible because doing all of the work
657 // with the mutex held makes it easier to ensure that connection invariants are maintained.
658 // If needed, the methods post commands to run later once the critical bits are done.
659 void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700660 EventEntry* eventEntry, const InputTarget* inputTarget,
661 bool resumeWithAppendedMotionSample);
Jeff Brown51d45a72010-06-17 20:52:56 -0700662 void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
663 void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
664 void timeoutDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
665 void resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
666 const sp<Connection>& connection, nsecs_t newTimeout);
667 void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700668 bool broken);
669 static bool handleReceiveCallback(int receiveFd, int events, void* data);
670
671 // Add or remove a connection to the mActiveConnections vector.
672 void activateConnectionLocked(Connection* connection);
673 void deactivateConnectionLocked(Connection* connection);
674
675 // Interesting events that we might like to log or tell the framework about.
Jeff Brown54bc2812010-06-15 01:31:58 -0700676 void onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700677 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700678 void onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700679 nsecs_t currentTime, const sp<Connection>& connection, bool recoveredFromANR);
Jeff Brown54bc2812010-06-15 01:31:58 -0700680 void onDispatchCycleANRLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700681 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700682 void onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700683 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700684
Jeff Brown51d45a72010-06-17 20:52:56 -0700685 // Outbound policy interactions.
Jeff Brown54bc2812010-06-15 01:31:58 -0700686 void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
687 void doNotifyInputChannelANRLockedInterruptible(CommandEntry* commandEntry);
688 void doNotifyInputChannelRecoveredFromANRLockedInterruptible(CommandEntry* commandEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700689};
690
691/* Enqueues and dispatches input events, endlessly. */
692class InputDispatcherThread : public Thread {
693public:
694 explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
695 ~InputDispatcherThread();
696
697private:
698 virtual bool threadLoop();
699
700 sp<InputDispatcherInterface> mDispatcher;
701};
702
703} // namespace android
704
705#endif // _UI_INPUT_DISPATCHER_PRIV_H