1 /* 2 * Copyright 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.hardware.camera2.cts.helpers; 18 19 import android.graphics.Rect; 20 import android.hardware.camera2.CameraCharacteristics; 21 import android.hardware.camera2.CaptureRequest; 22 import android.hardware.camera2.CaptureRequest.Builder; 23 import android.hardware.camera2.CaptureResult; 24 import android.hardware.camera2.params.MeteringRectangle; 25 import android.util.Log; 26 import android.util.Size; 27 28 import org.hamcrest.CoreMatchers; 29 import org.hamcrest.Matcher; 30 import org.junit.rules.ErrorCollector; 31 32 import java.util.ArrayList; 33 import java.util.Arrays; 34 import java.util.HashSet; 35 import java.util.List; 36 import java.util.Objects; 37 import java.util.Set; 38 39 /** 40 * A camera test ErrorCollector class to gather the test failures during a test, 41 * instead of failing the test immediately for each failure. 42 */ 43 public class CameraErrorCollector extends ErrorCollector { 44 45 private static final String TAG = "CameraErrorCollector"; 46 private static final boolean LOG_ERRORS = Log.isLoggable(TAG, Log.ERROR); 47 48 private String mCameraMsg = ""; 49 50 @Override 51 public void verify() throws Throwable { 52 // Do not remove if using JUnit 3 test runners. super.verify() is protected. 53 super.verify(); 54 } 55 56 /** 57 * Adds an unconditional error to the table. 58 * 59 * <p>Execution continues, but test will fail at the end.</p> 60 * 61 * @param message A string containing the failure reason. 62 */ 63 public void addMessage(String message) { 64 addErrorSuper(new Throwable(mCameraMsg + message)); 65 } 66 67 /** 68 * Adds a Throwable to the table. <p>Execution continues, but the test will fail at the end.</p> 69 */ 70 @Override 71 public void addError(Throwable error) { 72 addErrorSuper(new Throwable(mCameraMsg + error.getMessage(), error)); 73 } 74 75 private void addErrorSuper(Throwable error) { 76 if (LOG_ERRORS) Log.e(TAG, error.getMessage()); 77 super.addError(error); 78 } 79 80 /** 81 * Adds a failure to the table if {@code matcher} does not match {@code value}. 82 * Execution continues, but the test will fail at the end if the match fails. 83 * The camera id is included into the failure log. 84 */ 85 @Override 86 public <T> void checkThat(final T value, final Matcher<T> matcher) { 87 super.checkThat(mCameraMsg, value, matcher); 88 } 89 90 /** 91 * Adds a failure with the given {@code reason} to the table if 92 * {@code matcher} does not match {@code value}. Execution continues, but 93 * the test will fail at the end if the match fails. The camera id is 94 * included into the failure log. 95 */ 96 @Override 97 public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) { 98 super.checkThat(mCameraMsg + reason, value, matcher); 99 } 100 101 /** 102 * Set the camera id to this error collector object for logging purpose. 103 * 104 * @param id The camera id to be set. 105 */ 106 public void setCameraId(String id) { 107 if (id != null) { 108 mCameraMsg = "Test failed for camera " + id + ": "; 109 } else { 110 mCameraMsg = ""; 111 } 112 } 113 114 /** 115 * Adds a failure to the table if {@code condition} is not {@code true}. 116 * <p> 117 * Execution continues, but the test will fail at the end if the condition 118 * failed. 119 * </p> 120 * 121 * @param msg Message to be logged when check fails. 122 * @param condition Log the failure if it is not true. 123 */ 124 public boolean expectTrue(String msg, boolean condition) { 125 if (!condition) { 126 addMessage(msg); 127 } 128 129 return condition; 130 } 131 132 /** 133 * Check if the two values are equal. 134 * 135 * @param msg Message to be logged when check fails. 136 * @param expected Expected value to be checked against. 137 * @param actual Actual value to be checked. 138 * @return {@code true} if the two values are equal, {@code false} otherwise. 139 * 140 * @throws IllegalArgumentException if {@code expected} was {@code null} 141 */ 142 public <T> boolean expectEquals(String msg, T expected, T actual) { 143 if (expected == null) { 144 throw new IllegalArgumentException("expected value shouldn't be null"); 145 } 146 147 if (!Objects.equals(expected, actual)) { 148 addMessage(String.format("%s (expected = %s, actual = %s) ", msg, expected, 149 actual)); 150 return false; 151 } 152 153 return true; 154 } 155 156 /** 157 * Check if the two values are not equal. 158 * 159 * @param msg Message to be logged when check fails. 160 * @param expected Expected value to be checked against. 161 * @param actual Actual value to be checked. 162 * @return {@code true} if the two values are not equal, {@code false} otherwise. 163 */ 164 public <T> boolean expectNotEquals(String msg, T expected, T actual) { 165 if (Objects.equals(expected, actual)) { 166 addMessage(String.format("%s (expected = %s, actual = %s) ", msg, expected, 167 actual)); 168 return false; 169 } 170 171 return true; 172 } 173 174 /** 175 * Check if the two arrays of values are deeply equal. 176 * 177 * @param msg Message to be logged when check fails. 178 * @param expected Expected array of values to be checked against. 179 * @param actual Actual array of values to be checked. 180 * @return {@code true} if the two arrays of values are deeply equal, {@code false} otherwise. 181 * 182 * @throws IllegalArgumentException if {@code expected} was {@code null} 183 */ 184 public <T> boolean expectEquals(String msg, T[] expected, T[] actual) { 185 if (expected == null) { 186 throw new IllegalArgumentException("expected value shouldn't be null"); 187 } 188 189 if (!Arrays.deepEquals(expected, actual)) { 190 addMessage(String.format("%s (expected = %s, actual = %s) ", msg, 191 Arrays.deepToString(expected), Arrays.deepToString(actual))); 192 return false; 193 } 194 195 return true; 196 } 197 198 /** 199 * Check if the two arrays of values are not deeply equal. 200 * 201 * @param msg Message to be logged when check fails. 202 * @param expected Expected array of values to be checked against. 203 * @param actual Actual array of values to be checked. 204 * @return {@code true} if the two arrays of values are not deeply equal, {@code false} 205 * otherwise. 206 * 207 * @throws IllegalArgumentException if {@code expected} was {@code null} 208 */ 209 public <T> boolean expectNotEquals(String msg, T[] expected, T[] actual) { 210 if (expected == null) { 211 throw new IllegalArgumentException("expected value shouldn't be null"); 212 } 213 214 if (Arrays.deepEquals(expected, actual)) { 215 addMessage(String.format("%s (expected = %s, actual = %s) ", msg, 216 Arrays.deepToString(expected), Arrays.deepToString(actual))); 217 return false; 218 } 219 220 return true; 221 } 222 223 /** 224 * Check that the {@code actual} value is greater than the {@code expected} value. 225 * 226 * @param msg Message to be logged when check fails. 227 * @param expected The expected value to check that the actual value is larger than. 228 * @param actual Actual value to check. 229 * @return {@code true} if {@code actual} is greater than {@code expected}. 230 */ 231 public <T extends Comparable<? super T>> boolean expectGreater(String msg, T expected, 232 T actual) { 233 return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ", 234 msg, expected, actual), actual.compareTo(expected) > 0); 235 } 236 237 /** 238 * Check that the {@code actual} value is greater than or equal to the {@code expected} value. 239 * 240 * @param msg Message to be logged when check fails. 241 * @param expected The expected value to check that the actual value is larger than or equal to. 242 * @param actual Actual value to check. 243 * @return {@code true} if {@code actual} is greater than or equal to {@code expected}. 244 */ 245 public <T extends Comparable<? super T>> boolean expectGreaterOrEqual(String msg, T expected, 246 T actual) { 247 return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ", 248 msg, expected, actual), actual.compareTo(expected) >= 0); 249 } 250 251 /** 252 * Check that the {@code actual} value is less than the {@code expected} value. 253 * 254 * @param msg Message to be logged when check fails. 255 * @param expected The expected value to check that the actual value is less than. 256 * @param actual Actual value to check. 257 * @return {@code true} if {@code actual} is less than {@code expected}. 258 */ 259 public <T extends Comparable<? super T>> boolean expectLess(String msg, T expected, 260 T actual) { 261 return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ", 262 msg, expected, actual), actual.compareTo(expected) < 0); 263 } 264 265 /** 266 * Check that the {@code actual} value is less than or equal to the {@code expected} value. 267 * 268 * @param msg Message to be logged when check fails. 269 * @param expected The expected value to check that the actual value is less than or equal to. 270 * @param actual Actual value to check. 271 * @return {@code true} if {@code actual} is less than or equal to {@code expected}. 272 */ 273 public <T extends Comparable<? super T>> boolean expectLessOrEqual(String msg, T expected, 274 T actual) { 275 return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ", 276 msg, expected, actual), actual.compareTo(expected) <= 0); 277 } 278 279 /** 280 * Check if the two float values are equal with given error tolerance. 281 * 282 * @param msg Message to be logged when check fails. 283 * @param expected Expected value to be checked against. 284 * @param actual Actual value to be checked. 285 * @param tolerance The error margin for the equality check. 286 * @return {@code true} if the two values are equal, {@code false} otherwise. 287 */ 288 public <T> boolean expectEquals(String msg, float expected, float actual, float tolerance) { 289 if (expected == actual) { 290 return true; 291 } 292 293 if (!(Math.abs(expected - actual) <= tolerance)) { 294 addMessage(String.format("%s (expected = %s, actual = %s, tolerance = %s) ", msg, 295 expected, actual, tolerance)); 296 return false; 297 } 298 299 return true; 300 } 301 302 /** 303 * Check if the two double values are equal with given error tolerance. 304 * 305 * @param msg Message to be logged when check fails. 306 * @param expected Expected value to be checked against. 307 * @param actual Actual value to be checked. 308 * @param tolerance The error margin for the equality check 309 * @return {@code true} if the two values are equal, {@code false} otherwise. 310 */ 311 public <T> boolean expectEquals(String msg, double expected, double actual, double tolerance) { 312 if (expected == actual) { 313 return true; 314 } 315 316 if (!(Math.abs(expected - actual) <= tolerance)) { 317 addMessage(String.format("%s (expected = %s, actual = %s, tolerance = %s) ", msg, 318 expected, actual, tolerance)); 319 return false; 320 } 321 322 return true; 323 } 324 325 /** 326 * Check that all values in the list are greater than or equal to the min value. 327 * 328 * @param msg Message to be logged when check fails 329 * @param list The list of values to be checked 330 * @param min The smallest allowed value 331 */ 332 public <T extends Comparable<? super T>> void expectValuesGreaterOrEqual(String msg, 333 List<T> list, T min) { 334 for (T value : list) { 335 expectTrue(msg + String.format(", array value " + value.toString() + 336 " is less than %s", 337 min.toString()), value.compareTo(min) >= 0); 338 } 339 } 340 341 /** 342 * Check that all values in the array are greater than or equal to the min value. 343 * 344 * @param msg Message to be logged when check fails 345 * @param array The array of values to be checked 346 * @param min The smallest allowed value 347 */ 348 public <T extends Comparable<? super T>> void expectValuesGreaterOrEqual(String msg, 349 T[] array, T min) { 350 expectValuesGreaterOrEqual(msg, Arrays.asList(array), min); 351 } 352 353 /** 354 * Expect the list of values are in the range. 355 * 356 * @param msg Message to be logged 357 * @param list The list of values to be checked 358 * @param min The min value of the range 359 * @param max The max value of the range 360 */ 361 public <T extends Comparable<? super T>> void expectValuesInRange(String msg, List<T> list, 362 T min, T max) { 363 for (T value : list) { 364 expectTrue(msg + String.format(", array value " + value.toString() + 365 " is out of range [%s, %s]", 366 min.toString(), max.toString()), 367 value.compareTo(max)<= 0 && value.compareTo(min) >= 0); 368 } 369 } 370 371 /** 372 * Expect the array of values are in the range. 373 * 374 * @param msg Message to be logged 375 * @param array The array of values to be checked 376 * @param min The min value of the range 377 * @param max The max value of the range 378 */ 379 public <T extends Comparable<? super T>> void expectValuesInRange(String msg, T[] array, 380 T min, T max) { 381 expectValuesInRange(msg, Arrays.asList(array), min, max); 382 } 383 384 /** 385 * Expect the array of values are in the range. 386 * 387 * @param msg Message to be logged 388 * @param array The array of values to be checked 389 * @param min The min value of the range 390 * @param max The max value of the range 391 */ 392 public void expectValuesInRange(String msg, int[] array, int min, int max) { 393 ArrayList<Integer> l = new ArrayList<>(array.length); 394 for (int i : array) { 395 l.add(i); 396 } 397 expectValuesInRange(msg, l, min, max); 398 } 399 400 /** 401 * Expect the value is in the range. 402 * 403 * @param msg Message to be logged 404 * @param value The value to be checked 405 * @param min The min value of the range 406 * @param max The max value of the range 407 * 408 * @return {@code true} if the value was in range, {@code false} otherwise 409 */ 410 public <T extends Comparable<? super T>> boolean expectInRange(String msg, T value, 411 T min, T max) { 412 return expectTrue(msg + String.format(", value " + value.toString() 413 + " is out of range [%s, %s]", 414 min.toString(), max.toString()), 415 value.compareTo(max)<= 0 && value.compareTo(min) >= 0); 416 } 417 418 419 /** 420 * Check that two metering region arrays are similar enough by ensuring that each of their width, 421 * height, and all corners are within {@code errorPercent} of each other. 422 * 423 * <p>Note that the length of the arrays must be the same, and each weight must be the same 424 * as well. We assume the order is also equivalent.</p> 425 * 426 * <p>At most 1 error per each dissimilar metering region is collected.</p> 427 * 428 * @param msg Message to be logged 429 * @param expected The reference 'expected' values to be used to check against 430 * @param actual The actual values that were received 431 * @param errorPercent Within how many percent the components should be 432 * 433 * @return {@code true} if all expects passed, {@code false} otherwise 434 */ 435 public boolean expectMeteringRegionsAreSimilar(String msg, 436 MeteringRectangle[] expected, MeteringRectangle[] actual, 437 float errorPercent) { 438 String expectedActualMsg = String.format("expected (%s), actual (%s)", 439 Arrays.deepToString(expected), Arrays.deepToString(actual)); 440 441 String differentSizesMsg = String.format( 442 "%s: rect lists are different sizes; %s", 443 msg, expectedActualMsg); 444 445 String differentWeightsMsg = String.format( 446 "%s: rect weights are different; %s", 447 msg, expectedActualMsg); 448 449 if (!expectTrue(differentSizesMsg, actual != null)) { 450 return false; 451 } 452 453 if (!expectEquals(differentSizesMsg, expected.length, actual.length)) return false; 454 455 boolean succ = true; 456 for (int i = 0; i < expected.length; ++i) { 457 if (i < actual.length) { 458 // Avoid printing multiple errors for the same rectangle 459 if (!expectRectsAreSimilar( 460 msg, expected[i].getRect(), actual[i].getRect(), errorPercent)) { 461 succ = false; 462 continue; 463 } 464 if (!expectEquals(differentWeightsMsg, 465 expected[i].getMeteringWeight(), actual[i].getMeteringWeight())) { 466 succ = false; 467 continue; 468 } 469 } 470 } 471 472 return succ; 473 } 474 475 /** 476 * Check that two rectangles are similar enough by ensuring that their width, height, 477 * and all corners are within {@code errorPercent} of each other. 478 * 479 * <p>Only the first error is collected, to avoid spamming several error messages when 480 * the rectangle is hugely dissimilar.</p> 481 * 482 * @param msg Message to be logged 483 * @param expected The reference 'expected' value to be used to check against 484 * @param actual The actual value that was received 485 * @param errorPercent Within how many percent the components should be 486 * 487 * @return {@code true} if all expects passed, {@code false} otherwise 488 */ 489 public boolean expectRectsAreSimilar(String msg, Rect expected, Rect actual, 490 float errorPercent) { 491 String formattedMsg = String.format("%s: rects are not similar enough; expected (%s), " + 492 "actual (%s), error percent (%s), reason: ", 493 msg, expected, actual, errorPercent); 494 495 if (!expectSimilarValues( 496 formattedMsg, "too wide", "too narrow", actual.width(), expected.width(), 497 errorPercent)) return false; 498 499 if (!expectSimilarValues( 500 formattedMsg, "too tall", "too short", actual.height(), expected.height(), 501 errorPercent)) return false; 502 503 if (!expectSimilarValues( 504 formattedMsg, "left pt too right", "left pt too left", actual.left, expected.left, 505 errorPercent)) return false; 506 507 if (!expectSimilarValues( 508 formattedMsg, "right pt too right", "right pt too left", 509 actual.right, expected.right, errorPercent)) return false; 510 511 if (!expectSimilarValues( 512 formattedMsg, "top pt too low", "top pt too high", actual.top, expected.top, 513 errorPercent)) return false; 514 515 if (!expectSimilarValues( 516 formattedMsg, "bottom pt too low", "bottom pt too high", actual.top, expected.top, 517 errorPercent)) return false; 518 519 return true; 520 } 521 522 /** 523 * Check that the rectangle is centered within a certain tolerance of {@code errorPercent}, 524 * with respect to the {@code bounds} bounding rectangle. 525 * 526 * @param msg Message to be logged 527 * @param expectedBounds The width/height of the bounding rectangle 528 * @param actual The actual value that was received 529 * @param errorPercent Within how many percent the centering should be 530 */ 531 public void expectRectCentered(String msg, Size expectedBounds, Rect actual, 532 float errorPercent) { 533 String formattedMsg = String.format("%s: rect should be centered; expected bounds (%s), " + 534 "actual (%s), error percent (%s), reason: ", 535 msg, expectedBounds, actual, errorPercent); 536 537 int centerBoundX = expectedBounds.getWidth() / 2; 538 int centerBoundY = expectedBounds.getHeight() / 2; 539 540 expectSimilarValues( 541 formattedMsg, "too low", "too high", actual.centerY(), centerBoundY, 542 errorPercent); 543 544 expectSimilarValues( 545 formattedMsg, "too right", "too left", actual.centerX(), centerBoundX, 546 errorPercent); 547 } 548 549 private boolean expectSimilarValues( 550 String formattedMsg, String tooSmall, String tooLarge, int actualValue, 551 int expectedValue, float errorPercent) { 552 boolean succ = true; 553 succ = expectTrue(formattedMsg + tooLarge, 554 actualValue <= (expectedValue * (1.0f + errorPercent))) && succ; 555 succ = expectTrue(formattedMsg + tooSmall, 556 actualValue >= (expectedValue * (1.0f - errorPercent))) && succ; 557 558 return succ; 559 } 560 561 public void expectNotNull(String msg, Object obj) { 562 checkThat(msg, obj, CoreMatchers.notNullValue()); 563 } 564 565 public void expectNull(String msg, Object obj) { 566 if (obj != null) { 567 addMessage(msg); 568 } 569 } 570 571 /** 572 * Check if the values in the array are monotonically increasing (decreasing) and not all 573 * equal. 574 * 575 * @param array The array of values to be checked 576 * @param ascendingOrder The monotonicity ordering to be checked with 577 */ 578 public <T extends Comparable<? super T>> void checkArrayMonotonicityAndNotAllEqual(T[] array, 579 boolean ascendingOrder) { 580 String orderMsg = ascendingOrder ? ("increasing order") : ("decreasing order"); 581 for (int i = 0; i < array.length - 1; i++) { 582 int compareResult = array[i + 1].compareTo(array[i]); 583 boolean condition = compareResult >= 0; 584 if (!ascendingOrder) { 585 condition = compareResult <= 0; 586 } 587 588 expectTrue(String.format("Adjacent values (%s and %s) %s monotonicity is broken", 589 array[i].toString(), array[i + 1].toString(), orderMsg), condition); 590 } 591 592 expectTrue("All values of this array are equal: " + array[0].toString(), 593 array[0].compareTo(array[array.length - 1]) != 0); 594 } 595 596 /** 597 * Check if the key value is not null and return the value. 598 * 599 * @param characteristics The {@link CameraCharacteristics} to get the key from. 600 * @param key The {@link CameraCharacteristics} key to be checked. 601 * 602 * @return The value of the key. 603 */ 604 public <T> T expectKeyValueNotNull(CameraCharacteristics characteristics, 605 CameraCharacteristics.Key<T> key) { 606 607 T value = characteristics.get(key); 608 if (value == null) { 609 addMessage("Key " + key.getName() + " shouldn't be null"); 610 } 611 612 return value; 613 } 614 615 /** 616 * Check if the key value is not null and return the value. 617 * 618 * @param request The {@link CaptureRequest} to get the key from. 619 * @param key The {@link CaptureRequest} key to be checked. 620 * 621 * @return The value of the key. 622 */ 623 public <T> T expectKeyValueNotNull(CaptureRequest request, 624 CaptureRequest.Key<T> key) { 625 626 T value = request.get(key); 627 if (value == null) { 628 addMessage("Key " + key.getName() + " shouldn't be null"); 629 } 630 631 return value; 632 } 633 634 /** 635 * Check if the key value is not null and return the value. 636 * 637 * @param request The {@link CaptureRequest#Builder} to get the key from. 638 * @param key The {@link CaptureRequest} key to be checked. 639 * @return The value of the key. 640 */ 641 public <T> T expectKeyValueNotNull(Builder request, CaptureRequest.Key<T> key) { 642 643 T value = request.get(key); 644 if (value == null) { 645 addMessage("Key " + key.getName() + " shouldn't be null"); 646 } 647 648 return value; 649 } 650 651 /** 652 * Check if the key value is not null and return the value. 653 * 654 * @param result The {@link CaptureResult} to get the key from. 655 * @param key The {@link CaptureResult} key to be checked. 656 * @return The value of the key. 657 */ 658 public <T> T expectKeyValueNotNull(CaptureResult result, CaptureResult.Key<T> key) { 659 return expectKeyValueNotNull("", result, key); 660 } 661 662 /** 663 * Check if the key value is not null and return the value. 664 * 665 * @param msg The message to be logged. 666 * @param result The {@link CaptureResult} to get the key from. 667 * @param key The {@link CaptureResult} key to be checked. 668 * @return The value of the key. 669 */ 670 public <T> T expectKeyValueNotNull(String msg, CaptureResult result, CaptureResult.Key<T> key) { 671 672 T value = result.get(key); 673 if (value == null) { 674 addMessage(msg + " Key " + key.getName() + " shouldn't be null"); 675 } 676 677 return value; 678 } 679 680 /** 681 * Check if the key is non-null and the value is not equal to target. 682 * 683 * @param request The The {@link CaptureRequest#Builder} to get the key from. 684 * @param key The {@link CaptureRequest} key to be checked. 685 * @param expected The expected value of the CaptureRequest key. 686 */ 687 public <T> void expectKeyValueNotEquals( 688 Builder request, CaptureRequest.Key<T> key, T expected) { 689 if (request == null || key == null || expected == null) { 690 throw new IllegalArgumentException("request, key and expected shouldn't be null"); 691 } 692 693 T value; 694 if ((value = expectKeyValueNotNull(request, key)) == null) { 695 return; 696 } 697 698 String reason = "Key " + key.getName() + " shouldn't have value " + value.toString(); 699 checkThat(reason, value, CoreMatchers.not(expected)); 700 } 701 702 /** 703 * Check if the key is non-null and the value is not equal to target. 704 * 705 * @param result The {@link CaptureResult} to get the key from. 706 * @param key The {@link CaptureResult} key to be checked. 707 * @param expected The expected value of the CaptureResult key. 708 */ 709 public <T> void expectKeyValueNotEquals( 710 CaptureResult result, CaptureResult.Key<T> key, T expected) { 711 if (result == null || key == null || expected == null) { 712 throw new IllegalArgumentException("result, key and expected shouldn't be null"); 713 } 714 715 T value; 716 if ((value = expectKeyValueNotNull(result, key)) == null) { 717 return; 718 } 719 720 String reason = "Key " + key.getName() + " shouldn't have value " + value.toString(); 721 checkThat(reason, value, CoreMatchers.not(expected)); 722 } 723 724 /** 725 * Check if the value is non-null and the value is equal to target. 726 * 727 * @param result The {@link CaptureResult} to lookup the value in. 728 * @param key The {@link CaptureResult} key to be checked. 729 * @param expected The expected value of the {@link CaptureResult} key. 730 */ 731 public <T> void expectKeyValueEquals(CaptureResult result, CaptureResult.Key<T> key, 732 T expected) { 733 if (result == null || key == null || expected == null) { 734 throw new IllegalArgumentException("request, key and expected shouldn't be null"); 735 } 736 737 T value; 738 if ((value = expectKeyValueNotNull(result, key)) == null) { 739 return; 740 } 741 742 String reason = "Key " + key.getName() + " value " + value.toString() 743 + " doesn't match the expected value " + expected.toString(); 744 checkThat(reason, value, CoreMatchers.equalTo(expected)); 745 } 746 747 /** 748 * Check if the key is non-null and the value is equal to target. 749 * 750 * <p>Only check non-null if the target is null.</p> 751 * 752 * @param request The The {@link CaptureRequest#Builder} to get the key from. 753 * @param key The {@link CaptureRequest} key to be checked. 754 * @param expected The expected value of the CaptureRequest key. 755 */ 756 public <T> void expectKeyValueEquals(Builder request, CaptureRequest.Key<T> key, T expected) { 757 if (request == null || key == null || expected == null) { 758 throw new IllegalArgumentException("request, key and expected shouldn't be null"); 759 } 760 761 T value; 762 if ((value = expectKeyValueNotNull(request, key)) == null) { 763 return; 764 } 765 766 String reason = "Key " + key.getName() + " value " + value.toString() 767 + " doesn't match the expected value " + expected.toString(); 768 checkThat(reason, value, CoreMatchers.equalTo(expected)); 769 } 770 771 /** 772 * Check if the key is non-null, and the key value is greater than the expected value. 773 * 774 * @param result {@link CaptureResult} to check. 775 * @param key The {@link CaptureResult} key to be checked. 776 * @param expected The expected to be compared to the value for the given key. 777 */ 778 public <T extends Comparable<? super T>> void expectKeyValueGreaterOrEqual( 779 CaptureResult result, CaptureResult.Key<T> key, T expected) { 780 T value; 781 if ((value = expectKeyValueNotNull(result, key)) == null) { 782 return; 783 } 784 785 expectGreaterOrEqual(key.getName(), expected, value); 786 } 787 788 /** 789 * Check if the key is non-null, and the key value is greater than the expected value. 790 * 791 * @param characteristics {@link CameraCharacteristics} to check. 792 * @param key The {@link CameraCharacteristics} key to be checked. 793 * @param expected The expected to be compared to the value for the given key. 794 */ 795 public <T extends Comparable<? super T>> void expectKeyValueGreaterThan( 796 CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T expected) { 797 T value; 798 if ((value = expectKeyValueNotNull(characteristics, key)) == null) { 799 return; 800 } 801 802 expectGreater(key.getName(), expected, value); 803 } 804 805 /** 806 * Check if the key is non-null, and the key value is in the expected range. 807 * 808 * @param characteristics {@link CameraCharacteristics} to check. 809 * @param key The {@link CameraCharacteristics} key to be checked. 810 * @param min The min value of the range 811 * @param max The max value of the range 812 */ 813 public <T extends Comparable<? super T>> void expectKeyValueInRange( 814 CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T min, T max) { 815 T value; 816 if ((value = expectKeyValueNotNull(characteristics, key)) == null) { 817 return; 818 } 819 expectInRange(key.getName(), value, min, max); 820 } 821 822 /** 823 * Check if the key is non-null, and the key value is one of the expected values. 824 * 825 * @param characteristics {@link CameraCharacteristics} to check. 826 * @param key The {@link CameraCharacteristics} key to be checked. 827 * @param expected The expected values for the given key. 828 */ 829 public <T> void expectKeyValueIsIn(CameraCharacteristics characteristics, 830 CameraCharacteristics.Key<T> key, T... expected) { 831 T value = expectKeyValueNotNull(characteristics, key); 832 if (value == null) { 833 return; 834 } 835 String reason = "Key " + key.getName() + " value " + value 836 + " isn't one of the expected values " + Arrays.deepToString(expected); 837 expectContains(reason, expected, value); 838 } 839 840 /** 841 * Check if the key is non-null, and the key value is one of the expected values. 842 * 843 * @param request The The {@link CaptureRequest#Builder} to get the key from. 844 * @param key The {@link CaptureRequest} key to be checked. 845 * @param expected The expected values of the CaptureRequest key. 846 */ 847 public <T> void expectKeyValueIsIn(Builder request, CaptureRequest.Key<T> key, T... expected) { 848 T value = expectKeyValueNotNull(request, key); 849 if (value == null) { 850 return; 851 } 852 String reason = "Key " + key.getName() + " value " + value 853 + " isn't one of the expected values " + Arrays.deepToString(expected); 854 expectContains(reason, expected, value); 855 } 856 857 /** 858 * Check if the key is non-null, and the key value contains the expected element. 859 * 860 * @param characteristics {@link CameraCharacteristics} to check. 861 * @param key The {@link CameraCharacteristics} key to be checked. 862 * @param expected The expected element to be contained in the value for the given key. 863 */ 864 public <T> void expectKeyValueContains(CameraCharacteristics characteristics, 865 CameraCharacteristics.Key<T[]> key, T expected) { 866 T[] value; 867 if ((value = expectKeyValueNotNull(characteristics, key)) == null) { 868 return; 869 } 870 String reason = "Key " + key.getName() + " value " + value 871 + " doesn't contain the expected value " + expected; 872 expectContains(reason, value, expected); 873 } 874 875 /** 876 * Check if the key is non-null, and the key value contains the expected element. 877 * 878 * @param characteristics {@link CameraCharacteristics} to check. 879 * @param key The {@link CameraCharacteristics} key to be checked. 880 * @param expected The expected element to be contained in the value for the given key. 881 */ 882 public void expectKeyValueContains(CameraCharacteristics characteristics, 883 CameraCharacteristics.Key<int[]> key, int expected) { 884 int[] value; 885 if ((value = expectKeyValueNotNull(characteristics, key)) == null) { 886 return; 887 } 888 String reason = "Key " + key.getName() + " value " + value 889 + " doesn't contain the expected value " + expected; 890 expectContains(reason, value, expected); 891 } 892 893 /** 894 * Check if the key is non-null, and the key value contains the expected element. 895 * 896 * @param characteristics {@link CameraCharacteristics} to check. 897 * @param key The {@link CameraCharacteristics} key to be checked. 898 * @param expected The expected element to be contained in the value for the given key. 899 */ 900 public void expectKeyValueContains(CameraCharacteristics characteristics, 901 CameraCharacteristics.Key<boolean[]> key, boolean expected) { 902 boolean[] value; 903 if ((value = expectKeyValueNotNull(characteristics, key)) == null) { 904 return; 905 } 906 String reason = "Key " + key.getName() + " value " + value 907 + " doesn't contain the expected value " + expected; 908 expectContains(reason, value, expected); 909 } 910 911 /** 912 * Check if the {@code values} array contains the expected element. 913 * 914 * @param reason reason to print for failure. 915 * @param values array to check for membership in. 916 * @param expected the value to check. 917 */ 918 public <T> void expectContains(String reason, T[] values, T expected) { 919 if (values == null) { 920 throw new NullPointerException(); 921 } 922 checkThat(reason, expected, InMatcher.in(values)); 923 } 924 925 public <T> void expectContains(T[] values, T expected) { 926 String reason = "Expected value " + expected 927 + " is not contained in the given values " + values; 928 expectContains(reason, values, expected); 929 } 930 931 /** 932 * Specialize {@link InMatcher} class for integer primitive array. 933 */ 934 private static class IntInMatcher extends InMatcher<Integer> { 935 public IntInMatcher(int[] values) { 936 Preconditions.checkNotNull("values", values); 937 mValues = new ArrayList<>(values.length); 938 for (int i : values) { 939 mValues.add(i); 940 } 941 } 942 } 943 944 /** 945 * Check if the {@code values} array contains the expected element. 946 * 947 * <p>Specialized for primitive int arrays</p> 948 * 949 * @param reason reason to print for failure. 950 * @param values array to check for membership in. 951 * @param expected the value to check. 952 */ 953 public void expectContains(String reason, int[] values, int expected) { 954 if (values == null) { 955 throw new NullPointerException(); 956 } 957 958 checkThat(reason, expected, new IntInMatcher(values)); 959 } 960 961 public void expectContains(int[] values, int expected) { 962 String reason = "Expected value " + expected 963 + " is not contained in the given values " + values; 964 expectContains(reason, values, expected); 965 } 966 967 /** 968 * Specialize {@link BooleanInMatcher} class for boolean primitive array. 969 */ 970 private static class BooleanInMatcher extends InMatcher<Boolean> { 971 public BooleanInMatcher(boolean[] values) { 972 Preconditions.checkNotNull("values", values); 973 mValues = new ArrayList<>(values.length); 974 for (boolean i : values) { 975 mValues.add(i); 976 } 977 } 978 } 979 980 /** 981 * Check if the {@code values} array contains the expected element. 982 * 983 * <p>Specialized for primitive boolean arrays</p> 984 * 985 * @param reason reason to print for failure. 986 * @param values array to check for membership in. 987 * @param expected the value to check. 988 */ 989 public void expectContains(String reason, boolean[] values, boolean expected) { 990 if (values == null) { 991 throw new NullPointerException(); 992 } 993 994 checkThat(reason, expected, new BooleanInMatcher(values)); 995 } 996 997 /** 998 * Check if the {@code values} array contains the expected element. 999 * 1000 * <p>Specialized for primitive boolean arrays</p> 1001 * 1002 * @param values array to check for membership in. 1003 * @param expected the value to check. 1004 */ 1005 public void expectContains(boolean[] values, boolean expected) { 1006 String reason = "Expected value " + expected 1007 + " is not contained in the given values " + values; 1008 expectContains(reason, values, expected); 1009 } 1010 1011 /** 1012 * Check if the element inside of the list are unique. 1013 * 1014 * @param msg The message to be logged 1015 * @param list The list of values to be checked 1016 */ 1017 public <T> void expectValuesUnique(String msg, List<T> list) { 1018 Set<T> sizeSet = new HashSet<T>(list); 1019 expectTrue(msg + " each element must be distinct", sizeSet.size() == list.size()); 1020 } 1021 } 1022