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