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