| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.content.browser.input; | 5 package org.chromium.content.browser.input; |
| 6 | 6 |
| 7 import android.os.Handler; | 7 import android.os.Handler; |
| 8 import android.os.ResultReceiver; | 8 import android.os.ResultReceiver; |
| 9 import android.os.SystemClock; | 9 import android.os.SystemClock; |
| 10 import android.text.Editable; | 10 import android.text.Editable; |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 } | 331 } |
| 332 | 332 |
| 333 /** | 333 /** |
| 334 * @return true if the selected text is of password. | 334 * @return true if the selected text is of password. |
| 335 */ | 335 */ |
| 336 public boolean isSelectionPassword() { | 336 public boolean isSelectionPassword() { |
| 337 return mTextInputType == sTextInputTypePassword; | 337 return mTextInputType == sTextInputTypePassword; |
| 338 } | 338 } |
| 339 | 339 |
| 340 public boolean dispatchKeyEvent(KeyEvent event) { | 340 public boolean dispatchKeyEvent(KeyEvent event) { |
| 341 return translateAndSendNativeEvents(event); | 341 // Physical keyboards have their events come through here instead of |
| 342 // AdapterInputConnection. |
| 343 if (mInputConnection != null) { |
| 344 return mInputConnection.sendKeyEvent(event); |
| 345 } |
| 346 return translateAndSendNativeEvents(event, 0); |
| 342 } | 347 } |
| 343 | 348 |
| 344 private int shouldSendKeyEventWithKeyCode(String text) { | 349 private int shouldSendKeyEventWithKeyCode(String text) { |
| 345 if (text.length() != 1) return COMPOSITION_KEY_CODE; | 350 if (text.length() != 1) return COMPOSITION_KEY_CODE; |
| 346 | 351 |
| 347 if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER; | 352 if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER; |
| 348 else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB; | 353 else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB; |
| 349 else return COMPOSITION_KEY_CODE; | 354 else return COMPOSITION_KEY_CODE; |
| 350 } | 355 } |
| 351 | 356 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 // modification) so return an unknown key-code. | 405 // modification) so return an unknown key-code. |
| 401 return null; | 406 return null; |
| 402 } | 407 } |
| 403 | 408 |
| 404 void sendKeyEventWithKeyCode(int keyCode, int flags) { | 409 void sendKeyEventWithKeyCode(int keyCode, int flags) { |
| 405 long eventTime = SystemClock.uptimeMillis(); | 410 long eventTime = SystemClock.uptimeMillis(); |
| 406 mLastSyntheticKeyCode = keyCode; | 411 mLastSyntheticKeyCode = keyCode; |
| 407 translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime, | 412 translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime, |
| 408 KeyEvent.ACTION_DOWN, keyCode, 0, 0, | 413 KeyEvent.ACTION_DOWN, keyCode, 0, 0, |
| 409 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, | 414 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, |
| 410 flags)); | 415 flags), 0); |
| 411 translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMillis(), ev
entTime, | 416 translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMillis(), ev
entTime, |
| 412 KeyEvent.ACTION_UP, keyCode, 0, 0, | 417 KeyEvent.ACTION_UP, keyCode, 0, 0, |
| 413 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, | 418 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, |
| 414 flags)); | 419 flags), 0); |
| 415 } | 420 } |
| 416 | 421 |
| 417 // Calls from Java to C++ | 422 // Calls from Java to C++ |
| 418 // TODO: Add performance tracing to more complicated functions. | 423 // TODO: Add performance tracing to more complicated functions. |
| 419 | 424 |
| 420 boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorP
osition, | 425 boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorP
osition, |
| 421 boolean isCommit) { | 426 boolean isCommit) { |
| 422 if (mNativeImeAdapterAndroid == 0) return false; | 427 if (mNativeImeAdapterAndroid == 0) return false; |
| 423 mViewEmbedder.onImeEvent(); | 428 mViewEmbedder.onImeEvent(); |
| 424 | 429 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 439 keyCode = KeyEvent.KEYCODE_UNKNOWN; | 444 keyCode = KeyEvent.KEYCODE_UNKNOWN; |
| 440 } else { | 445 } else { |
| 441 keyCode = -1; | 446 keyCode = -1; |
| 442 } | 447 } |
| 443 | 448 |
| 444 // If this is a commit with no previous composition, then treat it a
s a native | 449 // If this is a commit with no previous composition, then treat it a
s a native |
| 445 // KeyDown/KeyUp pair with no composition rather than a synthetic pa
ir with | 450 // KeyDown/KeyUp pair with no composition rather than a synthetic pa
ir with |
| 446 // composition below. | 451 // composition below. |
| 447 if (keyCode > 0 && isCommit && mLastComposeText == null) { | 452 if (keyCode > 0 && isCommit && mLastComposeText == null) { |
| 448 mLastSyntheticKeyCode = keyCode; | 453 mLastSyntheticKeyCode = keyCode; |
| 449 return translateAndSendNativeEvents(keyEvent) && | 454 return translateAndSendNativeEvents(keyEvent, 0) |
| 450 translateAndSendNativeEvents(KeyEvent.changeAction( | 455 && translateAndSendNativeEvents( |
| 451 keyEvent, KeyEvent.ACTION_UP)); | 456 KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_
UP), 0); |
| 452 } | 457 } |
| 453 | 458 |
| 454 // When typing, there is no issue sending KeyDown and KeyUp events a
round the | 459 // When typing, there is no issue sending KeyDown and KeyUp events a
round the |
| 455 // composition event because those key events do nothing (other than
call JS | 460 // composition event because those key events do nothing (other than
call JS |
| 456 // handlers). Typing does not cause changes outside of a KeyPress e
vent which | 461 // handlers). Typing does not cause changes outside of a KeyPress e
vent which |
| 457 // we don't call here. However, if the key-code is a control key su
ch as | 462 // we don't call here. However, if the key-code is a control key su
ch as |
| 458 // KEYCODE_DEL then there never is an associated KeyPress event and
the KeyDown | 463 // KEYCODE_DEL then there never is an associated KeyPress event and
the KeyDown |
| 459 // event itself causes the action. The net result below is that the
Renderer calls | 464 // event itself causes the action. The net result below is that the
Renderer calls |
| 460 // cancelComposition() and then Android starts anew with setComposin
gRegion(). | 465 // cancelComposition() and then Android starts anew with setComposin
gRegion(). |
| 461 // This stopping and restarting of composition could be a source of
problems | 466 // This stopping and restarting of composition could be a source of
problems |
| (...skipping 30 matching lines...) Expand all Loading... |
| 492 mLastComposeText = textStr; | 497 mLastComposeText = textStr; |
| 493 return true; | 498 return true; |
| 494 } | 499 } |
| 495 | 500 |
| 496 void finishComposingText() { | 501 void finishComposingText() { |
| 497 mLastComposeText = null; | 502 mLastComposeText = null; |
| 498 if (mNativeImeAdapterAndroid == 0) return; | 503 if (mNativeImeAdapterAndroid == 0) return; |
| 499 nativeFinishComposingText(mNativeImeAdapterAndroid); | 504 nativeFinishComposingText(mNativeImeAdapterAndroid); |
| 500 } | 505 } |
| 501 | 506 |
| 502 boolean translateAndSendNativeEvents(KeyEvent event) { | 507 boolean translateAndSendNativeEvents(KeyEvent event, int accentChar) { |
| 503 if (mNativeImeAdapterAndroid == 0) return false; | 508 if (mNativeImeAdapterAndroid == 0) return false; |
| 504 | 509 |
| 505 int action = event.getAction(); | 510 int action = event.getAction(); |
| 506 if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) { | 511 if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) { |
| 507 // action == KeyEvent.ACTION_MULTIPLE | 512 // action == KeyEvent.ACTION_MULTIPLE |
| 508 // TODO(bulach): confirm the actual behavior. Apparently: | 513 // TODO(bulach): confirm the actual behavior. Apparently: |
| 509 // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a | 514 // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a |
| 510 // composition key down (229) followed by a commit text with the | 515 // composition key down (229) followed by a commit text with the |
| 511 // string from event.getUnicodeChars(). | 516 // string from event.getUnicodeChars(). |
| 512 // Otherwise, we'd need to send an event with a | 517 // Otherwise, we'd need to send an event with a |
| 513 // WebInputEvent::IsAutoRepeat modifier. We also need to verify when | 518 // WebInputEvent::IsAutoRepeat modifier. We also need to verify when |
| 514 // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOW
N, | 519 // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOW
N, |
| 515 // and if that's the case, we'll need to review when to send the Cha
r | 520 // and if that's the case, we'll need to review when to send the Cha
r |
| 516 // event. | 521 // event. |
| 517 return false; | 522 return false; |
| 518 } | 523 } |
| 519 mViewEmbedder.onImeEvent(); | 524 mViewEmbedder.onImeEvent(); |
| 525 int unicodeChar = AdapterInputConnection.maybeAddAccentToCharacter( |
| 526 accentChar, event.getUnicodeChar()); |
| 520 return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getActi
on(), | 527 return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getActi
on(), |
| 521 getModifiers(event.getMetaState()), event.getEventTime(), event.
getKeyCode(), | 528 getModifiers(event.getMetaState()), event.getEventTime(), event.
getKeyCode(), |
| 522 /*isSystemKey=*/false, event.getUnicodeChar()); | 529 /*isSystemKey=*/false, unicodeChar); |
| 523 } | 530 } |
| 524 | 531 |
| 525 boolean sendSyntheticKeyEvent(int eventType, long timestampMs, int keyCode,
int modifiers, | 532 boolean sendSyntheticKeyEvent(int eventType, long timestampMs, int keyCode,
int modifiers, |
| 526 int unicodeChar) { | 533 int unicodeChar) { |
| 527 if (mNativeImeAdapterAndroid == 0) return false; | 534 if (mNativeImeAdapterAndroid == 0) return false; |
| 528 | 535 |
| 529 nativeSendSyntheticKeyEvent( | 536 nativeSendSyntheticKeyEvent( |
| 530 mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, modif
iers, unicodeChar); | 537 mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, modif
iers, unicodeChar); |
| 531 return true; | 538 return true; |
| 532 } | 539 } |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid
, | 748 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid
, |
| 742 int before, int after); | 749 int before, int after); |
| 743 | 750 |
| 744 private native void nativeUnselect(long nativeImeAdapterAndroid); | 751 private native void nativeUnselect(long nativeImeAdapterAndroid); |
| 745 private native void nativeSelectAll(long nativeImeAdapterAndroid); | 752 private native void nativeSelectAll(long nativeImeAdapterAndroid); |
| 746 private native void nativeCut(long nativeImeAdapterAndroid); | 753 private native void nativeCut(long nativeImeAdapterAndroid); |
| 747 private native void nativeCopy(long nativeImeAdapterAndroid); | 754 private native void nativeCopy(long nativeImeAdapterAndroid); |
| 748 private native void nativePaste(long nativeImeAdapterAndroid); | 755 private native void nativePaste(long nativeImeAdapterAndroid); |
| 749 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid); | 756 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid); |
| 750 } | 757 } |
| OLD | NEW |