您的位置:首页 > 移动开发 > Android开发

Android应用程序键盘(Keyboard)消息处理机制分析(15)

2011-10-24 00:59 537 查看
Step 7. KeyboardInputMapper.processKey

这个函数定义在frameworks/base/libs/ui/InputReader.cpp文件中:

void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,

int32_t scanCode, uint32_t policyFlags) {

int32_t newMetaState;

nsecs_t downTime;

bool metaStateChanged = false;

{ // acquire lock

AutoMutex _l(mLock);

if (down) {

// Rotate key codes according to orientation if needed.

// Note: getDisplayInfo is non-reentrant so we can continue holding the lock.

if (mAssociatedDisplayId >= 0) {

int32_t orientation;

if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {

return;

}

keyCode = rotateKeyCode(keyCode, orientation);

}

// Add key down.

ssize_t keyDownIndex = findKeyDownLocked(scanCode);

if (keyDownIndex >= 0) {

// key repeat, be sure to use same keycode as before in case of rotation

keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;

} else {

// key down

if ((policyFlags & POLICY_FLAG_VIRTUAL)

&& mContext->shouldDropVirtualKey(when, getDevice(), keyCode, scanCode)) {

return;

}

mLocked.keyDowns.push();

KeyDown& keyDown = mLocked.keyDowns.editTop();

keyDown.keyCode = keyCode;

keyDown.scanCode = scanCode;

}

mLocked.downTime = when;

} else {

// Remove key down.

ssize_t keyDownIndex = findKeyDownLocked(scanCode);

if (keyDownIndex >= 0) {

// key up, be sure to use same keycode as before in case of rotation

keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;

mLocked.keyDowns.removeAt(size_t(keyDownIndex));

} else {

// key was not actually down

LOGI("Dropping key up from device %s because the key was not down. "

"keyCode=%d, scanCode=%d",

getDeviceName().string(), keyCode, scanCode);

return;

}

}

int32_t oldMetaState = mLocked.metaState;

newMetaState = updateMetaState(keyCode, down, oldMetaState);

if (oldMetaState != newMetaState) {

mLocked.metaState = newMetaState;

metaStateChanged = true;

}

downTime = mLocked.downTime;

} // release lock

if (metaStateChanged) {

getContext()->updateGlobalMetaState();

}

getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,

down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,

AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);

}

这个函数首先对对按键作一些处理,例如,当某一个DPAD键被按下时,根据当时屏幕方向的不同,它所表示的意义也不同,因此,这里需要根据当时屏幕的方向来调整键盘码:

// Rotate key codes according to orientation if needed.

// Note: getDisplayInfo is non-reentrant so we can continue holding the lock.

if (mAssociatedDisplayId >= 0) {

int32_t orientation;

if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {

return;

}

keyCode = rotateKeyCode(keyCode, orientation);

}

如果这个键是一直按着不放的,不管屏幕的方向如何,必须保证后面的键盘码和前面的一样:

// Add key down.

ssize_t keyDownIndex = findKeyDownLocked(scanCode);

if (keyDownIndex >= 0) {

// key repeat, be sure to use same keycode as before in case of rotation

keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;

} else {

// key down

if ((policyFlags & POLICY_FLAG_VIRTUAL)

&& mContext->shouldDropVirtualKey(when, getDevice(), keyCode, scanCode)) {

return;

}

mLocked.keyDowns.push();

KeyDown& keyDown = mLocked.keyDowns.editTop();

keyDown.keyCode = keyCode;

keyDown.scanCode = scanCode;

}

如果是第一次按下某个键,还必须把它保存在mLocked.keyDowns里面,就是为了处理上面讲的当这个键盘一直按着不放的时候屏幕方向发生改变的情况。

如果是松开键盘上的某个键,就把它从mLocked.keyDowns里面删除:

// Remove key down.

ssize_t keyDownIndex = findKeyDownLocked(scanCode);

if (keyDownIndex >= 0) {

// key up, be sure to use same keycode as before in case of rotation

keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;

mLocked.keyDowns.removeAt(size_t(keyDownIndex));

} else {

// key was not actually down

LOGI("Dropping key up from device %s because the key was not down. "

"keyCode=%d, scanCode=%d",

getDeviceName().string(), keyCode, scanCode);

return;

}

当然,对键盘事件的这些处理不是本文的重点,本文的重点是分析从键盘事件到当前激活的Activity窗口接收到这个键盘消息的过程。

最后,KeyboardInputMappger函数通知InputDispatcher,有键盘事件发生了:

getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,

down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,

AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息