OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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.annotation.TargetApi; | |
8 import android.graphics.Matrix; | |
9 import android.graphics.RectF; | |
10 import android.os.Build; | |
11 import android.test.InstrumentationTestCase; | |
12 import android.test.suitebuilder.annotation.SmallTest; | |
13 import android.text.TextUtils; | |
14 import android.view.View; | |
15 import android.view.inputmethod.CursorAnchorInfo; | |
16 import android.view.inputmethod.InputConnection; | |
17 | |
18 import org.chromium.base.test.util.Feature; | |
19 import org.chromium.base.test.util.MinAndroidSdkLevel; | |
20 import org.chromium.content.browser.RenderCoordinates; | |
21 import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper; | |
22 | |
23 /** | |
24 * Test for {@link CursorAnchorInfoController}. | |
25 */ | |
26 @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP) | |
27 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | |
28 public class CursorAnchorInfoControllerTest extends InstrumentationTestCase { | |
29 private static RenderCoordinates createRenderCoordinates(float deviceScaleFa ctor, | |
30 float contentOffsetYPix) { | |
31 RenderCoordinates renderCoordinates = new RenderCoordinates(); | |
32 renderCoordinates.setFrameInfoForTest(deviceScaleFactor, contentOffsetYP ix); | |
33 return renderCoordinates; | |
34 } | |
35 | |
36 private static final class TestViewDelegate implements CursorAnchorInfoContr oller.ViewDelegate { | |
37 public int mLocationX; | |
Ted C
2016/03/07 21:31:45
no leading m prefix for public fields.
kinaba
2016/03/10 06:24:12
Done.
| |
38 public int mLocationY; | |
39 @Override | |
40 public void getLocationOnScreen(View view, int[] location) { | |
41 location[0] = mLocationX; | |
42 location[1] = mLocationY; | |
43 } | |
44 } | |
45 | |
46 private static final class TestComposingTextDelegate | |
47 implements CursorAnchorInfoController.ComposingTextDelegate { | |
48 private String mText; | |
49 private int mSelectionStart = -1; | |
50 private int mSelectionEnd = -1; | |
51 private int mComposingTextStart = -1; | |
52 private int mComposingTextEnd = -1; | |
53 | |
54 @Override | |
55 public CharSequence getText() { | |
56 return mText; | |
57 } | |
58 @Override | |
59 public int getSelectionStart() { | |
60 return mSelectionStart; | |
61 } | |
62 @Override | |
63 public int getSelectionEnd() { | |
64 return mSelectionEnd; | |
65 } | |
66 @Override | |
67 public int getComposingTextStart() { | |
68 return mComposingTextStart; | |
69 } | |
70 @Override | |
71 public int getComposingTextEnd() { | |
72 return mComposingTextEnd; | |
73 } | |
74 | |
75 public void updateTextAndSelection(CursorAnchorInfoController controller , | |
76 String text, int compositionStart, int compositionEnd, int selec tionStart, | |
77 int selectionEnd) { | |
78 mText = text; | |
79 mSelectionStart = selectionStart; | |
80 mSelectionEnd = selectionEnd; | |
81 mComposingTextStart = compositionStart; | |
82 mComposingTextEnd = compositionEnd; | |
83 controller.invalidateLastCursorAnchorInfo(); | |
84 } | |
85 | |
86 public void clearTextAndSelection(CursorAnchorInfoController controller) { | |
87 updateTextAndSelection(controller, null, -1, -1, -1, -1); | |
88 } | |
89 } | |
90 | |
91 private void assertScaleAndTranslate(float expectedScale, float expectedTran slateX, | |
92 float expectedTranslateY, CursorAnchorInfo actual) { | |
93 Matrix expectedMatrix = new Matrix(); | |
94 expectedMatrix.setScale(expectedScale, expectedScale); | |
95 expectedMatrix.postTranslate(expectedTranslateX, expectedTranslateY); | |
96 float[] expectedMatrixValues = new float[12]; | |
97 expectedMatrix.getValues(expectedMatrixValues); | |
Ted C
2016/03/07 21:31:45
The documentation states it copies 9, is that inco
kinaba
2016/03/10 06:24:12
It's 9.
| |
98 float[] actualMatrixValues = new float[12]; | |
99 actual.getMatrix().getValues(actualMatrixValues); | |
100 for (int i = 0; i < expectedMatrixValues.length; ++i) { | |
101 assertEquals(expectedMatrixValues[i], actualMatrixValues[i]); | |
Ted C
2016/03/07 21:31:45
why not use Matrix.equals instead of comparing flo
kinaba
2016/03/10 06:24:12
Done.
| |
102 } | |
103 } | |
104 | |
105 private void assertHasInsertionMarker(int expectedFlags, float expectedHoriz ontal, | |
106 float expectedTop, float expectedBaseline, float expectedBottom, | |
107 CursorAnchorInfo actual) { | |
108 assertEquals(expectedFlags, actual.getInsertionMarkerFlags()); | |
109 assertEquals(expectedHorizontal, actual.getInsertionMarkerHorizontal()); | |
110 assertEquals(expectedTop, actual.getInsertionMarkerTop()); | |
111 assertEquals(expectedBaseline, actual.getInsertionMarkerBaseline()); | |
112 assertEquals(expectedBottom, actual.getInsertionMarkerBottom()); | |
113 } | |
114 | |
115 private void assertHasNoInsertionMarker(CursorAnchorInfo actual) { | |
116 assertEquals(0, actual.getInsertionMarkerFlags()); | |
117 assertTrue(Float.isNaN(actual.getInsertionMarkerHorizontal())); | |
118 assertTrue(Float.isNaN(actual.getInsertionMarkerTop())); | |
119 assertTrue(Float.isNaN(actual.getInsertionMarkerBaseline())); | |
120 assertTrue(Float.isNaN(actual.getInsertionMarkerBottom())); | |
121 } | |
122 | |
123 private void assertComposingText(CharSequence expectedComposingText, | |
124 int expectedComposingTextStart, CursorAnchorInfo actual) { | |
125 assertTrue(TextUtils.equals(expectedComposingText, actual.getComposingTe xt())); | |
126 assertEquals(expectedComposingTextStart, actual.getComposingTextStart()) ; | |
127 } | |
128 | |
129 private void assertSelection(int expecteSelectionStart, int expecteSelection End, | |
130 CursorAnchorInfo actual) { | |
131 assertEquals(expecteSelectionStart, actual.getSelectionStart()); | |
132 assertEquals(expecteSelectionEnd, actual.getSelectionEnd()); | |
133 } | |
134 | |
135 private void assertEquals(RectF expectedRect, RectF actualRect) { | |
Ted C
2016/03/07 21:31:45
same question as Matrix, why not use the .equals
kinaba
2016/03/10 06:24:12
Done.
| |
136 if (expectedRect == null) { | |
137 assertNull(actualRect); | |
138 return; | |
139 } | |
140 assertNotNull(actualRect); | |
141 assertEquals(actualRect.left, expectedRect.left); | |
142 assertEquals(actualRect.top, expectedRect.top); | |
143 assertEquals(actualRect.right, expectedRect.right); | |
144 assertEquals(actualRect.bottom, expectedRect.bottom); | |
145 } | |
146 | |
147 @SmallTest | |
148 @Feature({"Input-Text-IME"}) | |
149 public void testFocusedNodeChanged() { | |
150 TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(n ull); | |
151 TestViewDelegate viewDelegate = new TestViewDelegate(); | |
152 TestComposingTextDelegate composingTextDelegate = new TestComposingTextD elegate(); | |
153 CursorAnchorInfoController controller = CursorAnchorInfoController.creat eForTest( | |
154 immw, composingTextDelegate, viewDelegate); | |
155 View view = null; | |
156 | |
157 viewDelegate.mLocationX = 0; | |
158 viewDelegate.mLocationY = 0; | |
159 | |
160 assertFalse( | |
161 "IC#onRequestCursorUpdates() must be rejected if the focused nod e is not editable.", | |
162 controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_ MONITOR, view)); | |
163 | |
164 // Make sure that the focused node is considered to be non-editable by d efault. | |
165 controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3 .0f}); | |
Ted C
2016/03/07 21:31:45
pretty sure there is supposed to be a space after
kinaba
2016/03/10 06:24:12
Done.
| |
166 composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1 ); | |
167 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
168 true, true, 2.0f, 0.0f, 3.0f, view); | |
169 assertEquals(0, immw.getUpdateCursorAnchorInfoCounter()); | |
170 | |
171 controller.focusedNodeChanged(false); | |
172 composingTextDelegate.clearTextAndSelection(controller); | |
173 | |
174 // Make sure that the controller does not crash even if it is called whi le the focused node | |
175 // is not editable. | |
176 controller.setCompositionCharacterBounds(new float[]{30.0f, 1.0f, 32.0f, 3.0f}); | |
177 composingTextDelegate.updateTextAndSelection(controller, "1", 0, 1, 0, 1 ); | |
178 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 100.0f), | |
179 true, true, 2.0f, 0.0f, 3.0f, view); | |
180 assertEquals(0, immw.getUpdateCursorAnchorInfoCounter()); | |
181 } | |
182 | |
183 @SmallTest | |
184 @Feature({"Input-Text-IME"}) | |
185 public void testImmediateMode() { | |
186 TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(n ull); | |
187 TestViewDelegate viewDelegate = new TestViewDelegate(); | |
188 TestComposingTextDelegate composingTextDelegate = new TestComposingTextD elegate(); | |
189 CursorAnchorInfoController controller = CursorAnchorInfoController.creat eForTest( | |
190 immw, composingTextDelegate, viewDelegate); | |
191 View view = null; | |
192 viewDelegate.mLocationX = 0; | |
193 viewDelegate.mLocationY = 0; | |
194 | |
195 controller.focusedNodeChanged(true); | |
196 composingTextDelegate.clearTextAndSelection(controller); | |
197 | |
198 // Make sure that #updateCursorAnchorInfo() is not be called until the m atrix info becomes | |
199 // available with #onUpdateFrameInfo(). | |
200 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_IMMEDIATE, | |
201 view)); | |
202 controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3 .0f}); | |
203 composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1 ); | |
204 assertEquals(0, immw.getUpdateCursorAnchorInfoCounter()); | |
205 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
206 true, true, 2.0f, 0.0f, 3.0f, view); | |
207 assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); | |
208 assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
209 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
210 3.0f, immw.getLastCursorAnchorInfo()); | |
211 assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f), | |
212 immw.getLastCursorAnchorInfo().getCharacterBounds(0)); | |
213 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
214 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0)); | |
215 assertComposingText("0", 0, immw.getLastCursorAnchorInfo()); | |
216 assertSelection(0, 1, immw.getLastCursorAnchorInfo()); | |
217 immw.clearLastCursorAnchorInfo(); | |
218 | |
219 // Make sure that 2nd call of #onUpdateFrameInfo() is ignored. | |
220 controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f), | |
221 true, true, 2.0f, 0.0f, 3.0f, view); | |
222 assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); | |
223 | |
224 // Make sure that #onUpdateFrameInfo() is immediately called because the matrix info is | |
225 // already available. | |
226 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_IMMEDIATE, | |
227 view)); | |
228 assertEquals(2, immw.getUpdateCursorAnchorInfoCounter()); | |
229 assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
230 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
231 3.0f, immw.getLastCursorAnchorInfo()); | |
232 assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f), | |
233 immw.getLastCursorAnchorInfo().getCharacterBounds(0)); | |
234 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
235 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0)); | |
236 assertComposingText("0", 0, immw.getLastCursorAnchorInfo()); | |
237 assertSelection(0, 1, immw.getLastCursorAnchorInfo()); | |
238 immw.clearLastCursorAnchorInfo(); | |
239 | |
240 // Make sure that CURSOR_UPDATE_IMMEDIATE and CURSOR_UPDATE_MONITOR can be specified at | |
241 // the same time. | |
242 assertTrue(controller.onRequestCursorUpdates( | |
243 InputConnection.CURSOR_UPDATE_IMMEDIATE | InputConnection.CURSOR _UPDATE_MONITOR, | |
244 view)); | |
245 assertEquals(3, immw.getUpdateCursorAnchorInfoCounter()); | |
246 assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
247 immw.clearLastCursorAnchorInfo(); | |
248 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
249 true, true, 2.0f, 0.0f, 3.0f, view); | |
250 assertEquals(4, immw.getUpdateCursorAnchorInfoCounter()); | |
251 assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
252 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
253 3.0f, immw.getLastCursorAnchorInfo()); | |
254 assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f), | |
255 immw.getLastCursorAnchorInfo().getCharacterBounds(0)); | |
256 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
257 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0)); | |
258 assertComposingText("0", 0, immw.getLastCursorAnchorInfo()); | |
259 assertSelection(0, 1, immw.getLastCursorAnchorInfo()); | |
260 immw.clearLastCursorAnchorInfo(); | |
261 | |
262 // Make sure that CURSOR_UPDATE_IMMEDIATE is cleared if the focused node becomes | |
263 // non-editable. | |
264 controller.focusedNodeChanged(false); | |
265 controller.focusedNodeChanged(true); | |
266 composingTextDelegate.clearTextAndSelection(controller); | |
267 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_IMMEDIATE, | |
268 view)); | |
269 controller.focusedNodeChanged(false); | |
270 composingTextDelegate.clearTextAndSelection(controller); | |
271 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 100.0f), | |
272 true, true, 2.0f, 0.0f, 3.0f, view); | |
273 assertEquals(4, immw.getUpdateCursorAnchorInfoCounter()); | |
274 | |
275 // Make sure that CURSOR_UPDATE_IMMEDIATE can be enabled again. | |
276 controller.focusedNodeChanged(true); | |
277 composingTextDelegate.clearTextAndSelection(controller); | |
278 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_IMMEDIATE, | |
279 view)); | |
280 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
281 true, true, 2.0f, 0.0f, 3.0f, view); | |
282 assertEquals(5, immw.getUpdateCursorAnchorInfoCounter()); | |
283 assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
284 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
285 3.0f, immw.getLastCursorAnchorInfo()); | |
286 assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(0)) ; | |
287 assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0 )); | |
288 assertComposingText(null, -1, immw.getLastCursorAnchorInfo()); | |
289 assertSelection(-1, -1, immw.getLastCursorAnchorInfo()); | |
290 immw.clearLastCursorAnchorInfo(); | |
291 } | |
292 | |
293 @SmallTest | |
294 @Feature({"Input-Text-IME"}) | |
295 public void testMonitorMode() { | |
296 TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(n ull); | |
297 TestViewDelegate viewDelegate = new TestViewDelegate(); | |
298 TestComposingTextDelegate composingTextDelegate = new TestComposingTextD elegate(); | |
299 CursorAnchorInfoController controller = CursorAnchorInfoController.creat eForTest( | |
300 immw, composingTextDelegate, viewDelegate); | |
301 View view = null; | |
302 viewDelegate.mLocationX = 0; | |
303 viewDelegate.mLocationY = 0; | |
304 | |
305 controller.focusedNodeChanged(true); | |
306 composingTextDelegate.clearTextAndSelection(controller); | |
307 | |
308 // Make sure that #updateCursorAnchorInfo() is not be called until the m atrix info becomes | |
309 // available with #onUpdateFrameInfo(). | |
310 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_MONITOR, view)); | |
311 controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3 .0f}); | |
312 composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1 ); | |
313 assertEquals(0, immw.getUpdateCursorAnchorInfoCounter()); | |
314 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
315 true, true, 2.0f, 0.0f, 3.0f, view); | |
316 assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); | |
317 assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
318 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
319 3.0f, immw.getLastCursorAnchorInfo()); | |
320 assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f), | |
321 immw.getLastCursorAnchorInfo().getCharacterBounds(0)); | |
322 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
323 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0)); | |
324 assertComposingText("0", 0, immw.getLastCursorAnchorInfo()); | |
325 assertSelection(0, 1, immw.getLastCursorAnchorInfo()); | |
326 immw.clearLastCursorAnchorInfo(); | |
327 | |
328 // Make sure that #updateCursorAnchorInfo() is not be called if any coor dinate parameter is | |
329 // changed for better performance. | |
330 controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3 .0f}); | |
331 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
332 true, true, 2.0f, 0.0f, 3.0f, view); | |
333 assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); | |
334 | |
335 // Make sure that #updateCursorAnchorInfo() is called if #setComposition CharacterBounds() | |
336 // is called with a different parameter. | |
337 controller.setCompositionCharacterBounds(new float[]{30.0f, 1.0f, 32.0f, 3.0f}); | |
338 assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); | |
339 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
340 true, true, 2.0f, 0.0f, 3.0f, view); | |
341 assertEquals(2, immw.getUpdateCursorAnchorInfoCounter()); | |
342 assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
343 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
344 3.0f, immw.getLastCursorAnchorInfo()); | |
345 assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f), | |
346 immw.getLastCursorAnchorInfo().getCharacterBounds(0)); | |
347 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
348 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0)); | |
349 assertComposingText("0", 0, immw.getLastCursorAnchorInfo()); | |
350 assertSelection(0, 1, immw.getLastCursorAnchorInfo()); | |
351 immw.clearLastCursorAnchorInfo(); | |
352 | |
353 // Make sure that #updateCursorAnchorInfo() is called if #updateTextAndS election() | |
354 // is called with a different parameter. | |
355 composingTextDelegate.updateTextAndSelection(controller, "1", 0, 1, 0, 1 ); | |
356 assertEquals(2, immw.getUpdateCursorAnchorInfoCounter()); | |
357 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
358 true, true, 2.0f, 0.0f, 3.0f, view); | |
359 assertEquals(3, immw.getUpdateCursorAnchorInfoCounter()); | |
360 assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
361 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
362 3.0f, immw.getLastCursorAnchorInfo()); | |
363 assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f), | |
364 immw.getLastCursorAnchorInfo().getCharacterBounds(0)); | |
365 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
366 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0)); | |
367 assertComposingText("1", 0, immw.getLastCursorAnchorInfo()); | |
368 assertSelection(0, 1, immw.getLastCursorAnchorInfo()); | |
369 immw.clearLastCursorAnchorInfo(); | |
370 | |
371 // Make sure that #updateCursorAnchorInfo() is called if #onUpdateFrameI nfo() | |
372 // is called with a different parameter. | |
373 controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f), | |
374 true, true, 2.0f, 0.0f, 3.0f, view); | |
375 assertEquals(4, immw.getUpdateCursorAnchorInfoCounter()); | |
376 assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
377 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
378 3.0f, immw.getLastCursorAnchorInfo()); | |
379 assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f), | |
380 immw.getLastCursorAnchorInfo().getCharacterBounds(0)); | |
381 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
382 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0)); | |
383 assertComposingText("1", 0, immw.getLastCursorAnchorInfo()); | |
384 assertSelection(0, 1, immw.getLastCursorAnchorInfo()); | |
385 immw.clearLastCursorAnchorInfo(); | |
386 | |
387 // Make sure that #updateCursorAnchorInfo() is called when the view orig in is changed. | |
388 viewDelegate.mLocationX = 7; | |
389 viewDelegate.mLocationY = 9; | |
390 controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f), | |
391 true, true, 2.0f, 0.0f, 3.0f, view); | |
392 assertEquals(5, immw.getUpdateCursorAnchorInfoCounter()); | |
393 assertScaleAndTranslate(2.0f, 7.0f, 9.0f, immw.getLastCursorAnchorInfo() ); | |
394 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
395 3.0f, immw.getLastCursorAnchorInfo()); | |
396 assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f), | |
397 immw.getLastCursorAnchorInfo().getCharacterBounds(0)); | |
398 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
399 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0)); | |
400 assertComposingText("1", 0, immw.getLastCursorAnchorInfo()); | |
401 assertSelection(0, 1, immw.getLastCursorAnchorInfo()); | |
402 immw.clearLastCursorAnchorInfo(); | |
403 | |
404 // Make sure that CURSOR_UPDATE_IMMEDIATE is cleared if the focused node becomes | |
405 // non-editable. | |
406 controller.focusedNodeChanged(false); | |
407 controller.focusedNodeChanged(true); | |
408 composingTextDelegate.clearTextAndSelection(controller); | |
409 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_MONITOR, view)); | |
410 controller.focusedNodeChanged(false); | |
411 composingTextDelegate.clearTextAndSelection(controller); | |
412 controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3 .0f}); | |
413 composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1 ); | |
414 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
415 true, true, 2.0f, 0.0f, 3.0f, view); | |
416 assertEquals(5, immw.getUpdateCursorAnchorInfoCounter()); | |
417 | |
418 // Make sure that CURSOR_UPDATE_MONITOR can be enabled again. | |
419 controller.focusedNodeChanged(true); | |
420 composingTextDelegate.clearTextAndSelection(controller); | |
421 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_MONITOR, view)); | |
422 controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3 .0f}); | |
423 composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1 ); | |
424 assertEquals(5, immw.getUpdateCursorAnchorInfoCounter()); | |
425 viewDelegate.mLocationX = 0; | |
426 viewDelegate.mLocationY = 0; | |
427 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
428 true, true, 2.0f, 0.0f, 3.0f, view); | |
429 assertEquals(6, immw.getUpdateCursorAnchorInfoCounter()); | |
430 assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
431 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f, | |
432 3.0f, immw.getLastCursorAnchorInfo()); | |
433 assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f), | |
434 immw.getLastCursorAnchorInfo().getCharacterBounds(0)); | |
435 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
436 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0)); | |
437 assertComposingText("0", 0, immw.getLastCursorAnchorInfo()); | |
438 assertSelection(0, 1, immw.getLastCursorAnchorInfo()); | |
439 immw.clearLastCursorAnchorInfo(); | |
440 } | |
441 | |
442 @SmallTest | |
443 @Feature({"Input-Text-IME"}) | |
444 public void testSetCompositionCharacterBounds() { | |
445 TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(n ull); | |
446 TestViewDelegate viewDelegate = new TestViewDelegate(); | |
447 TestComposingTextDelegate composingTextDelegate = new TestComposingTextD elegate(); | |
448 CursorAnchorInfoController controller = CursorAnchorInfoController.creat eForTest( | |
449 immw, composingTextDelegate, viewDelegate); | |
450 View view = null; | |
451 | |
452 viewDelegate.mLocationX = 0; | |
453 viewDelegate.mLocationY = 0; | |
454 | |
455 controller.focusedNodeChanged(true); | |
456 composingTextDelegate.clearTextAndSelection(controller); | |
457 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_MONITOR, view)); | |
458 | |
459 composingTextDelegate.updateTextAndSelection(controller, "01234", 1, 3, 1, 1); | |
460 controller.setCompositionCharacterBounds(new float[]{0.0f, 1.0f, 2.0f, 3 .0f, | |
461 4.0f, 1.1f, 6.0f, 2.9f}); | |
462 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
463 false, false, Float.NaN, Float.NaN, Float.NaN, view); | |
464 assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); | |
465 assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(0)) ; | |
466 assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0 )); | |
467 assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f), | |
468 immw.getLastCursorAnchorInfo().getCharacterBounds(1)); | |
469 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
470 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(1)); | |
471 assertEquals(new RectF(4.0f, 1.1f, 6.0f, 2.9f), | |
472 immw.getLastCursorAnchorInfo().getCharacterBounds(2)); | |
473 assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
474 immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(2)); | |
475 assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(3)) ; | |
476 assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(3 )); | |
477 assertComposingText("12", 1, immw.getLastCursorAnchorInfo()); | |
478 assertSelection(1, 1, immw.getLastCursorAnchorInfo()); | |
479 } | |
480 | |
481 @SmallTest | |
482 @Feature({"Input-Text-IME"}) | |
483 public void testUpdateTextAndSelection() { | |
484 TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(n ull); | |
485 TestViewDelegate viewDelegate = new TestViewDelegate(); | |
486 TestComposingTextDelegate composingTextDelegate = new TestComposingTextD elegate(); | |
487 CursorAnchorInfoController controller = CursorAnchorInfoController.creat eForTest( | |
488 immw, composingTextDelegate, viewDelegate); | |
489 View view = null; | |
490 | |
491 viewDelegate.mLocationX = 0; | |
492 viewDelegate.mLocationY = 0; | |
493 | |
494 controller.focusedNodeChanged(true); | |
495 composingTextDelegate.clearTextAndSelection(controller); | |
496 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_MONITOR, view)); | |
497 | |
498 composingTextDelegate.updateTextAndSelection(controller, "01234", 3, 3, 1, 1); | |
499 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
500 false, false, Float.NaN, Float.NaN, Float.NaN, view); | |
501 assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); | |
502 assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(0)) ; | |
503 assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0 )); | |
504 assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(1)) ; | |
505 assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(1 )); | |
506 assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(2)) ; | |
507 assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(2 )); | |
508 assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(3)) ; | |
509 assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(3 )); | |
510 assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(4)) ; | |
511 assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(4 )); | |
512 assertComposingText("", 3, immw.getLastCursorAnchorInfo()); | |
513 assertSelection(1, 1, immw.getLastCursorAnchorInfo()); | |
514 } | |
515 | |
516 @SmallTest | |
517 @Feature({"Input-Text-IME"}) | |
518 public void testInsertionMarker() { | |
519 TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(n ull); | |
520 TestViewDelegate viewDelegate = new TestViewDelegate(); | |
521 TestComposingTextDelegate composingTextDelegate = new TestComposingTextD elegate(); | |
522 CursorAnchorInfoController controller = CursorAnchorInfoController.creat eForTest( | |
523 immw, composingTextDelegate, viewDelegate); | |
524 View view = null; | |
525 | |
526 controller.focusedNodeChanged(true); | |
527 composingTextDelegate.clearTextAndSelection(controller); | |
528 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_MONITOR, view)); | |
529 | |
530 // Test no insertion marker. | |
531 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
532 false, false, Float.NaN, Float.NaN, Float.NaN, view); | |
533 assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); | |
534 assertHasNoInsertionMarker(immw.getLastCursorAnchorInfo()); | |
535 immw.clearLastCursorAnchorInfo(); | |
536 | |
537 // Test a visible insertion marker. | |
538 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
539 true, true, 10.0f, 23.0f, 29.0f, view); | |
540 assertEquals(2, immw.getUpdateCursorAnchorInfoCounter()); | |
541 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, | |
542 10.0f, 23.0f, 29.0f, 29.0f, immw.getLastCursorAnchorInfo()); | |
543 immw.clearLastCursorAnchorInfo(); | |
544 | |
545 // Test a invisible insertion marker. | |
546 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
547 true, false, 10.0f, 23.0f, 29.0f, view); | |
548 assertEquals(3, immw.getUpdateCursorAnchorInfoCounter()); | |
549 assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION, | |
550 10.0f, 23.0f, 29.0f, 29.0f, immw.getLastCursorAnchorInfo()); | |
551 immw.clearLastCursorAnchorInfo(); | |
552 } | |
553 | |
554 @SmallTest | |
555 @Feature({"Input-Text-IME"}) | |
556 public void testMatrix() { | |
557 TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(n ull); | |
558 TestViewDelegate viewDelegate = new TestViewDelegate(); | |
559 TestComposingTextDelegate composingTextDelegate = new TestComposingTextD elegate(); | |
560 CursorAnchorInfoController controller = CursorAnchorInfoController.creat eForTest( | |
561 immw, composingTextDelegate, viewDelegate); | |
562 View view = null; | |
563 | |
564 controller.focusedNodeChanged(true); | |
565 composingTextDelegate.clearTextAndSelection(controller); | |
566 assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDA TE_MONITOR, view)); | |
567 | |
568 // Test no transformation | |
569 viewDelegate.mLocationX = 0; | |
570 viewDelegate.mLocationY = 0; | |
571 controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f), | |
572 false, false, Float.NaN, Float.NaN, Float.NaN, view); | |
573 assertEquals(1, immw.getUpdateCursorAnchorInfoCounter()); | |
574 assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
575 immw.clearLastCursorAnchorInfo(); | |
576 | |
577 // device scale factor == 2.0 | |
578 viewDelegate.mLocationX = 0; | |
579 viewDelegate.mLocationY = 0; | |
580 controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f), | |
581 false, false, Float.NaN, Float.NaN, Float.NaN, view); | |
582 assertEquals(2, immw.getUpdateCursorAnchorInfoCounter()); | |
583 assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo() ); | |
584 immw.clearLastCursorAnchorInfo(); | |
585 | |
586 // device scale factor == 2.0 | |
587 // view origin == (10, 141) | |
588 viewDelegate.mLocationX = 10; | |
589 viewDelegate.mLocationY = 141; | |
590 controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f), | |
591 false, false, Float.NaN, Float.NaN, Float.NaN, view); | |
592 assertEquals(3, immw.getUpdateCursorAnchorInfoCounter()); | |
593 assertScaleAndTranslate(2.0f, 10.0f, 141.0f, immw.getLastCursorAnchorInf o()); | |
594 immw.clearLastCursorAnchorInfo(); | |
595 | |
596 // device scale factor == 2.0 | |
597 // content offset Y = 40.0f | |
598 // view origin == (10, 141) | |
599 viewDelegate.mLocationX = 10; | |
600 viewDelegate.mLocationY = 141; | |
601 controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 40.0f), | |
602 false, false, Float.NaN, Float.NaN, Float.NaN, view); | |
603 assertEquals(4, immw.getUpdateCursorAnchorInfoCounter()); | |
604 assertScaleAndTranslate(2.0f, 10.0f, 181.0f, immw.getLastCursorAnchorInf o()); | |
605 immw.clearLastCursorAnchorInfo(); | |
606 } | |
607 } | |
OLD | NEW |