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