blob: 403afe7601d00dfc468762883a2d14316d2128b8 [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input reader.
5//
6#define LOG_TAG "InputReader"
7
8//#define LOG_NDEBUG 0
9
10// Log debug messages for each raw event received from the EventHub.
11#define DEBUG_RAW_EVENTS 0
12
13// Log debug messages about touch screen filtering hacks.
Jeff Brown50de30a2010-06-22 01:27:15 -070014#define DEBUG_HACKS 0
Jeff Browne839a582010-04-22 18:58:52 -070015
16// Log debug messages about virtual key processing.
Jeff Brown50de30a2010-06-22 01:27:15 -070017#define DEBUG_VIRTUAL_KEYS 0
Jeff Browne839a582010-04-22 18:58:52 -070018
19// Log debug messages about pointers.
Jeff Brown50de30a2010-06-22 01:27:15 -070020#define DEBUG_POINTERS 0
Jeff Browne839a582010-04-22 18:58:52 -070021
Jeff Brownf4a4ec22010-06-16 01:53:36 -070022// Log debug messages about pointer assignment calculations.
23#define DEBUG_POINTER_ASSIGNMENT 0
24
Jeff Browne839a582010-04-22 18:58:52 -070025#include <cutils/log.h>
26#include <ui/InputReader.h>
27
28#include <stddef.h>
29#include <unistd.h>
Jeff Browne839a582010-04-22 18:58:52 -070030#include <errno.h>
31#include <limits.h>
Jeff Brown5c1ed842010-07-14 18:48:53 -070032#include <math.h>
Jeff Browne839a582010-04-22 18:58:52 -070033
Jeff Brown54bc2812010-06-15 01:31:58 -070034/** Amount that trackball needs to move in order to generate a key event. */
35#define TRACKBALL_MOVEMENT_THRESHOLD 6
36
Jeff Brown54bc2812010-06-15 01:31:58 -070037
Jeff Browne839a582010-04-22 18:58:52 -070038namespace android {
39
40// --- Static Functions ---
41
42template<typename T>
43inline static T abs(const T& value) {
44 return value < 0 ? - value : value;
45}
46
47template<typename T>
48inline static T min(const T& a, const T& b) {
49 return a < b ? a : b;
50}
51
Jeff Brownf4a4ec22010-06-16 01:53:36 -070052template<typename T>
53inline static void swap(T& a, T& b) {
54 T temp = a;
55 a = b;
56 b = temp;
57}
58
59
Jeff Browne839a582010-04-22 18:58:52 -070060int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
61 int32_t mask;
62 switch (keyCode) {
Jeff Brown8575a872010-06-30 16:10:35 -070063 case AKEYCODE_ALT_LEFT:
Jeff Brown5c1ed842010-07-14 18:48:53 -070064 mask = AMETA_ALT_LEFT_ON;
Jeff Browne839a582010-04-22 18:58:52 -070065 break;
Jeff Brown8575a872010-06-30 16:10:35 -070066 case AKEYCODE_ALT_RIGHT:
Jeff Brown5c1ed842010-07-14 18:48:53 -070067 mask = AMETA_ALT_RIGHT_ON;
Jeff Browne839a582010-04-22 18:58:52 -070068 break;
Jeff Brown8575a872010-06-30 16:10:35 -070069 case AKEYCODE_SHIFT_LEFT:
Jeff Brown5c1ed842010-07-14 18:48:53 -070070 mask = AMETA_SHIFT_LEFT_ON;
Jeff Browne839a582010-04-22 18:58:52 -070071 break;
Jeff Brown8575a872010-06-30 16:10:35 -070072 case AKEYCODE_SHIFT_RIGHT:
Jeff Brown5c1ed842010-07-14 18:48:53 -070073 mask = AMETA_SHIFT_RIGHT_ON;
Jeff Browne839a582010-04-22 18:58:52 -070074 break;
Jeff Brown8575a872010-06-30 16:10:35 -070075 case AKEYCODE_SYM:
Jeff Brown5c1ed842010-07-14 18:48:53 -070076 mask = AMETA_SYM_ON;
Jeff Browne839a582010-04-22 18:58:52 -070077 break;
78 default:
79 return oldMetaState;
80 }
81
82 int32_t newMetaState = down ? oldMetaState | mask : oldMetaState & ~ mask
Jeff Brown5c1ed842010-07-14 18:48:53 -070083 & ~ (AMETA_ALT_ON | AMETA_SHIFT_ON);
Jeff Browne839a582010-04-22 18:58:52 -070084
Jeff Brown5c1ed842010-07-14 18:48:53 -070085 if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
86 newMetaState |= AMETA_ALT_ON;
Jeff Browne839a582010-04-22 18:58:52 -070087 }
88
Jeff Brown5c1ed842010-07-14 18:48:53 -070089 if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
90 newMetaState |= AMETA_SHIFT_ON;
Jeff Browne839a582010-04-22 18:58:52 -070091 }
92
93 return newMetaState;
94}
95
96static const int32_t keyCodeRotationMap[][4] = {
97 // key codes enumerated counter-clockwise with the original (unrotated) key first
98 // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation
Jeff Brown8575a872010-06-30 16:10:35 -070099 { AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT },
100 { AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN },
101 { AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT },
102 { AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP },
Jeff Browne839a582010-04-22 18:58:52 -0700103};
104static const int keyCodeRotationMapSize =
105 sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
106
107int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700108 if (orientation != InputReaderPolicyInterface::ROTATION_0) {
Jeff Browne839a582010-04-22 18:58:52 -0700109 for (int i = 0; i < keyCodeRotationMapSize; i++) {
110 if (keyCode == keyCodeRotationMap[i][0]) {
111 return keyCodeRotationMap[i][orientation];
112 }
113 }
114 }
115 return keyCode;
116}
117
118
Jeff Browne839a582010-04-22 18:58:52 -0700119// --- InputReader ---
120
121InputReader::InputReader(const sp<EventHubInterface>& eventHub,
Jeff Brown54bc2812010-06-15 01:31:58 -0700122 const sp<InputReaderPolicyInterface>& policy,
Jeff Browne839a582010-04-22 18:58:52 -0700123 const sp<InputDispatcherInterface>& dispatcher) :
124 mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700125 configureExcludedDevices();
Jeff Browne839a582010-04-22 18:58:52 -0700126 resetGlobalMetaState();
127 resetDisplayProperties();
Jeff Brown54bc2812010-06-15 01:31:58 -0700128 updateExportedVirtualKeyState();
Jeff Browne839a582010-04-22 18:58:52 -0700129}
130
131InputReader::~InputReader() {
132 for (size_t i = 0; i < mDevices.size(); i++) {
133 delete mDevices.valueAt(i);
134 }
135}
136
137void InputReader::loopOnce() {
138 RawEvent rawEvent;
139 mEventHub->getEvent(& rawEvent.deviceId, & rawEvent.type, & rawEvent.scanCode,
140 & rawEvent.keyCode, & rawEvent.flags, & rawEvent.value, & rawEvent.when);
141
142 // Replace the event timestamp so it is in same timebase as java.lang.System.nanoTime()
143 // and android.os.SystemClock.uptimeMillis() as expected by the rest of the system.
144 rawEvent.when = systemTime(SYSTEM_TIME_MONOTONIC);
145
146#if DEBUG_RAW_EVENTS
147 LOGD("Input event: device=0x%x type=0x%x scancode=%d keycode=%d value=%d",
148 rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
149 rawEvent.value);
150#endif
151
152 process(& rawEvent);
153}
154
155void InputReader::process(const RawEvent* rawEvent) {
156 switch (rawEvent->type) {
157 case EventHubInterface::DEVICE_ADDED:
158 handleDeviceAdded(rawEvent);
159 break;
160
161 case EventHubInterface::DEVICE_REMOVED:
162 handleDeviceRemoved(rawEvent);
163 break;
164
165 case EV_SYN:
166 handleSync(rawEvent);
167 break;
168
169 case EV_KEY:
170 handleKey(rawEvent);
171 break;
172
173 case EV_REL:
174 handleRelativeMotion(rawEvent);
175 break;
176
177 case EV_ABS:
178 handleAbsoluteMotion(rawEvent);
179 break;
180
181 case EV_SW:
182 handleSwitch(rawEvent);
183 break;
184 }
185}
186
187void InputReader::handleDeviceAdded(const RawEvent* rawEvent) {
188 InputDevice* device = getDevice(rawEvent->deviceId);
189 if (device) {
190 LOGW("Ignoring spurious device added event for deviceId %d.", rawEvent->deviceId);
191 return;
192 }
193
194 addDevice(rawEvent->when, rawEvent->deviceId);
195}
196
197void InputReader::handleDeviceRemoved(const RawEvent* rawEvent) {
198 InputDevice* device = getDevice(rawEvent->deviceId);
199 if (! device) {
200 LOGW("Ignoring spurious device removed event for deviceId %d.", rawEvent->deviceId);
201 return;
202 }
203
204 removeDevice(rawEvent->when, device);
205}
206
207void InputReader::handleSync(const RawEvent* rawEvent) {
208 InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
209 if (! device) return;
210
211 if (rawEvent->scanCode == SYN_MT_REPORT) {
212 // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
213 // We drop pointers with pressure <= 0 since that indicates they are not down.
214 if (device->isMultiTouchScreen()) {
215 uint32_t pointerIndex = device->multiTouchScreen.accumulator.pointerCount;
216
217 if (device->multiTouchScreen.accumulator.pointers[pointerIndex].fields) {
218 if (pointerIndex == MAX_POINTERS) {
219 LOGW("MultiTouch device driver returned more than maximum of %d pointers.",
220 MAX_POINTERS);
221 } else {
222 pointerIndex += 1;
223 device->multiTouchScreen.accumulator.pointerCount = pointerIndex;
224 }
225 }
226
227 device->multiTouchScreen.accumulator.pointers[pointerIndex].clear();
228 }
229 } else if (rawEvent->scanCode == SYN_REPORT) {
230 // General Sync: The driver has returned all data for the current event update.
231 if (device->isMultiTouchScreen()) {
232 if (device->multiTouchScreen.accumulator.isDirty()) {
233 onMultiTouchScreenStateChanged(rawEvent->when, device);
234 device->multiTouchScreen.accumulator.clear();
235 }
236 } else if (device->isSingleTouchScreen()) {
237 if (device->singleTouchScreen.accumulator.isDirty()) {
238 onSingleTouchScreenStateChanged(rawEvent->when, device);
239 device->singleTouchScreen.accumulator.clear();
240 }
241 }
242
243 if (device->trackball.accumulator.isDirty()) {
244 onTrackballStateChanged(rawEvent->when, device);
245 device->trackball.accumulator.clear();
246 }
247 }
248}
249
250void InputReader::handleKey(const RawEvent* rawEvent) {
251 InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
252 if (! device) return;
253
254 bool down = rawEvent->value != 0;
255 int32_t scanCode = rawEvent->scanCode;
256
Jeff Brown8575a872010-06-30 16:10:35 -0700257 if (device->isSingleTouchScreen()) {
Jeff Browne839a582010-04-22 18:58:52 -0700258 switch (rawEvent->scanCode) {
259 case BTN_TOUCH:
260 device->singleTouchScreen.accumulator.fields |=
261 InputDevice::SingleTouchScreenState::Accumulator::FIELD_BTN_TOUCH;
262 device->singleTouchScreen.accumulator.btnTouch = down;
Jeff Brown8575a872010-06-30 16:10:35 -0700263 return;
Jeff Browne839a582010-04-22 18:58:52 -0700264 }
Jeff Brown8575a872010-06-30 16:10:35 -0700265 }
266
267 if (device->isTrackball()) {
Jeff Browne839a582010-04-22 18:58:52 -0700268 switch (rawEvent->scanCode) {
269 case BTN_MOUSE:
270 device->trackball.accumulator.fields |=
271 InputDevice::TrackballState::Accumulator::FIELD_BTN_MOUSE;
272 device->trackball.accumulator.btnMouse = down;
Jeff Brown8575a872010-06-30 16:10:35 -0700273 return;
Jeff Browne839a582010-04-22 18:58:52 -0700274 }
275 }
Jeff Brown8575a872010-06-30 16:10:35 -0700276
277 if (device->isKeyboard()) {
278 int32_t keyCode = rawEvent->keyCode;
279 onKey(rawEvent->when, device, down, keyCode, scanCode, rawEvent->flags);
280 }
Jeff Browne839a582010-04-22 18:58:52 -0700281}
282
283void InputReader::handleRelativeMotion(const RawEvent* rawEvent) {
284 InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
285 if (! device) return;
286
287 if (device->isTrackball()) {
288 switch (rawEvent->scanCode) {
289 case REL_X:
290 device->trackball.accumulator.fields |=
291 InputDevice::TrackballState::Accumulator::FIELD_REL_X;
292 device->trackball.accumulator.relX = rawEvent->value;
293 break;
294 case REL_Y:
295 device->trackball.accumulator.fields |=
296 InputDevice::TrackballState::Accumulator::FIELD_REL_Y;
297 device->trackball.accumulator.relY = rawEvent->value;
298 break;
299 }
300 }
301}
302
303void InputReader::handleAbsoluteMotion(const RawEvent* rawEvent) {
304 InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
305 if (! device) return;
306
307 if (device->isMultiTouchScreen()) {
308 uint32_t pointerIndex = device->multiTouchScreen.accumulator.pointerCount;
309 InputDevice::MultiTouchScreenState::Accumulator::Pointer* pointer =
310 & device->multiTouchScreen.accumulator.pointers[pointerIndex];
311
312 switch (rawEvent->scanCode) {
313 case ABS_MT_POSITION_X:
314 pointer->fields |=
315 InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_POSITION_X;
316 pointer->absMTPositionX = rawEvent->value;
317 break;
318 case ABS_MT_POSITION_Y:
319 pointer->fields |=
320 InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_POSITION_Y;
321 pointer->absMTPositionY = rawEvent->value;
322 break;
323 case ABS_MT_TOUCH_MAJOR:
324 pointer->fields |=
325 InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TOUCH_MAJOR;
326 pointer->absMTTouchMajor = rawEvent->value;
327 break;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700328 case ABS_MT_TOUCH_MINOR:
329 pointer->fields |=
330 InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TOUCH_MINOR;
331 pointer->absMTTouchMinor = rawEvent->value;
332 break;
Jeff Browne839a582010-04-22 18:58:52 -0700333 case ABS_MT_WIDTH_MAJOR:
334 pointer->fields |=
335 InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
336 pointer->absMTWidthMajor = rawEvent->value;
337 break;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700338 case ABS_MT_WIDTH_MINOR:
339 pointer->fields |=
340 InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_WIDTH_MINOR;
341 pointer->absMTWidthMinor = rawEvent->value;
342 break;
343 case ABS_MT_ORIENTATION:
344 pointer->fields |=
345 InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_ORIENTATION;
346 pointer->absMTOrientation = rawEvent->value;
347 break;
Jeff Browne839a582010-04-22 18:58:52 -0700348 case ABS_MT_TRACKING_ID:
349 pointer->fields |=
350 InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TRACKING_ID;
351 pointer->absMTTrackingId = rawEvent->value;
352 break;
353 }
354 } else if (device->isSingleTouchScreen()) {
355 switch (rawEvent->scanCode) {
356 case ABS_X:
357 device->singleTouchScreen.accumulator.fields |=
358 InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_X;
359 device->singleTouchScreen.accumulator.absX = rawEvent->value;
360 break;
361 case ABS_Y:
362 device->singleTouchScreen.accumulator.fields |=
363 InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_Y;
364 device->singleTouchScreen.accumulator.absY = rawEvent->value;
365 break;
366 case ABS_PRESSURE:
367 device->singleTouchScreen.accumulator.fields |=
368 InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_PRESSURE;
369 device->singleTouchScreen.accumulator.absPressure = rawEvent->value;
370 break;
371 case ABS_TOOL_WIDTH:
372 device->singleTouchScreen.accumulator.fields |=
373 InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_TOOL_WIDTH;
374 device->singleTouchScreen.accumulator.absToolWidth = rawEvent->value;
375 break;
376 }
377 }
378}
379
380void InputReader::handleSwitch(const RawEvent* rawEvent) {
381 InputDevice* device = getNonIgnoredDevice(rawEvent->deviceId);
382 if (! device) return;
383
Jeff Brown54bc2812010-06-15 01:31:58 -0700384 onSwitch(rawEvent->when, device, rawEvent->scanCode, rawEvent->value);
Jeff Browne839a582010-04-22 18:58:52 -0700385}
386
387void InputReader::onKey(nsecs_t when, InputDevice* device,
388 bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags) {
389 /* Refresh display properties so we can rotate key codes according to display orientation */
390
391 if (! refreshDisplayProperties()) {
392 return;
393 }
394
395 /* Update device state */
396
397 int32_t oldMetaState = device->keyboard.current.metaState;
398 int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
399 if (oldMetaState != newMetaState) {
400 device->keyboard.current.metaState = newMetaState;
401 resetGlobalMetaState();
402 }
403
404 // FIXME if we send a down event about a rotated key press we should ensure that we send
405 // a corresponding up event about the rotated key press even if the orientation
406 // has changed in the meantime
407 keyCode = rotateKeyCode(keyCode, mDisplayOrientation);
408
409 if (down) {
410 device->keyboard.current.downTime = when;
411 }
412
413 /* Apply policy */
414
415 int32_t policyActions = mPolicy->interceptKey(when, device->id,
416 down, keyCode, scanCode, policyFlags);
417
418 if (! applyStandardInputDispatchPolicyActions(when, policyActions, & policyFlags)) {
419 return; // event dropped
420 }
421
422 /* Enqueue key event for dispatch */
423
424 int32_t keyEventAction;
425 if (down) {
426 device->keyboard.current.downTime = when;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700427 keyEventAction = AKEY_EVENT_ACTION_DOWN;
Jeff Browne839a582010-04-22 18:58:52 -0700428 } else {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700429 keyEventAction = AKEY_EVENT_ACTION_UP;
Jeff Browne839a582010-04-22 18:58:52 -0700430 }
431
Jeff Brown5c1ed842010-07-14 18:48:53 -0700432 int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM;
Jeff Brown54bc2812010-06-15 01:31:58 -0700433 if (policyActions & InputReaderPolicyInterface::ACTION_WOKE_HERE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700434 keyEventFlags = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE;
Jeff Browne839a582010-04-22 18:58:52 -0700435 }
436
Jeff Brown5c1ed842010-07-14 18:48:53 -0700437 mDispatcher->notifyKey(when, device->id, AINPUT_SOURCE_KEYBOARD, policyFlags,
Jeff Browne839a582010-04-22 18:58:52 -0700438 keyEventAction, keyEventFlags, keyCode, scanCode,
439 device->keyboard.current.metaState,
440 device->keyboard.current.downTime);
441}
442
Jeff Brown54bc2812010-06-15 01:31:58 -0700443void InputReader::onSwitch(nsecs_t when, InputDevice* device, int32_t switchCode,
444 int32_t switchValue) {
445 int32_t policyActions = mPolicy->interceptSwitch(when, switchCode, switchValue);
446
447 uint32_t policyFlags = 0;
448 applyStandardInputDispatchPolicyActions(when, policyActions, & policyFlags);
Jeff Browne839a582010-04-22 18:58:52 -0700449}
450
451void InputReader::onMultiTouchScreenStateChanged(nsecs_t when,
452 InputDevice* device) {
453 static const uint32_t REQUIRED_FIELDS =
454 InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_POSITION_X
455 | InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_POSITION_Y
456 | InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TOUCH_MAJOR
457 | InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
458
459 /* Refresh display properties so we can map touch screen coords into display coords */
460
461 if (! refreshDisplayProperties()) {
462 return;
463 }
464
465 /* Update device state */
466
467 InputDevice::MultiTouchScreenState* in = & device->multiTouchScreen;
468 InputDevice::TouchData* out = & device->touchScreen.currentTouch;
469
470 uint32_t inCount = in->accumulator.pointerCount;
471 uint32_t outCount = 0;
472 bool havePointerIds = true;
473
474 out->clear();
475
476 for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) {
477 uint32_t fields = in->accumulator.pointers[inIndex].fields;
478
479 if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) {
480#if DEBUG_POINTERS
481 LOGD("Pointers: Missing required multitouch pointer fields: index=%d, fields=%d",
482 inIndex, fields);
483 continue;
484#endif
485 }
486
487 if (in->accumulator.pointers[inIndex].absMTTouchMajor <= 0) {
488 // Pointer is not down. Drop it.
489 continue;
490 }
491
Jeff Brown5c1ed842010-07-14 18:48:53 -0700492 out->pointers[outCount].x = in->accumulator.pointers[inIndex].absMTPositionX;
493 out->pointers[outCount].y = in->accumulator.pointers[inIndex].absMTPositionY;
494
495 out->pointers[outCount].touchMajor = in->accumulator.pointers[inIndex].absMTTouchMajor;
496 out->pointers[outCount].touchMinor = (fields
497 & InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TOUCH_MINOR) != 0
498 ? in->accumulator.pointers[inIndex].absMTTouchMinor
499 : in->accumulator.pointers[inIndex].absMTTouchMajor;
500
501 out->pointers[outCount].toolMajor = in->accumulator.pointers[inIndex].absMTWidthMajor;
502 out->pointers[outCount].toolMinor = (fields
503 & InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_WIDTH_MINOR) != 0
504 ? in->accumulator.pointers[inIndex].absMTWidthMinor
505 : in->accumulator.pointers[inIndex].absMTWidthMajor;
506
507 out->pointers[outCount].orientation = (fields
508 & InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_ORIENTATION) != 0
509 ? in->accumulator.pointers[inIndex].absMTOrientation : 0;
510
511 // Derive an approximation of pressure and size.
Jeff Browne839a582010-04-22 18:58:52 -0700512 // FIXME assignment of pressure may be incorrect, probably better to let
513 // pressure = touch / width. Later on we pass width to MotionEvent as a size, which
514 // isn't quite right either. Should be using touch for that.
Jeff Browne839a582010-04-22 18:58:52 -0700515 out->pointers[outCount].pressure = in->accumulator.pointers[inIndex].absMTTouchMajor;
516 out->pointers[outCount].size = in->accumulator.pointers[inIndex].absMTWidthMajor;
517
518 if (havePointerIds) {
519 if (fields & InputDevice::MultiTouchScreenState::Accumulator::
520 FIELD_ABS_MT_TRACKING_ID) {
521 uint32_t id = uint32_t(in->accumulator.pointers[inIndex].absMTTrackingId);
522
523 if (id > MAX_POINTER_ID) {
524#if DEBUG_POINTERS
525 LOGD("Pointers: Ignoring driver provided pointer id %d because "
526 "it is larger than max supported id %d for optimizations",
527 id, MAX_POINTER_ID);
528#endif
529 havePointerIds = false;
530 }
531 else {
532 out->pointers[outCount].id = id;
533 out->idToIndex[id] = outCount;
534 out->idBits.markBit(id);
535 }
536 } else {
537 havePointerIds = false;
538 }
539 }
540
541 outCount += 1;
542 }
543
544 out->pointerCount = outCount;
545
546 onTouchScreenChanged(when, device, havePointerIds);
547}
548
549void InputReader::onSingleTouchScreenStateChanged(nsecs_t when,
550 InputDevice* device) {
Jeff Browne839a582010-04-22 18:58:52 -0700551 /* Refresh display properties so we can map touch screen coords into display coords */
552
553 if (! refreshDisplayProperties()) {
554 return;
555 }
556
557 /* Update device state */
558
559 InputDevice::SingleTouchScreenState* in = & device->singleTouchScreen;
560 InputDevice::TouchData* out = & device->touchScreen.currentTouch;
561
562 uint32_t fields = in->accumulator.fields;
563
564 if (fields & InputDevice::SingleTouchScreenState::Accumulator::FIELD_BTN_TOUCH) {
565 in->current.down = in->accumulator.btnTouch;
566 }
567
Jeff Brown50de30a2010-06-22 01:27:15 -0700568 if (fields & InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_X) {
Jeff Browne839a582010-04-22 18:58:52 -0700569 in->current.x = in->accumulator.absX;
Jeff Brown50de30a2010-06-22 01:27:15 -0700570 }
571
572 if (fields & InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_Y) {
Jeff Browne839a582010-04-22 18:58:52 -0700573 in->current.y = in->accumulator.absY;
Jeff Brown50de30a2010-06-22 01:27:15 -0700574 }
575
576 if (fields & InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_PRESSURE) {
Jeff Browne839a582010-04-22 18:58:52 -0700577 in->current.pressure = in->accumulator.absPressure;
Jeff Brown50de30a2010-06-22 01:27:15 -0700578 }
579
580 if (fields & InputDevice::SingleTouchScreenState::Accumulator::FIELD_ABS_TOOL_WIDTH) {
Jeff Browne839a582010-04-22 18:58:52 -0700581 in->current.size = in->accumulator.absToolWidth;
582 }
583
584 out->clear();
585
586 if (in->current.down) {
587 out->pointerCount = 1;
588 out->pointers[0].id = 0;
589 out->pointers[0].x = in->current.x;
590 out->pointers[0].y = in->current.y;
591 out->pointers[0].pressure = in->current.pressure;
592 out->pointers[0].size = in->current.size;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700593 out->pointers[0].touchMajor = in->current.pressure;
594 out->pointers[0].touchMinor = in->current.pressure;
595 out->pointers[0].toolMajor = in->current.size;
596 out->pointers[0].toolMinor = in->current.size;
597 out->pointers[0].orientation = 0;
Jeff Browne839a582010-04-22 18:58:52 -0700598 out->idToIndex[0] = 0;
599 out->idBits.markBit(0);
600 }
601
602 onTouchScreenChanged(when, device, true);
603}
604
605void InputReader::onTouchScreenChanged(nsecs_t when,
606 InputDevice* device, bool havePointerIds) {
607 /* Apply policy */
608
609 int32_t policyActions = mPolicy->interceptTouch(when);
610
611 uint32_t policyFlags = 0;
612 if (! applyStandardInputDispatchPolicyActions(when, policyActions, & policyFlags)) {
613 device->touchScreen.lastTouch.clear();
614 return; // event dropped
615 }
616
617 /* Preprocess pointer data */
618
619 if (device->touchScreen.parameters.useBadTouchFilter) {
620 if (device->touchScreen.applyBadTouchFilter()) {
621 havePointerIds = false;
622 }
623 }
624
625 if (device->touchScreen.parameters.useJumpyTouchFilter) {
626 if (device->touchScreen.applyJumpyTouchFilter()) {
627 havePointerIds = false;
628 }
629 }
630
631 if (! havePointerIds) {
632 device->touchScreen.calculatePointerIds();
633 }
634
635 InputDevice::TouchData temp;
636 InputDevice::TouchData* savedTouch;
637 if (device->touchScreen.parameters.useAveragingTouchFilter) {
638 temp.copyFrom(device->touchScreen.currentTouch);
639 savedTouch = & temp;
640
641 device->touchScreen.applyAveragingTouchFilter();
642 } else {
643 savedTouch = & device->touchScreen.currentTouch;
644 }
645
646 /* Process virtual keys or touches */
647
648 if (! consumeVirtualKeyTouches(when, device, policyFlags)) {
649 dispatchTouches(when, device, policyFlags);
650 }
651
652 // Copy current touch to last touch in preparation for the next cycle.
653 device->touchScreen.lastTouch.copyFrom(*savedTouch);
654}
655
656bool InputReader::consumeVirtualKeyTouches(nsecs_t when,
657 InputDevice* device, uint32_t policyFlags) {
Jeff Brownf16c26d2010-07-02 15:37:36 -0700658 switch (device->touchScreen.currentVirtualKey.status) {
659 case InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_CANCELED:
Jeff Browne839a582010-04-22 18:58:52 -0700660 if (device->touchScreen.currentTouch.pointerCount == 0) {
Jeff Brownf16c26d2010-07-02 15:37:36 -0700661 // Pointer went up after virtual key canceled.
662 device->touchScreen.currentVirtualKey.status =
663 InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_UP;
664 }
665 return true; // consumed
Jeff Browne839a582010-04-22 18:58:52 -0700666
Jeff Brownf16c26d2010-07-02 15:37:36 -0700667 case InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN:
668 if (device->touchScreen.currentTouch.pointerCount == 0) {
669 // Pointer went up while virtual key was down.
670 device->touchScreen.currentVirtualKey.status =
671 InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_UP;
Jeff Browne839a582010-04-22 18:58:52 -0700672#if DEBUG_VIRTUAL_KEYS
673 LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
674 device->touchScreen.currentVirtualKey.keyCode,
675 device->touchScreen.currentVirtualKey.scanCode);
676#endif
Jeff Brown5c1ed842010-07-14 18:48:53 -0700677 dispatchVirtualKey(when, device, policyFlags, AKEY_EVENT_ACTION_UP,
678 AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
Jeff Browne839a582010-04-22 18:58:52 -0700679 return true; // consumed
680 }
681
Jeff Brownf16c26d2010-07-02 15:37:36 -0700682 if (device->touchScreen.currentTouch.pointerCount == 1) {
683 const InputDevice::VirtualKey* virtualKey = device->touchScreen.findVirtualKeyHit();
684 if (virtualKey
685 && virtualKey->keyCode == device->touchScreen.currentVirtualKey.keyCode) {
686 // Pointer is still within the space of the virtual key.
687 return true; // consumed
688 }
Jeff Browne839a582010-04-22 18:58:52 -0700689 }
Jeff Browne839a582010-04-22 18:58:52 -0700690
Jeff Brownf16c26d2010-07-02 15:37:36 -0700691 // Pointer left virtual key area or another pointer also went down.
692 // Send key cancellation.
693 device->touchScreen.currentVirtualKey.status =
694 InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_CANCELED;
Jeff Browne839a582010-04-22 18:58:52 -0700695#if DEBUG_VIRTUAL_KEYS
Jeff Brownf16c26d2010-07-02 15:37:36 -0700696 LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
697 device->touchScreen.currentVirtualKey.keyCode,
698 device->touchScreen.currentVirtualKey.scanCode);
Jeff Browne839a582010-04-22 18:58:52 -0700699#endif
Jeff Brown5c1ed842010-07-14 18:48:53 -0700700 dispatchVirtualKey(when, device, policyFlags, AKEY_EVENT_ACTION_UP,
701 AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
702 | AKEY_EVENT_FLAG_CANCELED);
Jeff Brownf16c26d2010-07-02 15:37:36 -0700703 return true; // consumed
Jeff Browne839a582010-04-22 18:58:52 -0700704
Jeff Brownf16c26d2010-07-02 15:37:36 -0700705 default:
706 if (device->touchScreen.currentTouch.pointerCount == 1
707 && device->touchScreen.lastTouch.pointerCount == 0) {
708 // Pointer just went down. Check for virtual key hit.
709 const InputDevice::VirtualKey* virtualKey = device->touchScreen.findVirtualKeyHit();
710 if (virtualKey) {
711 device->touchScreen.currentVirtualKey.status =
712 InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN;
Jeff Browne839a582010-04-22 18:58:52 -0700713 device->touchScreen.currentVirtualKey.downTime = when;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700714 device->touchScreen.currentVirtualKey.keyCode = virtualKey->keyCode;
715 device->touchScreen.currentVirtualKey.scanCode = virtualKey->scanCode;
Jeff Browne839a582010-04-22 18:58:52 -0700716#if DEBUG_VIRTUAL_KEYS
Jeff Brownf16c26d2010-07-02 15:37:36 -0700717 LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
718 device->touchScreen.currentVirtualKey.keyCode,
719 device->touchScreen.currentVirtualKey.scanCode);
Jeff Browne839a582010-04-22 18:58:52 -0700720#endif
Jeff Brown5c1ed842010-07-14 18:48:53 -0700721 dispatchVirtualKey(when, device, policyFlags, AKEY_EVENT_ACTION_DOWN,
722 AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
Jeff Browne839a582010-04-22 18:58:52 -0700723 return true; // consumed
724 }
725 }
Jeff Brownf16c26d2010-07-02 15:37:36 -0700726 return false; // not consumed
Jeff Browne839a582010-04-22 18:58:52 -0700727 }
Jeff Browne839a582010-04-22 18:58:52 -0700728}
729
730void InputReader::dispatchVirtualKey(nsecs_t when,
731 InputDevice* device, uint32_t policyFlags,
732 int32_t keyEventAction, int32_t keyEventFlags) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700733 updateExportedVirtualKeyState();
734
Jeff Browne839a582010-04-22 18:58:52 -0700735 int32_t keyCode = device->touchScreen.currentVirtualKey.keyCode;
736 int32_t scanCode = device->touchScreen.currentVirtualKey.scanCode;
737 nsecs_t downTime = device->touchScreen.currentVirtualKey.downTime;
738 int32_t metaState = globalMetaState();
739
Jeff Brown5c1ed842010-07-14 18:48:53 -0700740 if (keyEventAction == AKEY_EVENT_ACTION_DOWN) {
Jeff Brownf16c26d2010-07-02 15:37:36 -0700741 mPolicy->virtualKeyDownFeedback();
742 }
Jeff Browne839a582010-04-22 18:58:52 -0700743
Jeff Brown50de30a2010-06-22 01:27:15 -0700744 int32_t policyActions = mPolicy->interceptKey(when, device->id,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700745 keyEventAction == AKEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
Jeff Brown50de30a2010-06-22 01:27:15 -0700746
747 if (applyStandardInputDispatchPolicyActions(when, policyActions, & policyFlags)) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700748 mDispatcher->notifyKey(when, device->id, AINPUT_SOURCE_KEYBOARD, policyFlags,
Jeff Brown50de30a2010-06-22 01:27:15 -0700749 keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
750 }
Jeff Browne839a582010-04-22 18:58:52 -0700751}
752
753void InputReader::dispatchTouches(nsecs_t when,
754 InputDevice* device, uint32_t policyFlags) {
755 uint32_t currentPointerCount = device->touchScreen.currentTouch.pointerCount;
756 uint32_t lastPointerCount = device->touchScreen.lastTouch.pointerCount;
757 if (currentPointerCount == 0 && lastPointerCount == 0) {
758 return; // nothing to do!
759 }
760
761 BitSet32 currentIdBits = device->touchScreen.currentTouch.idBits;
762 BitSet32 lastIdBits = device->touchScreen.lastTouch.idBits;
763
764 if (currentIdBits == lastIdBits) {
765 // No pointer id changes so this is a move event.
766 // The dispatcher takes care of batching moves so we don't have to deal with that here.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700767 int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE;
Jeff Browne839a582010-04-22 18:58:52 -0700768 dispatchTouch(when, device, policyFlags, & device->touchScreen.currentTouch,
Jeff Brown3cf1c9b2010-07-16 15:01:56 -0700769 currentIdBits, -1, motionEventAction);
Jeff Browne839a582010-04-22 18:58:52 -0700770 } else {
771 // There may be pointers going up and pointers going down at the same time when pointer
772 // ids are reported by the device driver.
773 BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
774 BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
775 BitSet32 activeIdBits(lastIdBits.value);
776
777 while (! upIdBits.isEmpty()) {
778 uint32_t upId = upIdBits.firstMarkedBit();
779 upIdBits.clearBit(upId);
780 BitSet32 oldActiveIdBits = activeIdBits;
781 activeIdBits.clearBit(upId);
782
783 int32_t motionEventAction;
784 if (activeIdBits.isEmpty()) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700785 motionEventAction = AMOTION_EVENT_ACTION_UP;
Jeff Browne839a582010-04-22 18:58:52 -0700786 } else {
Jeff Brown3cf1c9b2010-07-16 15:01:56 -0700787 motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP;
Jeff Browne839a582010-04-22 18:58:52 -0700788 }
789
790 dispatchTouch(when, device, policyFlags, & device->touchScreen.lastTouch,
Jeff Brown3cf1c9b2010-07-16 15:01:56 -0700791 oldActiveIdBits, upId, motionEventAction);
Jeff Browne839a582010-04-22 18:58:52 -0700792 }
793
794 while (! downIdBits.isEmpty()) {
795 uint32_t downId = downIdBits.firstMarkedBit();
796 downIdBits.clearBit(downId);
797 BitSet32 oldActiveIdBits = activeIdBits;
798 activeIdBits.markBit(downId);
799
800 int32_t motionEventAction;
801 if (oldActiveIdBits.isEmpty()) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700802 motionEventAction = AMOTION_EVENT_ACTION_DOWN;
Jeff Browne839a582010-04-22 18:58:52 -0700803 device->touchScreen.downTime = when;
804 } else {
Jeff Brown3cf1c9b2010-07-16 15:01:56 -0700805 motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN;
Jeff Browne839a582010-04-22 18:58:52 -0700806 }
807
808 dispatchTouch(when, device, policyFlags, & device->touchScreen.currentTouch,
Jeff Brown3cf1c9b2010-07-16 15:01:56 -0700809 activeIdBits, downId, motionEventAction);
Jeff Browne839a582010-04-22 18:58:52 -0700810 }
811 }
812}
813
814void InputReader::dispatchTouch(nsecs_t when, InputDevice* device, uint32_t policyFlags,
Jeff Brown3cf1c9b2010-07-16 15:01:56 -0700815 InputDevice::TouchData* touch, BitSet32 idBits, uint32_t changedId,
Jeff Browne839a582010-04-22 18:58:52 -0700816 int32_t motionEventAction) {
817 int32_t orientedWidth, orientedHeight;
818 switch (mDisplayOrientation) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700819 case InputReaderPolicyInterface::ROTATION_90:
820 case InputReaderPolicyInterface::ROTATION_270:
Jeff Browne839a582010-04-22 18:58:52 -0700821 orientedWidth = mDisplayHeight;
822 orientedHeight = mDisplayWidth;
823 break;
824 default:
825 orientedWidth = mDisplayWidth;
826 orientedHeight = mDisplayHeight;
827 break;
828 }
829
830 uint32_t pointerCount = 0;
831 int32_t pointerIds[MAX_POINTERS];
832 PointerCoords pointerCoords[MAX_POINTERS];
833
Jeff Brown4036f7f2010-06-29 16:52:21 -0700834 const InputDevice::TouchScreenState::Precalculated& precalculated =
835 device->touchScreen.precalculated;
836
Jeff Browne839a582010-04-22 18:58:52 -0700837 // Walk through the the active pointers and map touch screen coordinates (TouchData) into
838 // display coordinates (PointerCoords) and adjust for display orientation.
839 while (! idBits.isEmpty()) {
840 uint32_t id = idBits.firstMarkedBit();
841 idBits.clearBit(id);
842 uint32_t index = touch->idToIndex[id];
843
Jeff Brown4036f7f2010-06-29 16:52:21 -0700844 float x = float(touch->pointers[index].x
845 - precalculated.xOrigin) * precalculated.xScale;
846 float y = float(touch->pointers[index].y
847 - precalculated.yOrigin) * precalculated.yScale;
848 float pressure = float(touch->pointers[index].pressure
849 - precalculated.pressureOrigin) * precalculated.pressureScale;
850 float size = float(touch->pointers[index].size
851 - precalculated.sizeOrigin) * precalculated.sizeScale;
Jeff Browne839a582010-04-22 18:58:52 -0700852
Jeff Brown5c1ed842010-07-14 18:48:53 -0700853 float orientation = float(touch->pointers[index].orientation)
854 * precalculated.orientationScale;
855
856 bool vertical = abs(orientation) <= M_PI / 8;
857
Jeff Browne839a582010-04-22 18:58:52 -0700858 switch (mDisplayOrientation) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700859 case InputReaderPolicyInterface::ROTATION_90: {
Jeff Browne839a582010-04-22 18:58:52 -0700860 float xTemp = x;
861 x = y;
Jeff Brown51d45a72010-06-17 20:52:56 -0700862 y = mDisplayWidth - xTemp;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700863 vertical = ! vertical;
Jeff Browne839a582010-04-22 18:58:52 -0700864 break;
865 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700866 case InputReaderPolicyInterface::ROTATION_180: {
Jeff Browne839a582010-04-22 18:58:52 -0700867 x = mDisplayWidth - x;
868 y = mDisplayHeight - y;
869 break;
870 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700871 case InputReaderPolicyInterface::ROTATION_270: {
Jeff Browne839a582010-04-22 18:58:52 -0700872 float xTemp = x;
Jeff Brown51d45a72010-06-17 20:52:56 -0700873 x = mDisplayHeight - y;
Jeff Browne839a582010-04-22 18:58:52 -0700874 y = xTemp;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700875 vertical = ! vertical;
Jeff Browne839a582010-04-22 18:58:52 -0700876 break;
877 }
878 }
879
Jeff Brown5c1ed842010-07-14 18:48:53 -0700880 float touchMajor, touchMinor, toolMajor, toolMinor;
881 if (vertical) {
882 touchMajor = float(touch->pointers[index].touchMajor) * precalculated.yScale;
883 touchMinor = float(touch->pointers[index].touchMinor) * precalculated.xScale;
884 toolMajor = float(touch->pointers[index].toolMajor) * precalculated.yScale;
885 toolMinor = float(touch->pointers[index].toolMinor) * precalculated.xScale;
886 } else {
887 touchMajor = float(touch->pointers[index].touchMajor) * precalculated.xScale;
888 touchMinor = float(touch->pointers[index].touchMinor) * precalculated.yScale;
889 toolMajor = float(touch->pointers[index].toolMajor) * precalculated.xScale;
890 toolMinor = float(touch->pointers[index].toolMinor) * precalculated.yScale;
891 }
892
Jeff Browne839a582010-04-22 18:58:52 -0700893 pointerIds[pointerCount] = int32_t(id);
894
895 pointerCoords[pointerCount].x = x;
896 pointerCoords[pointerCount].y = y;
897 pointerCoords[pointerCount].pressure = pressure;
898 pointerCoords[pointerCount].size = size;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700899 pointerCoords[pointerCount].touchMajor = touchMajor;
900 pointerCoords[pointerCount].touchMinor = touchMinor;
901 pointerCoords[pointerCount].toolMajor = toolMajor;
902 pointerCoords[pointerCount].toolMinor = toolMinor;
903 pointerCoords[pointerCount].orientation = orientation;
Jeff Browne839a582010-04-22 18:58:52 -0700904
Jeff Brown3cf1c9b2010-07-16 15:01:56 -0700905 if (id == changedId) {
906 motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
907 }
908
Jeff Browne839a582010-04-22 18:58:52 -0700909 pointerCount += 1;
910 }
911
912 // Check edge flags by looking only at the first pointer since the flags are
913 // global to the event.
Jeff Browne839a582010-04-22 18:58:52 -0700914 int32_t motionEventEdgeFlags = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700915 if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
Jeff Browne839a582010-04-22 18:58:52 -0700916 if (pointerCoords[0].x <= 0) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700917 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
Jeff Browne839a582010-04-22 18:58:52 -0700918 } else if (pointerCoords[0].x >= orientedWidth) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700919 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
Jeff Browne839a582010-04-22 18:58:52 -0700920 }
921 if (pointerCoords[0].y <= 0) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700922 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
Jeff Browne839a582010-04-22 18:58:52 -0700923 } else if (pointerCoords[0].y >= orientedHeight) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700924 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
Jeff Browne839a582010-04-22 18:58:52 -0700925 }
926 }
927
928 nsecs_t downTime = device->touchScreen.downTime;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700929 mDispatcher->notifyMotion(when, device->id, AINPUT_SOURCE_TOUCHSCREEN, policyFlags,
Jeff Browne839a582010-04-22 18:58:52 -0700930 motionEventAction, globalMetaState(), motionEventEdgeFlags,
931 pointerCount, pointerIds, pointerCoords,
932 0, 0, downTime);
933}
934
935void InputReader::onTrackballStateChanged(nsecs_t when,
936 InputDevice* device) {
937 static const uint32_t DELTA_FIELDS =
938 InputDevice::TrackballState::Accumulator::FIELD_REL_X
939 | InputDevice::TrackballState::Accumulator::FIELD_REL_Y;
940
941 /* Refresh display properties so we can trackball moves according to display orientation */
942
943 if (! refreshDisplayProperties()) {
944 return;
945 }
946
947 /* Update device state */
948
949 uint32_t fields = device->trackball.accumulator.fields;
950 bool downChanged = fields & InputDevice::TrackballState::Accumulator::FIELD_BTN_MOUSE;
Jeff Brown51d45a72010-06-17 20:52:56 -0700951 bool deltaChanged = fields & DELTA_FIELDS;
Jeff Browne839a582010-04-22 18:58:52 -0700952
953 bool down;
954 if (downChanged) {
955 if (device->trackball.accumulator.btnMouse) {
956 device->trackball.current.down = true;
957 device->trackball.current.downTime = when;
958 down = true;
959 } else {
960 device->trackball.current.down = false;
961 down = false;
962 }
963 } else {
964 down = device->trackball.current.down;
965 }
966
967 /* Apply policy */
968
969 int32_t policyActions = mPolicy->interceptTrackball(when, downChanged, down, deltaChanged);
970
971 uint32_t policyFlags = 0;
972 if (! applyStandardInputDispatchPolicyActions(when, policyActions, & policyFlags)) {
973 return; // event dropped
974 }
975
976 /* Enqueue motion event for dispatch */
977
978 int32_t motionEventAction;
979 if (downChanged) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700980 motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Browne839a582010-04-22 18:58:52 -0700981 } else {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700982 motionEventAction = AMOTION_EVENT_ACTION_MOVE;
Jeff Browne839a582010-04-22 18:58:52 -0700983 }
984
985 int32_t pointerId = 0;
986 PointerCoords pointerCoords;
Jeff Brown51d45a72010-06-17 20:52:56 -0700987 pointerCoords.x = fields & InputDevice::TrackballState::Accumulator::FIELD_REL_X
988 ? device->trackball.accumulator.relX * device->trackball.precalculated.xScale : 0;
989 pointerCoords.y = fields & InputDevice::TrackballState::Accumulator::FIELD_REL_Y
990 ? device->trackball.accumulator.relY * device->trackball.precalculated.yScale : 0;
Jeff Browne839a582010-04-22 18:58:52 -0700991 pointerCoords.pressure = 1.0f; // XXX Consider making this 1.0f if down, 0 otherwise.
992 pointerCoords.size = 0;
Jeff Brown5c1ed842010-07-14 18:48:53 -0700993 pointerCoords.touchMajor = 0;
994 pointerCoords.touchMinor = 0;
995 pointerCoords.toolMajor = 0;
996 pointerCoords.toolMinor = 0;
997 pointerCoords.orientation = 0;
Jeff Browne839a582010-04-22 18:58:52 -0700998
999 float temp;
1000 switch (mDisplayOrientation) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001001 case InputReaderPolicyInterface::ROTATION_90:
Jeff Browne839a582010-04-22 18:58:52 -07001002 temp = pointerCoords.x;
1003 pointerCoords.x = pointerCoords.y;
1004 pointerCoords.y = - temp;
1005 break;
1006
Jeff Brown54bc2812010-06-15 01:31:58 -07001007 case InputReaderPolicyInterface::ROTATION_180:
Jeff Browne839a582010-04-22 18:58:52 -07001008 pointerCoords.x = - pointerCoords.x;
1009 pointerCoords.y = - pointerCoords.y;
1010 break;
1011
Jeff Brown54bc2812010-06-15 01:31:58 -07001012 case InputReaderPolicyInterface::ROTATION_270:
Jeff Browne839a582010-04-22 18:58:52 -07001013 temp = pointerCoords.x;
1014 pointerCoords.x = - pointerCoords.y;
1015 pointerCoords.y = temp;
1016 break;
1017 }
1018
Jeff Brown5c1ed842010-07-14 18:48:53 -07001019 mDispatcher->notifyMotion(when, device->id, AINPUT_SOURCE_TRACKBALL, policyFlags,
1020 motionEventAction, globalMetaState(), AMOTION_EVENT_EDGE_FLAG_NONE,
Jeff Browne839a582010-04-22 18:58:52 -07001021 1, & pointerId, & pointerCoords,
1022 device->trackball.precalculated.xPrecision,
1023 device->trackball.precalculated.yPrecision,
1024 device->trackball.current.downTime);
1025}
1026
1027void InputReader::onConfigurationChanged(nsecs_t when) {
1028 // Reset global meta state because it depends on the list of all configured devices.
1029 resetGlobalMetaState();
1030
1031 // Reset virtual keys, just in case.
Jeff Brown54bc2812010-06-15 01:31:58 -07001032 updateExportedVirtualKeyState();
1033
1034 // Update input configuration.
1035 updateExportedInputConfiguration();
Jeff Browne839a582010-04-22 18:58:52 -07001036
1037 // Enqueue configuration changed.
Jeff Brown54bc2812010-06-15 01:31:58 -07001038 mDispatcher->notifyConfigurationChanged(when);
Jeff Browne839a582010-04-22 18:58:52 -07001039}
1040
1041bool InputReader::applyStandardInputDispatchPolicyActions(nsecs_t when,
1042 int32_t policyActions, uint32_t* policyFlags) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001043 if (policyActions & InputReaderPolicyInterface::ACTION_APP_SWITCH_COMING) {
Jeff Browne839a582010-04-22 18:58:52 -07001044 mDispatcher->notifyAppSwitchComing(when);
1045 }
1046
Jeff Brown54bc2812010-06-15 01:31:58 -07001047 if (policyActions & InputReaderPolicyInterface::ACTION_WOKE_HERE) {
Jeff Browne839a582010-04-22 18:58:52 -07001048 *policyFlags |= POLICY_FLAG_WOKE_HERE;
1049 }
1050
Jeff Brown54bc2812010-06-15 01:31:58 -07001051 if (policyActions & InputReaderPolicyInterface::ACTION_BRIGHT_HERE) {
Jeff Browne839a582010-04-22 18:58:52 -07001052 *policyFlags |= POLICY_FLAG_BRIGHT_HERE;
1053 }
1054
Jeff Brown54bc2812010-06-15 01:31:58 -07001055 return policyActions & InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Browne839a582010-04-22 18:58:52 -07001056}
1057
1058void InputReader::resetDisplayProperties() {
1059 mDisplayWidth = mDisplayHeight = -1;
1060 mDisplayOrientation = -1;
1061}
1062
1063bool InputReader::refreshDisplayProperties() {
1064 int32_t newWidth, newHeight, newOrientation;
1065 if (mPolicy->getDisplayInfo(0, & newWidth, & newHeight, & newOrientation)) {
1066 if (newWidth != mDisplayWidth || newHeight != mDisplayHeight) {
1067 LOGD("Display size changed from %dx%d to %dx%d, updating device configuration",
1068 mDisplayWidth, mDisplayHeight, newWidth, newHeight);
1069
1070 mDisplayWidth = newWidth;
1071 mDisplayHeight = newHeight;
1072
1073 for (size_t i = 0; i < mDevices.size(); i++) {
1074 configureDeviceForCurrentDisplaySize(mDevices.valueAt(i));
1075 }
1076 }
1077
Jeff Brown4036f7f2010-06-29 16:52:21 -07001078 if (newOrientation != mDisplayOrientation) {
1079 LOGD("Display orientation changed to %d", mDisplayOrientation);
1080
1081 mDisplayOrientation = newOrientation;
1082 }
Jeff Browne839a582010-04-22 18:58:52 -07001083 return true;
1084 } else {
1085 resetDisplayProperties();
1086 return false;
1087 }
1088}
1089
1090InputDevice* InputReader::getDevice(int32_t deviceId) {
1091 ssize_t index = mDevices.indexOfKey(deviceId);
1092 return index >= 0 ? mDevices.valueAt((size_t) index) : NULL;
1093}
1094
1095InputDevice* InputReader::getNonIgnoredDevice(int32_t deviceId) {
1096 InputDevice* device = getDevice(deviceId);
1097 return device && ! device->ignored ? device : NULL;
1098}
1099
1100void InputReader::addDevice(nsecs_t when, int32_t deviceId) {
1101 uint32_t classes = mEventHub->getDeviceClasses(deviceId);
1102 String8 name = mEventHub->getDeviceName(deviceId);
1103 InputDevice* device = new InputDevice(deviceId, classes, name);
1104
1105 if (classes != 0) {
1106 LOGI("Device added: id=0x%x, name=%s, classes=%02x", device->id,
1107 device->name.string(), device->classes);
1108
1109 configureDevice(device);
1110 } else {
1111 LOGI("Device added: id=0x%x, name=%s (ignored non-input device)", device->id,
1112 device->name.string());
1113
1114 device->ignored = true;
1115 }
1116
1117 device->reset();
1118
1119 mDevices.add(deviceId, device);
1120
1121 if (! device->ignored) {
1122 onConfigurationChanged(when);
1123 }
1124}
1125
1126void InputReader::removeDevice(nsecs_t when, InputDevice* device) {
1127 mDevices.removeItem(device->id);
1128
1129 if (! device->ignored) {
1130 LOGI("Device removed: id=0x%x, name=%s, classes=%02x", device->id,
1131 device->name.string(), device->classes);
1132
1133 onConfigurationChanged(when);
1134 } else {
1135 LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)", device->id,
1136 device->name.string());
1137 }
1138
1139 delete device;
1140}
1141
1142void InputReader::configureDevice(InputDevice* device) {
1143 if (device->isMultiTouchScreen()) {
1144 configureAbsoluteAxisInfo(device, ABS_MT_POSITION_X, "X",
1145 & device->touchScreen.parameters.xAxis);
1146 configureAbsoluteAxisInfo(device, ABS_MT_POSITION_Y, "Y",
1147 & device->touchScreen.parameters.yAxis);
1148 configureAbsoluteAxisInfo(device, ABS_MT_TOUCH_MAJOR, "Pressure",
1149 & device->touchScreen.parameters.pressureAxis);
1150 configureAbsoluteAxisInfo(device, ABS_MT_WIDTH_MAJOR, "Size",
1151 & device->touchScreen.parameters.sizeAxis);
Jeff Brown5c1ed842010-07-14 18:48:53 -07001152 configureAbsoluteAxisInfo(device, ABS_MT_ORIENTATION, "Orientation",
1153 & device->touchScreen.parameters.orientationAxis);
Jeff Browne839a582010-04-22 18:58:52 -07001154 } else if (device->isSingleTouchScreen()) {
1155 configureAbsoluteAxisInfo(device, ABS_X, "X",
1156 & device->touchScreen.parameters.xAxis);
1157 configureAbsoluteAxisInfo(device, ABS_Y, "Y",
1158 & device->touchScreen.parameters.yAxis);
1159 configureAbsoluteAxisInfo(device, ABS_PRESSURE, "Pressure",
1160 & device->touchScreen.parameters.pressureAxis);
1161 configureAbsoluteAxisInfo(device, ABS_TOOL_WIDTH, "Size",
1162 & device->touchScreen.parameters.sizeAxis);
Jeff Brown5c1ed842010-07-14 18:48:53 -07001163 device->touchScreen.parameters.orientationAxis.valid = false;
Jeff Browne839a582010-04-22 18:58:52 -07001164 }
1165
1166 if (device->isTouchScreen()) {
1167 device->touchScreen.parameters.useBadTouchFilter =
1168 mPolicy->filterTouchEvents();
1169 device->touchScreen.parameters.useAveragingTouchFilter =
1170 mPolicy->filterTouchEvents();
1171 device->touchScreen.parameters.useJumpyTouchFilter =
1172 mPolicy->filterJumpyTouchEvents();
1173
Jeff Brown4036f7f2010-06-29 16:52:21 -07001174 if (device->touchScreen.parameters.pressureAxis.valid) {
1175 device->touchScreen.precalculated.pressureOrigin =
1176 device->touchScreen.parameters.pressureAxis.minValue;
1177 device->touchScreen.precalculated.pressureScale =
1178 1.0f / device->touchScreen.parameters.pressureAxis.range;
1179 } else {
1180 device->touchScreen.precalculated.pressureOrigin = 0;
1181 device->touchScreen.precalculated.pressureScale = 1.0f;
1182 }
1183
1184 if (device->touchScreen.parameters.sizeAxis.valid) {
1185 device->touchScreen.precalculated.sizeOrigin =
1186 device->touchScreen.parameters.sizeAxis.minValue;
1187 device->touchScreen.precalculated.sizeScale =
1188 1.0f / device->touchScreen.parameters.sizeAxis.range;
1189 } else {
1190 device->touchScreen.precalculated.sizeOrigin = 0;
1191 device->touchScreen.precalculated.sizeScale = 1.0f;
1192 }
Jeff Brown5c1ed842010-07-14 18:48:53 -07001193
1194 if (device->touchScreen.parameters.orientationAxis.valid
1195 && device->touchScreen.parameters.orientationAxis.maxValue > 0) {
1196 device->touchScreen.precalculated.orientationScale =
1197 M_PI_4 / device->touchScreen.parameters.orientationAxis.maxValue;
1198 } else {
1199 device->touchScreen.precalculated.orientationScale = 0.0f;
1200 }
Jeff Browne839a582010-04-22 18:58:52 -07001201 }
1202
1203 if (device->isTrackball()) {
1204 device->trackball.precalculated.xPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
1205 device->trackball.precalculated.yPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
1206 device->trackball.precalculated.xScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
1207 device->trackball.precalculated.yScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
1208 }
1209
1210 configureDeviceForCurrentDisplaySize(device);
1211}
1212
1213void InputReader::configureDeviceForCurrentDisplaySize(InputDevice* device) {
1214 if (device->isTouchScreen()) {
Jeff Brown4036f7f2010-06-29 16:52:21 -07001215 if (device->touchScreen.parameters.xAxis.valid
1216 && device->touchScreen.parameters.yAxis.valid) {
1217 device->touchScreen.precalculated.xOrigin =
1218 device->touchScreen.parameters.xAxis.minValue;
1219 device->touchScreen.precalculated.yOrigin =
1220 device->touchScreen.parameters.yAxis.minValue;
Jeff Browne839a582010-04-22 18:58:52 -07001221
Jeff Brown4036f7f2010-06-29 16:52:21 -07001222 if (mDisplayWidth < 0) {
1223 LOGD("Skipping part of touch screen configuration since display size is unknown.");
1224
1225 device->touchScreen.precalculated.xScale = 1.0f;
1226 device->touchScreen.precalculated.yScale = 1.0f;
1227 } else {
1228 LOGI("Device configured: id=0x%x, name=%s (display size was changed)", device->id,
1229 device->name.string());
1230
1231 device->touchScreen.precalculated.xScale =
1232 float(mDisplayWidth) / device->touchScreen.parameters.xAxis.range;
1233 device->touchScreen.precalculated.yScale =
1234 float(mDisplayHeight) / device->touchScreen.parameters.yAxis.range;
1235
1236 configureVirtualKeys(device);
1237 }
1238 } else {
1239 device->touchScreen.precalculated.xOrigin = 0;
1240 device->touchScreen.precalculated.xScale = 1.0f;
1241 device->touchScreen.precalculated.yOrigin = 0;
1242 device->touchScreen.precalculated.yScale = 1.0f;
Jeff Browne839a582010-04-22 18:58:52 -07001243 }
1244 }
1245}
1246
1247void InputReader::configureVirtualKeys(InputDevice* device) {
Jeff Brown4036f7f2010-06-29 16:52:21 -07001248 assert(device->touchScreen.parameters.xAxis.valid
1249 && device->touchScreen.parameters.yAxis.valid);
1250
Jeff Browne839a582010-04-22 18:58:52 -07001251 device->touchScreen.virtualKeys.clear();
1252
Jeff Brown54bc2812010-06-15 01:31:58 -07001253 Vector<InputReaderPolicyInterface::VirtualKeyDefinition> virtualKeyDefinitions;
Jeff Browne839a582010-04-22 18:58:52 -07001254 mPolicy->getVirtualKeyDefinitions(device->name, virtualKeyDefinitions);
1255 if (virtualKeyDefinitions.size() == 0) {
1256 return;
1257 }
1258
1259 device->touchScreen.virtualKeys.setCapacity(virtualKeyDefinitions.size());
1260
1261 int32_t touchScreenLeft = device->touchScreen.parameters.xAxis.minValue;
1262 int32_t touchScreenTop = device->touchScreen.parameters.yAxis.minValue;
1263 int32_t touchScreenWidth = device->touchScreen.parameters.xAxis.range;
1264 int32_t touchScreenHeight = device->touchScreen.parameters.yAxis.range;
1265
1266 for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001267 const InputReaderPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
Jeff Browne839a582010-04-22 18:58:52 -07001268 virtualKeyDefinitions[i];
1269
1270 device->touchScreen.virtualKeys.add();
1271 InputDevice::VirtualKey& virtualKey =
1272 device->touchScreen.virtualKeys.editTop();
1273
1274 virtualKey.scanCode = virtualKeyDefinition.scanCode;
1275 int32_t keyCode;
1276 uint32_t flags;
1277 if (mEventHub->scancodeToKeycode(device->id, virtualKey.scanCode,
1278 & keyCode, & flags)) {
Jeff Brownf16c26d2010-07-02 15:37:36 -07001279 LOGW(" VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
Jeff Browne839a582010-04-22 18:58:52 -07001280 device->touchScreen.virtualKeys.pop(); // drop the key
1281 continue;
1282 }
1283
1284 virtualKey.keyCode = keyCode;
1285 virtualKey.flags = flags;
1286
1287 // convert the key definition's display coordinates into touch coordinates for a hit box
1288 int32_t halfWidth = virtualKeyDefinition.width / 2;
1289 int32_t halfHeight = virtualKeyDefinition.height / 2;
1290
1291 virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
1292 * touchScreenWidth / mDisplayWidth + touchScreenLeft;
1293 virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
1294 * touchScreenWidth / mDisplayWidth + touchScreenLeft;
1295 virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
1296 * touchScreenHeight / mDisplayHeight + touchScreenTop;
1297 virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
1298 * touchScreenHeight / mDisplayHeight + touchScreenTop;
1299
1300 LOGI(" VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
1301 virtualKey.scanCode, virtualKey.keyCode,
1302 virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
1303 }
1304}
1305
1306void InputReader::configureAbsoluteAxisInfo(InputDevice* device,
1307 int axis, const char* name, InputDevice::AbsoluteAxisInfo* out) {
1308 if (! mEventHub->getAbsoluteInfo(device->id, axis,
1309 & out->minValue, & out->maxValue, & out->flat, &out->fuzz)) {
1310 out->range = out->maxValue - out->minValue;
1311 if (out->range != 0) {
1312 LOGI(" %s: min=%d max=%d flat=%d fuzz=%d",
1313 name, out->minValue, out->maxValue, out->flat, out->fuzz);
Jeff Brown4036f7f2010-06-29 16:52:21 -07001314 out->valid = true;
Jeff Browne839a582010-04-22 18:58:52 -07001315 return;
1316 }
1317 }
1318
Jeff Brown4036f7f2010-06-29 16:52:21 -07001319 out->valid = false;
Jeff Browne839a582010-04-22 18:58:52 -07001320 out->minValue = 0;
1321 out->maxValue = 0;
1322 out->flat = 0;
1323 out->fuzz = 0;
1324 out->range = 0;
Jeff Brown4036f7f2010-06-29 16:52:21 -07001325 LOGI(" %s: unknown axis values, marking as invalid", name);
Jeff Browne839a582010-04-22 18:58:52 -07001326}
1327
Jeff Brown54bc2812010-06-15 01:31:58 -07001328void InputReader::configureExcludedDevices() {
1329 Vector<String8> excludedDeviceNames;
1330 mPolicy->getExcludedDeviceNames(excludedDeviceNames);
1331
1332 for (size_t i = 0; i < excludedDeviceNames.size(); i++) {
1333 mEventHub->addExcludedDevice(excludedDeviceNames[i]);
1334 }
1335}
1336
Jeff Browne839a582010-04-22 18:58:52 -07001337void InputReader::resetGlobalMetaState() {
1338 mGlobalMetaState = -1;
1339}
1340
1341int32_t InputReader::globalMetaState() {
1342 if (mGlobalMetaState == -1) {
1343 mGlobalMetaState = 0;
1344 for (size_t i = 0; i < mDevices.size(); i++) {
1345 InputDevice* device = mDevices.valueAt(i);
1346 if (device->isKeyboard()) {
1347 mGlobalMetaState |= device->keyboard.current.metaState;
1348 }
1349 }
1350 }
1351 return mGlobalMetaState;
1352}
1353
Jeff Brown54bc2812010-06-15 01:31:58 -07001354void InputReader::updateExportedVirtualKeyState() {
Jeff Browne839a582010-04-22 18:58:52 -07001355 int32_t keyCode = -1, scanCode = -1;
1356
1357 for (size_t i = 0; i < mDevices.size(); i++) {
1358 InputDevice* device = mDevices.valueAt(i);
1359 if (device->isTouchScreen()) {
Jeff Brownf16c26d2010-07-02 15:37:36 -07001360 if (device->touchScreen.currentVirtualKey.status
1361 == InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN) {
Jeff Browne839a582010-04-22 18:58:52 -07001362 keyCode = device->touchScreen.currentVirtualKey.keyCode;
1363 scanCode = device->touchScreen.currentVirtualKey.scanCode;
1364 }
1365 }
1366 }
1367
Jeff Brown54bc2812010-06-15 01:31:58 -07001368 { // acquire exported state lock
Jeff Browne839a582010-04-22 18:58:52 -07001369 AutoMutex _l(mExportedStateLock);
1370
Jeff Brown54bc2812010-06-15 01:31:58 -07001371 mExportedVirtualKeyCode = keyCode;
1372 mExportedVirtualScanCode = scanCode;
1373 } // release exported state lock
Jeff Browne839a582010-04-22 18:58:52 -07001374}
1375
1376bool InputReader::getCurrentVirtualKey(int32_t* outKeyCode, int32_t* outScanCode) const {
Jeff Brown54bc2812010-06-15 01:31:58 -07001377 { // acquire exported state lock
1378 AutoMutex _l(mExportedStateLock);
Jeff Browne839a582010-04-22 18:58:52 -07001379
Jeff Brown54bc2812010-06-15 01:31:58 -07001380 *outKeyCode = mExportedVirtualKeyCode;
1381 *outScanCode = mExportedVirtualScanCode;
1382 return mExportedVirtualKeyCode != -1;
1383 } // release exported state lock
1384}
1385
1386void InputReader::updateExportedInputConfiguration() {
1387 int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
1388 int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
1389 int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
1390
1391 for (size_t i = 0; i < mDevices.size(); i++) {
1392 InputDevice* device = mDevices.valueAt(i);
1393 int32_t deviceClasses = device->classes;
1394
1395 if (deviceClasses & INPUT_DEVICE_CLASS_TOUCHSCREEN) {
1396 touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
1397 }
1398 if (deviceClasses & INPUT_DEVICE_CLASS_ALPHAKEY) {
1399 keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
1400 }
1401 if (deviceClasses & INPUT_DEVICE_CLASS_TRACKBALL) {
1402 navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
1403 } else if (deviceClasses & INPUT_DEVICE_CLASS_DPAD) {
1404 navigationConfig = InputConfiguration::NAVIGATION_DPAD;
1405 }
1406 }
1407
1408 { // acquire exported state lock
1409 AutoMutex _l(mExportedStateLock);
1410
1411 mExportedInputConfiguration.touchScreen = touchScreenConfig;
1412 mExportedInputConfiguration.keyboard = keyboardConfig;
1413 mExportedInputConfiguration.navigation = navigationConfig;
1414 } // release exported state lock
1415}
1416
1417void InputReader::getCurrentInputConfiguration(InputConfiguration* outConfiguration) const {
1418 { // acquire exported state lock
1419 AutoMutex _l(mExportedStateLock);
1420
1421 *outConfiguration = mExportedInputConfiguration;
1422 } // release exported state lock
1423}
1424
1425int32_t InputReader::getCurrentScanCodeState(int32_t deviceId, int32_t deviceClasses,
1426 int32_t scanCode) const {
1427 { // acquire exported state lock
1428 AutoMutex _l(mExportedStateLock);
1429
1430 if (mExportedVirtualScanCode == scanCode) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001431 return AKEY_STATE_VIRTUAL;
Jeff Brown54bc2812010-06-15 01:31:58 -07001432 }
1433 } // release exported state lock
1434
1435 return mEventHub->getScanCodeState(deviceId, deviceClasses, scanCode);
1436}
1437
1438int32_t InputReader::getCurrentKeyCodeState(int32_t deviceId, int32_t deviceClasses,
1439 int32_t keyCode) const {
1440 { // acquire exported state lock
1441 AutoMutex _l(mExportedStateLock);
1442
1443 if (mExportedVirtualKeyCode == keyCode) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001444 return AKEY_STATE_VIRTUAL;
Jeff Brown54bc2812010-06-15 01:31:58 -07001445 }
1446 } // release exported state lock
1447
1448 return mEventHub->getKeyCodeState(deviceId, deviceClasses, keyCode);
1449}
1450
1451int32_t InputReader::getCurrentSwitchState(int32_t deviceId, int32_t deviceClasses,
1452 int32_t sw) const {
1453 return mEventHub->getSwitchState(deviceId, deviceClasses, sw);
1454}
1455
1456bool InputReader::hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const {
1457 return mEventHub->hasKeys(numCodes, keyCodes, outFlags);
Jeff Browne839a582010-04-22 18:58:52 -07001458}
1459
1460
1461// --- InputReaderThread ---
1462
1463InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
1464 Thread(/*canCallJava*/ true), mReader(reader) {
1465}
1466
1467InputReaderThread::~InputReaderThread() {
1468}
1469
1470bool InputReaderThread::threadLoop() {
1471 mReader->loopOnce();
1472 return true;
1473}
1474
1475} // namespace android