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 verify()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 */ addMessage(String message)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 addError(Throwable error)70 public void addError(Throwable error) { 71 addErrorSuper(new Throwable(mCameraMsg + error.getMessage(), error)); 72 } 73 addErrorSuper(Throwable error)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 checkThat(final T value, final Matcher<T> matcher)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 checkThat(final String reason, final T value, final Matcher<T> matcher)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 */ setCameraId(String id)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 */ expectTrue(String msg, boolean condition)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 */ expectEquals(String msg, T expected, T actual)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 */ expectNotEquals(String msg, T expected, T actual)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 */ expectEquals(String msg, T[] expected, T[] actual)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 */ expectNotEquals(String msg, T[] expected, T[] actual)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 */ expectGreater(String msg, T expected, T actual)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 */ expectGreaterOrEqual(String msg, T expected, T actual)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 */ expectLess(String msg, T expected, T actual)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 */ expectLessOrEqual(String msg, T expected, T actual)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 */ expectEquals(String msg, float expected, float actual, float tolerance)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 */ expectEquals(String msg, double expected, double actual, double tolerance)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 */ expectValuesGreaterOrEqual(String msg, List<T> list, T min)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 */ expectValuesGreaterOrEqual(String msg, T[] array, T min)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 */ expectValuesInRange(String msg, List<T> list, T min, T max)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 */ expectValuesInRange(String msg, T[] array, T min, T max)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 */ expectValuesInRange(String msg, int[] array, int min, int max)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 */ expectInRange(String msg, T value, T min, T max)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 */ expectMeteringRegionsAreSimilar(String msg, MeteringRectangle[] expected, MeteringRectangle[] actual, float errorPercent)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 */ expectRectsAreSimilar(String msg, Rect expected, Rect actual, float errorPercent)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 */ expectSizesAreSimilar(String msg, Size expected, Size actual, float errorPercent)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 */ expectRectCentered(String msg, Size expectedBounds, Rect actual, float errorPercent)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 expectSimilarValues( String formattedMsg, String tooSmall, String tooLarge, int actualValue, int expectedValue, float errorPercent)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 expectNotNull(String msg, Object obj)583 public void expectNotNull(String msg, Object obj) { 584 checkThat(msg, obj, CoreMatchers.notNullValue()); 585 } 586 expectNull(String msg, Object obj)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 */ checkArrayMonotonicityAndNotAllEqual(T[] array, boolean ascendingOrder)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 */ expectKeyValueNotNull(CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key)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 */ expectKeyValueNotNull(CaptureRequest request, CaptureRequest.Key<T> key)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 */ expectKeyValueNotNull(Builder request, CaptureRequest.Key<T> key)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 */ expectKeyValueNotNull(CaptureResult result, CaptureResult.Key<T> key)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 */ expectKeyValueNotNull(String msg, CaptureResult result, CaptureResult.Key<T> key)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 */ expectKeyValueNotEquals( Builder request, CaptureRequest.Key<T> key, T expected)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 */ expectKeyValueNotEquals( CaptureResult result, CaptureResult.Key<T> key, T expected)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 */ expectKeyValueEquals(CaptureResult result, CaptureResult.Key<T> key, T expected)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 */ expectKeyValueEquals(Builder request, CaptureRequest.Key<T> key, T expected)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 */ expectKeyValueGreaterOrEqual( CaptureResult result, CaptureResult.Key<T> key, T expected)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 */ expectKeyValueGreaterThan( CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T expected)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 */ expectKeyValueInRange( CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T min, T max)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 */ expectKeyValueInRange( Builder request, CaptureRequest.Key<T> key, T min, T max)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 */ expectKeyValueIsIn(CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T... expected)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 */ expectKeyValueIsIn(Builder request, CaptureRequest.Key<T> key, T... expected)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 */ expectKeyValueIsIn(CaptureResult result, CaptureResult.Key<T> key, T... expected)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 */ expectKeyValueContains(CameraCharacteristics characteristics, CameraCharacteristics.Key<T[]> key, T expected)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 */ expectKeyValueContains(CameraCharacteristics characteristics, CameraCharacteristics.Key<int[]> key, int expected)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 */ expectKeyValueContains(CameraCharacteristics characteristics, CameraCharacteristics.Key<boolean[]> key, boolean expected)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 */ expectContains(String reason, T[] values, T expected)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 expectContains(T[] values, T expected)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> { IntInMatcher(int[] values)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 */ expectContains(String reason, int[] values, int expected)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 expectContains(int[] values, int expected)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> { BooleanInMatcher(boolean[] values)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 */ expectContains(String reason, boolean[] values, boolean expected)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 */ expectContains(boolean[] values, boolean expected)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 */ expectValuesUnique(String msg, List<T> list)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 expectImageProperties(String msg, Image image, int format, Size size, long timestampNs)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