1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.hardware.camera2.cts; 18 19 import static android.hardware.camera2.CameraCharacteristics.*; 20 21 import android.graphics.ImageFormat; 22 import android.graphics.Rect; 23 import android.hardware.camera2.CameraCharacteristics; 24 import android.hardware.camera2.CameraMetadata; 25 import android.hardware.camera2.CaptureRequest; 26 import android.hardware.camera2.CaptureResult; 27 import android.hardware.camera2.CameraCharacteristics.Key; 28 import android.hardware.camera2.cts.helpers.StaticMetadata; 29 import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel; 30 import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase; 31 import android.hardware.camera2.params.StreamConfigurationMap; 32 import android.platform.test.annotations.AppModeFull; 33 import android.util.Log; 34 import android.util.Pair; 35 import android.util.Size; 36 37 import java.util.ArrayList; 38 import java.util.Arrays; 39 import java.util.Collection; 40 import java.util.HashMap; 41 import java.util.HashSet; 42 import java.util.List; 43 import java.util.Set; 44 45 /** 46 * <p> 47 * This class covers the {@link CameraCharacteristics} tests that are not 48 * covered by {@link CaptureRequestTest} and {@link ExtendedCameraCharacteristicsTest} 49 * </p> 50 * <p> 51 * Note that most of the tests in this class don't require camera open. 52 * </p> 53 */ 54 @AppModeFull 55 public class StaticMetadataTest extends Camera2AndroidTestCase { 56 private static final String TAG = "StaticMetadataTest"; 57 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); 58 private static final float MIN_FPS_FOR_FULL_DEVICE = 20.0f; 59 private String mCameraId; 60 61 // Last defined capability enum, for iterating over all of them 62 private static final int LAST_CAPABILITY_ENUM = REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME; 63 64 /** 65 * Test the available capability for different hardware support level devices. 66 */ 67 public void testHwSupportedLevel() throws Exception { 68 Key<StreamConfigurationMap> key = 69 CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP; 70 final float SIZE_ERROR_MARGIN = 0.03f; 71 for (String id : mCameraIds) { 72 initStaticMetadata(id); 73 StreamConfigurationMap configs = mStaticInfo.getValueFromKeyNonNull(key); 74 Rect activeRect = mStaticInfo.getActiveArraySizeChecked(); 75 Size sensorSize = new Size(activeRect.width(), activeRect.height()); 76 List<Integer> availableCaps = mStaticInfo.getAvailableCapabilitiesChecked(); 77 78 mCollector.expectTrue("All devices must contains BACKWARD_COMPATIBLE capability or " + 79 "DEPTH_OUTPUT capabillity" , 80 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) || 81 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) ); 82 83 if (mStaticInfo.isHardwareLevelAtLeast( 84 CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3)) { 85 mCollector.expectTrue("Level 3 device must contain YUV_REPROCESSING capability", 86 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING)); 87 mCollector.expectTrue("Level 3 device must contain RAW capability", 88 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_RAW)); 89 } 90 91 if (mStaticInfo.isHardwareLevelAtLeastFull()) { 92 // Capability advertisement must be right. 93 mCollector.expectTrue("Full device must contain MANUAL_SENSOR capability", 94 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)); 95 mCollector.expectTrue("Full device must contain MANUAL_POST_PROCESSING capability", 96 availableCaps.contains( 97 REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING)); 98 mCollector.expectTrue("Full device must contain BURST_CAPTURE capability", 99 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE)); 100 101 // Need support per frame control 102 mCollector.expectTrue("Full device must support per frame control", 103 mStaticInfo.isPerFrameControlSupported()); 104 } 105 106 if (mStaticInfo.isHardwareLevelLegacy()) { 107 mCollector.expectTrue("Legacy devices must contain BACKWARD_COMPATIBLE capability", 108 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE)); 109 } 110 111 if (availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) { 112 mCollector.expectTrue("MANUAL_SENSOR capability always requires " + 113 "READ_SENSOR_SETTINGS capability as well", 114 availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS)); 115 } 116 117 if (mStaticInfo.isColorOutputSupported()) { 118 // Max jpeg resolution must be very close to sensor resolution 119 Size[] jpegSizes = mStaticInfo.getJpegOutputSizesChecked(); 120 Size maxJpegSize = CameraTestUtils.getMaxSize(jpegSizes); 121 float croppedWidth = (float)sensorSize.getWidth(); 122 float croppedHeight = (float)sensorSize.getHeight(); 123 float sensorAspectRatio = (float)sensorSize.getWidth() / (float)sensorSize.getHeight(); 124 float maxJpegAspectRatio = (float)maxJpegSize.getWidth() / (float)maxJpegSize.getHeight(); 125 if (sensorAspectRatio < maxJpegAspectRatio) { 126 croppedHeight = (float)sensorSize.getWidth() / maxJpegAspectRatio; 127 } else if (sensorAspectRatio > maxJpegAspectRatio) { 128 croppedWidth = (float)sensorSize.getHeight() * maxJpegAspectRatio; 129 } 130 Size croppedSensorSize = new Size((int)croppedWidth, (int)croppedHeight); 131 mCollector.expectSizesAreSimilar( 132 "Active array size or cropped active array size and max JPEG size should be similar", 133 croppedSensorSize, maxJpegSize, SIZE_ERROR_MARGIN); 134 } 135 136 // TODO: test all the keys mandatory for all capability devices. 137 } 138 } 139 140 /** 141 * Test max number of output stream reported by device 142 */ 143 public void testMaxNumOutputStreams() throws Exception { 144 for (String id : mCameraIds) { 145 initStaticMetadata(id); 146 int maxNumStreamsRaw = mStaticInfo.getMaxNumOutputStreamsRawChecked(); 147 int maxNumStreamsProc = mStaticInfo.getMaxNumOutputStreamsProcessedChecked(); 148 int maxNumStreamsProcStall = mStaticInfo.getMaxNumOutputStreamsProcessedStallChecked(); 149 150 mCollector.expectTrue("max number of raw output streams must be a non negative number", 151 maxNumStreamsRaw >= 0); 152 mCollector.expectTrue("max number of processed (stalling) output streams must be >= 1", 153 maxNumStreamsProcStall >= 1); 154 155 if (mStaticInfo.isHardwareLevelAtLeastFull()) { 156 mCollector.expectTrue("max number of processed (non-stalling) output streams" + 157 "must be >= 3 for FULL device", 158 maxNumStreamsProc >= 3); 159 } else if (mStaticInfo.isColorOutputSupported()) { 160 mCollector.expectTrue("max number of processed (non-stalling) output streams" + 161 "must be >= 2 for devices that support color output", 162 maxNumStreamsProc >= 2); 163 } 164 } 165 166 } 167 168 /** 169 * Test advertised capability does match available keys and vice versa 170 */ 171 public void testCapabilities() throws Exception { 172 for (String id : mCameraIds) { 173 initStaticMetadata(id); 174 List<Integer> availableCaps = mStaticInfo.getAvailableCapabilitiesChecked(); 175 176 for (Integer capability = REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE; 177 capability <= LAST_CAPABILITY_ENUM; capability++) { 178 boolean isCapabilityAvailable = availableCaps.contains(capability); 179 validateCapability(capability, isCapabilityAvailable); 180 } 181 // Note: Static metadata for capabilities is tested in ExtendedCameraCharacteristicsTest 182 } 183 } 184 185 /** 186 * Check if request keys' presence match expectation. 187 * 188 * @param capabilityName The name string of capability being tested. Used for output messages. 189 * @param requestKeys The capture request keys to be checked 190 * @param expectedPresence Expected presence of {@code requestKeys}. {@code true} for expecting 191 * all keys are available. Otherwise {@code false} 192 * @return {@code true} if request keys' presence match expectation. Otherwise {@code false} 193 */ 194 private boolean validateRequestKeysPresence(String capabilityName, 195 Collection<CaptureRequest.Key<?>> requestKeys, boolean expectedPresence) { 196 boolean actualPresence = mStaticInfo.areRequestKeysAvailable(requestKeys); 197 if (expectedPresence != actualPresence) { 198 if (expectedPresence) { 199 for (CaptureRequest.Key<?> key : requestKeys) { 200 if (!mStaticInfo.areKeysAvailable(key)) { 201 mCollector.addMessage(String.format( 202 "Camera %s list capability %s but doesn't contain request key %s", 203 mCameraId, capabilityName, key.getName())); 204 } 205 } 206 } else { 207 Log.w(TAG, String.format( 208 "Camera %s doesn't list capability %s but contain all required keys", 209 mCameraId, capabilityName)); 210 } 211 return false; 212 } 213 return true; 214 } 215 216 /** 217 * Check if result keys' presence match expectation. 218 * 219 * @param capabilityName The name string of capability being tested. Used for output messages. 220 * @param resultKeys The capture result keys to be checked 221 * @param expectedPresence Expected presence of {@code resultKeys}. {@code true} for expecting 222 * all keys are available. Otherwise {@code false} 223 * @return {@code true} if result keys' presence match expectation. Otherwise {@code false} 224 */ 225 private boolean validateResultKeysPresence(String capabilityName, 226 Collection<CaptureResult.Key<?>> resultKeys, boolean expectedPresence) { 227 boolean actualPresence = mStaticInfo.areResultKeysAvailable(resultKeys); 228 if (expectedPresence != actualPresence) { 229 if (expectedPresence) { 230 for (CaptureResult.Key<?> key : resultKeys) { 231 if (!mStaticInfo.areKeysAvailable(key)) { 232 mCollector.addMessage(String.format( 233 "Camera %s list capability %s but doesn't contain result key %s", 234 mCameraId, capabilityName, key.getName())); 235 } 236 } 237 } else { 238 Log.w(TAG, String.format( 239 "Camera %s doesn't list capability %s but contain all required keys", 240 mCameraId, capabilityName)); 241 } 242 return false; 243 } 244 return true; 245 } 246 247 /** 248 * Check if characteristics keys' presence match expectation. 249 * 250 * @param capabilityName The name string of capability being tested. Used for output messages. 251 * @param characteristicsKeys The characteristics keys to be checked 252 * @param expectedPresence Expected presence of {@code characteristicsKeys}. {@code true} for 253 * expecting all keys are available. Otherwise {@code false} 254 * @return {@code true} if characteristics keys' presence match expectation. 255 * Otherwise {@code false} 256 */ 257 private boolean validateCharacteristicsKeysPresence(String capabilityName, 258 Collection<CameraCharacteristics.Key<?>> characteristicsKeys, 259 boolean expectedPresence) { 260 boolean actualPresence = mStaticInfo.areCharacteristicsKeysAvailable(characteristicsKeys); 261 if (expectedPresence != actualPresence) { 262 if (expectedPresence) { 263 for (CameraCharacteristics.Key<?> key : characteristicsKeys) { 264 if (!mStaticInfo.areKeysAvailable(key)) { 265 mCollector.addMessage(String.format( 266 "Camera %s list capability %s but doesn't contain" + 267 "characteristics key %s", 268 mCameraId, capabilityName, key.getName())); 269 } 270 } 271 } else { 272 Log.w(TAG, String.format( 273 "Camera %s doesn't list capability %s but contain all required keys", 274 mCameraId, capabilityName)); 275 } 276 return false; 277 } 278 return true; 279 } 280 281 private void validateCapability(Integer capability, boolean isCapabilityAvailable) { 282 List<CaptureRequest.Key<?>> requestKeys = new ArrayList<>(); 283 Set<CaptureResult.Key<?>> resultKeys = new HashSet<>(); 284 // Capability requirements other than key presences 285 List<Pair<String, Boolean>> additionalRequirements = new ArrayList<>(); 286 287 /* For available capabilities, only check request keys in this test 288 Characteristics keys are tested in ExtendedCameraCharacteristicsTest 289 Result keys are tested in CaptureResultTest */ 290 String capabilityName; 291 switch (capability) { 292 case REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE: 293 capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE"; 294 requestKeys.add(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE); 295 requestKeys.add(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION); 296 requestKeys.add(CaptureRequest.CONTROL_AE_MODE); 297 requestKeys.add(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE); 298 requestKeys.add(CaptureRequest.CONTROL_AF_MODE); 299 requestKeys.add(CaptureRequest.CONTROL_AF_TRIGGER); 300 requestKeys.add(CaptureRequest.CONTROL_AWB_MODE); 301 requestKeys.add(CaptureRequest.CONTROL_CAPTURE_INTENT); 302 requestKeys.add(CaptureRequest.CONTROL_EFFECT_MODE); 303 requestKeys.add(CaptureRequest.CONTROL_MODE); 304 requestKeys.add(CaptureRequest.CONTROL_SCENE_MODE); 305 requestKeys.add(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE); 306 requestKeys.add(CaptureRequest.FLASH_MODE); 307 requestKeys.add(CaptureRequest.JPEG_GPS_LOCATION); 308 requestKeys.add(CaptureRequest.JPEG_ORIENTATION); 309 requestKeys.add(CaptureRequest.JPEG_QUALITY); 310 requestKeys.add(CaptureRequest.JPEG_THUMBNAIL_QUALITY); 311 requestKeys.add(CaptureRequest.JPEG_THUMBNAIL_SIZE); 312 requestKeys.add(CaptureRequest.SCALER_CROP_REGION); 313 requestKeys.add(CaptureRequest.STATISTICS_FACE_DETECT_MODE); 314 if (mStaticInfo.getAeMaxRegionsChecked() > 0) { 315 requestKeys.add(CaptureRequest.CONTROL_AE_REGIONS); 316 } else { 317 mCollector.expectTrue( 318 "CONTROL_AE_REGIONS is available but aeMaxRegion is 0", 319 !mStaticInfo.areKeysAvailable(CaptureRequest.CONTROL_AE_REGIONS)); 320 } 321 if (mStaticInfo.getAwbMaxRegionsChecked() > 0) { 322 requestKeys.add(CaptureRequest.CONTROL_AWB_REGIONS); 323 } else { 324 mCollector.expectTrue( 325 "CONTROL_AWB_REGIONS is available but awbMaxRegion is 0", 326 !mStaticInfo.areKeysAvailable(CaptureRequest.CONTROL_AWB_REGIONS)); 327 } 328 if (mStaticInfo.getAfMaxRegionsChecked() > 0) { 329 requestKeys.add(CaptureRequest.CONTROL_AF_REGIONS); 330 } else { 331 mCollector.expectTrue( 332 "CONTROL_AF_REGIONS is available but afMaxRegion is 0", 333 !mStaticInfo.areKeysAvailable(CaptureRequest.CONTROL_AF_REGIONS)); 334 } 335 break; 336 case REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING: 337 capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING"; 338 requestKeys.add(CaptureRequest.TONEMAP_MODE); 339 requestKeys.add(CaptureRequest.COLOR_CORRECTION_GAINS); 340 requestKeys.add(CaptureRequest.COLOR_CORRECTION_TRANSFORM); 341 requestKeys.add(CaptureRequest.SHADING_MODE); 342 requestKeys.add(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE); 343 requestKeys.add(CaptureRequest.TONEMAP_CURVE); 344 requestKeys.add(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE); 345 requestKeys.add(CaptureRequest.CONTROL_AWB_LOCK); 346 347 // Legacy mode always doesn't support these requirements 348 Boolean contrastCurveModeSupported = false; 349 Boolean gammaAndPresetModeSupported = false; 350 Boolean offColorAberrationModeSupported = false; 351 if (mStaticInfo.isHardwareLevelAtLeastLimited() && mStaticInfo.isColorOutputSupported()) { 352 int[] tonemapModes = mStaticInfo.getAvailableToneMapModesChecked(); 353 List<Integer> modeList = (tonemapModes.length == 0) ? 354 new ArrayList<Integer>() : 355 Arrays.asList(CameraTestUtils.toObject(tonemapModes)); 356 contrastCurveModeSupported = 357 modeList.contains(CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE); 358 gammaAndPresetModeSupported = 359 modeList.contains(CameraMetadata.TONEMAP_MODE_GAMMA_VALUE) && 360 modeList.contains(CameraMetadata.TONEMAP_MODE_PRESET_CURVE); 361 362 int[] colorAberrationModes = 363 mStaticInfo.getAvailableColorAberrationModesChecked(); 364 modeList = (colorAberrationModes.length == 0) ? 365 new ArrayList<Integer>() : 366 Arrays.asList(CameraTestUtils.toObject(colorAberrationModes)); 367 offColorAberrationModeSupported = 368 modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF); 369 } 370 Boolean tonemapModeQualified = 371 contrastCurveModeSupported || gammaAndPresetModeSupported; 372 additionalRequirements.add(new Pair<String, Boolean>( 373 "Tonemap mode must include {CONTRAST_CURVE} and/or " + 374 "{GAMMA_VALUE, PRESET_CURVE}", 375 tonemapModeQualified)); 376 additionalRequirements.add(new Pair<String, Boolean>( 377 "Color aberration mode must include OFF", offColorAberrationModeSupported)); 378 additionalRequirements.add(new Pair<String, Boolean>( 379 "Must support AWB lock", mStaticInfo.isAwbLockSupported())); 380 break; 381 case REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR: 382 capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR"; 383 requestKeys.add(CaptureRequest.CONTROL_AE_LOCK); 384 requestKeys.add(CaptureRequest.SENSOR_FRAME_DURATION); 385 requestKeys.add(CaptureRequest.SENSOR_EXPOSURE_TIME); 386 requestKeys.add(CaptureRequest.SENSOR_SENSITIVITY); 387 if (mStaticInfo.hasFocuser()) { 388 requestKeys.add(CaptureRequest.LENS_APERTURE); 389 requestKeys.add(CaptureRequest.LENS_FOCUS_DISTANCE); 390 requestKeys.add(CaptureRequest.LENS_FILTER_DENSITY); 391 requestKeys.add(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE); 392 } 393 requestKeys.add(CaptureRequest.BLACK_LEVEL_LOCK); 394 additionalRequirements.add(new Pair<String, Boolean>( 395 "Must support AE lock", mStaticInfo.isAeLockSupported())); 396 break; 397 case REQUEST_AVAILABLE_CAPABILITIES_RAW: 398 // RAW_CAPABILITY needs to check for not just capture request keys 399 validateRawCapability(isCapabilityAvailable); 400 return; 401 case REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE: 402 // Tested in ExtendedCameraCharacteristicsTest 403 return; 404 case REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS: 405 capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS"; 406 resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION); 407 resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME); 408 resultKeys.add(CaptureResult.SENSOR_SENSITIVITY); 409 if (mStaticInfo.hasFocuser()) { 410 resultKeys.add(CaptureResult.LENS_APERTURE); 411 resultKeys.add(CaptureResult.LENS_FOCUS_DISTANCE); 412 resultKeys.add(CaptureResult.LENS_FILTER_DENSITY); 413 } 414 break; 415 416 case REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING: 417 case REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING: 418 // Tested in ExtendedCameraCharacteristicsTest 419 return; 420 case REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT: 421 // Tested in ExtendedCameracharacteristicsTest 422 return; 423 case REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO: 424 case REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING: 425 case REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA: 426 case REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME: 427 // Tested in ExtendedCameraCharacteristicsTest 428 return; 429 default: 430 capabilityName = "Unknown"; 431 assertTrue(String.format("Unknown capability set: %d", capability), 432 !isCapabilityAvailable); 433 return; 434 } 435 436 // Check additional requirements and exit early if possible 437 if (!isCapabilityAvailable) { 438 for (Pair<String, Boolean> p : additionalRequirements) { 439 String requirement = p.first; 440 Boolean meetRequirement = p.second; 441 // No further check is needed if we've found why capability cannot be advertised 442 if (!meetRequirement) { 443 Log.v(TAG, String.format( 444 "Camera %s doesn't list capability %s because of requirement: %s", 445 mCameraId, capabilityName, requirement)); 446 return; 447 } 448 } 449 } 450 451 boolean matchExpectation = true; 452 if (!requestKeys.isEmpty()) { 453 matchExpectation &= validateRequestKeysPresence( 454 capabilityName, requestKeys, isCapabilityAvailable); 455 } 456 if(!resultKeys.isEmpty()) { 457 matchExpectation &= validateResultKeysPresence( 458 capabilityName, resultKeys, isCapabilityAvailable); 459 } 460 461 // Check additional requirements 462 for (Pair<String, Boolean> p : additionalRequirements) { 463 String requirement = p.first; 464 Boolean meetRequirement = p.second; 465 if (isCapabilityAvailable && !meetRequirement) { 466 mCollector.addMessage(String.format( 467 "Camera %s list capability %s but does not meet the requirement: %s", 468 mCameraId, capabilityName, requirement)); 469 } 470 } 471 472 // In case of isCapabilityAvailable == true, error has been filed in 473 // validateRequest/ResultKeysPresence 474 if (!matchExpectation && !isCapabilityAvailable) { 475 mCollector.addMessage(String.format( 476 "Camera %s doesn't list capability %s but meets all requirements", 477 mCameraId, capabilityName)); 478 } 479 } 480 481 private void validateRawCapability(boolean isCapabilityAvailable) { 482 String capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_RAW"; 483 484 Set<CaptureRequest.Key<?>> requestKeys = new HashSet<>(); 485 requestKeys.add(CaptureRequest.HOT_PIXEL_MODE); 486 requestKeys.add(CaptureRequest.STATISTICS_HOT_PIXEL_MAP_MODE); 487 488 Set<CameraCharacteristics.Key<?>> characteristicsKeys = new HashSet<>(); 489 characteristicsKeys.add(HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES); 490 characteristicsKeys.add(SENSOR_BLACK_LEVEL_PATTERN); 491 characteristicsKeys.add(SENSOR_CALIBRATION_TRANSFORM1); 492 characteristicsKeys.add(SENSOR_COLOR_TRANSFORM1); 493 characteristicsKeys.add(SENSOR_FORWARD_MATRIX1); 494 characteristicsKeys.add(SENSOR_INFO_ACTIVE_ARRAY_SIZE); 495 characteristicsKeys.add(SENSOR_INFO_COLOR_FILTER_ARRANGEMENT); 496 characteristicsKeys.add(SENSOR_INFO_WHITE_LEVEL); 497 characteristicsKeys.add(SENSOR_REFERENCE_ILLUMINANT1); 498 characteristicsKeys.add(STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES); 499 500 Set<CaptureResult.Key<?>> resultKeys = new HashSet<>(); 501 resultKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT); 502 resultKeys.add(CaptureResult.SENSOR_GREEN_SPLIT); 503 resultKeys.add(CaptureResult.SENSOR_NOISE_PROFILE); 504 505 boolean rawOutputSupported = mStaticInfo.getRawOutputSizesChecked().length > 0; 506 boolean requestKeysPresent = mStaticInfo.areRequestKeysAvailable(requestKeys); 507 boolean characteristicsKeysPresent = 508 mStaticInfo.areCharacteristicsKeysAvailable(characteristicsKeys); 509 boolean resultKeysPresent = mStaticInfo.areResultKeysAvailable(resultKeys); 510 boolean expectCapabilityPresent = rawOutputSupported && requestKeysPresent && 511 characteristicsKeysPresent && resultKeysPresent; 512 513 if (isCapabilityAvailable != expectCapabilityPresent) { 514 if (isCapabilityAvailable) { 515 mCollector.expectTrue( 516 "REQUEST_AVAILABLE_CAPABILITIES_RAW should support RAW_SENSOR output", 517 rawOutputSupported); 518 validateRequestKeysPresence(capabilityName, requestKeys, isCapabilityAvailable); 519 validateResultKeysPresence(capabilityName, resultKeys, isCapabilityAvailable); 520 validateCharacteristicsKeysPresence(capabilityName, characteristicsKeys, 521 isCapabilityAvailable); 522 } else { 523 mCollector.addMessage(String.format( 524 "Camera %s doesn't list capability %s but contain all required keys" + 525 " and RAW format output", 526 mCameraId, capabilityName)); 527 } 528 } 529 } 530 531 /** 532 * Test lens facing. 533 */ 534 public void testLensFacing() throws Exception { 535 for (String id : mCameraIds) { 536 initStaticMetadata(id); 537 mStaticInfo.getLensFacingChecked(); 538 } 539 } 540 541 private float getFpsForMaxSize(String cameraId) throws Exception { 542 HashMap<Size, Long> minFrameDurationMap = 543 mStaticInfo.getAvailableMinFrameDurationsForFormatChecked(ImageFormat.YUV_420_888); 544 545 Size[] sizes = CameraTestUtils.getSupportedSizeForFormat(ImageFormat.YUV_420_888, 546 cameraId, mCameraManager); 547 Size maxSize = CameraTestUtils.getMaxSize(sizes); 548 Long minDuration = minFrameDurationMap.get(maxSize); 549 if (VERBOSE) { 550 Log.v(TAG, "min frame duration for size " + maxSize + " is " + minDuration); 551 } 552 assertTrue("min duration for max size must be postive number", 553 minDuration != null && minDuration > 0); 554 555 return 1e9f / minDuration; 556 } 557 558 /** 559 * Initialize static metadata for a given camera id. 560 */ 561 private void initStaticMetadata(String cameraId) throws Exception { 562 mCameraId = cameraId; 563 mCollector.setCameraId(cameraId); 564 mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId), 565 CheckLevel.COLLECT, /* collector */mCollector); 566 } 567 } 568