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

Side by Side 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 unified diff | Download patch
OLDNEW
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.content.res.Configuration; 7 import android.content.res.Configuration;
8 import android.os.Handler; 8 import android.os.Handler;
9 import android.os.ResultReceiver; 9 import android.os.ResultReceiver;
10 import android.os.SystemClock; 10 import android.os.SystemClock;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 static char[] sSingleCharArray = new char[1]; 102 static char[] sSingleCharArray = new char[1];
103 static KeyCharacterMap sKeyCharacterMap; 103 static KeyCharacterMap sKeyCharacterMap;
104 104
105 private long mNativeImeAdapterAndroid; 105 private long mNativeImeAdapterAndroid;
106 private InputMethodManagerWrapper mInputMethodManagerWrapper; 106 private InputMethodManagerWrapper mInputMethodManagerWrapper;
107 private AdapterInputConnection mInputConnection; 107 private AdapterInputConnection mInputConnection;
108 private final ImeAdapterDelegate mViewEmbedder; 108 private final ImeAdapterDelegate mViewEmbedder;
109 private final Handler mHandler; 109 private final Handler mHandler;
110 private int mTextInputType; 110 private int mTextInputType;
111 private int mTextInputFlags; 111 private int mTextInputFlags;
112 private String mLastComposeText;
113
114 @VisibleForTesting
115 int mLastSyntheticKeyCode;
116 112
117 @VisibleForTesting 113 @VisibleForTesting
118 boolean mIsShowWithoutHideOutstanding = false; 114 boolean mIsShowWithoutHideOutstanding = false;
119 115
120 /** 116 /**
121 * @param wrapper InputMethodManagerWrapper that should receive all the call directed to 117 * @param wrapper InputMethodManagerWrapper that should receive all the call directed to
122 * InputMethodManager. 118 * InputMethodManager.
123 * @param embedder The view that is used for callbacks from ImeAdapter. 119 * @param embedder The view that is used for callbacks from ImeAdapter.
124 */ 120 */
125 public ImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embe dder) { 121 public ImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embe dder) {
(...skipping 30 matching lines...) Expand all
156 InputMethodManagerWrapper getInputMethodManagerWrapper() { 152 InputMethodManagerWrapper getInputMethodManagerWrapper() {
157 return mInputMethodManagerWrapper; 153 return mInputMethodManagerWrapper;
158 } 154 }
159 155
160 /** 156 /**
161 * Set the current active InputConnection when a new InputConnection is cons tructed. 157 * Set the current active InputConnection when a new InputConnection is cons tructed.
162 * @param inputConnection The input connection that is currently used with I ME. 158 * @param inputConnection The input connection that is currently used with I ME.
163 */ 159 */
164 void setInputConnection(AdapterInputConnection inputConnection) { 160 void setInputConnection(AdapterInputConnection inputConnection) {
165 mInputConnection = inputConnection; 161 mInputConnection = inputConnection;
166 mLastComposeText = null;
167 } 162 }
168 163
169 /** 164 /**
170 * Should be used only by AdapterInputConnection. 165 * Should be used only by AdapterInputConnection.
171 * @return The input type of currently focused element. 166 * @return The input type of currently focused element.
172 */ 167 */
173 int getTextInputType() { 168 int getTextInputType() {
174 return mTextInputType; 169 return mTextInputType;
175 } 170 }
176 171
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 private void attach(long nativeImeAdapter, int textInputType, int textInputF lags, 234 private void attach(long nativeImeAdapter, int textInputType, int textInputF lags,
240 boolean delayDismissInput) { 235 boolean delayDismissInput) {
241 Log.d(TAG, "attach"); 236 Log.d(TAG, "attach");
242 if (mNativeImeAdapterAndroid != 0) { 237 if (mNativeImeAdapterAndroid != 0) {
243 nativeResetImeAdapter(mNativeImeAdapterAndroid); 238 nativeResetImeAdapter(mNativeImeAdapterAndroid);
244 } 239 }
245 if (nativeImeAdapter != 0) { 240 if (nativeImeAdapter != 0) {
246 nativeAttachImeAdapter(nativeImeAdapter); 241 nativeAttachImeAdapter(nativeImeAdapter);
247 } 242 }
248 mNativeImeAdapterAndroid = nativeImeAdapter; 243 mNativeImeAdapterAndroid = nativeImeAdapter;
249 mLastComposeText = null;
250 mTextInputFlags = textInputFlags; 244 mTextInputFlags = textInputFlags;
251 if (textInputType == mTextInputType) return; 245 if (textInputType == mTextInputType) return;
252 mTextInputType = textInputType; 246 mTextInputType = textInputType;
253 mHandler.removeCallbacks(mDismissInputRunnable); // okay if not found 247 mHandler.removeCallbacks(mDismissInputRunnable); // okay if not found
254 if (mTextInputType == TextInputType.NONE) { 248 if (mTextInputType == TextInputType.NONE) {
255 if (delayDismissInput) { 249 if (delayDismissInput) {
256 // Set a delayed task to do unfocus. This avoids hiding the keyb oard when tabbing 250 // Set a delayed task to do unfocus. This avoids hiding the keyb oard when tabbing
257 // through text inputs or when JS rapidly changes focus to anoth er text element. 251 // through text inputs or when JS rapidly changes focus to anoth er text element.
258 mHandler.postDelayed(mDismissInputRunnable, INPUT_DISMISS_DELAY) ; 252 mHandler.postDelayed(mDismissInputRunnable, INPUT_DISMISS_DELAY) ;
259 mIsShowWithoutHideOutstanding = false; 253 mIsShowWithoutHideOutstanding = false;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 public boolean hasTextInputType() { 302 public boolean hasTextInputType() {
309 return isTextInputType(mTextInputType); 303 return isTextInputType(mTextInputType);
310 } 304 }
311 305
312 public boolean dispatchKeyEvent(KeyEvent event) { 306 public boolean dispatchKeyEvent(KeyEvent event) {
313 Log.d(TAG, "dispatchKeyEvent: action [%d], keycode [%d]", event.getActio n(), 307 Log.d(TAG, "dispatchKeyEvent: action [%d], keycode [%d]", event.getActio n(),
314 event.getKeyCode()); 308 event.getKeyCode());
315 if (mInputConnection != null) { 309 if (mInputConnection != null) {
316 return mInputConnection.sendKeyEvent(event); 310 return mInputConnection.sendKeyEvent(event);
317 } 311 }
318 return translateAndSendNativeEvents(event); 312 return sendKeyEvent(event);
319 }
320
321 private int shouldSendKeyEventWithKeyCode(String text) {
322 if (text.length() != 1) return COMPOSITION_KEY_CODE;
323
324 if (text.equals("\n")) {
325 return KeyEvent.KEYCODE_ENTER;
326 } else if (text.equals("\t")) {
327 return KeyEvent.KEYCODE_TAB;
328 } else {
329 return COMPOSITION_KEY_CODE;
330 }
331 }
332
333 /**
334 * @return Android KeyEvent for a single unicode character. Only one KeyEve nt is returned
335 * even if the system determined that various modifier keys (like Shift) wou ld also have
336 * been pressed.
337 */
338 private static KeyEvent androidKeyEventForCharacter(char chr) {
339 if (sKeyCharacterMap == null) {
340 sKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYB OARD);
341 }
342 sSingleCharArray[0] = chr;
343 // TODO: Evaluate cost of this system call.
344 KeyEvent[] events = sKeyCharacterMap.getEvents(sSingleCharArray);
345 if (events == null) { // No known key sequence will create that charact er.
346 return null;
347 }
348
349 for (int i = 0; i < events.length; ++i) {
350 if (events[i].getAction() == KeyEvent.ACTION_DOWN
351 && !KeyEvent.isModifierKey(events[i].getKeyCode())) {
352 return events[i];
353 }
354 }
355
356 return null; // No printing characters were found.
357 } 313 }
358 314
359 /** 315 /**
360 * @see BaseInputConnection#performContextMenuAction(int) 316 * @see BaseInputConnection#performContextMenuAction(int)
361 */ 317 */
362 public boolean performContextMenuAction(int id) { 318 boolean performContextMenuAction(int id) {
363 Log.d(TAG, "performContextMenuAction: id [%d]", id); 319 Log.d(TAG, "performContextMenuAction: id [%d]", id);
364 return mViewEmbedder.performContextMenuAction(id); 320 return mViewEmbedder.performContextMenuAction(id);
365 } 321 }
366 322
367 @VisibleForTesting 323 boolean performEditorAction(int actionCode) {
368 public static KeyEvent getTypedKeyEventGuess(String oldtext, String newtext) { 324 if (mNativeImeAdapterAndroid == 0) return false;
369 // Starting typing a new composition should add only a single character. Any composition 325 if (actionCode == EditorInfo.IME_ACTION_NEXT) {
370 // beginning with text longer than that must come from something other t han typing so 326 sendSyntheticKeyPress(KeyEvent.KEYCODE_TAB,
371 // return 0. 327 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
372 if (oldtext == null) { 328 | KeyEvent.FLAG_EDITOR_ACTION);
373 if (newtext.length() == 1) { 329 } else {
374 return androidKeyEventForCharacter(newtext.charAt(0)); 330 sendSyntheticKeyPress(KeyEvent.KEYCODE_ENTER,
375 } else { 331 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
376 return null; 332 | KeyEvent.FLAG_EDITOR_ACTION);
377 }
378 } 333 }
379 334 return true;
380 // The content has grown in length: assume the last character is the key that caused it.
381 if (newtext.length() > oldtext.length() && newtext.startsWith(oldtext)) {
382 return androidKeyEventForCharacter(newtext.charAt(newtext.length() - 1));
383 }
384
385 // The content has shrunk in length: assume that backspace was pressed.
386 if (oldtext.length() > newtext.length() && oldtext.startsWith(newtext)) {
387 return new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
388 }
389
390 // The content is unchanged or has undergone a complex change (i.e. not a simple tail
391 // modification) so return an unknown key-code.
392 return null;
393 } 335 }
394 336
395 void sendKeyEventWithKeyCode(int keyCode, int flags) { 337 @VisibleForTesting
338 protected void sendSyntheticKeyPress(int keyCode, int flags) {
396 long eventTime = SystemClock.uptimeMillis(); 339 long eventTime = SystemClock.uptimeMillis();
397 mLastSyntheticKeyCode = keyCode; 340 sendKeyEvent(new KeyEvent(eventTime, eventTime,
398 translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime,
399 KeyEvent.ACTION_DOWN, keyCode, 0, 0, 341 KeyEvent.ACTION_DOWN, keyCode, 0, 0,
400 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 342 KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
401 flags)); 343 flags));
402 translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMillis(), ev entTime, 344 sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
403 KeyEvent.ACTION_UP, keyCode, 0, 0, 345 KeyEvent.ACTION_UP, keyCode, 0, 0,
404 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 346 KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
405 flags)); 347 flags));
406 } 348 }
407 349
408 // Calls from Java to C++ 350 boolean sendCompositionToNative(CharSequence text, int newCursorPosition, bo olean isCommit) {
409 // TODO: Add performance tracing to more complicated functions.
410 boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorP osition,
411 boolean isCommit) {
412 if (mNativeImeAdapterAndroid == 0) return false; 351 if (mNativeImeAdapterAndroid == 0) return false;
413 mViewEmbedder.onImeEvent(); 352 mViewEmbedder.onImeEvent();
414 353
415 String textStr = text.toString(); 354 long timestampMs = SystemClock.uptimeMillis();
416 int keyCode = shouldSendKeyEventWithKeyCode(textStr); 355 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEventType. RawKeyDown,
417 long timeStampMs = SystemClock.uptimeMillis(); 356 timestampMs, COMPOSITION_KEY_CODE, 0, 0);
418 357
419 if (keyCode != COMPOSITION_KEY_CODE) { 358 if (isCommit) {
420 sendKeyEventWithKeyCode(keyCode, 359 nativeCommitText(mNativeImeAdapterAndroid, text.toString());
421 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE) ;
422 } else { 360 } else {
423 KeyEvent keyEvent = getTypedKeyEventGuess(mLastComposeText, textStr) ; 361 nativeSetComposingText(
424 int modifiers = 0; 362 mNativeImeAdapterAndroid, text, text.toString(), newCursorPo sition);
425 if (keyEvent != null) {
426 keyCode = keyEvent.getKeyCode();
427 modifiers = getModifiers(keyEvent.getMetaState());
428 } else if (!textStr.equals(mLastComposeText)) {
429 keyCode = KeyEvent.KEYCODE_UNKNOWN;
430 } else {
431 keyCode = -1;
432 }
433
434 // If this is a single-character commit with no previous composition , then treat it as
435 // a native KeyDown/KeyUp pair with no composition rather than a syn thetic pair with
436 // composition below.
437 if (keyCode > 0 && isCommit && mLastComposeText == null && textStr.l ength() == 1) {
438 mLastSyntheticKeyCode = keyCode;
439 return translateAndSendNativeEvents(keyEvent)
440 && translateAndSendNativeEvents(
441 KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_ UP));
442 }
443
444 // Always send compose events. This is a quick fix for http://crbug. com/476497.
445 keyCode = COMPOSITION_KEY_CODE;
446 modifiers = 0;
447
448 // When typing, there is no issue sending KeyDown and KeyUp events a round the
449 // composition event because those key events do nothing (other than call JS
450 // handlers). Typing does not cause changes outside of a KeyPress e vent which
451 // we don't call here. However, if the key-code is a control key su ch as
452 // KEYCODE_DEL then there never is an associated KeyPress event and the KeyDown
453 // event itself causes the action. The net result below is that the Renderer calls
454 // cancelComposition() and then Android starts anew with setComposin gRegion().
455 // This stopping and restarting of composition could be a source of problems
456 // with 3rd party keyboards.
457 //
458 // An alternative is to *not* call nativeSetComposingText() in the n on-commit case
459 // below. This avoids the restart of composition described above bu t fails to send
460 // an update to the composition while in composition which, strictly speaking,
461 // does not match the spec.
462 //
463 // For now, the solution is to endure the restarting of composition and only dive
464 // into the alternate solution should there be problems in the field . --bcwhite
465
466 if (keyCode >= 0) {
467 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEv entType.RawKeyDown,
468 timeStampMs, keyCode, modifiers, 0);
469 }
470
471 if (isCommit) {
472 nativeCommitText(mNativeImeAdapterAndroid, textStr);
473 textStr = null;
474 } else {
475 nativeSetComposingText(mNativeImeAdapterAndroid, text, textStr, newCursorPosition);
476 }
477
478 if (keyCode >= 0) {
479 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEv entType.KeyUp,
480 timeStampMs, keyCode, modifiers, 0);
481 }
482
483 mLastSyntheticKeyCode = keyCode;
484 } 363 }
485 364
486 mLastComposeText = textStr; 365 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEventType. KeyUp,
366 timestampMs, COMPOSITION_KEY_CODE, 0, 0);
487 return true; 367 return true;
488 } 368 }
489 369
490 @VisibleForTesting 370 @VisibleForTesting
491 protected void finishComposingText() { 371 protected void finishComposingText() {
492 mLastComposeText = null;
493 if (mNativeImeAdapterAndroid == 0) return; 372 if (mNativeImeAdapterAndroid == 0) return;
494 nativeFinishComposingText(mNativeImeAdapterAndroid); 373 nativeFinishComposingText(mNativeImeAdapterAndroid);
495 } 374 }
496 375
497 boolean translateAndSendNativeEvents(KeyEvent event) { 376 boolean sendKeyEvent(KeyEvent event) {
498 if (mNativeImeAdapterAndroid == 0) return false; 377 if (mNativeImeAdapterAndroid == 0) return false;
499 378
500 int action = event.getAction(); 379 int action = event.getAction();
501 if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) { 380 if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) {
502 // action == KeyEvent.ACTION_MULTIPLE 381 // action == KeyEvent.ACTION_MULTIPLE
503 // TODO(bulach): confirm the actual behavior. Apparently: 382 // TODO(bulach): confirm the actual behavior. Apparently:
504 // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a 383 // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a
505 // composition key down (229) followed by a commit text with the 384 // composition key down (229) followed by a commit text with the
506 // string from event.getUnicodeChars(). 385 // string from event.getUnicodeChars().
507 // Otherwise, we'd need to send an event with a 386 // Otherwise, we'd need to send an event with a
508 // WebInputEvent::IsAutoRepeat modifier. We also need to verify when 387 // WebInputEvent::IsAutoRepeat modifier. We also need to verify when
509 // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOW N, 388 // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOW N,
510 // and if that's the case, we'll need to review when to send the Cha r 389 // and if that's the case, we'll need to review when to send the Cha r
511 // event. 390 // event.
512 return false; 391 return false;
513 } 392 }
514 mViewEmbedder.onImeEvent(); 393 mViewEmbedder.onImeEvent();
515 return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getActi on(), 394 return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getActi on(),
516 getModifiers(event.getMetaState()), event.getEventTime(), event. getKeyCode(), 395 getModifiers(event.getMetaState()), event.getEventTime(), event. getKeyCode(),
517 event.getScanCode(), /*isSystemKey=*/false, event.g etUnicodeChar()); 396 event.getScanCode(), /*isSystemKey=*/false, event.g etUnicodeChar());
518 } 397 }
519 398
520 boolean sendSyntheticKeyEvent(int eventType, long timestampMs, int keyCode, int modifiers,
521 int unicodeChar) {
522 if (mNativeImeAdapterAndroid == 0) return false;
523
524 nativeSendSyntheticKeyEvent(
525 mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, modif iers, unicodeChar);
526 return true;
527 }
528
529 /** 399 /**
530 * Send a request to the native counterpart to delete a given range of chara cters. 400 * Send a request to the native counterpart to delete a given range of chara cters.
531 * @param beforeLength Number of characters to extend the selection by befor e the existing 401 * @param beforeLength Number of characters to extend the selection by befor e the existing
532 * selection. 402 * selection.
533 * @param afterLength Number of characters to extend the selection by after the existing 403 * @param afterLength Number of characters to extend the selection by after the existing
534 * selection. 404 * selection.
535 * @return Whether the native counterpart of ImeAdapter received the call. 405 * @return Whether the native counterpart of ImeAdapter received the call.
536 */ 406 */
537 boolean deleteSurroundingText(int beforeLength, int afterLength) { 407 boolean deleteSurroundingText(int beforeLength, int afterLength) {
538 mViewEmbedder.onImeEvent(); 408 mViewEmbedder.onImeEvent();
539 if (mNativeImeAdapterAndroid == 0) return false; 409 if (mNativeImeAdapterAndroid == 0) return false;
410 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, WebInputEventType. RawKeyDown,
411 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, 0);
540 nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afte rLength); 412 nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afte rLength);
413 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid,
414 WebInputEventType.KeyUp, SystemClock.uptimeMillis(), COMPOSITION _KEY_CODE, 0, 0);
541 return true; 415 return true;
542 } 416 }
543 417
544 /** 418 /**
545 * Send a request to the native counterpart to set the selection to given ra nge. 419 * Send a request to the native counterpart to set the selection to given ra nge.
546 * @param start Selection start index. 420 * @param start Selection start index.
547 * @param end Selection end index. 421 * @param end Selection end index.
548 * @return Whether the native counterpart of ImeAdapter received the call. 422 * @return Whether the native counterpart of ImeAdapter received the call.
549 */ 423 */
550 boolean setEditableSelectionOffsets(int start, int end) { 424 boolean setEditableSelectionOffsets(int start, int end) {
551 if (mNativeImeAdapterAndroid == 0) return false; 425 if (mNativeImeAdapterAndroid == 0) return false;
552 nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end); 426 nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end);
553 return true; 427 return true;
554 } 428 }
555 429
556 /** 430 /**
557 * Send a request to the native counterpart to set composing region to given indices. 431 * Send a request to the native counterpart to set composing region to given indices.
558 * @param start The start of the composition. 432 * @param start The start of the composition.
559 * @param end The end of the composition. 433 * @param end The end of the composition.
560 * @return Whether the native counterpart of ImeAdapter received the call. 434 * @return Whether the native counterpart of ImeAdapter received the call.
561 */ 435 */
562 boolean setComposingRegion(CharSequence text, int start, int end) { 436 boolean setComposingRegion(CharSequence text, int start, int end) {
563 if (mNativeImeAdapterAndroid == 0) return false; 437 if (mNativeImeAdapterAndroid == 0) return false;
564 nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end); 438 nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
565 mLastComposeText = text != null ? text.toString() : null;
566 return true; 439 return true;
567 } 440 }
568 441
569 @CalledByNative 442 @CalledByNative
570 private void focusedNodeChanged(boolean isEditable) { 443 private void focusedNodeChanged(boolean isEditable) {
571 Log.d(TAG, "focusedNodeChanged"); 444 Log.d(TAG, "focusedNodeChanged");
572 if (mInputConnection != null && isEditable) mInputConnection.restartInpu t(); 445 if (mInputConnection != null && isEditable) mInputConnection.restartInpu t();
573 } 446 }
574 447
575 @CalledByNative 448 @CalledByNative
(...skipping 13 matching lines...) Expand all
589 nativeAppendUnderlineSpan(underlines, spannableString.getSpanSta rt(span), 462 nativeAppendUnderlineSpan(underlines, spannableString.getSpanSta rt(span),
590 spannableString.getSpanEnd(span)); 463 spannableString.getSpanEnd(span));
591 } 464 }
592 } 465 }
593 } 466 }
594 467
595 @CalledByNative 468 @CalledByNative
596 private void cancelComposition() { 469 private void cancelComposition() {
597 Log.d(TAG, "cancelComposition"); 470 Log.d(TAG, "cancelComposition");
598 if (mInputConnection != null) mInputConnection.restartInput(); 471 if (mInputConnection != null) mInputConnection.restartInput();
599 mLastComposeText = null;
600 } 472 }
601 473
602 @CalledByNative 474 @CalledByNative
603 void detach() { 475 void detach() {
604 Log.d(TAG, "detach"); 476 Log.d(TAG, "detach");
605 mHandler.removeCallbacks(mDismissInputRunnable); 477 mHandler.removeCallbacks(mDismissInputRunnable);
606 mNativeImeAdapterAndroid = 0; 478 mNativeImeAdapterAndroid = 0;
607 mTextInputType = 0; 479 mTextInputType = 0;
608 } 480 }
609 481
(...skipping 21 matching lines...) Expand all
631 private native void nativeSetEditableSelectionOffsets(long nativeImeAdapterA ndroid, 503 private native void nativeSetEditableSelectionOffsets(long nativeImeAdapterA ndroid,
632 int start, int end); 504 int start, int end);
633 505
634 private native void nativeSetComposingRegion(long nativeImeAdapterAndroid, i nt start, int end); 506 private native void nativeSetComposingRegion(long nativeImeAdapterAndroid, i nt start, int end);
635 507
636 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid , 508 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid ,
637 int before, int after); 509 int before, int after);
638 510
639 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid); 511 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid);
640 } 512 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698