blob: 711a658c359818865bca6e3de1d8f02c286d2fb0 [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
150 /* Gets the key repeat timeout or -1 if automatic key repeating is disabled. */
151 virtual nsecs_t getKeyRepeatTimeout() = 0;
152
Jeff Brown50de30a2010-06-22 01:27:15 -0700153 /* Waits for key event input targets to become available.
Jeff Brown51d45a72010-06-17 20:52:56 -0700154 * If the event is being injected, injectorPid and injectorUid should specify the
155 * process id and used id of the injecting application, otherwise they should both
156 * be -1.
157 * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
Jeff Brown50de30a2010-06-22 01:27:15 -0700158 virtual int32_t waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700159 int32_t injectorPid, int32_t injectorUid,
Jeff Brown54bc2812010-06-15 01:31:58 -0700160 Vector<InputTarget>& outTargets) = 0;
161
Jeff Brown50de30a2010-06-22 01:27:15 -0700162 /* Waits for motion event targets to become available.
Jeff Brown51d45a72010-06-17 20:52:56 -0700163 * If the event is being injected, injectorPid and injectorUid should specify the
164 * process id and used id of the injecting application, otherwise they should both
165 * be -1.
166 * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
Jeff Brown50de30a2010-06-22 01:27:15 -0700167 virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700168 int32_t injectorPid, int32_t injectorUid,
Jeff Brown54bc2812010-06-15 01:31:58 -0700169 Vector<InputTarget>& outTargets) = 0;
Jeff Brown542412c2010-08-18 15:51:08 -0700170
171 /* Gets the maximum suggested event delivery rate per second.
172 * This value is used to throttle motion event movement actions on a per-device
173 * basis. It is not intended to be a hard limit.
174 */
175 virtual int32_t getMaxEventsPerSecond() = 0;
Jeff Brown54bc2812010-06-15 01:31:58 -0700176};
177
178
Jeff Browne839a582010-04-22 18:58:52 -0700179/* Notifies the system about input events generated by the input reader.
180 * The dispatcher is expected to be mostly asynchronous. */
181class InputDispatcherInterface : public virtual RefBase {
182protected:
183 InputDispatcherInterface() { }
184 virtual ~InputDispatcherInterface() { }
185
186public:
187 /* Runs a single iteration of the dispatch loop.
188 * Nominally processes one queued event, a timeout, or a response from an input consumer.
189 *
190 * This method should only be called on the input dispatcher thread.
191 */
192 virtual void dispatchOnce() = 0;
193
194 /* Notifies the dispatcher about new events.
Jeff Browne839a582010-04-22 18:58:52 -0700195 *
196 * These methods should only be called on the input reader thread.
197 */
Jeff Brown54bc2812010-06-15 01:31:58 -0700198 virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
Jeff Browne839a582010-04-22 18:58:52 -0700199 virtual void notifyAppSwitchComing(nsecs_t eventTime) = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700200 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700201 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
202 int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700203 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700204 uint32_t policyFlags, int32_t action, int32_t flags,
205 int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -0700206 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
207 float xPrecision, float yPrecision, nsecs_t downTime) = 0;
208
Jeff Brown51d45a72010-06-17 20:52:56 -0700209 /* Injects an input event and optionally waits for sync.
Jeff Brownf67c53e2010-07-28 15:48:59 -0700210 * The synchronization mode determines whether the method blocks while waiting for
211 * input injection to proceed.
Jeff Brown51d45a72010-06-17 20:52:56 -0700212 * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
213 *
214 * This method may be called on any thread (usually by the input manager).
215 */
216 virtual int32_t injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -0700217 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
Jeff Brown51d45a72010-06-17 20:52:56 -0700218
Jeff Brown50de30a2010-06-22 01:27:15 -0700219 /* Preempts input dispatch in progress by making pending synchronous
220 * dispatches asynchronous instead. This method is generally called during a focus
221 * transition from one application to the next so as to enable the new application
222 * to start receiving input as soon as possible without having to wait for the
223 * old application to finish up.
224 *
225 * This method may be called on any thread (usually by the input manager).
226 */
227 virtual void preemptInputDispatch() = 0;
228
Jeff Browne839a582010-04-22 18:58:52 -0700229 /* Registers or unregister input channels that may be used as targets for input events.
230 *
231 * These methods may be called on any thread (usually by the input manager).
232 */
233 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
234 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
235};
236
Jeff Brown54bc2812010-06-15 01:31:58 -0700237/* Dispatches events to input targets. Some functions of the input dispatcher, such as
238 * identifying input targets, are controlled by a separate policy object.
239 *
240 * IMPORTANT INVARIANT:
241 * Because the policy can potentially block or cause re-entrance into the input dispatcher,
242 * the input dispatcher never calls into the policy while holding its internal locks.
243 * The implementation is also carefully designed to recover from scenarios such as an
244 * input channel becoming unregistered while identifying input targets or processing timeouts.
245 *
246 * Methods marked 'Locked' must be called with the lock acquired.
247 *
248 * Methods marked 'LockedInterruptible' must be called with the lock acquired but
249 * may during the course of their execution release the lock, call into the policy, and
250 * then reacquire the lock. The caller is responsible for recovering gracefully.
251 *
252 * A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
253 */
Jeff Browne839a582010-04-22 18:58:52 -0700254class InputDispatcher : public InputDispatcherInterface {
255protected:
256 virtual ~InputDispatcher();
257
258public:
Jeff Brown54bc2812010-06-15 01:31:58 -0700259 explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
Jeff Browne839a582010-04-22 18:58:52 -0700260
261 virtual void dispatchOnce();
262
Jeff Brown54bc2812010-06-15 01:31:58 -0700263 virtual void notifyConfigurationChanged(nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700264 virtual void notifyAppSwitchComing(nsecs_t eventTime);
Jeff Brown5c1ed842010-07-14 18:48:53 -0700265 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700266 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
267 int32_t scanCode, int32_t metaState, nsecs_t downTime);
Jeff Brown5c1ed842010-07-14 18:48:53 -0700268 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700269 uint32_t policyFlags, int32_t action, int32_t flags,
270 int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -0700271 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
272 float xPrecision, float yPrecision, nsecs_t downTime);
273
Jeff Brown51d45a72010-06-17 20:52:56 -0700274 virtual int32_t injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -0700275 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -0700276
Jeff Brown50de30a2010-06-22 01:27:15 -0700277 virtual void preemptInputDispatch();
278
Jeff Browne839a582010-04-22 18:58:52 -0700279 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
280 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
281
282private:
283 template <typename T>
284 struct Link {
285 T* next;
286 T* prev;
287 };
288
289 struct EventEntry : Link<EventEntry> {
290 enum {
291 TYPE_SENTINEL,
292 TYPE_CONFIGURATION_CHANGED,
293 TYPE_KEY,
294 TYPE_MOTION
295 };
296
297 int32_t refCount;
298 int32_t type;
299 nsecs_t eventTime;
Jeff Brown54bc2812010-06-15 01:31:58 -0700300
Jeff Brownf67c53e2010-07-28 15:48:59 -0700301 int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
302 bool injectionIsAsync; // set to true if injection is not waiting for the result
303 int32_t injectorPid; // -1 if not injected
304 int32_t injectorUid; // -1 if not injected
Jeff Brown51d45a72010-06-17 20:52:56 -0700305
Jeff Brown54bc2812010-06-15 01:31:58 -0700306 bool dispatchInProgress; // initially false, set to true while dispatching
Jeff Brownf67c53e2010-07-28 15:48:59 -0700307 int32_t pendingSyncDispatches; // the number of synchronous dispatches in progress
Jeff Brown51d45a72010-06-17 20:52:56 -0700308
309 inline bool isInjected() { return injectorPid >= 0; }
Jeff Browne839a582010-04-22 18:58:52 -0700310 };
311
312 struct ConfigurationChangedEntry : EventEntry {
Jeff Browne839a582010-04-22 18:58:52 -0700313 };
314
315 struct KeyEntry : EventEntry {
316 int32_t deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700317 int32_t source;
Jeff Browne839a582010-04-22 18:58:52 -0700318 uint32_t policyFlags;
319 int32_t action;
320 int32_t flags;
321 int32_t keyCode;
322 int32_t scanCode;
323 int32_t metaState;
324 int32_t repeatCount;
325 nsecs_t downTime;
326 };
327
328 struct MotionSample {
329 MotionSample* next;
330
331 nsecs_t eventTime;
332 PointerCoords pointerCoords[MAX_POINTERS];
333 };
334
335 struct MotionEntry : EventEntry {
336 int32_t deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700337 int32_t source;
Jeff Browne839a582010-04-22 18:58:52 -0700338 uint32_t policyFlags;
339 int32_t action;
Jeff Brownaf30ff62010-09-01 17:01:00 -0700340 int32_t flags;
Jeff Browne839a582010-04-22 18:58:52 -0700341 int32_t metaState;
342 int32_t edgeFlags;
343 float xPrecision;
344 float yPrecision;
345 nsecs_t downTime;
346 uint32_t pointerCount;
347 int32_t pointerIds[MAX_POINTERS];
348
349 // Linked list of motion samples associated with this motion event.
350 MotionSample firstSample;
351 MotionSample* lastSample;
Jeff Brown542412c2010-08-18 15:51:08 -0700352
353 uint32_t countSamples() const;
Jeff Browne839a582010-04-22 18:58:52 -0700354 };
355
Jeff Brown54bc2812010-06-15 01:31:58 -0700356 // Tracks the progress of dispatching a particular event to a particular connection.
Jeff Browne839a582010-04-22 18:58:52 -0700357 struct DispatchEntry : Link<DispatchEntry> {
358 EventEntry* eventEntry; // the event to dispatch
359 int32_t targetFlags;
360 float xOffset;
361 float yOffset;
362 nsecs_t timeout;
363
364 // True if dispatch has started.
365 bool inProgress;
366
367 // For motion events:
368 // Pointer to the first motion sample to dispatch in this cycle.
369 // Usually NULL to indicate that the list of motion samples begins at
370 // MotionEntry::firstSample. Otherwise, some samples were dispatched in a previous
371 // cycle and this pointer indicates the location of the first remainining sample
372 // to dispatch during the current cycle.
373 MotionSample* headMotionSample;
374 // Pointer to a motion sample to dispatch in the next cycle if the dispatcher was
375 // unable to send all motion samples during this cycle. On the next cycle,
376 // headMotionSample will be initialized to tailMotionSample and tailMotionSample
377 // will be set to NULL.
378 MotionSample* tailMotionSample;
Jeff Brownf67c53e2010-07-28 15:48:59 -0700379
380 inline bool isSyncTarget() {
381 return targetFlags & InputTarget::FLAG_SYNC;
382 }
Jeff Browne839a582010-04-22 18:58:52 -0700383 };
384
Jeff Brown54bc2812010-06-15 01:31:58 -0700385 // A command entry captures state and behavior for an action to be performed in the
386 // dispatch loop after the initial processing has taken place. It is essentially
387 // a kind of continuation used to postpone sensitive policy interactions to a point
388 // in the dispatch loop where it is safe to release the lock (generally after finishing
389 // the critical parts of the dispatch cycle).
390 //
391 // The special thing about commands is that they can voluntarily release and reacquire
392 // the dispatcher lock at will. Initially when the command starts running, the
393 // dispatcher lock is held. However, if the command needs to call into the policy to
394 // do some work, it can release the lock, do the work, then reacquire the lock again
395 // before returning.
396 //
397 // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
398 // never calls into the policy while holding its lock.
399 //
400 // Commands are implicitly 'LockedInterruptible'.
401 struct CommandEntry;
402 typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
403
Jeff Brown51d45a72010-06-17 20:52:56 -0700404 class Connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700405 struct CommandEntry : Link<CommandEntry> {
406 CommandEntry();
407 ~CommandEntry();
408
409 Command command;
410
411 // parameters for the command (usage varies by command)
Jeff Brown51d45a72010-06-17 20:52:56 -0700412 sp<Connection> connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700413 };
414
415 // Generic queue implementation.
Jeff Browne839a582010-04-22 18:58:52 -0700416 template <typename T>
417 struct Queue {
418 T head;
419 T tail;
420
421 inline Queue() {
422 head.prev = NULL;
423 head.next = & tail;
424 tail.prev = & head;
425 tail.next = NULL;
426 }
427
428 inline bool isEmpty() {
429 return head.next == & tail;
430 }
431
432 inline void enqueueAtTail(T* entry) {
433 T* last = tail.prev;
434 last->next = entry;
435 entry->prev = last;
436 entry->next = & tail;
437 tail.prev = entry;
438 }
439
440 inline void enqueueAtHead(T* entry) {
441 T* first = head.next;
442 head.next = entry;
443 entry->prev = & head;
444 entry->next = first;
445 first->prev = entry;
446 }
447
448 inline void dequeue(T* entry) {
449 entry->prev->next = entry->next;
450 entry->next->prev = entry->prev;
451 }
452
453 inline T* dequeueAtHead() {
454 T* first = head.next;
455 dequeue(first);
456 return first;
457 }
458 };
459
460 /* Allocates queue entries and performs reference counting as needed. */
461 class Allocator {
462 public:
463 Allocator();
464
Jeff Brown51d45a72010-06-17 20:52:56 -0700465 ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
466 KeyEntry* obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700467 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -0700468 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
469 int32_t repeatCount, nsecs_t downTime);
470 MotionEntry* obtainMotionEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700471 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700472 int32_t flags, int32_t metaState, int32_t edgeFlags,
473 float xPrecision, float yPrecision,
Jeff Brown51d45a72010-06-17 20:52:56 -0700474 nsecs_t downTime, uint32_t pointerCount,
475 const int32_t* pointerIds, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700476 DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700477 CommandEntry* obtainCommandEntry(Command command);
Jeff Browne839a582010-04-22 18:58:52 -0700478
479 void releaseEventEntry(EventEntry* entry);
480 void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
481 void releaseKeyEntry(KeyEntry* entry);
482 void releaseMotionEntry(MotionEntry* entry);
483 void releaseDispatchEntry(DispatchEntry* entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700484 void releaseCommandEntry(CommandEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700485
486 void appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -0700487 nsecs_t eventTime, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700488
489 private:
490 Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
491 Pool<KeyEntry> mKeyEntryPool;
492 Pool<MotionEntry> mMotionEntryPool;
493 Pool<MotionSample> mMotionSamplePool;
494 Pool<DispatchEntry> mDispatchEntryPool;
Jeff Brown54bc2812010-06-15 01:31:58 -0700495 Pool<CommandEntry> mCommandEntryPool;
Jeff Brown51d45a72010-06-17 20:52:56 -0700496
497 void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700498 };
499
500 /* Manages the dispatch state associated with a single input channel. */
501 class Connection : public RefBase {
502 protected:
503 virtual ~Connection();
504
505 public:
506 enum Status {
507 // Everything is peachy.
508 STATUS_NORMAL,
509 // An unrecoverable communication error has occurred.
510 STATUS_BROKEN,
511 // The client is not responding.
512 STATUS_NOT_RESPONDING,
513 // The input channel has been unregistered.
514 STATUS_ZOMBIE
515 };
516
517 Status status;
518 sp<InputChannel> inputChannel;
519 InputPublisher inputPublisher;
520 Queue<DispatchEntry> outboundQueue;
521 nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
522
523 nsecs_t lastEventTime; // the time when the event was originally captured
524 nsecs_t lastDispatchTime; // the time when the last event was dispatched
525 nsecs_t lastANRTime; // the time when the last ANR was recorded
526
527 explicit Connection(const sp<InputChannel>& inputChannel);
528
Jeff Brown54bc2812010-06-15 01:31:58 -0700529 inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
530
531 const char* getStatusLabel() const;
Jeff Browne839a582010-04-22 18:58:52 -0700532
533 // Finds a DispatchEntry in the outbound queue associated with the specified event.
534 // Returns NULL if not found.
535 DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const;
536
537 // Determine whether this connection has a pending synchronous dispatch target.
538 // Since there can only ever be at most one such target at a time, if there is one,
539 // it must be at the tail because nothing else can be enqueued after it.
540 inline bool hasPendingSyncTarget() {
Jeff Brownf67c53e2010-07-28 15:48:59 -0700541 return ! outboundQueue.isEmpty() && outboundQueue.tail.prev->isSyncTarget();
Jeff Browne839a582010-04-22 18:58:52 -0700542 }
543
544 // Gets the time since the current event was originally obtained from the input driver.
545 inline double getEventLatencyMillis(nsecs_t currentTime) {
546 return (currentTime - lastEventTime) / 1000000.0;
547 }
548
549 // Gets the time since the current event entered the outbound dispatch queue.
550 inline double getDispatchLatencyMillis(nsecs_t currentTime) {
551 return (currentTime - lastDispatchTime) / 1000000.0;
552 }
553
554 // Gets the time since the current event ANR was declared, if applicable.
555 inline double getANRLatencyMillis(nsecs_t currentTime) {
556 return (currentTime - lastANRTime) / 1000000.0;
557 }
558
559 status_t initialize();
Jeff Brown51d45a72010-06-17 20:52:56 -0700560
561 void setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout);
Jeff Browne839a582010-04-22 18:58:52 -0700562 };
563
Jeff Brown54bc2812010-06-15 01:31:58 -0700564 sp<InputDispatcherPolicyInterface> mPolicy;
Jeff Browne839a582010-04-22 18:58:52 -0700565
566 Mutex mLock;
567
Jeff Browne839a582010-04-22 18:58:52 -0700568 Allocator mAllocator;
Jeff Browne839a582010-04-22 18:58:52 -0700569 sp<PollLoop> mPollLoop;
570
Jeff Brown54bc2812010-06-15 01:31:58 -0700571 Queue<EventEntry> mInboundQueue;
572 Queue<CommandEntry> mCommandQueue;
573
Jeff Browne839a582010-04-22 18:58:52 -0700574 // All registered connections mapped by receive pipe file descriptor.
575 KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
576
Jeff Brown0cacb872010-08-17 15:59:26 -0700577 ssize_t getConnectionIndex(const sp<InputChannel>& inputChannel);
578
Jeff Browne839a582010-04-22 18:58:52 -0700579 // Active connections are connections that have a non-empty outbound queue.
Jeff Brown51d45a72010-06-17 20:52:56 -0700580 // We don't use a ref-counted pointer here because we explicitly abort connections
581 // during unregistration which causes the connection's outbound queue to be cleared
582 // and the connection itself to be deactivated.
Jeff Browne839a582010-04-22 18:58:52 -0700583 Vector<Connection*> mActiveConnections;
584
Jeff Brown51d45a72010-06-17 20:52:56 -0700585 // List of connections that have timed out. Only used by dispatchOnce()
586 // We don't use a ref-counted pointer here because it is not possible for a connection
587 // to be unregistered while processing timed out connections since we hold the lock for
588 // the duration.
589 Vector<Connection*> mTimedOutConnections;
590
Jeff Brown54bc2812010-06-15 01:31:58 -0700591 // Preallocated key and motion event objects used only to ask the input dispatcher policy
Jeff Browne839a582010-04-22 18:58:52 -0700592 // for the targets of an event that is to be dispatched.
593 KeyEvent mReusableKeyEvent;
594 MotionEvent mReusableMotionEvent;
595
596 // The input targets that were most recently identified for dispatch.
597 // If there is a synchronous event dispatch in progress, the current input targets will
598 // remain unchanged until the dispatch has completed or been aborted.
599 Vector<InputTarget> mCurrentInputTargets;
Jeff Brown54bc2812010-06-15 01:31:58 -0700600 bool mCurrentInputTargetsValid; // false while targets are being recomputed
Jeff Browne839a582010-04-22 18:58:52 -0700601
Jeff Brown51d45a72010-06-17 20:52:56 -0700602 // Event injection and synchronization.
603 Condition mInjectionResultAvailableCondition;
Jeff Brown51d45a72010-06-17 20:52:56 -0700604 EventEntry* createEntryFromInputEventLocked(const InputEvent* event);
605 void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
606
Jeff Brownf67c53e2010-07-28 15:48:59 -0700607 Condition mInjectionSyncFinishedCondition;
608 void decrementPendingSyncDispatchesLocked(EventEntry* entry);
609
Jeff Brown542412c2010-08-18 15:51:08 -0700610 // Throttling state.
611 struct ThrottleState {
612 nsecs_t minTimeBetweenEvents;
613
614 nsecs_t lastEventTime;
615 int32_t lastDeviceId;
616 uint32_t lastSource;
617
618 uint32_t originalSampleCount; // only collected during debugging
619 } mThrottleState;
620
Jeff Browne839a582010-04-22 18:58:52 -0700621 // Key repeat tracking.
622 // XXX Move this up to the input reader instead.
623 struct KeyRepeatState {
624 KeyEntry* lastKeyEntry; // or null if no repeat
625 nsecs_t nextRepeatTime;
626 } mKeyRepeatState;
627
628 void resetKeyRepeatLocked();
629
Jeff Brown54bc2812010-06-15 01:31:58 -0700630 // Deferred command processing.
631 bool runCommandsLockedInterruptible();
632 CommandEntry* postCommandLocked(Command command);
633
Jeff Browne839a582010-04-22 18:58:52 -0700634 // Process events that have just been dequeued from the head of the input queue.
Jeff Brown54bc2812010-06-15 01:31:58 -0700635 void processConfigurationChangedLockedInterruptible(
636 nsecs_t currentTime, ConfigurationChangedEntry* entry);
637 void processKeyLockedInterruptible(
638 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout);
639 void processKeyRepeatLockedInterruptible(
640 nsecs_t currentTime, nsecs_t keyRepeatTimeout);
641 void processMotionLockedInterruptible(
642 nsecs_t currentTime, MotionEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700643
644 // Identify input targets for an event and dispatch to them.
Jeff Brown54bc2812010-06-15 01:31:58 -0700645 void identifyInputTargetsAndDispatchKeyLockedInterruptible(
646 nsecs_t currentTime, KeyEntry* entry);
647 void identifyInputTargetsAndDispatchMotionLockedInterruptible(
648 nsecs_t currentTime, MotionEntry* entry);
649 void dispatchEventToCurrentInputTargetsLocked(
650 nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
Jeff Browne839a582010-04-22 18:58:52 -0700651
652 // Manage the dispatch cycle for a single connection.
Jeff Brown51d45a72010-06-17 20:52:56 -0700653 // These methods are deliberately not Interruptible because doing all of the work
654 // with the mutex held makes it easier to ensure that connection invariants are maintained.
655 // If needed, the methods post commands to run later once the critical bits are done.
656 void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700657 EventEntry* eventEntry, const InputTarget* inputTarget,
658 bool resumeWithAppendedMotionSample);
Jeff Brown51d45a72010-06-17 20:52:56 -0700659 void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
660 void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
661 void timeoutDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
662 void resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
663 const sp<Connection>& connection, nsecs_t newTimeout);
664 void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700665 bool broken);
666 static bool handleReceiveCallback(int receiveFd, int events, void* data);
667
668 // Add or remove a connection to the mActiveConnections vector.
669 void activateConnectionLocked(Connection* connection);
670 void deactivateConnectionLocked(Connection* connection);
671
672 // Interesting events that we might like to log or tell the framework about.
Jeff Brown54bc2812010-06-15 01:31:58 -0700673 void onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700674 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700675 void onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700676 nsecs_t currentTime, const sp<Connection>& connection, bool recoveredFromANR);
Jeff Brown54bc2812010-06-15 01:31:58 -0700677 void onDispatchCycleANRLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700678 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700679 void onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700680 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700681
Jeff Brown51d45a72010-06-17 20:52:56 -0700682 // Outbound policy interactions.
Jeff Brown54bc2812010-06-15 01:31:58 -0700683 void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
684 void doNotifyInputChannelANRLockedInterruptible(CommandEntry* commandEntry);
685 void doNotifyInputChannelRecoveredFromANRLockedInterruptible(CommandEntry* commandEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700686};
687
688/* Enqueues and dispatches input events, endlessly. */
689class InputDispatcherThread : public Thread {
690public:
691 explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
692 ~InputDispatcherThread();
693
694private:
695 virtual bool threadLoop();
696
697 sp<InputDispatcherInterface> mDispatcher;
698};
699
700} // namespace android
701
702#endif // _UI_INPUT_DISPATCHER_PRIV_H