blob: aed4fa112b145d1610326688f3151d7a0527d50d [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;
Jeff Brown542412c2010-08-18 15:51:08 -0700162
163 /* Gets the maximum suggested event delivery rate per second.
164 * This value is used to throttle motion event movement actions on a per-device
165 * basis. It is not intended to be a hard limit.
166 */
167 virtual int32_t getMaxEventsPerSecond() = 0;
Jeff Brown54bc2812010-06-15 01:31:58 -0700168};
169
170
Jeff Browne839a582010-04-22 18:58:52 -0700171/* Notifies the system about input events generated by the input reader.
172 * The dispatcher is expected to be mostly asynchronous. */
173class InputDispatcherInterface : public virtual RefBase {
174protected:
175 InputDispatcherInterface() { }
176 virtual ~InputDispatcherInterface() { }
177
178public:
179 /* Runs a single iteration of the dispatch loop.
180 * Nominally processes one queued event, a timeout, or a response from an input consumer.
181 *
182 * This method should only be called on the input dispatcher thread.
183 */
184 virtual void dispatchOnce() = 0;
185
186 /* Notifies the dispatcher about new events.
Jeff Browne839a582010-04-22 18:58:52 -0700187 *
188 * These methods should only be called on the input reader thread.
189 */
Jeff Brown54bc2812010-06-15 01:31:58 -0700190 virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
Jeff Browne839a582010-04-22 18:58:52 -0700191 virtual void notifyAppSwitchComing(nsecs_t eventTime) = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700192 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700193 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
194 int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700195 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700196 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
197 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
198 float xPrecision, float yPrecision, nsecs_t downTime) = 0;
199
Jeff Brown51d45a72010-06-17 20:52:56 -0700200 /* Injects an input event and optionally waits for sync.
Jeff Brownf67c53e2010-07-28 15:48:59 -0700201 * The synchronization mode determines whether the method blocks while waiting for
202 * input injection to proceed.
Jeff Brown51d45a72010-06-17 20:52:56 -0700203 * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
204 *
205 * This method may be called on any thread (usually by the input manager).
206 */
207 virtual int32_t injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -0700208 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
Jeff Brown51d45a72010-06-17 20:52:56 -0700209
Jeff Brown50de30a2010-06-22 01:27:15 -0700210 /* Preempts input dispatch in progress by making pending synchronous
211 * dispatches asynchronous instead. This method is generally called during a focus
212 * transition from one application to the next so as to enable the new application
213 * to start receiving input as soon as possible without having to wait for the
214 * old application to finish up.
215 *
216 * This method may be called on any thread (usually by the input manager).
217 */
218 virtual void preemptInputDispatch() = 0;
219
Jeff Browne839a582010-04-22 18:58:52 -0700220 /* Registers or unregister input channels that may be used as targets for input events.
221 *
222 * These methods may be called on any thread (usually by the input manager).
223 */
224 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
225 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
226};
227
Jeff Brown54bc2812010-06-15 01:31:58 -0700228/* Dispatches events to input targets. Some functions of the input dispatcher, such as
229 * identifying input targets, are controlled by a separate policy object.
230 *
231 * IMPORTANT INVARIANT:
232 * Because the policy can potentially block or cause re-entrance into the input dispatcher,
233 * the input dispatcher never calls into the policy while holding its internal locks.
234 * The implementation is also carefully designed to recover from scenarios such as an
235 * input channel becoming unregistered while identifying input targets or processing timeouts.
236 *
237 * Methods marked 'Locked' must be called with the lock acquired.
238 *
239 * Methods marked 'LockedInterruptible' must be called with the lock acquired but
240 * may during the course of their execution release the lock, call into the policy, and
241 * then reacquire the lock. The caller is responsible for recovering gracefully.
242 *
243 * A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
244 */
Jeff Browne839a582010-04-22 18:58:52 -0700245class InputDispatcher : public InputDispatcherInterface {
246protected:
247 virtual ~InputDispatcher();
248
249public:
Jeff Brown54bc2812010-06-15 01:31:58 -0700250 explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
Jeff Browne839a582010-04-22 18:58:52 -0700251
252 virtual void dispatchOnce();
253
Jeff Brown54bc2812010-06-15 01:31:58 -0700254 virtual void notifyConfigurationChanged(nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700255 virtual void notifyAppSwitchComing(nsecs_t eventTime);
Jeff Brown5c1ed842010-07-14 18:48:53 -0700256 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700257 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
258 int32_t scanCode, int32_t metaState, nsecs_t downTime);
Jeff Brown5c1ed842010-07-14 18:48:53 -0700259 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700260 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
261 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
262 float xPrecision, float yPrecision, nsecs_t downTime);
263
Jeff Brown51d45a72010-06-17 20:52:56 -0700264 virtual int32_t injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -0700265 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -0700266
Jeff Brown50de30a2010-06-22 01:27:15 -0700267 virtual void preemptInputDispatch();
268
Jeff Browne839a582010-04-22 18:58:52 -0700269 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
270 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
271
272private:
273 template <typename T>
274 struct Link {
275 T* next;
276 T* prev;
277 };
278
279 struct EventEntry : Link<EventEntry> {
280 enum {
281 TYPE_SENTINEL,
282 TYPE_CONFIGURATION_CHANGED,
283 TYPE_KEY,
284 TYPE_MOTION
285 };
286
287 int32_t refCount;
288 int32_t type;
289 nsecs_t eventTime;
Jeff Brown54bc2812010-06-15 01:31:58 -0700290
Jeff Brownf67c53e2010-07-28 15:48:59 -0700291 int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
292 bool injectionIsAsync; // set to true if injection is not waiting for the result
293 int32_t injectorPid; // -1 if not injected
294 int32_t injectorUid; // -1 if not injected
Jeff Brown51d45a72010-06-17 20:52:56 -0700295
Jeff Brown54bc2812010-06-15 01:31:58 -0700296 bool dispatchInProgress; // initially false, set to true while dispatching
Jeff Brownf67c53e2010-07-28 15:48:59 -0700297 int32_t pendingSyncDispatches; // the number of synchronous dispatches in progress
Jeff Brown51d45a72010-06-17 20:52:56 -0700298
299 inline bool isInjected() { return injectorPid >= 0; }
Jeff Browne839a582010-04-22 18:58:52 -0700300 };
301
302 struct ConfigurationChangedEntry : EventEntry {
Jeff Browne839a582010-04-22 18:58:52 -0700303 };
304
305 struct KeyEntry : EventEntry {
306 int32_t deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700307 int32_t source;
Jeff Browne839a582010-04-22 18:58:52 -0700308 uint32_t policyFlags;
309 int32_t action;
310 int32_t flags;
311 int32_t keyCode;
312 int32_t scanCode;
313 int32_t metaState;
314 int32_t repeatCount;
315 nsecs_t downTime;
316 };
317
318 struct MotionSample {
319 MotionSample* next;
320
321 nsecs_t eventTime;
322 PointerCoords pointerCoords[MAX_POINTERS];
323 };
324
325 struct MotionEntry : EventEntry {
326 int32_t deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700327 int32_t source;
Jeff Browne839a582010-04-22 18:58:52 -0700328 uint32_t policyFlags;
329 int32_t action;
330 int32_t metaState;
331 int32_t edgeFlags;
332 float xPrecision;
333 float yPrecision;
334 nsecs_t downTime;
335 uint32_t pointerCount;
336 int32_t pointerIds[MAX_POINTERS];
337
338 // Linked list of motion samples associated with this motion event.
339 MotionSample firstSample;
340 MotionSample* lastSample;
Jeff Brown542412c2010-08-18 15:51:08 -0700341
342 uint32_t countSamples() const;
Jeff Browne839a582010-04-22 18:58:52 -0700343 };
344
Jeff Brown54bc2812010-06-15 01:31:58 -0700345 // Tracks the progress of dispatching a particular event to a particular connection.
Jeff Browne839a582010-04-22 18:58:52 -0700346 struct DispatchEntry : Link<DispatchEntry> {
347 EventEntry* eventEntry; // the event to dispatch
348 int32_t targetFlags;
349 float xOffset;
350 float yOffset;
351 nsecs_t timeout;
352
353 // True if dispatch has started.
354 bool inProgress;
355
356 // For motion events:
357 // Pointer to the first motion sample to dispatch in this cycle.
358 // Usually NULL to indicate that the list of motion samples begins at
359 // MotionEntry::firstSample. Otherwise, some samples were dispatched in a previous
360 // cycle and this pointer indicates the location of the first remainining sample
361 // to dispatch during the current cycle.
362 MotionSample* headMotionSample;
363 // Pointer to a motion sample to dispatch in the next cycle if the dispatcher was
364 // unable to send all motion samples during this cycle. On the next cycle,
365 // headMotionSample will be initialized to tailMotionSample and tailMotionSample
366 // will be set to NULL.
367 MotionSample* tailMotionSample;
Jeff Brownf67c53e2010-07-28 15:48:59 -0700368
369 inline bool isSyncTarget() {
370 return targetFlags & InputTarget::FLAG_SYNC;
371 }
Jeff Browne839a582010-04-22 18:58:52 -0700372 };
373
Jeff Brown54bc2812010-06-15 01:31:58 -0700374 // A command entry captures state and behavior for an action to be performed in the
375 // dispatch loop after the initial processing has taken place. It is essentially
376 // a kind of continuation used to postpone sensitive policy interactions to a point
377 // in the dispatch loop where it is safe to release the lock (generally after finishing
378 // the critical parts of the dispatch cycle).
379 //
380 // The special thing about commands is that they can voluntarily release and reacquire
381 // the dispatcher lock at will. Initially when the command starts running, the
382 // dispatcher lock is held. However, if the command needs to call into the policy to
383 // do some work, it can release the lock, do the work, then reacquire the lock again
384 // before returning.
385 //
386 // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
387 // never calls into the policy while holding its lock.
388 //
389 // Commands are implicitly 'LockedInterruptible'.
390 struct CommandEntry;
391 typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
392
Jeff Brown51d45a72010-06-17 20:52:56 -0700393 class Connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700394 struct CommandEntry : Link<CommandEntry> {
395 CommandEntry();
396 ~CommandEntry();
397
398 Command command;
399
400 // parameters for the command (usage varies by command)
Jeff Brown51d45a72010-06-17 20:52:56 -0700401 sp<Connection> connection;
Jeff Brown54bc2812010-06-15 01:31:58 -0700402 };
403
404 // Generic queue implementation.
Jeff Browne839a582010-04-22 18:58:52 -0700405 template <typename T>
406 struct Queue {
407 T head;
408 T tail;
409
410 inline Queue() {
411 head.prev = NULL;
412 head.next = & tail;
413 tail.prev = & head;
414 tail.next = NULL;
415 }
416
417 inline bool isEmpty() {
418 return head.next == & tail;
419 }
420
421 inline void enqueueAtTail(T* entry) {
422 T* last = tail.prev;
423 last->next = entry;
424 entry->prev = last;
425 entry->next = & tail;
426 tail.prev = entry;
427 }
428
429 inline void enqueueAtHead(T* entry) {
430 T* first = head.next;
431 head.next = entry;
432 entry->prev = & head;
433 entry->next = first;
434 first->prev = entry;
435 }
436
437 inline void dequeue(T* entry) {
438 entry->prev->next = entry->next;
439 entry->next->prev = entry->prev;
440 }
441
442 inline T* dequeueAtHead() {
443 T* first = head.next;
444 dequeue(first);
445 return first;
446 }
447 };
448
449 /* Allocates queue entries and performs reference counting as needed. */
450 class Allocator {
451 public:
452 Allocator();
453
Jeff Brown51d45a72010-06-17 20:52:56 -0700454 ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
455 KeyEntry* obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700456 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -0700457 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
458 int32_t repeatCount, nsecs_t downTime);
459 MotionEntry* obtainMotionEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700460 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -0700461 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
462 nsecs_t downTime, uint32_t pointerCount,
463 const int32_t* pointerIds, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700464 DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700465 CommandEntry* obtainCommandEntry(Command command);
Jeff Browne839a582010-04-22 18:58:52 -0700466
467 void releaseEventEntry(EventEntry* entry);
468 void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
469 void releaseKeyEntry(KeyEntry* entry);
470 void releaseMotionEntry(MotionEntry* entry);
471 void releaseDispatchEntry(DispatchEntry* entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700472 void releaseCommandEntry(CommandEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700473
474 void appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -0700475 nsecs_t eventTime, const PointerCoords* pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -0700476
477 private:
478 Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
479 Pool<KeyEntry> mKeyEntryPool;
480 Pool<MotionEntry> mMotionEntryPool;
481 Pool<MotionSample> mMotionSamplePool;
482 Pool<DispatchEntry> mDispatchEntryPool;
Jeff Brown54bc2812010-06-15 01:31:58 -0700483 Pool<CommandEntry> mCommandEntryPool;
Jeff Brown51d45a72010-06-17 20:52:56 -0700484
485 void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700486 };
487
488 /* Manages the dispatch state associated with a single input channel. */
489 class Connection : public RefBase {
490 protected:
491 virtual ~Connection();
492
493 public:
494 enum Status {
495 // Everything is peachy.
496 STATUS_NORMAL,
497 // An unrecoverable communication error has occurred.
498 STATUS_BROKEN,
499 // The client is not responding.
500 STATUS_NOT_RESPONDING,
501 // The input channel has been unregistered.
502 STATUS_ZOMBIE
503 };
504
505 Status status;
506 sp<InputChannel> inputChannel;
507 InputPublisher inputPublisher;
508 Queue<DispatchEntry> outboundQueue;
509 nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
510
511 nsecs_t lastEventTime; // the time when the event was originally captured
512 nsecs_t lastDispatchTime; // the time when the last event was dispatched
513 nsecs_t lastANRTime; // the time when the last ANR was recorded
514
515 explicit Connection(const sp<InputChannel>& inputChannel);
516
Jeff Brown54bc2812010-06-15 01:31:58 -0700517 inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
518
519 const char* getStatusLabel() const;
Jeff Browne839a582010-04-22 18:58:52 -0700520
521 // Finds a DispatchEntry in the outbound queue associated with the specified event.
522 // Returns NULL if not found.
523 DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const;
524
525 // Determine whether this connection has a pending synchronous dispatch target.
526 // Since there can only ever be at most one such target at a time, if there is one,
527 // it must be at the tail because nothing else can be enqueued after it.
528 inline bool hasPendingSyncTarget() {
Jeff Brownf67c53e2010-07-28 15:48:59 -0700529 return ! outboundQueue.isEmpty() && outboundQueue.tail.prev->isSyncTarget();
Jeff Browne839a582010-04-22 18:58:52 -0700530 }
531
532 // Gets the time since the current event was originally obtained from the input driver.
533 inline double getEventLatencyMillis(nsecs_t currentTime) {
534 return (currentTime - lastEventTime) / 1000000.0;
535 }
536
537 // Gets the time since the current event entered the outbound dispatch queue.
538 inline double getDispatchLatencyMillis(nsecs_t currentTime) {
539 return (currentTime - lastDispatchTime) / 1000000.0;
540 }
541
542 // Gets the time since the current event ANR was declared, if applicable.
543 inline double getANRLatencyMillis(nsecs_t currentTime) {
544 return (currentTime - lastANRTime) / 1000000.0;
545 }
546
547 status_t initialize();
Jeff Brown51d45a72010-06-17 20:52:56 -0700548
549 void setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout);
Jeff Browne839a582010-04-22 18:58:52 -0700550 };
551
Jeff Brown54bc2812010-06-15 01:31:58 -0700552 sp<InputDispatcherPolicyInterface> mPolicy;
Jeff Browne839a582010-04-22 18:58:52 -0700553
554 Mutex mLock;
555
Jeff Browne839a582010-04-22 18:58:52 -0700556 Allocator mAllocator;
Jeff Browne839a582010-04-22 18:58:52 -0700557 sp<PollLoop> mPollLoop;
558
Jeff Brown54bc2812010-06-15 01:31:58 -0700559 Queue<EventEntry> mInboundQueue;
560 Queue<CommandEntry> mCommandQueue;
561
Jeff Browne839a582010-04-22 18:58:52 -0700562 // All registered connections mapped by receive pipe file descriptor.
563 KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
564
Jeff Brown0cacb872010-08-17 15:59:26 -0700565 ssize_t getConnectionIndex(const sp<InputChannel>& inputChannel);
566
Jeff Browne839a582010-04-22 18:58:52 -0700567 // Active connections are connections that have a non-empty outbound queue.
Jeff Brown51d45a72010-06-17 20:52:56 -0700568 // We don't use a ref-counted pointer here because we explicitly abort connections
569 // during unregistration which causes the connection's outbound queue to be cleared
570 // and the connection itself to be deactivated.
Jeff Browne839a582010-04-22 18:58:52 -0700571 Vector<Connection*> mActiveConnections;
572
Jeff Brown51d45a72010-06-17 20:52:56 -0700573 // List of connections that have timed out. Only used by dispatchOnce()
574 // We don't use a ref-counted pointer here because it is not possible for a connection
575 // to be unregistered while processing timed out connections since we hold the lock for
576 // the duration.
577 Vector<Connection*> mTimedOutConnections;
578
Jeff Brown54bc2812010-06-15 01:31:58 -0700579 // Preallocated key and motion event objects used only to ask the input dispatcher policy
Jeff Browne839a582010-04-22 18:58:52 -0700580 // for the targets of an event that is to be dispatched.
581 KeyEvent mReusableKeyEvent;
582 MotionEvent mReusableMotionEvent;
583
584 // The input targets that were most recently identified for dispatch.
585 // If there is a synchronous event dispatch in progress, the current input targets will
586 // remain unchanged until the dispatch has completed or been aborted.
587 Vector<InputTarget> mCurrentInputTargets;
Jeff Brown54bc2812010-06-15 01:31:58 -0700588 bool mCurrentInputTargetsValid; // false while targets are being recomputed
Jeff Browne839a582010-04-22 18:58:52 -0700589
Jeff Brown51d45a72010-06-17 20:52:56 -0700590 // Event injection and synchronization.
591 Condition mInjectionResultAvailableCondition;
Jeff Brown51d45a72010-06-17 20:52:56 -0700592 EventEntry* createEntryFromInputEventLocked(const InputEvent* event);
593 void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
594
Jeff Brownf67c53e2010-07-28 15:48:59 -0700595 Condition mInjectionSyncFinishedCondition;
596 void decrementPendingSyncDispatchesLocked(EventEntry* entry);
597
Jeff Brown542412c2010-08-18 15:51:08 -0700598 // Throttling state.
599 struct ThrottleState {
600 nsecs_t minTimeBetweenEvents;
601
602 nsecs_t lastEventTime;
603 int32_t lastDeviceId;
604 uint32_t lastSource;
605
606 uint32_t originalSampleCount; // only collected during debugging
607 } mThrottleState;
608
Jeff Browne839a582010-04-22 18:58:52 -0700609 // Key repeat tracking.
610 // XXX Move this up to the input reader instead.
611 struct KeyRepeatState {
612 KeyEntry* lastKeyEntry; // or null if no repeat
613 nsecs_t nextRepeatTime;
614 } mKeyRepeatState;
615
616 void resetKeyRepeatLocked();
617
Jeff Brown54bc2812010-06-15 01:31:58 -0700618 // Deferred command processing.
619 bool runCommandsLockedInterruptible();
620 CommandEntry* postCommandLocked(Command command);
621
Jeff Browne839a582010-04-22 18:58:52 -0700622 // Process events that have just been dequeued from the head of the input queue.
Jeff Brown54bc2812010-06-15 01:31:58 -0700623 void processConfigurationChangedLockedInterruptible(
624 nsecs_t currentTime, ConfigurationChangedEntry* entry);
625 void processKeyLockedInterruptible(
626 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout);
627 void processKeyRepeatLockedInterruptible(
628 nsecs_t currentTime, nsecs_t keyRepeatTimeout);
629 void processMotionLockedInterruptible(
630 nsecs_t currentTime, MotionEntry* entry);
Jeff Browne839a582010-04-22 18:58:52 -0700631
632 // Identify input targets for an event and dispatch to them.
Jeff Brown54bc2812010-06-15 01:31:58 -0700633 void identifyInputTargetsAndDispatchKeyLockedInterruptible(
634 nsecs_t currentTime, KeyEntry* entry);
635 void identifyInputTargetsAndDispatchMotionLockedInterruptible(
636 nsecs_t currentTime, MotionEntry* entry);
637 void dispatchEventToCurrentInputTargetsLocked(
638 nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
Jeff Browne839a582010-04-22 18:58:52 -0700639
640 // Manage the dispatch cycle for a single connection.
Jeff Brown51d45a72010-06-17 20:52:56 -0700641 // These methods are deliberately not Interruptible because doing all of the work
642 // with the mutex held makes it easier to ensure that connection invariants are maintained.
643 // If needed, the methods post commands to run later once the critical bits are done.
644 void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700645 EventEntry* eventEntry, const InputTarget* inputTarget,
646 bool resumeWithAppendedMotionSample);
Jeff Brown51d45a72010-06-17 20:52:56 -0700647 void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
648 void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
649 void timeoutDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
650 void resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
651 const sp<Connection>& connection, nsecs_t newTimeout);
652 void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
Jeff Browne839a582010-04-22 18:58:52 -0700653 bool broken);
654 static bool handleReceiveCallback(int receiveFd, int events, void* data);
655
656 // Add or remove a connection to the mActiveConnections vector.
657 void activateConnectionLocked(Connection* connection);
658 void deactivateConnectionLocked(Connection* connection);
659
660 // Interesting events that we might like to log or tell the framework about.
Jeff Brown54bc2812010-06-15 01:31:58 -0700661 void onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700662 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700663 void onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700664 nsecs_t currentTime, const sp<Connection>& connection, bool recoveredFromANR);
Jeff Brown54bc2812010-06-15 01:31:58 -0700665 void onDispatchCycleANRLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700666 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700667 void onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -0700668 nsecs_t currentTime, const sp<Connection>& connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700669
Jeff Brown51d45a72010-06-17 20:52:56 -0700670 // Outbound policy interactions.
Jeff Brown54bc2812010-06-15 01:31:58 -0700671 void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
672 void doNotifyInputChannelANRLockedInterruptible(CommandEntry* commandEntry);
673 void doNotifyInputChannelRecoveredFromANRLockedInterruptible(CommandEntry* commandEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700674};
675
676/* Enqueues and dispatches input events, endlessly. */
677class InputDispatcherThread : public Thread {
678public:
679 explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
680 ~InputDispatcherThread();
681
682private:
683 virtual bool threadLoop();
684
685 sp<InputDispatcherInterface> mDispatcher;
686};
687
688} // namespace android
689
690#endif // _UI_INPUT_DISPATCHER_PRIV_H