Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java

Issue 1403453002: Delete best-effort keycode guessing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Apply changwan@ code review comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
index 109c8b8021d70a2f401804e823d5cc5c92c5242e..7eb72e77ed7608c310548c813f369e7dae9f34ea 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
@@ -109,10 +109,6 @@ public class ImeAdapter {
private final Handler mHandler;
private int mTextInputType;
private int mTextInputFlags;
- private String mLastComposeText;
-
- @VisibleForTesting
- int mLastSyntheticKeyCode;
@VisibleForTesting
boolean mIsShowWithoutHideOutstanding = false;
@@ -163,7 +159,6 @@ public class ImeAdapter {
*/
void setInputConnection(AdapterInputConnection inputConnection) {
mInputConnection = inputConnection;
- mLastComposeText = null;
}
/**
@@ -246,7 +241,6 @@ public class ImeAdapter {
nativeAttachImeAdapter(nativeImeAdapter);
}
mNativeImeAdapterAndroid = nativeImeAdapter;
- mLastComposeText = null;
mTextInputFlags = textInputFlags;
if (textInputType == mTextInputType) return;
mTextInputType = textInputType;
@@ -315,186 +309,71 @@ public class ImeAdapter {
if (mInputConnection != null) {
return mInputConnection.sendKeyEvent(event);
}
- return translateAndSendNativeEvents(event);
- }
-
- private int shouldSendKeyEventWithKeyCode(String text) {
- if (text.length() != 1) return COMPOSITION_KEY_CODE;
-
- if (text.equals("\n")) {
- return KeyEvent.KEYCODE_ENTER;
- } else if (text.equals("\t")) {
- return KeyEvent.KEYCODE_TAB;
- } else {
- return COMPOSITION_KEY_CODE;
- }
- }
-
- /**
- * @return Android KeyEvent for a single unicode character. Only one KeyEvent is returned
- * even if the system determined that various modifier keys (like Shift) would also have
- * been pressed.
- */
- private static KeyEvent androidKeyEventForCharacter(char chr) {
- if (sKeyCharacterMap == null) {
- sKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
- }
- sSingleCharArray[0] = chr;
- // TODO: Evaluate cost of this system call.
- KeyEvent[] events = sKeyCharacterMap.getEvents(sSingleCharArray);
- if (events == null) { // No known key sequence will create that character.
- return null;
- }
-
- for (int i = 0; i < events.length; ++i) {
- if (events[i].getAction() == KeyEvent.ACTION_DOWN
- && !KeyEvent.isModifierKey(events[i].getKeyCode())) {
- return events[i];
- }
- }
-
- return null; // No printing characters were found.
+ return sendKeyEvent(event);
}
/**
* @see BaseInputConnection#performContextMenuAction(int)
*/
- public boolean performContextMenuAction(int id) {
+ boolean performContextMenuAction(int id) {
Log.d(TAG, "performContextMenuAction: id [%d]", id);
return mViewEmbedder.performContextMenuAction(id);
}
- @VisibleForTesting
- public static KeyEvent getTypedKeyEventGuess(String oldtext, String newtext) {
- // Starting typing a new composition should add only a single character. Any composition
- // beginning with text longer than that must come from something other than typing so
- // return 0.
- if (oldtext == null) {
- if (newtext.length() == 1) {
- return androidKeyEventForCharacter(newtext.charAt(0));
- } else {
- return null;
- }
- }
-
- // The content has grown in length: assume the last character is the key that caused it.
- if (newtext.length() > oldtext.length() && newtext.startsWith(oldtext)) {
- return androidKeyEventForCharacter(newtext.charAt(newtext.length() - 1));
- }
-
- // The content has shrunk in length: assume that backspace was pressed.
- if (oldtext.length() > newtext.length() && oldtext.startsWith(newtext)) {
- return new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
+ boolean performEditorAction(int actionCode) {
+ if (mNativeImeAdapterAndroid == 0) return false;
+ if (actionCode == EditorInfo.IME_ACTION_NEXT) {
+ sendSyntheticKeyPress(KeyEvent.KEYCODE_TAB,
+ KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
+ | KeyEvent.FLAG_EDITOR_ACTION);
+ } else {
+ sendSyntheticKeyPress(KeyEvent.KEYCODE_ENTER,
+ KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
+ | KeyEvent.FLAG_EDITOR_ACTION);
}
-
- // The content is unchanged or has undergone a complex change (i.e. not a simple tail
- // modification) so return an unknown key-code.
- return null;
+ return true;
}
- void sendKeyEventWithKeyCode(int keyCode, int flags) {
+ @VisibleForTesting
+ protected void sendSyntheticKeyPress(int keyCode, int flags) {
long eventTime = SystemClock.uptimeMillis();
- mLastSyntheticKeyCode = keyCode;
- translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime,
+ sendKeyEvent(new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, keyCode, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
flags));
- translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
+ sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
KeyEvent.ACTION_UP, keyCode, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
flags));
}
- // Calls from Java to C++
- // TODO: Add performance tracing to more complicated functions.
- boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorPosition,
- boolean isCommit) {
+ boolean sendCompositionToNative(CharSequence text, int newCursorPosition, boolean isCommit) {
if (mNativeImeAdapterAndroid == 0) return false;
mViewEmbedder.onImeEvent();
- String textStr = text.toString();
- int keyCode = shouldSendKeyEventWithKeyCode(textStr);
- long timeStampMs = SystemClock.uptimeMillis();
+ long timestampMs = SystemClock.uptimeMillis();
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEventType.RawKeyDown,
+ timestampMs, COMPOSITION_KEY_CODE, 0, 0);
- if (keyCode != COMPOSITION_KEY_CODE) {
- sendKeyEventWithKeyCode(keyCode,
- KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);
+ if (isCommit) {
+ nativeCommitText(mNativeImeAdapterAndroid, text.toString());
} else {
- KeyEvent keyEvent = getTypedKeyEventGuess(mLastComposeText, textStr);
- int modifiers = 0;
- if (keyEvent != null) {
- keyCode = keyEvent.getKeyCode();
- modifiers = getModifiers(keyEvent.getMetaState());
- } else if (!textStr.equals(mLastComposeText)) {
- keyCode = KeyEvent.KEYCODE_UNKNOWN;
- } else {
- keyCode = -1;
- }
-
- // If this is a single-character commit with no previous composition, then treat it as
- // a native KeyDown/KeyUp pair with no composition rather than a synthetic pair with
- // composition below.
- if (keyCode > 0 && isCommit && mLastComposeText == null && textStr.length() == 1) {
- mLastSyntheticKeyCode = keyCode;
- return translateAndSendNativeEvents(keyEvent)
- && translateAndSendNativeEvents(
- KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_UP));
- }
-
- // Always send compose events. This is a quick fix for http://crbug.com/476497.
- keyCode = COMPOSITION_KEY_CODE;
- modifiers = 0;
-
- // When typing, there is no issue sending KeyDown and KeyUp events around the
- // composition event because those key events do nothing (other than call JS
- // handlers). Typing does not cause changes outside of a KeyPress event which
- // we don't call here. However, if the key-code is a control key such as
- // KEYCODE_DEL then there never is an associated KeyPress event and the KeyDown
- // event itself causes the action. The net result below is that the Renderer calls
- // cancelComposition() and then Android starts anew with setComposingRegion().
- // This stopping and restarting of composition could be a source of problems
- // with 3rd party keyboards.
- //
- // An alternative is to *not* call nativeSetComposingText() in the non-commit case
- // below. This avoids the restart of composition described above but fails to send
- // an update to the composition while in composition which, strictly speaking,
- // does not match the spec.
- //
- // For now, the solution is to endure the restarting of composition and only dive
- // into the alternate solution should there be problems in the field. --bcwhite
-
- if (keyCode >= 0) {
- nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEventType.RawKeyDown,
- timeStampMs, keyCode, modifiers, 0);
- }
-
- if (isCommit) {
- nativeCommitText(mNativeImeAdapterAndroid, textStr);
- textStr = null;
- } else {
- nativeSetComposingText(mNativeImeAdapterAndroid, text, textStr, newCursorPosition);
- }
-
- if (keyCode >= 0) {
- nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEventType.KeyUp,
- timeStampMs, keyCode, modifiers, 0);
- }
-
- mLastSyntheticKeyCode = keyCode;
+ nativeSetComposingText(
+ mNativeImeAdapterAndroid, text, text.toString(), newCursorPosition);
}
- mLastComposeText = textStr;
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEventType.KeyUp,
+ timestampMs, COMPOSITION_KEY_CODE, 0, 0);
return true;
}
@VisibleForTesting
protected void finishComposingText() {
- mLastComposeText = null;
if (mNativeImeAdapterAndroid == 0) return;
nativeFinishComposingText(mNativeImeAdapterAndroid);
}
- boolean translateAndSendNativeEvents(KeyEvent event) {
+ boolean sendKeyEvent(KeyEvent event) {
if (mNativeImeAdapterAndroid == 0) return false;
int action = event.getAction();
@@ -517,15 +396,6 @@ public class ImeAdapter {
event.getScanCode(), /*isSystemKey=*/false, event.getUnicodeChar());
}
- boolean sendSyntheticKeyEvent(int eventType, long timestampMs, int keyCode, int modifiers,
- int unicodeChar) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeSendSyntheticKeyEvent(
- mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, modifiers, unicodeChar);
- return true;
- }
-
/**
* Send a request to the native counterpart to delete a given range of characters.
* @param beforeLength Number of characters to extend the selection by before the existing
@@ -537,7 +407,11 @@ public class ImeAdapter {
boolean deleteSurroundingText(int beforeLength, int afterLength) {
mViewEmbedder.onImeEvent();
if (mNativeImeAdapterAndroid == 0) return false;
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEventType.RawKeyDown,
+ SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, 0);
nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afterLength);
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid,
+ WebInputEventType.KeyUp, SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, 0);
return true;
}
@@ -562,7 +436,6 @@ public class ImeAdapter {
boolean setComposingRegion(CharSequence text, int start, int end) {
if (mNativeImeAdapterAndroid == 0) return false;
nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
- mLastComposeText = text != null ? text.toString() : null;
return true;
}
@@ -596,7 +469,6 @@ public class ImeAdapter {
private void cancelComposition() {
Log.d(TAG, "cancelComposition");
if (mInputConnection != null) mInputConnection.restartInput();
- mLastComposeText = null;
}
@CalledByNative

Powered by Google App Engine
This is Rietveld 408576698