| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.content.browser.input; | |
| 6 | |
| 7 import android.content.Context; | |
| 8 import android.os.IBinder; | |
| 9 import android.os.ResultReceiver; | |
| 10 import android.test.suitebuilder.annotation.MediumTest; | |
| 11 import android.test.suitebuilder.annotation.SmallTest; | |
| 12 import android.view.View; | |
| 13 import android.view.inputmethod.EditorInfo; | |
| 14 | |
| 15 import org.chromium.base.test.util.Feature; | |
| 16 import org.chromium.content.browser.input.AdapterInputConnection.ImeState; | |
| 17 import org.chromium.content_shell_apk.ContentShellTestBase; | |
| 18 | |
| 19 import java.util.ArrayList; | |
| 20 | |
| 21 /** | |
| 22 * Tests AdapterInputConnection class and its callbacks to ImeAdapter. | |
| 23 */ | |
| 24 public class AdapterInputConnectionTest extends ContentShellTestBase { | |
| 25 | |
| 26 private AdapterInputConnection mConnection; | |
| 27 private TestInputMethodManagerWrapper mWrapper; | |
| 28 private TestImeAdapter mImeAdapter; | |
| 29 | |
| 30 @Override | |
| 31 public void setUp() throws Exception { | |
| 32 super.setUp(); | |
| 33 launchContentShellWithUrl("about:blank"); | |
| 34 waitForActiveShellToBeDoneLoading(); | |
| 35 mWrapper = new TestInputMethodManagerWrapper(getActivity()); | |
| 36 TestImeAdapterDelegate imeAdapterDelegate = | |
| 37 new TestImeAdapterDelegate(getContentViewCore().getContainerView
()); | |
| 38 mImeAdapter = new TestImeAdapter(mWrapper, imeAdapterDelegate); | |
| 39 mConnection = new AdapterInputConnection( | |
| 40 getContentViewCore().getContainerView(), mImeAdapter, 0, 0, new
EditorInfo()); | |
| 41 } | |
| 42 | |
| 43 @SmallTest | |
| 44 @Feature({"TextInput", "Main"}) | |
| 45 public void testAdjustLengthBeforeAndAfterSelection() throws Throwable { | |
| 46 final String ga = "\uAC00"; | |
| 47 final String smiley = "\uD83D\uDE0A"; // multi character codepoint | |
| 48 | |
| 49 // No need to adjust length. | |
| 50 assertFalse(AdapterInputConnection.isIndexBetweenUtf16SurrogatePair("a",
0)); | |
| 51 assertFalse(AdapterInputConnection.isIndexBetweenUtf16SurrogatePair(ga,
0)); | |
| 52 assertFalse(AdapterInputConnection.isIndexBetweenUtf16SurrogatePair("aa"
, 1)); | |
| 53 assertFalse(AdapterInputConnection.isIndexBetweenUtf16SurrogatePair("a"
+ smiley + "a", 1)); | |
| 54 | |
| 55 // Needs to adjust length. | |
| 56 assertTrue(AdapterInputConnection.isIndexBetweenUtf16SurrogatePair(smile
y, 1)); | |
| 57 assertTrue(AdapterInputConnection.isIndexBetweenUtf16SurrogatePair(smile
y + "a", 1)); | |
| 58 } | |
| 59 | |
| 60 @MediumTest | |
| 61 @Feature({"TextInput", "Main"}) | |
| 62 @RerunWithUpdatedContainerView | |
| 63 public void testSetComposingText() throws Throwable { | |
| 64 mConnection.setComposingText("t", 1); | |
| 65 assertCorrectState("t", 1, 1, 0, 1, mConnection.getImeStateForTesting())
; | |
| 66 mWrapper.verifyUpdateSelectionCall(0, 1, 1, 0, 1); | |
| 67 | |
| 68 mConnection.setComposingText("te", 1); | |
| 69 assertCorrectState("te", 2, 2, 0, 2, mConnection.getImeStateForTesting()
); | |
| 70 mWrapper.verifyUpdateSelectionCall(1, 2, 2, 0, 2); | |
| 71 | |
| 72 mConnection.setComposingText("tes", 1); | |
| 73 assertCorrectState("tes", 3, 3, 0, 3, mConnection.getImeStateForTesting(
)); | |
| 74 mWrapper.verifyUpdateSelectionCall(2, 3, 3, 0, 3); | |
| 75 | |
| 76 mConnection.setComposingText("test", 1); | |
| 77 assertCorrectState("test", 4, 4, 0, 4, mConnection.getImeStateForTesting
()); | |
| 78 mWrapper.verifyUpdateSelectionCall(3, 4, 4, 0, 4); | |
| 79 } | |
| 80 | |
| 81 @MediumTest | |
| 82 @Feature({"TextInput", "Main"}) | |
| 83 public void testSelectionUpdatesDuringBatch() throws Throwable { | |
| 84 mConnection.beginBatchEdit(); | |
| 85 mConnection.setComposingText("t", 1); | |
| 86 assertEquals(0, mWrapper.getUpdateSelectionCallCount()); | |
| 87 mConnection.setComposingText("te", 1); | |
| 88 assertEquals(0, mWrapper.getUpdateSelectionCallCount()); | |
| 89 mConnection.beginBatchEdit(); | |
| 90 mConnection.setComposingText("tes", 1); | |
| 91 assertEquals(0, mWrapper.getUpdateSelectionCallCount()); | |
| 92 mConnection.endBatchEdit(); | |
| 93 mConnection.setComposingText("test", 1); | |
| 94 assertEquals(0, mWrapper.getUpdateSelectionCallCount()); | |
| 95 mConnection.endBatchEdit(); | |
| 96 assertEquals(1, mWrapper.getUpdateSelectionCallCount()); | |
| 97 mWrapper.verifyUpdateSelectionCall(0, 4, 4, 0, 4); | |
| 98 } | |
| 99 | |
| 100 private static class TestImeAdapter extends ImeAdapter { | |
| 101 private final ArrayList<Integer> mKeyEventQueue = new ArrayList<Integer>
(); | |
| 102 | |
| 103 public TestImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDeleg
ate embedder) { | |
| 104 super(wrapper, embedder); | |
| 105 } | |
| 106 | |
| 107 @Override | |
| 108 public void sendSyntheticKeyPress(int keyCode, int flags) { | |
| 109 mKeyEventQueue.add(keyCode); | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 private static class TestInputMethodManagerWrapper extends InputMethodManage
rWrapper { | |
| 114 private final ArrayList<ImeState> mUpdates = new ArrayList<ImeState>(); | |
| 115 | |
| 116 public TestInputMethodManagerWrapper(Context context) { | |
| 117 super(context); | |
| 118 } | |
| 119 | |
| 120 @Override | |
| 121 public void restartInput(View view) {} | |
| 122 | |
| 123 @Override | |
| 124 public void showSoftInput(View view, int flags, ResultReceiver resultRec
eiver) {} | |
| 125 | |
| 126 @Override | |
| 127 public boolean isActive(View view) { | |
| 128 return true; | |
| 129 } | |
| 130 | |
| 131 @Override | |
| 132 public boolean hideSoftInputFromWindow(IBinder windowToken, int flags, | |
| 133 ResultReceiver resultReceiver) { | |
| 134 return true; | |
| 135 } | |
| 136 | |
| 137 @Override | |
| 138 public void updateSelection(View view, int selStart, int selEnd, | |
| 139 int candidatesStart, int candidatesEnd) { | |
| 140 mUpdates.add(new ImeState("", selStart, selEnd, candidatesStart, can
didatesEnd)); | |
| 141 } | |
| 142 | |
| 143 public int getUpdateSelectionCallCount() { | |
| 144 return mUpdates.size(); | |
| 145 } | |
| 146 | |
| 147 public void verifyUpdateSelectionCall(int index, int selectionStart, int
selectionEnd, | |
| 148 int compositionStart, int compositionEnd) { | |
| 149 ImeState state = mUpdates.get(index); | |
| 150 assertEquals("Selection start did not match", selectionStart, state.
selectionStart); | |
| 151 assertEquals("Selection end did not match", selectionEnd, state.sele
ctionEnd); | |
| 152 assertEquals("Composition start did not match", compositionStart, | |
| 153 state.compositionStart); | |
| 154 assertEquals("Composition end did not match", compositionEnd, state.
compositionEnd); | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 private static void assertCorrectState(String text, int selectionStart, int
selectionEnd, | |
| 159 int compositionStart, int compositionEnd, ImeState actual) { | |
| 160 assertEquals("Text did not match", text, actual.text); | |
| 161 assertEquals("Selection start did not match", selectionStart, actual.sel
ectionStart); | |
| 162 assertEquals("Selection end did not match", selectionEnd, actual.selecti
onEnd); | |
| 163 assertEquals("Composition start did not match", compositionStart, actual
.compositionStart); | |
| 164 assertEquals("Composition end did not match", compositionEnd, actual.com
positionEnd); | |
| 165 } | |
| 166 } | |
| OLD | NEW |