OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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.app.Activity; | 7 import android.app.Activity; |
8 import android.content.ClipData; | 8 import android.content.ClipData; |
9 import android.content.ClipboardManager; | 9 import android.content.ClipboardManager; |
10 import android.content.Context; | 10 import android.content.Context; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 | 257 |
258 finishComposingText(mConnection); | 258 finishComposingText(mConnection); |
259 waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 5, "hllo ", 1
, 1, -1, -1); | 259 waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 5, "hllo ", 1
, 1, -1, -1); |
260 | 260 |
261 commitText(mConnection, "\n", 1); | 261 commitText(mConnection, "\n", 1); |
262 waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 6, "h\nllo ",
2, 2, -1, -1); | 262 waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 6, "h\nllo ",
2, 2, -1, -1); |
263 } | 263 } |
264 | 264 |
265 @SmallTest | 265 @SmallTest |
266 @Feature({"TextInput", "Main"}) | 266 @Feature({"TextInput", "Main"}) |
| 267 public void testGuessedKeycodeFromTyping() throws Throwable { |
| 268 assertEquals(0, ImeAdapter.getTypedKeycodeGuess(null, "")); |
| 269 assertEquals(KeyEvent.KEYCODE_X, ImeAdapter.getTypedKeycodeGuess(null, "
x")); |
| 270 assertEquals(0, ImeAdapter.getTypedKeycodeGuess(null, "xyz")); |
| 271 |
| 272 assertEquals(0, ImeAdapter.getTypedKeycodeGuess("abc", "abc")); |
| 273 assertEquals(KeyEvent.KEYCODE_DEL, ImeAdapter.getTypedKeycodeGuess("abc"
, "")); |
| 274 |
| 275 assertEquals(KeyEvent.KEYCODE_H, ImeAdapter.getTypedKeycodeGuess("", "h"
)); |
| 276 assertEquals(KeyEvent.KEYCODE_DEL, ImeAdapter.getTypedKeycodeGuess("h",
"")); |
| 277 assertEquals(KeyEvent.KEYCODE_E, ImeAdapter.getTypedKeycodeGuess("h", "h
e")); |
| 278 assertEquals(KeyEvent.KEYCODE_L, ImeAdapter.getTypedKeycodeGuess("he", "
hel")); |
| 279 assertEquals(KeyEvent.KEYCODE_O, ImeAdapter.getTypedKeycodeGuess("hel",
"helo")); |
| 280 assertEquals(KeyEvent.KEYCODE_DEL, ImeAdapter.getTypedKeycodeGuess("helo
", "hel")); |
| 281 assertEquals(KeyEvent.KEYCODE_L, ImeAdapter.getTypedKeycodeGuess("hel",
"hell")); |
| 282 assertEquals(KeyEvent.KEYCODE_L, ImeAdapter.getTypedKeycodeGuess("hell",
"helll")); |
| 283 assertEquals(KeyEvent.KEYCODE_DEL, ImeAdapter.getTypedKeycodeGuess("hell
l", "hell")); |
| 284 assertEquals(KeyEvent.KEYCODE_O, ImeAdapter.getTypedKeycodeGuess("hell",
"hello")); |
| 285 |
| 286 assertEquals(KeyEvent.KEYCODE_X, ImeAdapter.getTypedKeycodeGuess("xxx",
"xxxx")); |
| 287 assertEquals(KeyEvent.KEYCODE_X, ImeAdapter.getTypedKeycodeGuess("xxx",
"xxxxx")); |
| 288 assertEquals(KeyEvent.KEYCODE_DEL, ImeAdapter.getTypedKeycodeGuess("xxx"
, "xx")); |
| 289 assertEquals(KeyEvent.KEYCODE_DEL, ImeAdapter.getTypedKeycodeGuess("xxx"
, "x")); |
| 290 |
| 291 assertEquals(KeyEvent.KEYCODE_Y, ImeAdapter.getTypedKeycodeGuess("xxx",
"xxxy")); |
| 292 assertEquals(KeyEvent.KEYCODE_Y, ImeAdapter.getTypedKeycodeGuess("xxx",
"xxxxy")); |
| 293 assertEquals(0, ImeAdapter.getTypedKeycodeGuess("xxx", "xy")); |
| 294 assertEquals(0, ImeAdapter.getTypedKeycodeGuess("xxx", "y")); |
| 295 |
| 296 assertEquals(0, ImeAdapter.getTypedKeycodeGuess("foo", "bar")); |
| 297 assertEquals(0, ImeAdapter.getTypedKeycodeGuess("foo", "bars")); |
| 298 assertEquals(0, ImeAdapter.getTypedKeycodeGuess("foo", "ba")); |
| 299 } |
| 300 |
| 301 @SmallTest |
| 302 @Feature({"TextInput", "Main"}) |
| 303 public void testKeyCodesWhileComposingText() throws Throwable { |
| 304 DOMUtils.focusNode(mContentViewCore, "textarea"); |
| 305 assertWaitForKeyboardStatus(true); |
| 306 |
| 307 // The calls below are a reflection of what the stock Google Keyboard (A
ndroid 4.4) sends |
| 308 // when the noted key is touched on screen. Exercise care when altering
to make sure |
| 309 // that the test reflects reality. If this test breaks, it's possible t
hat code has |
| 310 // changed and different calls need to be made instead. |
| 311 mConnection = (TestAdapterInputConnection) getAdapterInputConnection(); |
| 312 waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 0, "", 0, 0,
-1, -1); |
| 313 |
| 314 // H |
| 315 expectUpdateStateCall(mConnection); |
| 316 setComposingText(mConnection, "h", 1); |
| 317 assertEquals(KeyEvent.KEYCODE_H, mImeAdapter.mLastSyntheticKeyCode); |
| 318 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 319 assertUpdateStateCall(mConnection, 1000); |
| 320 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 321 |
| 322 // O |
| 323 expectUpdateStateCall(mConnection); |
| 324 setComposingText(mConnection, "ho", 1); |
| 325 assertEquals(KeyEvent.KEYCODE_O, mImeAdapter.mLastSyntheticKeyCode); |
| 326 assertEquals("ho", mConnection.getTextBeforeCursor(9, 0)); |
| 327 assertUpdateStateCall(mConnection, 1000); |
| 328 assertEquals("ho", mConnection.getTextBeforeCursor(9, 0)); |
| 329 |
| 330 // DEL |
| 331 expectUpdateStateCall(mConnection); |
| 332 setComposingText(mConnection, "h", 1); |
| 333 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 334 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 335 assertUpdateStateCall(mConnection, 1000); |
| 336 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 337 setComposingRegion(mConnection, 0, 1); // DEL calls cancelComposition()
then restarts |
| 338 |
| 339 // I |
| 340 setComposingText(mConnection, "hi", 1); |
| 341 assertEquals(KeyEvent.KEYCODE_I, mImeAdapter.mLastSyntheticKeyCode); |
| 342 assertEquals("hi", mConnection.getTextBeforeCursor(9, 0)); |
| 343 |
| 344 // SPACE |
| 345 commitText(mConnection, "hi", 1); |
| 346 assertEquals(0, mImeAdapter.mLastSyntheticKeyCode); |
| 347 commitText(mConnection, " ", 1); |
| 348 assertEquals(KeyEvent.KEYCODE_SPACE, mImeAdapter.mLastSyntheticKeyCode); |
| 349 assertEquals("hi ", mConnection.getTextBeforeCursor(9, 0)); |
| 350 |
| 351 // DEL |
| 352 deleteSurroundingText(mConnection, 1, 0); |
| 353 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 354 setComposingRegion(mConnection, 0, 2); |
| 355 assertEquals("hi", mConnection.getTextBeforeCursor(9, 0)); |
| 356 |
| 357 // DEL |
| 358 setComposingText(mConnection, "h", 1); |
| 359 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 360 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 361 |
| 362 // DEL |
| 363 commitText(mConnection, "", 1); |
| 364 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 365 assertEquals("", mConnection.getTextBeforeCursor(9, 0)); |
| 366 |
| 367 // DEL (on empty input) |
| 368 deleteSurroundingText(mConnection, 1, 0); // BS on empty still sends 1,
0 |
| 369 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 370 assertEquals("", mConnection.getTextBeforeCursor(9, 0)); |
| 371 } |
| 372 |
| 373 @SmallTest |
| 374 @Feature({"TextInput", "Main"}) |
| 375 public void testKeyCodesWhileTypingText() throws Throwable { |
| 376 DOMUtils.focusNode(mContentViewCore, "textarea"); |
| 377 assertWaitForKeyboardStatus(true); |
| 378 |
| 379 // The calls below are a reflection of what the Hacker's Keyboard sends
when the noted |
| 380 // key is touched on screen. Exercise care when altering to make sure t
hat the test |
| 381 // reflects reality. |
| 382 mConnection = (TestAdapterInputConnection) getAdapterInputConnection(); |
| 383 waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 0, "", 0, 0,
-1, -1); |
| 384 |
| 385 // H |
| 386 expectUpdateStateCall(mConnection); |
| 387 commitText(mConnection, "h", 1); |
| 388 assertEquals(KeyEvent.KEYCODE_H, mImeAdapter.mLastSyntheticKeyCode); |
| 389 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 390 assertUpdateStateCall(mConnection, 1000); |
| 391 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 392 |
| 393 // O |
| 394 expectUpdateStateCall(mConnection); |
| 395 commitText(mConnection, "o", 1); |
| 396 assertEquals(KeyEvent.KEYCODE_O, mImeAdapter.mLastSyntheticKeyCode); |
| 397 assertEquals("ho", mConnection.getTextBeforeCursor(9, 0)); |
| 398 assertUpdateStateCall(mConnection, 1000); |
| 399 assertEquals("ho", mConnection.getTextBeforeCursor(9, 0)); |
| 400 |
| 401 // DEL |
| 402 expectUpdateStateCall(mConnection); |
| 403 deleteSurroundingText(mConnection, 1, 0); |
| 404 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 405 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 406 assertUpdateStateCall(mConnection, 1000); |
| 407 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 408 |
| 409 // I |
| 410 expectUpdateStateCall(mConnection); |
| 411 commitText(mConnection, "i", 1); |
| 412 assertEquals(KeyEvent.KEYCODE_I, mImeAdapter.mLastSyntheticKeyCode); |
| 413 assertEquals("hi", mConnection.getTextBeforeCursor(9, 0)); |
| 414 assertUpdateStateCall(mConnection, 1000); |
| 415 assertEquals("hi", mConnection.getTextBeforeCursor(9, 0)); |
| 416 |
| 417 // SPACE |
| 418 expectUpdateStateCall(mConnection); |
| 419 commitText(mConnection, " ", 1); |
| 420 assertEquals(KeyEvent.KEYCODE_SPACE, mImeAdapter.mLastSyntheticKeyCode); |
| 421 assertEquals("hi ", mConnection.getTextBeforeCursor(9, 0)); |
| 422 assertUpdateStateCall(mConnection, 1000); |
| 423 assertEquals("hi ", mConnection.getTextBeforeCursor(9, 0)); |
| 424 |
| 425 // DEL |
| 426 expectUpdateStateCall(mConnection); |
| 427 deleteSurroundingText(mConnection, 1, 0); |
| 428 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 429 assertEquals("hi", mConnection.getTextBeforeCursor(9, 0)); |
| 430 assertUpdateStateCall(mConnection, 1000); |
| 431 assertEquals("hi", mConnection.getTextBeforeCursor(9, 0)); |
| 432 |
| 433 // DEL |
| 434 expectUpdateStateCall(mConnection); |
| 435 deleteSurroundingText(mConnection, 1, 0); |
| 436 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 437 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 438 assertUpdateStateCall(mConnection, 1000); |
| 439 assertEquals("h", mConnection.getTextBeforeCursor(9, 0)); |
| 440 |
| 441 // DEL |
| 442 expectUpdateStateCall(mConnection); |
| 443 deleteSurroundingText(mConnection, 1, 0); |
| 444 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 445 assertEquals("", mConnection.getTextBeforeCursor(9, 0)); |
| 446 assertUpdateStateCall(mConnection, 1000); |
| 447 assertEquals("", mConnection.getTextBeforeCursor(9, 0)); |
| 448 |
| 449 // DEL (on empty input) |
| 450 deleteSurroundingText(mConnection, 1, 0); // BS on empty still sends 1,
0 |
| 451 assertEquals(KeyEvent.KEYCODE_DEL, mImeAdapter.mLastSyntheticKeyCode); |
| 452 assertEquals("", mConnection.getTextBeforeCursor(9, 0)); |
| 453 } |
| 454 |
| 455 @SmallTest |
| 456 @Feature({"TextInput", "Main"}) |
267 public void testEnterKeyEventWhileComposingText() throws Throwable { | 457 public void testEnterKeyEventWhileComposingText() throws Throwable { |
268 DOMUtils.focusNode(mContentViewCore, "input_radio"); | 458 DOMUtils.focusNode(mContentViewCore, "input_radio"); |
269 assertWaitForKeyboardStatus(false); | 459 assertWaitForKeyboardStatus(false); |
270 DOMUtils.focusNode(mContentViewCore, "textarea"); | 460 DOMUtils.focusNode(mContentViewCore, "textarea"); |
271 assertWaitForKeyboardStatus(true); | 461 assertWaitForKeyboardStatus(true); |
272 | 462 |
273 mConnection = (TestAdapterInputConnection) getAdapterInputConnection(); | 463 mConnection = (TestAdapterInputConnection) getAdapterInputConnection(); |
274 waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 0, "", 0, 0,
-1, -1); | 464 waitAndVerifyEditableCallback(mConnection.mImeUpdateQueue, 0, "", 0, 0,
-1, -1); |
275 | 465 |
276 setComposingText(mConnection, "hello", 1); | 466 setComposingText(mConnection, "hello", 1); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { | 510 assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { |
321 @Override | 511 @Override |
322 public boolean isSatisfied() { | 512 public boolean isSatisfied() { |
323 return states.size() > index; | 513 return states.size() > index; |
324 } | 514 } |
325 })); | 515 })); |
326 states.get(index).assertEqualState( | 516 states.get(index).assertEqualState( |
327 text, selectionStart, selectionEnd, compositionStart, compositio
nEnd); | 517 text, selectionStart, selectionEnd, compositionStart, compositio
nEnd); |
328 } | 518 } |
329 | 519 |
| 520 private void expectUpdateStateCall(final TestAdapterInputConnection connecti
on) { |
| 521 connection.mImeUpdateQueue.clear(); |
| 522 } |
| 523 |
| 524 private void assertUpdateStateCall(final TestAdapterInputConnection connecti
on, int maxms) |
| 525 throws Exception { |
| 526 while (connection.mImeUpdateQueue.size() == 0 && maxms > 0) { |
| 527 try { |
| 528 Thread.sleep(50); |
| 529 } catch (Exception e) { |
| 530 // Not really a problem since we're just going to sleep again. |
| 531 } |
| 532 maxms -= 50; |
| 533 } |
| 534 assertTrue(connection.mImeUpdateQueue.size() > 0); |
| 535 } |
| 536 |
330 private void assertClipboardContents(final Activity activity, final String e
xpectedContents) | 537 private void assertClipboardContents(final Activity activity, final String e
xpectedContents) |
331 throws InterruptedException { | 538 throws InterruptedException { |
332 assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { | 539 assertTrue(CriteriaHelper.pollForCriteria(new Criteria() { |
333 @Override | 540 @Override |
334 public boolean isSatisfied() { | 541 public boolean isSatisfied() { |
335 return ThreadUtils.runOnUiThreadBlockingNoException(new Callable
<Boolean>() { | 542 return ThreadUtils.runOnUiThreadBlockingNoException(new Callable
<Boolean>() { |
336 @Override | 543 @Override |
337 public Boolean call() throws Exception { | 544 public Boolean call() throws Exception { |
338 ClipboardManager clipboardManager = | 545 ClipboardManager clipboardManager = |
339 (ClipboardManager) activity.getSystemService( | 546 (ClipboardManager) activity.getSystemService( |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 | 649 |
443 private void finishComposingText(final AdapterInputConnection connection) { | 650 private void finishComposingText(final AdapterInputConnection connection) { |
444 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | 651 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
445 @Override | 652 @Override |
446 public void run() { | 653 public void run() { |
447 connection.finishComposingText(); | 654 connection.finishComposingText(); |
448 } | 655 } |
449 }); | 656 }); |
450 } | 657 } |
451 | 658 |
| 659 private void deleteSurroundingText(final AdapterInputConnection connection,
final int before, |
| 660 final int after) { |
| 661 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 662 @Override |
| 663 public void run() { |
| 664 connection.deleteSurroundingText(before, after); |
| 665 } |
| 666 }); |
| 667 } |
| 668 |
452 private static class TestAdapterInputConnectionFactory extends | 669 private static class TestAdapterInputConnectionFactory extends |
453 ImeAdapter.AdapterInputConnectionFactory { | 670 ImeAdapter.AdapterInputConnectionFactory { |
454 @Override | 671 @Override |
455 public AdapterInputConnection get(View view, ImeAdapter imeAdapter, | 672 public AdapterInputConnection get(View view, ImeAdapter imeAdapter, |
456 Editable editable, EditorInfo outAttrs) { | 673 Editable editable, EditorInfo outAttrs) { |
457 return new TestAdapterInputConnection(view, imeAdapter, editable, ou
tAttrs); | 674 return new TestAdapterInputConnection(view, imeAdapter, editable, ou
tAttrs); |
458 } | 675 } |
459 } | 676 } |
460 | 677 |
461 private static class TestAdapterInputConnection extends AdapterInputConnecti
on { | 678 private static class TestAdapterInputConnection extends AdapterInputConnecti
on { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 public void assertEqualState(String text, int selectionStart, int select
ionEnd, | 712 public void assertEqualState(String text, int selectionStart, int select
ionEnd, |
496 int compositionStart, int compositionEnd) { | 713 int compositionStart, int compositionEnd) { |
497 assertEquals("Text did not match", text, mText); | 714 assertEquals("Text did not match", text, mText); |
498 assertEquals("Selection start did not match", selectionStart, mSelec
tionStart); | 715 assertEquals("Selection start did not match", selectionStart, mSelec
tionStart); |
499 assertEquals("Selection end did not match", selectionEnd, mSelection
End); | 716 assertEquals("Selection end did not match", selectionEnd, mSelection
End); |
500 assertEquals("Composition start did not match", compositionStart, mC
ompositionStart); | 717 assertEquals("Composition start did not match", compositionStart, mC
ompositionStart); |
501 assertEquals("Composition end did not match", compositionEnd, mCompo
sitionEnd); | 718 assertEquals("Composition end did not match", compositionEnd, mCompo
sitionEnd); |
502 } | 719 } |
503 } | 720 } |
504 } | 721 } |
OLD | NEW |