blob: 20935604e96fe4500e7dee36d7532beaec145f2c [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_READER_H
18#define _UI_INPUT_READER_H
19
20#include <ui/EventHub.h>
21#include <ui/Input.h>
Jeff Browne839a582010-04-22 18:58:52 -070022#include <ui/InputDispatcher.h>
23#include <utils/KeyedVector.h>
24#include <utils/threads.h>
25#include <utils/Timers.h>
26#include <utils/RefBase.h>
27#include <utils/String8.h>
28#include <utils/BitSet.h>
29
30#include <stddef.h>
31#include <unistd.h>
32
33/* Maximum pointer id value supported.
34 * (This is limited by our use of BitSet32 to track pointer assignments.) */
35#define MAX_POINTER_ID 32
36
Jeff Browne839a582010-04-22 18:58:52 -070037/* Maximum number of historical samples to average. */
38#define AVERAGING_HISTORY_SIZE 5
39
40
41namespace android {
42
43extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
44extern int32_t rotateKeyCode(int32_t keyCode, int32_t orientation);
45
46/*
47 * An input device structure tracks the state of a single input device.
48 *
49 * This structure is only used by ReaderThread and is not intended to be shared with
50 * DispatcherThread (because that would require locking). This works out fine because
51 * DispatcherThread is only interested in cooked event data anyways and does not need
52 * any of the low-level data from InputDevice.
53 */
54struct InputDevice {
55 struct AbsoluteAxisInfo {
56 int32_t minValue; // minimum value
57 int32_t maxValue; // maximum value
58 int32_t range; // range of values, equal to maxValue - minValue
59 int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8
60 int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
61 };
62
63 struct VirtualKey {
64 int32_t keyCode;
65 int32_t scanCode;
66 uint32_t flags;
67
68 // computed hit box, specified in touch screen coords based on known display size
69 int32_t hitLeft;
70 int32_t hitTop;
71 int32_t hitRight;
72 int32_t hitBottom;
73
74 inline bool isHit(int32_t x, int32_t y) const {
75 return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
76 }
77 };
78
79 struct KeyboardState {
80 struct Current {
81 int32_t metaState;
82 nsecs_t downTime; // time of most recent key down
83 } current;
84
85 void reset();
86 };
87
88 struct TrackballState {
89 struct Accumulator {
90 enum {
91 FIELD_BTN_MOUSE = 1,
92 FIELD_REL_X = 2,
93 FIELD_REL_Y = 4
94 };
95
96 uint32_t fields;
97
98 bool btnMouse;
99 int32_t relX;
100 int32_t relY;
101
102 inline void clear() {
103 fields = 0;
104 }
105
106 inline bool isDirty() {
107 return fields != 0;
108 }
109 } accumulator;
110
111 struct Current {
112 bool down;
113 nsecs_t downTime;
114 } current;
115
116 struct Precalculated {
117 float xScale;
118 float yScale;
119 float xPrecision;
120 float yPrecision;
121 } precalculated;
122
123 void reset();
124 };
125
126 struct SingleTouchScreenState {
127 struct Accumulator {
128 enum {
129 FIELD_BTN_TOUCH = 1,
130 FIELD_ABS_X = 2,
131 FIELD_ABS_Y = 4,
132 FIELD_ABS_PRESSURE = 8,
133 FIELD_ABS_TOOL_WIDTH = 16
134 };
135
136 uint32_t fields;
137
138 bool btnTouch;
139 int32_t absX;
140 int32_t absY;
141 int32_t absPressure;
142 int32_t absToolWidth;
143
144 inline void clear() {
145 fields = 0;
146 }
147
148 inline bool isDirty() {
149 return fields != 0;
150 }
151 } accumulator;
152
153 struct Current {
154 bool down;
155 int32_t x;
156 int32_t y;
157 int32_t pressure;
158 int32_t size;
159 } current;
160
161 void reset();
162 };
163
164 struct MultiTouchScreenState {
165 struct Accumulator {
166 enum {
167 FIELD_ABS_MT_POSITION_X = 1,
168 FIELD_ABS_MT_POSITION_Y = 2,
169 FIELD_ABS_MT_TOUCH_MAJOR = 4,
170 FIELD_ABS_MT_WIDTH_MAJOR = 8,
171 FIELD_ABS_MT_TRACKING_ID = 16
172 };
173
174 uint32_t pointerCount;
175 struct Pointer {
176 uint32_t fields;
177
178 int32_t absMTPositionX;
179 int32_t absMTPositionY;
180 int32_t absMTTouchMajor;
181 int32_t absMTWidthMajor;
182 int32_t absMTTrackingId;
183
184 inline void clear() {
185 fields = 0;
186 }
187 } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks
188
189 inline void clear() {
190 pointerCount = 0;
191 pointers[0].clear();
192 }
193
194 inline bool isDirty() {
195 return pointerCount != 0;
196 }
197 } accumulator;
198
199 void reset();
200 };
201
202 struct PointerData {
203 uint32_t id;
204 int32_t x;
205 int32_t y;
206 int32_t pressure;
207 int32_t size;
208 };
209
210 struct TouchData {
211 uint32_t pointerCount;
212 PointerData pointers[MAX_POINTERS];
213 BitSet32 idBits;
214 uint32_t idToIndex[MAX_POINTER_ID];
215
216 void copyFrom(const TouchData& other);
217
218 inline void clear() {
219 pointerCount = 0;
220 idBits.clear();
221 }
222 };
223
224 // common state used for both single-touch and multi-touch screens after the initial
225 // touch decoding has been performed
226 struct TouchScreenState {
227 Vector<VirtualKey> virtualKeys;
228
229 struct Parameters {
230 bool useBadTouchFilter;
231 bool useJumpyTouchFilter;
232 bool useAveragingTouchFilter;
233
234 AbsoluteAxisInfo xAxis;
235 AbsoluteAxisInfo yAxis;
236 AbsoluteAxisInfo pressureAxis;
237 AbsoluteAxisInfo sizeAxis;
238 } parameters;
239
240 // The touch data of the current sample being processed.
241 TouchData currentTouch;
242
243 // The touch data of the previous sample that was processed. This is updated
244 // incrementally while the current sample is being processed.
245 TouchData lastTouch;
246
247 // The time the primary pointer last went down.
248 nsecs_t downTime;
249
250 struct CurrentVirtualKeyState {
251 bool down;
252 nsecs_t downTime;
253 int32_t keyCode;
254 int32_t scanCode;
255 } currentVirtualKey;
256
257 struct AveragingTouchFilterState {
258 // Individual history tracks are stored by pointer id
259 uint32_t historyStart[MAX_POINTERS];
260 uint32_t historyEnd[MAX_POINTERS];
261 struct {
262 struct {
263 int32_t x;
264 int32_t y;
265 int32_t pressure;
266 } pointers[MAX_POINTERS];
267 } historyData[AVERAGING_HISTORY_SIZE];
268 } averagingTouchFilter;
269
270 struct JumpTouchFilterState {
271 int32_t jumpyPointsDropped;
272 } jumpyTouchFilter;
273
274 struct Precalculated {
275 float xScale;
276 float yScale;
277 float pressureScale;
278 float sizeScale;
279 } precalculated;
280
281 void reset();
282
283 bool applyBadTouchFilter();
284 bool applyJumpyTouchFilter();
285 void applyAveragingTouchFilter();
286 void calculatePointerIds();
287
288 bool isPointInsideDisplay(int32_t x, int32_t y) const;
289 };
290
291 InputDevice(int32_t id, uint32_t classes, String8 name);
292
293 int32_t id;
294 uint32_t classes;
295 String8 name;
296 bool ignored;
297
298 KeyboardState keyboard;
299 TrackballState trackball;
300 TouchScreenState touchScreen;
301 union {
302 SingleTouchScreenState singleTouchScreen;
303 MultiTouchScreenState multiTouchScreen;
304 };
305
306 void reset();
307
308 inline bool isKeyboard() const { return classes & INPUT_DEVICE_CLASS_KEYBOARD; }
309 inline bool isAlphaKey() const { return classes & INPUT_DEVICE_CLASS_ALPHAKEY; }
310 inline bool isTrackball() const { return classes & INPUT_DEVICE_CLASS_TRACKBALL; }
311 inline bool isDPad() const { return classes & INPUT_DEVICE_CLASS_DPAD; }
312 inline bool isSingleTouchScreen() const { return (classes
313 & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT))
314 == INPUT_DEVICE_CLASS_TOUCHSCREEN; }
315 inline bool isMultiTouchScreen() const { return classes
316 & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT; }
317 inline bool isTouchScreen() const { return classes
318 & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT); }
319};
320
321
Jeff Brown54bc2812010-06-15 01:31:58 -0700322/*
323 * Input reader policy interface.
324 *
325 * The input reader policy is used by the input reader to interact with the Window Manager
326 * and other system components.
327 *
328 * The actual implementation is partially supported by callbacks into the DVM
329 * via JNI. This interface is also mocked in the unit tests.
330 */
331class InputReaderPolicyInterface : public virtual RefBase {
332protected:
333 InputReaderPolicyInterface() { }
334 virtual ~InputReaderPolicyInterface() { }
335
336public:
337 /* Display orientations. */
338 enum {
339 ROTATION_0 = 0,
340 ROTATION_90 = 1,
341 ROTATION_180 = 2,
342 ROTATION_270 = 3
343 };
344
345 /* Actions returned by interceptXXX methods. */
346 enum {
347 // The input dispatcher should do nothing and discard the input unless other
348 // flags are set.
349 ACTION_NONE = 0,
350
351 // The input dispatcher should dispatch the input to the application.
352 ACTION_DISPATCH = 0x00000001,
353
354 // The input dispatcher should perform special filtering in preparation for
355 // a pending app switch.
356 ACTION_APP_SWITCH_COMING = 0x00000002,
357
358 // The input dispatcher should add POLICY_FLAG_WOKE_HERE to the policy flags it
359 // passes through the dispatch pipeline.
360 ACTION_WOKE_HERE = 0x00000004,
361
362 // The input dispatcher should add POLICY_FLAG_BRIGHT_HERE to the policy flags it
363 // passes through the dispatch pipeline.
Jeff Brown50de30a2010-06-22 01:27:15 -0700364 ACTION_BRIGHT_HERE = 0x00000008,
365
366 // The input dispatcher should add POLICY_FLAG_INTERCEPT_DISPATCH to the policy flags
367 // it passed through the dispatch pipeline.
368 ACTION_INTERCEPT_DISPATCH = 0x00000010
Jeff Brown54bc2812010-06-15 01:31:58 -0700369 };
370
371 /* Describes a virtual key. */
372 struct VirtualKeyDefinition {
373 int32_t scanCode;
374
375 // configured position data, specified in display coords
376 int32_t centerX;
377 int32_t centerY;
378 int32_t width;
379 int32_t height;
380 };
381
382 /* Gets information about the display with the specified id.
383 * Returns true if the display info is available, false otherwise.
384 */
385 virtual bool getDisplayInfo(int32_t displayId,
386 int32_t* width, int32_t* height, int32_t* orientation) = 0;
387
388 /* Provides feedback for a virtual key.
389 */
390 virtual void virtualKeyFeedback(nsecs_t when, int32_t deviceId,
391 int32_t action, int32_t flags, int32_t keyCode,
392 int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
393
394 /* Intercepts a key event.
395 * The policy can use this method as an opportunity to perform power management functions
396 * and early event preprocessing.
397 *
398 * Returns a policy action constant such as ACTION_DISPATCH.
399 */
400 virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
401 bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags) = 0;
402
403 /* Intercepts a trackball event.
404 * The policy can use this method as an opportunity to perform power management functions
405 * and early event preprocessing.
406 *
407 * Returns a policy action constant such as ACTION_DISPATCH.
408 */
409 virtual int32_t interceptTrackball(nsecs_t when, bool buttonChanged, bool buttonDown,
410 bool rolled) = 0;
411
412 /* Intercepts a touch event.
413 * The policy can use this method as an opportunity to perform power management functions
414 * and early event preprocessing.
415 *
416 * Returns a policy action constant such as ACTION_DISPATCH.
417 */
418 virtual int32_t interceptTouch(nsecs_t when) = 0;
419
420 /* Intercepts a switch event.
421 * The policy can use this method as an opportunity to perform power management functions
422 * and early event preprocessing.
423 *
424 * Switches are not dispatched to applications so this method should
425 * usually return ACTION_NONE.
426 */
427 virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) = 0;
428
429 /* Determines whether to turn on some hacks we have to improve the touch interaction with a
430 * certain device whose screen currently is not all that good.
431 */
432 virtual bool filterTouchEvents() = 0;
433
434 /* Determines whether to turn on some hacks to improve touch interaction with another device
435 * where touch coordinate data can get corrupted.
436 */
437 virtual bool filterJumpyTouchEvents() = 0;
438
439 /* Gets the configured virtual key definitions for an input device. */
440 virtual void getVirtualKeyDefinitions(const String8& deviceName,
441 Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0;
442
443 /* Gets the excluded device names for the platform. */
444 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
445};
446
447
448/* Processes raw input events and sends cooked event data to an input dispatcher. */
Jeff Browne839a582010-04-22 18:58:52 -0700449class InputReaderInterface : public virtual RefBase {
450protected:
451 InputReaderInterface() { }
452 virtual ~InputReaderInterface() { }
453
454public:
455 /* Runs a single iteration of the processing loop.
456 * Nominally reads and processes one incoming message from the EventHub.
457 *
458 * This method should be called on the input reader thread.
459 */
460 virtual void loopOnce() = 0;
461
462 /* Gets the current virtual key. Returns false if not down.
463 *
464 * This method may be called on any thread (usually by the input manager).
465 */
466 virtual bool getCurrentVirtualKey(int32_t* outKeyCode, int32_t* outScanCode) const = 0;
Jeff Brown54bc2812010-06-15 01:31:58 -0700467
468 /* Gets the current input device configuration.
469 *
470 * This method may be called on any thread (usually by the input manager).
471 */
472 virtual void getCurrentInputConfiguration(InputConfiguration* outConfiguration) const = 0;
473
474 /*
475 * Query current input state.
476 * deviceId may be -1 to search for the device automatically, filtered by class.
477 * deviceClasses may be -1 to ignore device class while searching.
478 */
479 virtual int32_t getCurrentScanCodeState(int32_t deviceId, int32_t deviceClasses,
480 int32_t scanCode) const = 0;
481 virtual int32_t getCurrentKeyCodeState(int32_t deviceId, int32_t deviceClasses,
482 int32_t keyCode) const = 0;
483 virtual int32_t getCurrentSwitchState(int32_t deviceId, int32_t deviceClasses,
484 int32_t sw) const = 0;
485
486 /* Determine whether physical keys exist for the given framework-domain key codes. */
487 virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const = 0;
Jeff Browne839a582010-04-22 18:58:52 -0700488};
489
Jeff Brown54bc2812010-06-15 01:31:58 -0700490
Jeff Browne839a582010-04-22 18:58:52 -0700491/* The input reader reads raw event data from the event hub and processes it into input events
Jeff Brown54bc2812010-06-15 01:31:58 -0700492 * that it sends to the input dispatcher. Some functions of the input reader, such as early
493 * event filtering in low power states, are controlled by a separate policy object.
494 *
495 * IMPORTANT INVARIANT:
496 * Because the policy can potentially block or cause re-entrance into the input reader,
497 * the input reader never calls into the policy while holding its internal locks.
Jeff Browne839a582010-04-22 18:58:52 -0700498 */
499class InputReader : public InputReaderInterface {
500public:
501 InputReader(const sp<EventHubInterface>& eventHub,
Jeff Brown54bc2812010-06-15 01:31:58 -0700502 const sp<InputReaderPolicyInterface>& policy,
Jeff Browne839a582010-04-22 18:58:52 -0700503 const sp<InputDispatcherInterface>& dispatcher);
504 virtual ~InputReader();
505
506 virtual void loopOnce();
507
508 virtual bool getCurrentVirtualKey(int32_t* outKeyCode, int32_t* outScanCode) const;
509
Jeff Brown54bc2812010-06-15 01:31:58 -0700510 virtual void getCurrentInputConfiguration(InputConfiguration* outConfiguration) const;
511
512 virtual int32_t getCurrentScanCodeState(int32_t deviceId, int32_t deviceClasses,
513 int32_t scanCode) const;
514 virtual int32_t getCurrentKeyCodeState(int32_t deviceId, int32_t deviceClasses,
515 int32_t keyCode) const;
516 virtual int32_t getCurrentSwitchState(int32_t deviceId, int32_t deviceClasses,
517 int32_t sw) const;
518
519 virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const;
520
Jeff Browne839a582010-04-22 18:58:52 -0700521private:
522 // Lock that must be acquired while manipulating state that may be concurrently accessed
523 // from other threads by input state query methods. It should be held for as short a
524 // time as possible.
525 //
526 // Exported state:
527 // - global virtual key code and scan code
528 // - device list and immutable properties of devices such as id, name, and class
529 // (but not other internal device state)
530 mutable Mutex mExportedStateLock;
531
Jeff Brown54bc2812010-06-15 01:31:58 -0700532 // current virtual key information (lock mExportedStateLock)
533 int32_t mExportedVirtualKeyCode;
534 int32_t mExportedVirtualScanCode;
535
536 // current input configuration (lock mExportedStateLock)
537 InputConfiguration mExportedInputConfiguration;
Jeff Browne839a582010-04-22 18:58:52 -0700538
539 // combined key meta state
540 int32_t mGlobalMetaState;
541
542 sp<EventHubInterface> mEventHub;
Jeff Brown54bc2812010-06-15 01:31:58 -0700543 sp<InputReaderPolicyInterface> mPolicy;
Jeff Browne839a582010-04-22 18:58:52 -0700544 sp<InputDispatcherInterface> mDispatcher;
545
546 KeyedVector<int32_t, InputDevice*> mDevices;
547
548 // display properties needed to translate touch screen coordinates into display coordinates
549 int32_t mDisplayOrientation;
550 int32_t mDisplayWidth;
551 int32_t mDisplayHeight;
552
553 // low-level input event decoding
554 void process(const RawEvent* rawEvent);
555 void handleDeviceAdded(const RawEvent* rawEvent);
556 void handleDeviceRemoved(const RawEvent* rawEvent);
557 void handleSync(const RawEvent* rawEvent);
558 void handleKey(const RawEvent* rawEvent);
559 void handleRelativeMotion(const RawEvent* rawEvent);
560 void handleAbsoluteMotion(const RawEvent* rawEvent);
561 void handleSwitch(const RawEvent* rawEvent);
562
563 // input policy processing and dispatch
564 void onKey(nsecs_t when, InputDevice* device, bool down,
565 int32_t keyCode, int32_t scanCode, uint32_t policyFlags);
Jeff Brown54bc2812010-06-15 01:31:58 -0700566 void onSwitch(nsecs_t when, InputDevice* device, int32_t switchCode, int32_t switchValue);
Jeff Browne839a582010-04-22 18:58:52 -0700567 void onSingleTouchScreenStateChanged(nsecs_t when, InputDevice* device);
568 void onMultiTouchScreenStateChanged(nsecs_t when, InputDevice* device);
569 void onTouchScreenChanged(nsecs_t when, InputDevice* device, bool havePointerIds);
570 void onTrackballStateChanged(nsecs_t when, InputDevice* device);
571 void onConfigurationChanged(nsecs_t when);
572
573 bool applyStandardInputDispatchPolicyActions(nsecs_t when,
574 int32_t policyActions, uint32_t* policyFlags);
575
576 bool consumeVirtualKeyTouches(nsecs_t when, InputDevice* device, uint32_t policyFlags);
577 void dispatchVirtualKey(nsecs_t when, InputDevice* device, uint32_t policyFlags,
578 int32_t keyEventAction, int32_t keyEventFlags);
579 void dispatchTouches(nsecs_t when, InputDevice* device, uint32_t policyFlags);
580 void dispatchTouch(nsecs_t when, InputDevice* device, uint32_t policyFlags,
581 InputDevice::TouchData* touch, BitSet32 idBits, int32_t motionEventAction);
582
583 // display
584 void resetDisplayProperties();
585 bool refreshDisplayProperties();
586
587 // device management
588 InputDevice* getDevice(int32_t deviceId);
589 InputDevice* getNonIgnoredDevice(int32_t deviceId);
590 void addDevice(nsecs_t when, int32_t deviceId);
591 void removeDevice(nsecs_t when, InputDevice* device);
592 void configureDevice(InputDevice* device);
593 void configureDeviceForCurrentDisplaySize(InputDevice* device);
594 void configureVirtualKeys(InputDevice* device);
595 void configureAbsoluteAxisInfo(InputDevice* device, int axis, const char* name,
596 InputDevice::AbsoluteAxisInfo* out);
Jeff Brown54bc2812010-06-15 01:31:58 -0700597 void configureExcludedDevices();
Jeff Browne839a582010-04-22 18:58:52 -0700598
599 // global meta state management for all devices
600 void resetGlobalMetaState();
601 int32_t globalMetaState();
602
603 // virtual key management
Jeff Brown54bc2812010-06-15 01:31:58 -0700604 void updateExportedVirtualKeyState();
605
606 // input configuration management
607 void updateExportedInputConfiguration();
Jeff Browne839a582010-04-22 18:58:52 -0700608};
609
610
611/* Reads raw events from the event hub and processes them, endlessly. */
612class InputReaderThread : public Thread {
613public:
614 InputReaderThread(const sp<InputReaderInterface>& reader);
615 virtual ~InputReaderThread();
616
617private:
618 sp<InputReaderInterface> mReader;
619
620 virtual bool threadLoop();
621};
622
623} // namespace android
624
625#endif // _UI_INPUT_READER_H