More native input dispatch work.

Removed old input dispatch code.
Refactored the policy callbacks.
Pushed a tiny bit of the power manager state down to native.
Fixed long press on MENU.
Made the virtual key detection and cancelation a bit more precise.

Change-Id: I5d8c1062f7ea0ab3b54c6fadb058c4d5f5a9e02e
This commit is contained in:
Jeff Brown 2010-07-02 15:37:36 -07:00
parent bf83375c73
commit f16c26dec9
3 changed files with 89 additions and 61 deletions

View File

@ -250,7 +250,13 @@ struct InputDevice {
nsecs_t downTime;
struct CurrentVirtualKeyState {
bool down;
enum Status {
STATUS_UP,
STATUS_DOWN,
STATUS_CANCELED
};
Status status;
nsecs_t downTime;
int32_t keyCode;
int32_t scanCode;
@ -295,6 +301,7 @@ struct InputDevice {
void calculatePointerIds();
bool isPointInsideDisplay(int32_t x, int32_t y) const;
const InputDevice::VirtualKey* findVirtualKeyHit() const;
};
InputDevice(int32_t id, uint32_t classes, String8 name);
@ -390,11 +397,9 @@ public:
virtual bool getDisplayInfo(int32_t displayId,
int32_t* width, int32_t* height, int32_t* orientation) = 0;
/* Provides feedback for a virtual key.
/* Provides feedback for a virtual key down.
*/
virtual void virtualKeyFeedback(nsecs_t when, int32_t deviceId,
int32_t action, int32_t flags, int32_t keyCode,
int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
virtual void virtualKeyDownFeedback() = 0;
/* Intercepts a key event.
* The policy can use this method as an opportunity to perform power management functions

View File

@ -299,14 +299,13 @@ void InputDispatcher::processKeyRepeatLockedInterruptible(
uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
if (entry->refCount == 1) {
entry->eventTime = currentTime;
entry->downTime = currentTime;
entry->policyFlags = policyFlags;
entry->repeatCount += 1;
} else {
KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
entry->deviceId, entry->nature, policyFlags,
entry->action, entry->flags, entry->keyCode, entry->scanCode,
entry->metaState, entry->repeatCount + 1, currentTime);
entry->metaState, entry->repeatCount + 1, entry->downTime);
mKeyRepeatState.lastKeyEntry = newEntry;
mAllocator.releaseKeyEntry(entry);
@ -314,6 +313,10 @@ void InputDispatcher::processKeyRepeatLockedInterruptible(
entry = newEntry;
}
if (entry->repeatCount == 1) {
entry->flags |= KEY_EVENT_FLAG_LONG_PRESS;
}
mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout;
#if DEBUG_OUTBOUND_EVENT_DETAILS

View File

@ -189,7 +189,7 @@ void InputDevice::TrackballState::reset() {
void InputDevice::TouchScreenState::reset() {
lastTouch.clear();
downTime = 0;
currentVirtualKey.down = false;
currentVirtualKey.status = CurrentVirtualKeyState::STATUS_UP;
for (uint32_t i = 0; i < MAX_POINTERS; i++) {
averagingTouchFilter.historyStart[i] = 0;
@ -746,6 +746,29 @@ bool InputDevice::TouchScreenState::isPointInsideDisplay(int32_t x, int32_t y) c
&& y <= parameters.yAxis.maxValue;
}
const InputDevice::VirtualKey* InputDevice::TouchScreenState::findVirtualKeyHit() const {
int32_t x = currentTouch.pointers[0].x;
int32_t y = currentTouch.pointers[0].y;
for (size_t i = 0; i < virtualKeys.size(); i++) {
const InputDevice::VirtualKey& virtualKey = virtualKeys[i];
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
"left=%d, top=%d, right=%d, bottom=%d",
x, y,
virtualKey.keyCode, virtualKey.scanCode,
virtualKey.hitLeft, virtualKey.hitTop,
virtualKey.hitRight, virtualKey.hitBottom);
#endif
if (virtualKey.isHit(x, y)) {
return & virtualKey;
}
}
return NULL;
}
// --- InputDevice::SingleTouchScreenState ---
@ -1269,81 +1292,76 @@ void InputReader::onTouchScreenChanged(nsecs_t when,
bool InputReader::consumeVirtualKeyTouches(nsecs_t when,
InputDevice* device, uint32_t policyFlags) {
if (device->touchScreen.currentVirtualKey.down) {
switch (device->touchScreen.currentVirtualKey.status) {
case InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_CANCELED:
if (device->touchScreen.currentTouch.pointerCount == 0) {
// Pointer went up while virtual key was down. Send key up event.
device->touchScreen.currentVirtualKey.down = false;
// Pointer went up after virtual key canceled.
device->touchScreen.currentVirtualKey.status =
InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_UP;
}
return true; // consumed
case InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN:
if (device->touchScreen.currentTouch.pointerCount == 0) {
// Pointer went up while virtual key was down.
device->touchScreen.currentVirtualKey.status =
InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_UP;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
device->touchScreen.currentVirtualKey.keyCode,
device->touchScreen.currentVirtualKey.scanCode);
#endif
dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
return true; // consumed
}
int32_t x = device->touchScreen.currentTouch.pointers[0].x;
int32_t y = device->touchScreen.currentTouch.pointers[0].y;
if (device->touchScreen.isPointInsideDisplay(x, y)
|| device->touchScreen.currentTouch.pointerCount != 1) {
// Pointer moved inside the display area or another pointer also went down.
// Send key cancellation.
device->touchScreen.currentVirtualKey.down = false;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
device->touchScreen.currentVirtualKey.keyCode,
device->touchScreen.currentVirtualKey.scanCode);
#endif
dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY
| KEY_EVENT_FLAG_CANCELED);
// Clear the last touch data so we will consider the pointer as having just been
// pressed down when generating subsequent motion events.
device->touchScreen.lastTouch.clear();
return false; // not consumed
if (device->touchScreen.currentTouch.pointerCount == 1) {
const InputDevice::VirtualKey* virtualKey = device->touchScreen.findVirtualKeyHit();
if (virtualKey
&& virtualKey->keyCode == device->touchScreen.currentVirtualKey.keyCode) {
// Pointer is still within the space of the virtual key.
return true; // consumed
}
}
} else if (device->touchScreen.currentTouch.pointerCount == 1
&& device->touchScreen.lastTouch.pointerCount == 0) {
int32_t x = device->touchScreen.currentTouch.pointers[0].x;
int32_t y = device->touchScreen.currentTouch.pointers[0].y;
for (size_t i = 0; i < device->touchScreen.virtualKeys.size(); i++) {
const InputDevice::VirtualKey& virtualKey = device->touchScreen.virtualKeys[i];
// Pointer left virtual key area or another pointer also went down.
// Send key cancellation.
device->touchScreen.currentVirtualKey.status =
InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_CANCELED;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
"left=%d, top=%d, right=%d, bottom=%d",
x, y,
virtualKey.keyCode, virtualKey.scanCode,
virtualKey.hitLeft, virtualKey.hitTop,
virtualKey.hitRight, virtualKey.hitBottom);
LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
device->touchScreen.currentVirtualKey.keyCode,
device->touchScreen.currentVirtualKey.scanCode);
#endif
dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP,
KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY
| KEY_EVENT_FLAG_CANCELED);
return true; // consumed
if (virtualKey.isHit(x, y)) {
device->touchScreen.currentVirtualKey.down = true;
default:
if (device->touchScreen.currentTouch.pointerCount == 1
&& device->touchScreen.lastTouch.pointerCount == 0) {
// Pointer just went down. Check for virtual key hit.
const InputDevice::VirtualKey* virtualKey = device->touchScreen.findVirtualKeyHit();
if (virtualKey) {
device->touchScreen.currentVirtualKey.status =
InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN;
device->touchScreen.currentVirtualKey.downTime = when;
device->touchScreen.currentVirtualKey.keyCode = virtualKey.keyCode;
device->touchScreen.currentVirtualKey.scanCode = virtualKey.scanCode;
device->touchScreen.currentVirtualKey.keyCode = virtualKey->keyCode;
device->touchScreen.currentVirtualKey.scanCode = virtualKey->scanCode;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
device->touchScreen.currentVirtualKey.keyCode,
device->touchScreen.currentVirtualKey.scanCode);
LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
device->touchScreen.currentVirtualKey.keyCode,
device->touchScreen.currentVirtualKey.scanCode);
#endif
dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_DOWN,
KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
return true; // consumed
}
}
return false; // not consumed
}
return false; // not consumed
}
void InputReader::dispatchVirtualKey(nsecs_t when,
@ -1356,8 +1374,9 @@ void InputReader::dispatchVirtualKey(nsecs_t when,
nsecs_t downTime = device->touchScreen.currentVirtualKey.downTime;
int32_t metaState = globalMetaState();
mPolicy->virtualKeyFeedback(when, device->id, keyEventAction, keyEventFlags,
keyCode, scanCode, metaState, downTime);
if (keyEventAction == KEY_EVENT_ACTION_DOWN) {
mPolicy->virtualKeyDownFeedback();
}
int32_t policyActions = mPolicy->interceptKey(when, device->id,
keyEventAction == KEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
@ -1852,7 +1871,7 @@ void InputReader::configureVirtualKeys(InputDevice* device) {
uint32_t flags;
if (mEventHub->scancodeToKeycode(device->id, virtualKey.scanCode,
& keyCode, & flags)) {
LOGI(" VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
LOGW(" VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
device->touchScreen.virtualKeys.pop(); // drop the key
continue;
}
@ -1933,7 +1952,8 @@ void InputReader::updateExportedVirtualKeyState() {
for (size_t i = 0; i < mDevices.size(); i++) {
InputDevice* device = mDevices.valueAt(i);
if (device->isTouchScreen()) {
if (device->touchScreen.currentVirtualKey.down) {
if (device->touchScreen.currentVirtualKey.status
== InputDevice::TouchScreenState::CurrentVirtualKeyState::STATUS_DOWN) {
keyCode = device->touchScreen.currentVirtualKey.keyCode;
scanCode = device->touchScreen.currentVirtualKey.scanCode;
}