1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.view.inputmethod; 18 19import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION; 20import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION; 21import static android.view.inputmethod.CursorAnchorInfo.FLAG_IS_RTL; 22 23import static org.junit.Assert.assertEquals; 24import static org.junit.Assert.assertFalse; 25import static org.junit.Assert.assertNull; 26import static org.junit.Assert.assertTrue; 27 28import android.graphics.Matrix; 29import android.graphics.RectF; 30import android.os.Parcel; 31import android.support.test.filters.SmallTest; 32import android.support.test.runner.AndroidJUnit4; 33import android.text.TextUtils; 34import android.view.inputmethod.CursorAnchorInfo.Builder; 35 36import org.junit.Test; 37import org.junit.runner.RunWith; 38 39import java.util.Objects; 40 41@SmallTest 42@RunWith(AndroidJUnit4.class) 43public class CursorAnchorInfoTest { 44 private static final float EPSILON = 0.0000001f; 45 46 private static final RectF[] MANY_BOUNDS = new RectF[] { 47 new RectF(101.0f, 201.0f, 301.0f, 401.0f), 48 new RectF(102.0f, 202.0f, 302.0f, 402.0f), 49 new RectF(103.0f, 203.0f, 303.0f, 403.0f), 50 new RectF(104.0f, 204.0f, 304.0f, 404.0f), 51 new RectF(105.0f, 205.0f, 305.0f, 405.0f), 52 new RectF(106.0f, 206.0f, 306.0f, 406.0f), 53 new RectF(107.0f, 207.0f, 307.0f, 407.0f), 54 new RectF(108.0f, 208.0f, 308.0f, 408.0f), 55 new RectF(109.0f, 209.0f, 309.0f, 409.0f), 56 new RectF(110.0f, 210.0f, 310.0f, 410.0f), 57 new RectF(111.0f, 211.0f, 311.0f, 411.0f), 58 new RectF(112.0f, 212.0f, 312.0f, 412.0f), 59 new RectF(113.0f, 213.0f, 313.0f, 413.0f), 60 new RectF(114.0f, 214.0f, 314.0f, 414.0f), 61 new RectF(115.0f, 215.0f, 315.0f, 415.0f), 62 new RectF(116.0f, 216.0f, 316.0f, 416.0f), 63 new RectF(117.0f, 217.0f, 317.0f, 417.0f), 64 new RectF(118.0f, 218.0f, 318.0f, 418.0f), 65 new RectF(119.0f, 219.0f, 319.0f, 419.0f), 66 }; 67 private static final int[] MANY_FLAGS_ARRAY = new int[] { 68 FLAG_HAS_INVISIBLE_REGION, 69 FLAG_HAS_INVISIBLE_REGION | FLAG_HAS_VISIBLE_REGION, 70 FLAG_HAS_VISIBLE_REGION, 71 FLAG_HAS_VISIBLE_REGION, 72 FLAG_HAS_VISIBLE_REGION, 73 FLAG_HAS_VISIBLE_REGION, 74 FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL, 75 FLAG_HAS_INVISIBLE_REGION | FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL, 76 FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL, 77 FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL, 78 FLAG_HAS_VISIBLE_REGION, 79 FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL, 80 FLAG_HAS_VISIBLE_REGION, 81 FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL, 82 FLAG_HAS_VISIBLE_REGION, 83 FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL, 84 FLAG_HAS_VISIBLE_REGION, 85 FLAG_HAS_INVISIBLE_REGION, 86 FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL, 87 }; 88 89 @Test 90 public void testBuilder() throws Exception { 91 final int SELECTION_START = 30; 92 final int SELECTION_END = 40; 93 final int COMPOSING_TEXT_START = 32; 94 final String COMPOSING_TEXT = "test"; 95 final int INSERTION_MARKER_FLAGS = 96 FLAG_HAS_VISIBLE_REGION | FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL; 97 final float INSERTION_MARKER_HORIZONTAL = 10.5f; 98 final float INSERTION_MARKER_TOP = 100.1f; 99 final float INSERTION_MARKER_BASELINE = 110.4f; 100 final float INSERTION_MARKER_BOTOM = 111.0f; 101 102 Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX); 103 TRANSFORM_MATRIX.setScale(10.0f, 20.0f); 104 105 final Builder builder = new Builder(); 106 builder.setSelectionRange(SELECTION_START, SELECTION_END) 107 .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT) 108 .setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP, 109 INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM, INSERTION_MARKER_FLAGS) 110 .setMatrix(TRANSFORM_MATRIX); 111 for (int i = 0; i < MANY_BOUNDS.length; i++) { 112 final RectF bounds = MANY_BOUNDS[i]; 113 final int flags = MANY_FLAGS_ARRAY[i]; 114 builder.addCharacterBounds(i, bounds.left, bounds.top, bounds.right, bounds.bottom, 115 flags); 116 } 117 118 final CursorAnchorInfo info = builder.build(); 119 assertEquals(SELECTION_START, info.getSelectionStart()); 120 assertEquals(SELECTION_END, info.getSelectionEnd()); 121 assertEquals(COMPOSING_TEXT_START, info.getComposingTextStart()); 122 assertTrue(TextUtils.equals(COMPOSING_TEXT, info.getComposingText())); 123 assertEquals(INSERTION_MARKER_FLAGS, info.getInsertionMarkerFlags()); 124 assertEquals(INSERTION_MARKER_HORIZONTAL, info.getInsertionMarkerHorizontal(), EPSILON); 125 assertEquals(INSERTION_MARKER_TOP, info.getInsertionMarkerTop(), EPSILON); 126 assertEquals(INSERTION_MARKER_BASELINE, info.getInsertionMarkerBaseline(), EPSILON); 127 assertEquals(INSERTION_MARKER_BOTOM, info.getInsertionMarkerBottom(), EPSILON); 128 assertEquals(TRANSFORM_MATRIX, info.getMatrix()); 129 for (int i = 0; i < MANY_BOUNDS.length; i++) { 130 final RectF expectedBounds = MANY_BOUNDS[i]; 131 assertEquals(expectedBounds, info.getCharacterBounds(i)); 132 } 133 assertNull(info.getCharacterBounds(-1)); 134 assertNull(info.getCharacterBounds(MANY_BOUNDS.length + 1)); 135 for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) { 136 final int expectedFlags = MANY_FLAGS_ARRAY[i]; 137 assertEquals(expectedFlags, info.getCharacterBoundsFlags(i)); 138 } 139 assertEquals(0, info.getCharacterBoundsFlags(-1)); 140 assertEquals(0, info.getCharacterBoundsFlags(MANY_BOUNDS.length + 1)); 141 142 // Make sure that the builder can reproduce the same object. 143 final CursorAnchorInfo info2 = builder.build(); 144 assertEquals(SELECTION_START, info2.getSelectionStart()); 145 assertEquals(SELECTION_END, info2.getSelectionEnd()); 146 assertEquals(COMPOSING_TEXT_START, info2.getComposingTextStart()); 147 assertTrue(TextUtils.equals(COMPOSING_TEXT, info2.getComposingText())); 148 assertEquals(INSERTION_MARKER_FLAGS, info2.getInsertionMarkerFlags()); 149 assertEquals(INSERTION_MARKER_HORIZONTAL, info2.getInsertionMarkerHorizontal(), EPSILON); 150 assertEquals(INSERTION_MARKER_TOP, info2.getInsertionMarkerTop(), EPSILON); 151 assertEquals(INSERTION_MARKER_BASELINE, info2.getInsertionMarkerBaseline(), EPSILON); 152 assertEquals(INSERTION_MARKER_BOTOM, info2.getInsertionMarkerBottom(), EPSILON); 153 assertEquals(TRANSFORM_MATRIX, info2.getMatrix()); 154 for (int i = 0; i < MANY_BOUNDS.length; i++) { 155 final RectF expectedBounds = MANY_BOUNDS[i]; 156 assertEquals(expectedBounds, info2.getCharacterBounds(i)); 157 } 158 assertNull(info2.getCharacterBounds(-1)); 159 assertNull(info2.getCharacterBounds(MANY_BOUNDS.length + 1)); 160 for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) { 161 final int expectedFlags = MANY_FLAGS_ARRAY[i]; 162 assertEquals(expectedFlags, info2.getCharacterBoundsFlags(i)); 163 } 164 assertEquals(0, info2.getCharacterBoundsFlags(-1)); 165 assertEquals(0, info2.getCharacterBoundsFlags(MANY_BOUNDS.length + 1)); 166 assertEquals(info, info2); 167 assertEquals(info.hashCode(), info2.hashCode()); 168 169 // Make sure that object can be marshaled via {@link Parsel}. 170 final CursorAnchorInfo info3 = cloneViaParcel(info2); 171 assertEquals(SELECTION_START, info3.getSelectionStart()); 172 assertEquals(SELECTION_END, info3.getSelectionEnd()); 173 assertEquals(COMPOSING_TEXT_START, info3.getComposingTextStart()); 174 assertTrue(TextUtils.equals(COMPOSING_TEXT, info3.getComposingText())); 175 assertEquals(INSERTION_MARKER_FLAGS, info3.getInsertionMarkerFlags()); 176 assertEquals(INSERTION_MARKER_HORIZONTAL, info3.getInsertionMarkerHorizontal(), EPSILON); 177 assertEquals(INSERTION_MARKER_TOP, info3.getInsertionMarkerTop(), EPSILON); 178 assertEquals(INSERTION_MARKER_BASELINE, info3.getInsertionMarkerBaseline(), EPSILON); 179 assertEquals(INSERTION_MARKER_BOTOM, info3.getInsertionMarkerBottom(), EPSILON); 180 assertEquals(TRANSFORM_MATRIX, info3.getMatrix()); 181 for (int i = 0; i < MANY_BOUNDS.length; i++) { 182 final RectF expectedBounds = MANY_BOUNDS[i]; 183 assertEquals(expectedBounds, info3.getCharacterBounds(i)); 184 } 185 assertNull(info3.getCharacterBounds(-1)); 186 assertNull(info3.getCharacterBounds(MANY_BOUNDS.length + 1)); 187 for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) { 188 final int expectedFlags = MANY_FLAGS_ARRAY[i]; 189 assertEquals(expectedFlags, info3.getCharacterBoundsFlags(i)); 190 } 191 assertEquals(0, info3.getCharacterBoundsFlags(-1)); 192 assertEquals(0, info3.getCharacterBoundsFlags(MANY_BOUNDS.length + 1)); 193 assertEquals(info.hashCode(), info3.hashCode()); 194 195 builder.reset(); 196 final CursorAnchorInfo uninitializedInfo = builder.build(); 197 assertEquals(-1, uninitializedInfo.getSelectionStart()); 198 assertEquals(-1, uninitializedInfo.getSelectionEnd()); 199 assertEquals(-1, uninitializedInfo.getComposingTextStart()); 200 assertNull(uninitializedInfo.getComposingText()); 201 assertEquals(0, uninitializedInfo.getInsertionMarkerFlags()); 202 assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerHorizontal(), EPSILON); 203 assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerTop(), EPSILON); 204 assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBaseline(), EPSILON); 205 assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBottom(), EPSILON); 206 assertEquals(Matrix.IDENTITY_MATRIX, uninitializedInfo.getMatrix()); 207 } 208 209 private static void assertNotEquals(final CursorAnchorInfo reference, 210 final CursorAnchorInfo actual) { 211 assertFalse(Objects.equals(reference, actual)); 212 } 213 214 @Test 215 public void testEquality() throws Exception { 216 final Matrix MATRIX1 = new Matrix(); 217 MATRIX1.setTranslate(10.0f, 20.0f); 218 final Matrix MATRIX2 = new Matrix(); 219 MATRIX2.setTranslate(110.0f, 120.0f); 220 final Matrix NAN_MATRIX = new Matrix(); 221 NAN_MATRIX.setValues(new float[]{ 222 Float.NaN, Float.NaN, Float.NaN, 223 Float.NaN, Float.NaN, Float.NaN, 224 Float.NaN, Float.NaN, Float.NaN}); 225 final int SELECTION_START1 = 2; 226 final int SELECTION_END1 = 7; 227 final String COMPOSING_TEXT1 = "0123456789"; 228 final int COMPOSING_TEXT_START1 = 0; 229 final int INSERTION_MARKER_FLAGS1 = FLAG_HAS_VISIBLE_REGION; 230 final float INSERTION_MARKER_HORIZONTAL1 = 10.5f; 231 final float INSERTION_MARKER_TOP1 = 100.1f; 232 final float INSERTION_MARKER_BASELINE1 = 110.4f; 233 final float INSERTION_MARKER_BOTOM1 = 111.0f; 234 final int SELECTION_START2 = 4; 235 final int SELECTION_END2 = 8; 236 final String COMPOSING_TEXT2 = "9876543210"; 237 final int COMPOSING_TEXT_START2 = 3; 238 final int INSERTION_MARKER_FLAGS2 = 239 FLAG_HAS_VISIBLE_REGION | FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL; 240 final float INSERTION_MARKER_HORIZONTAL2 = 14.5f; 241 final float INSERTION_MARKER_TOP2 = 200.1f; 242 final float INSERTION_MARKER_BASELINE2 = 210.4f; 243 final float INSERTION_MARKER_BOTOM2 = 211.0f; 244 245 // Default instance should be equal. 246 assertEquals(new Builder().build(), new Builder().build()); 247 248 assertEquals( 249 new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(), 250 new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build()); 251 assertNotEquals( 252 new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(), 253 new Builder().setSelectionRange(SELECTION_START1, SELECTION_END2).build()); 254 assertNotEquals( 255 new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(), 256 new Builder().setSelectionRange(SELECTION_START2, SELECTION_END1).build()); 257 assertNotEquals( 258 new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(), 259 new Builder().setSelectionRange(SELECTION_START2, SELECTION_END2).build()); 260 assertEquals( 261 new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(), 262 new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build()); 263 assertNotEquals( 264 new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(), 265 new Builder().setComposingText(COMPOSING_TEXT_START2, COMPOSING_TEXT1).build()); 266 assertNotEquals( 267 new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(), 268 new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT2).build()); 269 assertNotEquals( 270 new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(), 271 new Builder().setComposingText(COMPOSING_TEXT_START2, COMPOSING_TEXT2).build()); 272 273 // For insertion marker locations, {@link Float#NaN} is treated as if it was a number. 274 assertEquals( 275 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 276 Float.NaN, Float.NaN, Float.NaN, Float.NaN, 277 INSERTION_MARKER_FLAGS1).build(), 278 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 279 Float.NaN, Float.NaN, Float.NaN, Float.NaN, 280 INSERTION_MARKER_FLAGS1).build()); 281 282 // Check Matrix. 283 assertEquals( 284 new Builder().setMatrix(MATRIX1).build(), 285 new Builder().setMatrix(MATRIX1).build()); 286 assertNotEquals( 287 new Builder().setMatrix(MATRIX1).build(), 288 new Builder().setMatrix(MATRIX2).build()); 289 assertNotEquals( 290 new Builder().setMatrix(MATRIX1).build(), 291 new Builder().setMatrix(NAN_MATRIX).build()); 292 // Unlike insertion marker locations, {@link Float#NaN} in the matrix is treated as just a 293 // NaN as usual (NaN == NaN -> false). 294 assertNotEquals( 295 new Builder().setMatrix(NAN_MATRIX).build(), 296 new Builder().setMatrix(NAN_MATRIX).build()); 297 298 assertEquals( 299 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 300 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 301 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 302 INSERTION_MARKER_FLAGS1).build(), 303 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 304 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 305 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 306 INSERTION_MARKER_FLAGS1).build()); 307 assertNotEquals( 308 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 309 Float.NaN, INSERTION_MARKER_TOP1, 310 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 311 INSERTION_MARKER_FLAGS1).build(), 312 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 313 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 314 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 315 INSERTION_MARKER_FLAGS1).build()); 316 assertNotEquals( 317 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 318 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 319 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 320 INSERTION_MARKER_FLAGS1).build(), 321 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 322 INSERTION_MARKER_HORIZONTAL2, INSERTION_MARKER_TOP1, 323 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 324 INSERTION_MARKER_FLAGS1).build()); 325 assertNotEquals( 326 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 327 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 328 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 329 INSERTION_MARKER_FLAGS1).build(), 330 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 331 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP2, 332 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 333 INSERTION_MARKER_FLAGS1).build()); 334 assertNotEquals( 335 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 336 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 337 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 338 INSERTION_MARKER_FLAGS1).build(), 339 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 340 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 341 INSERTION_MARKER_BASELINE2, INSERTION_MARKER_BOTOM1, 342 INSERTION_MARKER_FLAGS1).build()); 343 assertNotEquals( 344 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 345 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 346 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 347 INSERTION_MARKER_FLAGS1).build(), 348 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 349 INSERTION_MARKER_HORIZONTAL2, INSERTION_MARKER_TOP1, 350 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 351 INSERTION_MARKER_FLAGS1).build()); 352 assertNotEquals( 353 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 354 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 355 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 356 INSERTION_MARKER_FLAGS1).build(), 357 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 358 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 359 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM2, 360 INSERTION_MARKER_FLAGS1).build()); 361 assertNotEquals( 362 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 363 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 364 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 365 INSERTION_MARKER_FLAGS1).build(), 366 new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation( 367 INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1, 368 INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1, 369 INSERTION_MARKER_FLAGS2).build()); 370 } 371 372 @Test 373 public void testMatrixIsCopied() throws Exception { 374 final Matrix MATRIX1 = new Matrix(); 375 MATRIX1.setTranslate(10.0f, 20.0f); 376 final Matrix MATRIX2 = new Matrix(); 377 MATRIX2.setTranslate(110.0f, 120.0f); 378 final Matrix MATRIX3 = new Matrix(); 379 MATRIX3.setTranslate(210.0f, 220.0f); 380 final Matrix matrix = new Matrix(); 381 final Builder builder = new Builder(); 382 383 matrix.set(MATRIX1); 384 builder.setMatrix(matrix); 385 matrix.postRotate(90.0f); 386 387 final CursorAnchorInfo firstInstance = builder.build(); 388 assertEquals(MATRIX1, firstInstance.getMatrix()); 389 matrix.set(MATRIX2); 390 builder.setMatrix(matrix); 391 final CursorAnchorInfo secondInstance = builder.build(); 392 assertEquals(MATRIX1, firstInstance.getMatrix()); 393 assertEquals(MATRIX2, secondInstance.getMatrix()); 394 395 matrix.set(MATRIX3); 396 assertEquals(MATRIX1, firstInstance.getMatrix()); 397 assertEquals(MATRIX2, secondInstance.getMatrix()); 398 } 399 400 @Test 401 public void testMatrixIsRequired() throws Exception { 402 final int SELECTION_START = 30; 403 final int SELECTION_END = 40; 404 final int COMPOSING_TEXT_START = 32; 405 final String COMPOSING_TEXT = "test"; 406 final int INSERTION_MARKER_FLAGS = FLAG_HAS_VISIBLE_REGION; 407 final float INSERTION_MARKER_HORIZONTAL = 10.5f; 408 final float INSERTION_MARKER_TOP = 100.1f; 409 final float INSERTION_MARKER_BASELINE = 110.4f; 410 final float INSERTION_MARKER_BOTOM = 111.0f; 411 Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX); 412 TRANSFORM_MATRIX.setScale(10.0f, 20.0f); 413 414 final Builder builder = new Builder(); 415 // Check twice to make sure if Builder#reset() works as expected. 416 for (int repeatCount = 0; repeatCount < 2; ++repeatCount) { 417 builder.setSelectionRange(SELECTION_START, SELECTION_END) 418 .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT); 419 try { 420 // Should succeed as coordinate transformation matrix is not required if no 421 // positional information is specified. 422 builder.build(); 423 } catch (IllegalArgumentException ex) { 424 assertTrue(false); 425 } 426 427 builder.setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP, 428 INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM, INSERTION_MARKER_FLAGS); 429 try { 430 // Coordinate transformation matrix is required if no positional information is 431 // specified. 432 builder.build(); 433 assertTrue(false); 434 } catch (IllegalArgumentException ex) { 435 } 436 437 builder.setMatrix(TRANSFORM_MATRIX); 438 try { 439 // Should succeed as coordinate transformation matrix is required. 440 builder.build(); 441 } catch (IllegalArgumentException ex) { 442 assertTrue(false); 443 } 444 445 builder.reset(); 446 } 447 } 448 449 @Test 450 public void testBuilderAddCharacterBounds() throws Exception { 451 // A negative index should be rejected. 452 try { 453 new Builder().addCharacterBounds(-1, 0.0f, 0.0f, 0.0f, 0.0f, FLAG_HAS_VISIBLE_REGION); 454 assertTrue(false); 455 } catch (IllegalArgumentException ex) { 456 } 457 } 458 459 private static CursorAnchorInfo cloneViaParcel(final CursorAnchorInfo src) { 460 Parcel parcel = null; 461 try { 462 parcel = Parcel.obtain(); 463 src.writeToParcel(parcel, 0); 464 parcel.setDataPosition(0); 465 return new CursorAnchorInfo(parcel); 466 } finally { 467 if (parcel != null) { 468 parcel.recycle(); 469 } 470 } 471 } 472} 473