Bug 844290 - Refactor GeckoInputConnection key handling code; r=cpeterson

This commit is contained in:
Jim Chen 2013-02-28 13:17:21 -05:00
parent bc85f57c13
commit 7b87561c4f

View File

@ -661,15 +661,7 @@ class GeckoInputConnection
return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return processKeyDown(keyCode, event);
}
private boolean processKeyDown(int keyCode, KeyEvent event) {
if (keyCode > KeyEvent.getMaxKeyCode())
return false;
private boolean shouldProcessKey(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_MENU:
case KeyEvent.KEYCODE_BACK:
@ -677,87 +669,96 @@ class GeckoInputConnection
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_SEARCH:
return false;
}
return true;
}
private boolean shouldSkipKeyListener(int keyCode, KeyEvent event) {
if (mIMEState == IME_STATE_DISABLED ||
mIMEState == IME_STATE_PLUGIN) {
return true;
}
// Preserve enter and tab keys for the browser
if (keyCode == KeyEvent.KEYCODE_ENTER ||
keyCode == KeyEvent.KEYCODE_TAB) {
return true;
}
// BaseKeyListener returns false even if it handled these keys for us,
// so we skip the key listener entirely and handle these ourselves
if (keyCode == KeyEvent.KEYCODE_DEL ||
keyCode == KeyEvent.KEYCODE_FORWARD_DEL) {
return true;
}
return false;
}
private KeyEvent translateKey(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 &&
mIMEActionHint.equalsIgnoreCase("next"))
event = new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB);
break;
default:
mIMEActionHint.equalsIgnoreCase("next")) {
return new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB);
}
break;
}
return event;
}
private boolean processKey(int keyCode, KeyEvent event, boolean down) {
if (keyCode > KeyEvent.getMaxKeyCode() ||
!shouldProcessKey(keyCode, event)) {
return false;
}
event = translateKey(keyCode, event);
keyCode = event.getKeyCode();
View view = getView();
KeyListener keyListener = TextKeyListener.getInstance();
// KeyListener returns true if it handled the event for us. KeyListener is only
// safe to use on the UI thread; therefore we need to pass a proxy Editable to it
if (mIMEState == IME_STATE_DISABLED ||
mIMEState == IME_STATE_PLUGIN ||
keyCode == KeyEvent.KEYCODE_ENTER ||
keyCode == KeyEvent.KEYCODE_DEL ||
keyCode == KeyEvent.KEYCODE_TAB ||
(event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 ||
view == null) {
if (view == null) {
mEditableClient.sendEvent(GeckoEvent.createKeyEvent(event));
return true;
}
// KeyListener returns true if it handled the event for us. KeyListener is only
// safe to use on the UI thread; therefore we need to pass a proxy Editable to it
KeyListener keyListener = TextKeyListener.getInstance();
Handler uiHandler = view.getRootView().getHandler();
Handler icHandler = mEditableClient.getInputConnectionHandler();
Editable uiEditable = mThreadUtils.getEditableForUiThread(uiHandler, icHandler);
if (!keyListener.onKeyDown(view, uiEditable, keyCode, event)) {
boolean skip = shouldSkipKeyListener(keyCode, event);
if (skip ||
(down && !keyListener.onKeyDown(view, uiEditable, keyCode, event)) ||
(!down && !keyListener.onKeyUp(view, uiEditable, keyCode, event))) {
mEditableClient.sendEvent(GeckoEvent.createKeyEvent(event));
if (skip && down) {
// Usually, the down key listener call above adjusts meta states for us.
// However, if we skip that call above, we have to manually adjust meta
// states so the meta states remain consistent
TextKeyListener.adjustMetaAfterKeypress(uiEditable);
}
}
return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return processKey(keyCode, event, true);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return processKeyUp(keyCode, event);
}
private boolean processKeyUp(int keyCode, KeyEvent event) {
if (keyCode > KeyEvent.getMaxKeyCode())
return false;
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_SEARCH:
case KeyEvent.KEYCODE_MENU:
return false;
default:
break;
}
View view = getView();
KeyListener keyListener = TextKeyListener.getInstance();
// KeyListener returns true if it handled the event for us. KeyListener is only
// safe to use on the UI thread; therefore we need to pass a proxy Editable to it
if (mIMEState == IME_STATE_DISABLED ||
mIMEState == IME_STATE_PLUGIN ||
keyCode == KeyEvent.KEYCODE_ENTER ||
keyCode == KeyEvent.KEYCODE_DEL ||
(event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 ||
view == null) {
mEditableClient.sendEvent(GeckoEvent.createKeyEvent(event));
return true;
}
Handler uiHandler = view.getRootView().getHandler();
Handler icHandler = mEditableClient.getInputConnectionHandler();
Editable uiEditable = mThreadUtils.getEditableForUiThread(uiHandler, icHandler);
if (!keyListener.onKeyUp(view, uiEditable, keyCode, event)) {
mEditableClient.sendEvent(GeckoEvent.createKeyEvent(event));
}
return true;
return processKey(keyCode, event, false);
}
@Override
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
// KEYCODE_UNKNOWN means the characters are in KeyEvent.getCharacters()
return commitText(event.getCharacters(), 1);
}
while ((repeatCount--) != 0) {
if (!processKeyDown(keyCode, event) ||
!processKeyUp(keyCode, event)) {
if (!processKey(keyCode, event, true) ||
!processKey(keyCode, event, false)) {
return false;
}
}