1 /* 2 * Copyright 2013 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 android.content.Context; 20 import android.graphics.ImageFormat; 21 import android.hardware.camera2.CameraCaptureSession; 22 import android.hardware.camera2.CameraCharacteristics; 23 import android.hardware.camera2.CameraDevice; 24 import android.hardware.camera2.CaptureFailure; 25 import android.hardware.camera2.CaptureRequest; 26 import android.hardware.camera2.CaptureResult; 27 import android.hardware.camera2.params.BlackLevelPattern; 28 import android.hardware.camera2.TotalCaptureResult; 29 import android.media.Image; 30 import android.media.ImageReader; 31 import android.os.Build; 32 import android.os.SystemClock; 33 import android.util.Pair; 34 import android.util.Size; 35 import android.hardware.camera2.cts.helpers.CameraErrorCollector; 36 import android.hardware.camera2.cts.helpers.StaticMetadata; 37 import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase; 38 39 import static android.hardware.camera2.cts.CameraTestUtils.*; 40 import static android.hardware.camera2.cts.helpers.CameraSessionUtils.*; 41 import static junit.framework.Assert.*; 42 43 import android.util.Log; 44 import android.view.Surface; 45 46 import java.util.ArrayList; 47 import java.util.Arrays; 48 import java.util.HashMap; 49 import java.util.HashSet; 50 import java.util.List; 51 import java.util.Map; 52 import java.util.Set; 53 import java.util.concurrent.LinkedBlockingQueue; 54 import java.util.concurrent.TimeUnit; 55 56 import org.junit.runners.Parameterized; 57 import org.junit.runner.RunWith; 58 import org.junit.Test; 59 60 @RunWith(Parameterized.class) 61 public class CaptureResultTest extends Camera2AndroidTestCase { 62 private static final String TAG = "CaptureResultTest"; 63 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); 64 private static final int MAX_NUM_IMAGES = MAX_READER_IMAGES; 65 private static final int NUM_FRAMES_VERIFIED = 30; 66 private static final long WAIT_FOR_RESULT_TIMEOUT_MS = 3000; 67 68 /** Load validation jni on initialization. */ 69 static { 70 System.loadLibrary("ctscamera2_jni"); 71 } 72 73 // List tracking the failed test keys. 74 75 @Override setUp()76 public void setUp() throws Exception { 77 super.setUp(); 78 } 79 80 @Override tearDown()81 public void tearDown() throws Exception { 82 super.tearDown(); 83 } 84 85 /** 86 * <p> 87 * Basic non-null check test for multiple capture results. 88 * </p> 89 * <p> 90 * When capturing many frames, some camera devices may return some results that have null keys 91 * randomly, which is an API violation and could cause application crash randomly. This test 92 * runs a typical flexible yuv capture many times, and checks if there is any null entries in 93 * a capture result. 94 * </p> 95 */ 96 @Test testCameraCaptureResultAllKeys()97 public void testCameraCaptureResultAllKeys() throws Exception { 98 for (String id : mCameraIdsUnderTest) { 99 try { 100 openDevice(id); 101 if (mStaticInfo.isColorOutputSupported()) { 102 // Create image reader and surface. 103 Size size = mOrderedPreviewSizes.get(0); 104 createDefaultImageReader(size, ImageFormat.YUV_420_888, MAX_NUM_IMAGES, 105 new ImageDropperListener()); 106 } else { 107 Size size = getMaxDepthSize(id, mCameraManager); 108 createDefaultImageReader(size, ImageFormat.DEPTH16, MAX_NUM_IMAGES, 109 new ImageDropperListener()); 110 } 111 112 // Configure output streams. 113 List<Surface> outputSurfaces = new ArrayList<Surface>(1); 114 outputSurfaces.add(mReaderSurface); 115 createSession(outputSurfaces); 116 117 CaptureRequest.Builder requestBuilder = 118 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 119 assertNotNull("Failed to create capture request", requestBuilder); 120 requestBuilder.addTarget(mReaderSurface); 121 122 // Start capture 123 SimpleCaptureCallback captureListener = new SimpleCaptureCallback(); 124 startCapture(requestBuilder.build(), /*repeating*/true, captureListener, mHandler); 125 126 // Verify results 127 validateCaptureResult(mCollector, captureListener, mStaticInfo, mAllStaticInfo, 128 null/*requestedPhysicalIds*/, requestBuilder, NUM_FRAMES_VERIFIED); 129 130 stopCapture(/*fast*/false); 131 } finally { 132 closeDevice(id); 133 closeDefaultImageReader(); 134 } 135 } 136 } 137 138 /** 139 * Check partial results conform to its specification. 140 * <p> 141 * The test is skipped if partial result is not supported on device. </p> 142 * <p>Test summary:<ul> 143 * <li>1. Number of partial results is less than or equal to 144 * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT}. 145 * <li>2. Each key appeared in partial results must be unique across all partial results. 146 * <li>3. All keys appeared in partial results must be present in TotalCaptureResult 147 * <li>4. Also test onCaptureComplete callback always happen after onCaptureStart or 148 * onCaptureProgressed callbacks. 149 * </ul></p> 150 */ 151 @Test testPartialResult()152 public void testPartialResult() throws Exception { 153 final int NUM_FRAMES_TESTED = 30; 154 final int WAIT_FOR_RESULT_TIMOUT_MS = 2000; 155 for (String id : mCameraIdsUnderTest) { 156 try { 157 // Skip the test if partial result is not supported 158 int partialResultCount = mAllStaticInfo.get(id).getPartialResultCount(); 159 if (partialResultCount == 1) { 160 continue; 161 } 162 163 openDevice(id); 164 // Create image reader and surface. 165 if (mStaticInfo.isColorOutputSupported()) { 166 Size size = mOrderedPreviewSizes.get(0); 167 createDefaultImageReader(size, ImageFormat.YUV_420_888, MAX_NUM_IMAGES, 168 new ImageDropperListener()); 169 } else { 170 Size size = getMaxDepthSize(id, mCameraManager); 171 createDefaultImageReader(size, ImageFormat.DEPTH16, MAX_NUM_IMAGES, 172 new ImageDropperListener()); 173 } 174 175 // Configure output streams. 176 List<Surface> outputSurfaces = new ArrayList<Surface>(1); 177 outputSurfaces.add(mReaderSurface); 178 createSession(outputSurfaces); 179 180 CaptureRequest.Builder requestBuilder = 181 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 182 assertNotNull("Failed to create capture request", requestBuilder); 183 requestBuilder.addTarget(mReaderSurface); 184 TotalAndPartialResultListener listener = 185 new TotalAndPartialResultListener(); 186 187 // Start capture 188 for (Integer frame = 0; frame < NUM_FRAMES_TESTED; frame++) { 189 // Set a different tag for each request so the listener can group 190 // partial results by each request 191 requestBuilder.setTag(frame); 192 startCapture( 193 requestBuilder.build(), /*repeating*/false, 194 listener, mHandler); 195 } 196 197 // Verify capture results 198 for (int frame = 0; frame < NUM_FRAMES_TESTED; frame++) { 199 Pair<TotalCaptureResult, List<CaptureResult>> resultPair = 200 listener.getCaptureResultPairs(WAIT_FOR_RESULT_TIMOUT_MS); 201 202 List<CaptureResult> partialResults = resultPair.second; 203 204 if (partialResults == null) { 205 // HAL only sends total result is legal 206 partialResults = new ArrayList<>(); 207 } 208 209 TotalCaptureResult totalResult = resultPair.first; 210 211 mCollector.expectLessOrEqual("Too many partial results", 212 partialResultCount, partialResults.size()); 213 Set<CaptureResult.Key<?>> appearedPartialKeys = 214 new HashSet<CaptureResult.Key<?>>(); 215 for (CaptureResult partialResult : partialResults) { 216 mCollector.expectEquals("Partial capture result camera ID must be correct", 217 partialResult.getCameraId(), id); 218 List<CaptureResult.Key<?>> partialKeys = partialResult.getKeys(); 219 mCollector.expectValuesUnique("Partial result keys: ", partialKeys); 220 for (CaptureResult.Key<?> key : partialKeys) { 221 mCollector.expectTrue( 222 String.format("Key %s appears in multiple partial results", 223 key.getName()), 224 !appearedPartialKeys.contains(key)); 225 } 226 appearedPartialKeys.addAll(partialKeys); 227 } 228 229 // Test total result against the partial results 230 mCollector.expectEquals("Total capture result camera ID must be correct", 231 totalResult.getCameraId(), id); 232 List<CaptureResult.Key<?>> totalResultKeys = totalResult.getKeys(); 233 mCollector.expectTrue( 234 "TotalCaptureResult must be a super set of partial capture results", 235 totalResultKeys.containsAll(appearedPartialKeys)); 236 237 List<CaptureResult> totalResultPartials = totalResult.getPartialResults(); 238 mCollector.expectEquals("TotalCaptureResult's partial results must match " + 239 "the ones observed by #onCaptureProgressed", 240 partialResults, totalResultPartials); 241 242 if (VERBOSE) { 243 Log.v(TAG, "testPartialResult - Observed " + 244 partialResults.size() + "; queried for " + 245 totalResultPartials.size()); 246 } 247 } 248 249 int errorCode = listener.getErrorCode(); 250 if ((errorCode & TotalAndPartialResultListener.ERROR_DUPLICATED_REQUEST) != 0) { 251 mCollector.addMessage("Listener received multiple onCaptureComplete" + 252 " callback for the same request"); 253 } 254 if ((errorCode & TotalAndPartialResultListener.ERROR_WRONG_CALLBACK_ORDER) != 0) { 255 mCollector.addMessage("Listener received onCaptureStart or" + 256 " onCaptureProgressed after onCaptureComplete"); 257 } 258 259 stopCapture(/*fast*/false); 260 } finally { 261 closeDevice(id); 262 closeDefaultImageReader(); 263 } 264 } 265 } 266 267 /** 268 * Check that the timestamps passed in the results, buffers, and capture callbacks match for 269 * a single request, and increase monotonically 270 */ 271 @Test testResultTimestamps()272 public void testResultTimestamps() throws Exception { 273 for (String id : mCameraIdsUnderTest) { 274 ImageReader previewReader = null; 275 ImageReader jpegReader = null; 276 277 CaptureResult resultForNdk = null; 278 279 SimpleImageReaderListener jpegListener = new SimpleImageReaderListener(); 280 SimpleImageReaderListener prevListener = new SimpleImageReaderListener(); 281 try { 282 if (!mAllStaticInfo.get(id).isColorOutputSupported()) { 283 Log.i(TAG, "Camera " + id + " does not support color outputs, skipping"); 284 continue; 285 } 286 287 openDevice(id); 288 CaptureRequest.Builder previewBuilder = 289 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 290 CaptureRequest.Builder multiBuilder = 291 mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 292 293 // Create image reader and surface. 294 Size previewSize = mOrderedPreviewSizes.get(0); 295 Size jpegSize = mOrderedStillSizes.get(0); 296 297 // Create ImageReaders. 298 previewReader = makeImageReader(previewSize, ImageFormat.YUV_420_888, 299 MAX_NUM_IMAGES, prevListener, mHandler); 300 jpegReader = makeImageReader(jpegSize, ImageFormat.JPEG, 301 MAX_NUM_IMAGES, jpegListener, mHandler); 302 303 // Configure output streams with preview and jpeg streams. 304 List<Surface> outputSurfaces = new ArrayList<>(Arrays.asList( 305 previewReader.getSurface(), jpegReader.getSurface())); 306 307 SessionListener mockSessionListener = getMockSessionListener(); 308 309 CameraCaptureSession session = configureAndVerifySession(mockSessionListener, 310 mCamera, outputSurfaces, mHandler); 311 312 // Configure the requests. 313 previewBuilder.addTarget(previewReader.getSurface()); 314 multiBuilder.addTarget(previewReader.getSurface()); 315 multiBuilder.addTarget(jpegReader.getSurface()); 316 317 if (mStaticInfo.isEnableZslSupported()) { 318 // Turn off ZSL to ensure timestamps are increasing 319 previewBuilder.set(CaptureRequest.CONTROL_ENABLE_ZSL, false); 320 multiBuilder.set(CaptureRequest.CONTROL_ENABLE_ZSL, false); 321 } 322 323 CaptureCallback mockCaptureCallback = getMockCaptureListener(); 324 325 // Capture targeting only preview 326 Pair<TotalCaptureResult, Long> result = captureAndVerifyResult(mockCaptureCallback, 327 session, previewBuilder.build(), mHandler); 328 329 // Check if all timestamps are the same 330 Image prevImage = prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS); 331 validateTimestamps("Result 1", result.first, 332 prevImage, result.second); 333 prevImage.close(); 334 335 // Capture targeting both jpeg and preview 336 Pair<TotalCaptureResult, Long> result2 = captureAndVerifyResult(mockCaptureCallback, 337 session, multiBuilder.build(), mHandler); 338 339 // Check if all timestamps are the same 340 prevImage = prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS); 341 Image jpegImage = jpegListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS); 342 validateTimestamps("Result 2 Preview", result2.first, 343 prevImage, result2.second); 344 validateTimestamps("Result 2 Jpeg", result2.first, 345 jpegImage, result2.second); 346 prevImage.close(); 347 jpegImage.close(); 348 349 // Check if timestamps are increasing 350 mCollector.expectGreater("Timestamps must be increasing.", result.second, 351 result2.second); 352 353 // Capture two preview frames 354 long startTime = SystemClock.elapsedRealtimeNanos(); 355 Pair<TotalCaptureResult, Long> result3 = captureAndVerifyResult(mockCaptureCallback, 356 session, previewBuilder.build(), mHandler); 357 Pair<TotalCaptureResult, Long> result4 = captureAndVerifyResult(mockCaptureCallback, 358 session, previewBuilder.build(), mHandler); 359 long clockDiff = SystemClock.elapsedRealtimeNanos() - startTime; 360 long resultDiff = result4.second - result3.second; 361 362 // Check if all timestamps are the same 363 prevImage = prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS); 364 validateTimestamps("Result 3", result3.first, 365 prevImage, result3.second); 366 prevImage.close(); 367 prevImage = prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS); 368 validateTimestamps("Result 4", result4.first, 369 prevImage, result4.second); 370 prevImage.close(); 371 372 // Check that the timestamps monotonically increase at a reasonable rate 373 mCollector.expectGreaterOrEqual("Timestamps increase faster than system clock.", 374 resultDiff, clockDiff); 375 mCollector.expectGreater("Timestamps must be increasing.", result3.second, 376 result4.second); 377 378 resultForNdk = result.first; 379 } finally { 380 closeDevice(id); 381 closeImageReader(previewReader); 382 closeImageReader(jpegReader); 383 } 384 385 mCollector.expectTrue( 386 "validateACameraMetadataFromCameraMetadataCriticalTagsNative failed", 387 validateACameraMetadataFromCameraMetadataCriticalTagsNative(resultForNdk, 388 resultForNdk.get(CaptureResult.SENSOR_TIMESTAMP))); 389 390 long timestamp = resultForNdk.get(CaptureResult.SENSOR_TIMESTAMP); 391 mCollector.expectTrue( 392 "stashACameraMetadataFromCameraMetadataNative failed", 393 stashACameraMetadataFromCameraMetadataNative(resultForNdk)); 394 395 // Try to drop the Java side object here 396 resultForNdk = null; 397 int[] block = null; 398 final int count = 9; 399 for (int i = 0; i < count + 1; i++) { 400 block = new int[1000000]; 401 block[1000 + i] = i; 402 403 Runtime.getRuntime().gc(); 404 Runtime.getRuntime().runFinalization(); 405 406 mCollector.expectTrue("This should never fail", block[1000 + i] == i); 407 } 408 mCollector.expectTrue( 409 "validateStashedACameraMetadataFromCameraMetadataNative failed", 410 validateStashedACameraMetadataFromCameraMetadataNative(timestamp)); 411 mCollector.expectTrue("This should never fail", block[1000 + count] == count); 412 } 413 } 414 validateTimestamps(String msg, TotalCaptureResult result, Image resultImage, long captureTime)415 private void validateTimestamps(String msg, TotalCaptureResult result, Image resultImage, 416 long captureTime) { 417 mCollector.expectKeyValueEquals(result, CaptureResult.SENSOR_TIMESTAMP, captureTime); 418 mCollector.expectEquals(msg + ": Capture timestamp must be same as resultImage timestamp", 419 resultImage.getTimestamp(), captureTime); 420 } 421 validateCaptureResult(CameraErrorCollector errorCollector, SimpleCaptureCallback captureListener, StaticMetadata staticInfo, Map<String, StaticMetadata> allStaticInfo, List<String> requestedPhysicalIds, CaptureRequest.Builder requestBuilder, int numFramesVerified)422 public static void validateCaptureResult(CameraErrorCollector errorCollector, 423 SimpleCaptureCallback captureListener, StaticMetadata staticInfo, 424 Map<String, StaticMetadata> allStaticInfo, List<String> requestedPhysicalIds, 425 CaptureRequest.Builder requestBuilder, int numFramesVerified) throws Exception { 426 // List that includes all public keys from CaptureResult 427 List<CaptureResult.Key<?>> allKeys = getAllCaptureResultKeys(); 428 // Get the waived keys for current camera device 429 List<CaptureResult.Key<?>> waiverKeys = getWaiverKeysForCamera(staticInfo); 430 if (requestedPhysicalIds == null) { 431 requestedPhysicalIds = new ArrayList<String>(); 432 } 433 434 HashMap<String, List<CaptureResult.Key<?>>> physicalWaiverKeys = new HashMap<>(); 435 for (String physicalId : requestedPhysicalIds) { 436 StaticMetadata physicalStaticInfo = allStaticInfo.get(physicalId); 437 physicalWaiverKeys.put(physicalId, getWaiverKeysForCamera(physicalStaticInfo)); 438 } 439 440 TotalCaptureResult result = null; 441 // List of (frameNumber, physical camera Id) pairs 442 ArrayList<Pair<Long, String>> droppedPhysicalResults = new ArrayList<>(); 443 for (int i = 0; i < numFramesVerified; i++) { 444 result = captureListener.getTotalCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS); 445 446 Map<String, CaptureResult> physicalCaptureResults = result.getPhysicalCameraResults(); 447 ArrayList<String> droppedIds = new ArrayList<String>(requestedPhysicalIds); 448 droppedIds.removeAll(physicalCaptureResults.keySet()); 449 for (String droppedId : droppedIds) { 450 droppedPhysicalResults.add( 451 new Pair<Long, String>(result.getFrameNumber(), droppedId)); 452 } 453 454 validateOneCaptureResult(errorCollector, staticInfo, waiverKeys, allKeys, 455 requestBuilder, result, null/*cameraId*/, i); 456 for (String physicalId : physicalCaptureResults.keySet()) { 457 StaticMetadata physicalStaticInfo = allStaticInfo.get(physicalId); 458 validateOneCaptureResult(errorCollector, physicalStaticInfo, 459 physicalWaiverKeys.get(physicalId), 460 allKeys, null/*requestBuilder*/, physicalCaptureResults.get(physicalId), 461 physicalId, i); 462 } 463 } 464 465 // Verify that all dropped physical camera results are notified via capture failure. 466 while (captureListener.hasMoreFailures()) { 467 ArrayList<CaptureFailure> failures = 468 captureListener.getCaptureFailures(/*maxNumFailures*/ 1); 469 for (CaptureFailure failure : failures) { 470 String failedPhysicalId = failure.getPhysicalCameraId(); 471 Long failedFrameNumber = failure.getFrameNumber(); 472 if (failedPhysicalId != null) { 473 droppedPhysicalResults.removeIf( 474 n -> n.equals( 475 new Pair<Long, String>(failedFrameNumber, failedPhysicalId))); 476 } 477 } 478 } 479 errorCollector.expectTrue("Not all dropped results for physical cameras are notified", 480 droppedPhysicalResults.isEmpty()); 481 } 482 validateOneCaptureResult(CameraErrorCollector errorCollector, StaticMetadata staticInfo, List<CaptureResult.Key<?>> skippedKeys, List<CaptureResult.Key<?>> allKeys, CaptureRequest.Builder requestBuilder, CaptureResult result, String cameraId, int resultCount)483 private static void validateOneCaptureResult(CameraErrorCollector errorCollector, 484 StaticMetadata staticInfo, List<CaptureResult.Key<?>> skippedKeys, 485 List<CaptureResult.Key<?>> allKeys, 486 CaptureRequest.Builder requestBuilder, CaptureResult result, String cameraId, 487 int resultCount) throws Exception { 488 String failMsg = "Failed capture result " + resultCount + " test"; 489 String cameraIdString = " "; 490 if (cameraId != null) { 491 cameraIdString += "for physical camera " + cameraId; 492 } 493 boolean verifyMatchRequest = (requestBuilder != null); 494 for (CaptureResult.Key<?> key : allKeys) { 495 if (!skippedKeys.contains(key)) { 496 /** 497 * Check the critical tags here. 498 * TODO: Can use the same key for request and result when request/result 499 * becomes symmetric (b/14059883). Then below check can be wrapped into 500 * a generic function. 501 */ 502 String msg = failMsg + cameraIdString + "for key " + key.getName(); 503 if (verifyMatchRequest) { 504 if (key.equals(CaptureResult.CONTROL_AE_MODE)) { 505 errorCollector.expectEquals(msg, 506 requestBuilder.get(CaptureRequest.CONTROL_AE_MODE), 507 result.get(CaptureResult.CONTROL_AE_MODE)); 508 } else if (key.equals(CaptureResult.CONTROL_AF_MODE)) { 509 errorCollector.expectEquals(msg, 510 requestBuilder.get(CaptureRequest.CONTROL_AF_MODE), 511 result.get(CaptureResult.CONTROL_AF_MODE)); 512 } else if (key.equals(CaptureResult.CONTROL_AWB_MODE)) { 513 errorCollector.expectEquals(msg, 514 requestBuilder.get(CaptureRequest.CONTROL_AWB_MODE), 515 result.get(CaptureResult.CONTROL_AWB_MODE)); 516 } else if (key.equals(CaptureResult.CONTROL_MODE)) { 517 errorCollector.expectEquals(msg, 518 requestBuilder.get(CaptureRequest.CONTROL_MODE), 519 result.get(CaptureResult.CONTROL_MODE)); 520 } else if (key.equals(CaptureResult.STATISTICS_FACE_DETECT_MODE)) { 521 errorCollector.expectEquals(msg, 522 requestBuilder.get(CaptureRequest.STATISTICS_FACE_DETECT_MODE), 523 result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE)); 524 } else if (key.equals(CaptureResult.NOISE_REDUCTION_MODE)) { 525 errorCollector.expectEquals(msg, 526 requestBuilder.get(CaptureRequest.NOISE_REDUCTION_MODE), 527 result.get(CaptureResult.NOISE_REDUCTION_MODE)); 528 } else if (key.equals(CaptureResult.NOISE_REDUCTION_MODE)) { 529 errorCollector.expectEquals(msg, 530 requestBuilder.get(CaptureRequest.NOISE_REDUCTION_MODE), 531 result.get(CaptureResult.NOISE_REDUCTION_MODE)); 532 } else if (key.equals(CaptureResult.REQUEST_PIPELINE_DEPTH)) { 533 534 } else if (key.equals(CaptureResult.STATISTICS_OIS_DATA_MODE)) { 535 errorCollector.expectEquals(msg, 536 requestBuilder.get(CaptureRequest.STATISTICS_OIS_DATA_MODE), 537 result.get(CaptureResult.STATISTICS_OIS_DATA_MODE)); 538 } else if (key.equals(CaptureResult.DISTORTION_CORRECTION_MODE)) { 539 errorCollector.expectEquals(msg, 540 requestBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE), 541 result.get(CaptureResult.DISTORTION_CORRECTION_MODE)); 542 } else if (key.equals(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL)) { 543 float[] blackLevel = errorCollector.expectKeyValueNotNull( 544 result, CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL); 545 if (blackLevel != null && staticInfo.isMonochromeCamera()) { 546 errorCollector.expectEquals( 547 "Monochrome camera dynamic blacklevel must be 2x2", 548 blackLevel.length, 4); 549 for (int index = 1; index < blackLevel.length; index++) { 550 errorCollector.expectEquals( 551 "Monochrome camera 2x2 channels blacklevel value must be the same.", 552 blackLevel[index], blackLevel[0]); 553 } 554 } 555 } else { 556 // Only do non-null check for the rest of keys. 557 errorCollector.expectKeyValueNotNull(failMsg, result, key); 558 } 559 } else { 560 // Only do non-null check for the rest of keys. 561 errorCollector.expectKeyValueNotNull(failMsg, result, key); 562 } 563 } else { 564 // These keys should always be null 565 if (key.equals(CaptureResult.CONTROL_AE_REGIONS)) { 566 errorCollector.expectNull( 567 "Capture result contains AE regions but aeMaxRegions is 0" 568 + cameraIdString, 569 result.get(CaptureResult.CONTROL_AE_REGIONS)); 570 } else if (key.equals(CaptureResult.CONTROL_AWB_REGIONS)) { 571 errorCollector.expectNull( 572 "Capture result contains AWB regions but awbMaxRegions is 0" 573 + cameraIdString, 574 result.get(CaptureResult.CONTROL_AWB_REGIONS)); 575 } else if (key.equals(CaptureResult.CONTROL_AF_REGIONS)) { 576 errorCollector.expectNull( 577 "Capture result contains AF regions but afMaxRegions is 0" 578 + cameraIdString, 579 result.get(CaptureResult.CONTROL_AF_REGIONS)); 580 } 581 } 582 } 583 } 584 585 /* 586 * Add waiver keys per camera device hardware level and capability. 587 * 588 * Must be called after camera device is opened. 589 */ getWaiverKeysForCamera(StaticMetadata staticInfo)590 private static List<CaptureResult.Key<?>> getWaiverKeysForCamera(StaticMetadata staticInfo) { 591 List<CaptureResult.Key<?>> waiverKeys = new ArrayList<>(); 592 593 // Global waiver keys 594 waiverKeys.add(CaptureResult.JPEG_GPS_LOCATION); 595 waiverKeys.add(CaptureResult.JPEG_ORIENTATION); 596 waiverKeys.add(CaptureResult.JPEG_QUALITY); 597 waiverKeys.add(CaptureResult.JPEG_THUMBNAIL_QUALITY); 598 waiverKeys.add(CaptureResult.JPEG_THUMBNAIL_SIZE); 599 600 if (!staticInfo.isUltraHighResolutionSensor()) { 601 waiverKeys.add(CaptureResult.SENSOR_PIXEL_MODE); 602 waiverKeys.add(CaptureResult.SENSOR_RAW_BINNING_FACTOR_USED); 603 } 604 605 // Keys only present when corresponding control is on are being 606 // verified in its own functional test 607 // Only present in certain tonemap mode. Test in CaptureRequestTest. 608 waiverKeys.add(CaptureResult.TONEMAP_CURVE); 609 waiverKeys.add(CaptureResult.TONEMAP_GAMMA); 610 waiverKeys.add(CaptureResult.TONEMAP_PRESET_CURVE); 611 // Only present when test pattern mode is SOLID_COLOR. 612 // TODO: verify this key in test pattern test later 613 waiverKeys.add(CaptureResult.SENSOR_TEST_PATTERN_DATA); 614 // Only present when STATISTICS_LENS_SHADING_MAP_MODE is ON 615 waiverKeys.add(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP); 616 // Only present when STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES is ON 617 waiverKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP); 618 // Only present when face detection is on 619 waiverKeys.add(CaptureResult.STATISTICS_FACES); 620 // Only present in reprocessing capture result. 621 waiverKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR); 622 623 // LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID not required if key is not supported. 624 if (!staticInfo.isLogicalMultiCamera() || 625 !staticInfo.isActivePhysicalCameraIdSupported()) { 626 waiverKeys.add(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID); 627 } 628 629 //Keys not required if RAW is not supported 630 if (!staticInfo.isCapabilitySupported( 631 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) { 632 waiverKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT); 633 waiverKeys.add(CaptureResult.SENSOR_GREEN_SPLIT); 634 waiverKeys.add(CaptureResult.SENSOR_NOISE_PROFILE); 635 } else if (staticInfo.isMonochromeCamera()) { 636 waiverKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT); 637 waiverKeys.add(CaptureResult.SENSOR_GREEN_SPLIT); 638 } 639 640 boolean calibrationReported = staticInfo.areKeysAvailable( 641 CameraCharacteristics.LENS_POSE_ROTATION, 642 CameraCharacteristics.LENS_POSE_TRANSLATION, 643 CameraCharacteristics.LENS_INTRINSIC_CALIBRATION); 644 645 // If any of distortion coefficients is reported in CameraCharacteristics, HAL must 646 // also report (one of) them in CaptureResult 647 boolean distortionReported = 648 staticInfo.areKeysAvailable( 649 CameraCharacteristics.LENS_RADIAL_DISTORTION) || 650 staticInfo.areKeysAvailable( 651 CameraCharacteristics.LENS_DISTORTION); 652 653 //Keys for lens distortion correction 654 boolean distortionCorrectionSupported = staticInfo.isDistortionCorrectionSupported(); 655 if (!distortionCorrectionSupported) { 656 waiverKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE); 657 } 658 659 boolean mustReportDistortion = true; 660 // These keys must present on either DEPTH or distortion correction devices 661 if (!staticInfo.isCapabilitySupported( 662 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) && 663 !distortionCorrectionSupported && 664 !distortionReported) { 665 mustReportDistortion = false; 666 waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION); 667 waiverKeys.add(CaptureResult.LENS_DISTORTION); 668 } else { 669 // Radial distortion doesn't need to be present for new devices, or old devices that 670 // opt in the new lens distortion tag. 671 CameraCharacteristics c = staticInfo.getCharacteristics(); 672 if (Build.VERSION.DEVICE_INITIAL_SDK_INT > Build.VERSION_CODES.O_MR1 || 673 c.get(CameraCharacteristics.LENS_DISTORTION) != null) { 674 waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION); 675 } 676 } 677 678 // Calibration keys must exist for 679 // - DEPTH capable devices 680 // - Devices that reports calibration keys in static metadata 681 // - Devices that reports lens distortion keys in static metadata 682 if (!staticInfo.isCapabilitySupported( 683 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) && 684 !calibrationReported && !mustReportDistortion) { 685 waiverKeys.add(CaptureResult.LENS_POSE_ROTATION); 686 waiverKeys.add(CaptureResult.LENS_POSE_TRANSLATION); 687 waiverKeys.add(CaptureResult.LENS_INTRINSIC_CALIBRATION); 688 } 689 690 // Waived if RAW output is not supported 691 int[] outputFormats = staticInfo.getAvailableFormats( 692 StaticMetadata.StreamDirection.Output); 693 boolean supportRaw = false; 694 for (int format : outputFormats) { 695 if (format == ImageFormat.RAW_SENSOR || format == ImageFormat.RAW10 || 696 format == ImageFormat.RAW12 || format == ImageFormat.RAW_PRIVATE) { 697 supportRaw = true; 698 break; 699 } 700 } 701 if (!supportRaw) { 702 waiverKeys.add(CaptureResult.CONTROL_POST_RAW_SENSITIVITY_BOOST); 703 } 704 705 // Waived if MONOCHROME capability 706 if (staticInfo.isMonochromeCamera()) { 707 waiverKeys.add(CaptureResult.COLOR_CORRECTION_MODE); 708 waiverKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM); 709 waiverKeys.add(CaptureResult.COLOR_CORRECTION_GAINS); 710 } 711 712 if (staticInfo.getAeMaxRegionsChecked() == 0) { 713 waiverKeys.add(CaptureResult.CONTROL_AE_REGIONS); 714 } 715 if (staticInfo.getAwbMaxRegionsChecked() == 0) { 716 waiverKeys.add(CaptureResult.CONTROL_AWB_REGIONS); 717 } 718 if (staticInfo.getAfMaxRegionsChecked() == 0) { 719 waiverKeys.add(CaptureResult.CONTROL_AF_REGIONS); 720 } 721 722 // Keys for dynamic black/white levels 723 if (!staticInfo.isOpticalBlackRegionSupported()) { 724 waiverKeys.add(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL); 725 waiverKeys.add(CaptureResult.SENSOR_DYNAMIC_WHITE_LEVEL); 726 } 727 728 if (!staticInfo.isEnableZslSupported()) { 729 waiverKeys.add(CaptureResult.CONTROL_ENABLE_ZSL); 730 } 731 732 if (!staticInfo.isAfSceneChangeSupported()) { 733 waiverKeys.add(CaptureResult.CONTROL_AF_SCENE_CHANGE); 734 } 735 736 if (!staticInfo.isOisDataModeSupported()) { 737 waiverKeys.add(CaptureResult.STATISTICS_OIS_DATA_MODE); 738 waiverKeys.add(CaptureResult.STATISTICS_OIS_SAMPLES); 739 } 740 741 if (staticInfo.getAvailableExtendedSceneModeCapsChecked().length == 0) { 742 waiverKeys.add(CaptureResult.CONTROL_EXTENDED_SCENE_MODE); 743 } 744 745 if (!staticInfo.isRotateAndCropSupported()) { 746 waiverKeys.add(CaptureResult.SCALER_ROTATE_AND_CROP); 747 } 748 749 if (staticInfo.isHardwareLevelAtLeastFull()) { 750 return waiverKeys; 751 } 752 753 /* 754 * Hardware Level = LIMITED or LEGACY 755 */ 756 // Key not present if certain control is not supported 757 if (!staticInfo.isColorCorrectionSupported()) { 758 waiverKeys.add(CaptureResult.COLOR_CORRECTION_GAINS); 759 waiverKeys.add(CaptureResult.COLOR_CORRECTION_MODE); 760 waiverKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM); 761 } 762 763 if (!staticInfo.isManualColorAberrationControlSupported()) { 764 waiverKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE); 765 } 766 767 if (!staticInfo.isManualToneMapSupported()) { 768 waiverKeys.add(CaptureResult.TONEMAP_MODE); 769 } 770 771 if (!staticInfo.isEdgeModeControlSupported()) { 772 waiverKeys.add(CaptureResult.EDGE_MODE); 773 } 774 775 if (!staticInfo.isHotPixelMapModeControlSupported()) { 776 waiverKeys.add(CaptureResult.HOT_PIXEL_MODE); 777 } 778 779 if (!staticInfo.isNoiseReductionModeControlSupported()) { 780 waiverKeys.add(CaptureResult.NOISE_REDUCTION_MODE); 781 } 782 783 if (!staticInfo.isManualLensShadingMapSupported()) { 784 waiverKeys.add(CaptureResult.SHADING_MODE); 785 } 786 787 //Keys not required if neither MANUAL_SENSOR nor READ_SENSOR_SETTINGS is supported 788 if (!staticInfo.isCapabilitySupported( 789 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR) && 790 !staticInfo.isCapabilitySupported( 791 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS)) { 792 waiverKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME); 793 waiverKeys.add(CaptureResult.SENSOR_SENSITIVITY); 794 waiverKeys.add(CaptureResult.LENS_FOCUS_DISTANCE); 795 waiverKeys.add(CaptureResult.LENS_APERTURE); 796 } 797 798 if (!staticInfo.isCapabilitySupported( 799 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) { 800 waiverKeys.add(CaptureResult.SENSOR_FRAME_DURATION); 801 waiverKeys.add(CaptureResult.BLACK_LEVEL_LOCK); 802 waiverKeys.add(CaptureResult.LENS_FOCUS_RANGE); 803 waiverKeys.add(CaptureResult.LENS_STATE); 804 waiverKeys.add(CaptureResult.LENS_FILTER_DENSITY); 805 } 806 807 if (staticInfo.isHardwareLevelLimited() && staticInfo.isColorOutputSupported()) { 808 return waiverKeys; 809 } 810 811 /* 812 * Hardware Level = EXTERNAL 813 */ 814 if (staticInfo.isExternalCamera()) { 815 waiverKeys.add(CaptureResult.LENS_FOCAL_LENGTH); 816 waiverKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE); 817 waiverKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW); 818 } 819 820 if (staticInfo.isExternalCamera() && staticInfo.isColorOutputSupported()) { 821 return waiverKeys; 822 } 823 824 /* 825 * Hardware Level = LEGACY or no regular output is supported 826 */ 827 waiverKeys.add(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER); 828 waiverKeys.add(CaptureResult.CONTROL_AE_STATE); 829 waiverKeys.add(CaptureResult.CONTROL_AWB_STATE); 830 waiverKeys.add(CaptureResult.FLASH_STATE); 831 waiverKeys.add(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE); 832 waiverKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW); 833 waiverKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP_MODE); 834 waiverKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER); 835 waiverKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE); 836 waiverKeys.add(CaptureResult.CONTROL_AE_TARGET_FPS_RANGE); 837 waiverKeys.add(CaptureResult.CONTROL_AF_TRIGGER); 838 839 if (staticInfo.isHardwareLevelLegacy()) { 840 return waiverKeys; 841 } 842 843 /* 844 * Regular output not supported, only depth, waive color-output-related keys 845 */ 846 waiverKeys.add(CaptureResult.CONTROL_SCENE_MODE); 847 waiverKeys.add(CaptureResult.CONTROL_EFFECT_MODE); 848 waiverKeys.add(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE); 849 waiverKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE); 850 waiverKeys.add(CaptureResult.NOISE_REDUCTION_MODE); 851 waiverKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE); 852 waiverKeys.add(CaptureResult.CONTROL_AE_ANTIBANDING_MODE); 853 waiverKeys.add(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION); 854 waiverKeys.add(CaptureResult.CONTROL_AE_LOCK); 855 waiverKeys.add(CaptureResult.CONTROL_AE_MODE); 856 waiverKeys.add(CaptureResult.CONTROL_AF_MODE); 857 waiverKeys.add(CaptureResult.CONTROL_AWB_MODE); 858 waiverKeys.add(CaptureResult.CONTROL_AWB_LOCK); 859 waiverKeys.add(CaptureResult.CONTROL_ZOOM_RATIO); 860 waiverKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE); 861 waiverKeys.add(CaptureResult.FLASH_MODE); 862 waiverKeys.add(CaptureResult.SCALER_CROP_REGION); 863 waiverKeys.add(CaptureResult.SCALER_ROTATE_AND_CROP); 864 865 return waiverKeys; 866 } 867 868 /** 869 * A capture listener implementation for collecting both partial and total results. 870 * 871 * <p> This is not a full-blown class and has some implicit assumptions. The class groups 872 * capture results by capture request, so the user must guarantee each request this listener 873 * is listening is unique. This class is not thread safe, so don't attach an instance object 874 * with multiple handlers.</p> 875 * */ 876 private static class TotalAndPartialResultListener 877 extends CameraCaptureSession.CaptureCallback { 878 static final int ERROR_DUPLICATED_REQUEST = 1 << 0; 879 static final int ERROR_WRONG_CALLBACK_ORDER = 1 << 1; 880 881 private final LinkedBlockingQueue<Pair<TotalCaptureResult, List<CaptureResult>> > mQueue = 882 new LinkedBlockingQueue<>(); 883 private final HashMap<CaptureRequest, List<CaptureResult>> mPartialResultsMap = 884 new HashMap<CaptureRequest, List<CaptureResult>>(); 885 private final HashSet<CaptureRequest> completedRequests = new HashSet<>(); 886 private int errorCode = 0; 887 888 @Override onCaptureStarted( CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber)889 public void onCaptureStarted( 890 CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) 891 { 892 checkCallbackOrder(request); 893 createMapEntryIfNecessary(request); 894 } 895 896 @Override onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result)897 public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, 898 TotalCaptureResult result) { 899 try { 900 List<CaptureResult> partialResultsList = mPartialResultsMap.get(request); 901 if (partialResultsList == null) { 902 Log.w(TAG, "onCaptureCompleted: unknown request"); 903 } 904 mQueue.put(new Pair<TotalCaptureResult, List<CaptureResult>>( 905 result, partialResultsList)); 906 mPartialResultsMap.remove(request); 907 boolean newEntryAdded = completedRequests.add(request); 908 if (!newEntryAdded) { 909 Integer frame = (Integer) request.getTag(); 910 Log.e(TAG, "Frame " + frame + "ERROR_DUPLICATED_REQUEST"); 911 errorCode |= ERROR_DUPLICATED_REQUEST; 912 } 913 } catch (InterruptedException e) { 914 throw new UnsupportedOperationException( 915 "Can't handle InterruptedException in onCaptureCompleted"); 916 } 917 } 918 919 @Override onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult)920 public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, 921 CaptureResult partialResult) { 922 createMapEntryIfNecessary(request); 923 List<CaptureResult> partialResultsList = mPartialResultsMap.get(request); 924 partialResultsList.add(partialResult); 925 } 926 createMapEntryIfNecessary(CaptureRequest request)927 private void createMapEntryIfNecessary(CaptureRequest request) { 928 if (!mPartialResultsMap.containsKey(request)) { 929 // create a new entry in the map 930 mPartialResultsMap.put(request, new ArrayList<CaptureResult>()); 931 } 932 } 933 checkCallbackOrder(CaptureRequest request)934 private void checkCallbackOrder(CaptureRequest request) { 935 if (completedRequests.contains(request)) { 936 Integer frame = (Integer) request.getTag(); 937 Log.e(TAG, "Frame " + frame + "ERROR_WRONG_CALLBACK_ORDER"); 938 errorCode |= ERROR_WRONG_CALLBACK_ORDER; 939 } 940 } 941 getCaptureResultPairs(long timeout)942 public Pair<TotalCaptureResult, List<CaptureResult>> getCaptureResultPairs(long timeout) { 943 try { 944 Pair<TotalCaptureResult, List<CaptureResult>> result = 945 mQueue.poll(timeout, TimeUnit.MILLISECONDS); 946 assertNotNull("Wait for a capture result timed out in " + timeout + "ms", result); 947 return result; 948 } catch (InterruptedException e) { 949 throw new UnsupportedOperationException("Unhandled interrupted exception", e); 950 } 951 } 952 getErrorCode()953 public int getErrorCode() { 954 return errorCode; 955 } 956 } 957 958 // Returns true if `result` has timestamp `sensorTimestamp` when queried from the NDK via 959 // ACameraMetadata_fromCameraMetadata(). validateACameraMetadataFromCameraMetadataCriticalTagsNative( CaptureResult result, long sensorTimestamp)960 private static native boolean validateACameraMetadataFromCameraMetadataCriticalTagsNative( 961 CaptureResult result, long sensorTimestamp); 962 963 // First stash a native ACameraMetadata created from a capture result, then compare the stored value 964 // to the passed-in timestamp. stashACameraMetadataFromCameraMetadataNative(CaptureResult result)965 private static native boolean stashACameraMetadataFromCameraMetadataNative(CaptureResult result); validateStashedACameraMetadataFromCameraMetadataNative(long timestamp)966 private static native boolean validateStashedACameraMetadataFromCameraMetadataNative(long timestamp); 967 968 /** 969 * TODO: Use CameraCharacteristics.getAvailableCaptureResultKeys() once we can filter out 970 * @hide keys. 971 * 972 */ 973 974 /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ 975 * The key entries below this point are generated from metadata 976 * definitions in /system/media/camera/docs. Do not modify by hand or 977 * modify the comment blocks at the start or end. 978 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/ 979 getAllCaptureResultKeys()980 private static List<CaptureResult.Key<?>> getAllCaptureResultKeys() { 981 ArrayList<CaptureResult.Key<?>> resultKeys = new ArrayList<CaptureResult.Key<?>>(); 982 resultKeys.add(CaptureResult.COLOR_CORRECTION_MODE); 983 resultKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM); 984 resultKeys.add(CaptureResult.COLOR_CORRECTION_GAINS); 985 resultKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE); 986 resultKeys.add(CaptureResult.CONTROL_AE_ANTIBANDING_MODE); 987 resultKeys.add(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION); 988 resultKeys.add(CaptureResult.CONTROL_AE_LOCK); 989 resultKeys.add(CaptureResult.CONTROL_AE_MODE); 990 resultKeys.add(CaptureResult.CONTROL_AE_REGIONS); 991 resultKeys.add(CaptureResult.CONTROL_AE_TARGET_FPS_RANGE); 992 resultKeys.add(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER); 993 resultKeys.add(CaptureResult.CONTROL_AF_MODE); 994 resultKeys.add(CaptureResult.CONTROL_AF_REGIONS); 995 resultKeys.add(CaptureResult.CONTROL_AF_TRIGGER); 996 resultKeys.add(CaptureResult.CONTROL_AWB_LOCK); 997 resultKeys.add(CaptureResult.CONTROL_AWB_MODE); 998 resultKeys.add(CaptureResult.CONTROL_AWB_REGIONS); 999 resultKeys.add(CaptureResult.CONTROL_CAPTURE_INTENT); 1000 resultKeys.add(CaptureResult.CONTROL_EFFECT_MODE); 1001 resultKeys.add(CaptureResult.CONTROL_MODE); 1002 resultKeys.add(CaptureResult.CONTROL_SCENE_MODE); 1003 resultKeys.add(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE); 1004 resultKeys.add(CaptureResult.CONTROL_AE_STATE); 1005 resultKeys.add(CaptureResult.CONTROL_AF_STATE); 1006 resultKeys.add(CaptureResult.CONTROL_AWB_STATE); 1007 resultKeys.add(CaptureResult.CONTROL_POST_RAW_SENSITIVITY_BOOST); 1008 resultKeys.add(CaptureResult.CONTROL_ENABLE_ZSL); 1009 resultKeys.add(CaptureResult.CONTROL_AF_SCENE_CHANGE); 1010 resultKeys.add(CaptureResult.CONTROL_EXTENDED_SCENE_MODE); 1011 resultKeys.add(CaptureResult.CONTROL_ZOOM_RATIO); 1012 resultKeys.add(CaptureResult.EDGE_MODE); 1013 resultKeys.add(CaptureResult.FLASH_MODE); 1014 resultKeys.add(CaptureResult.FLASH_STATE); 1015 resultKeys.add(CaptureResult.HOT_PIXEL_MODE); 1016 resultKeys.add(CaptureResult.JPEG_GPS_LOCATION); 1017 resultKeys.add(CaptureResult.JPEG_ORIENTATION); 1018 resultKeys.add(CaptureResult.JPEG_QUALITY); 1019 resultKeys.add(CaptureResult.JPEG_THUMBNAIL_QUALITY); 1020 resultKeys.add(CaptureResult.JPEG_THUMBNAIL_SIZE); 1021 resultKeys.add(CaptureResult.LENS_APERTURE); 1022 resultKeys.add(CaptureResult.LENS_FILTER_DENSITY); 1023 resultKeys.add(CaptureResult.LENS_FOCAL_LENGTH); 1024 resultKeys.add(CaptureResult.LENS_FOCUS_DISTANCE); 1025 resultKeys.add(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE); 1026 resultKeys.add(CaptureResult.LENS_POSE_ROTATION); 1027 resultKeys.add(CaptureResult.LENS_POSE_TRANSLATION); 1028 resultKeys.add(CaptureResult.LENS_FOCUS_RANGE); 1029 resultKeys.add(CaptureResult.LENS_STATE); 1030 resultKeys.add(CaptureResult.LENS_INTRINSIC_CALIBRATION); 1031 resultKeys.add(CaptureResult.LENS_RADIAL_DISTORTION); 1032 resultKeys.add(CaptureResult.LENS_DISTORTION); 1033 resultKeys.add(CaptureResult.NOISE_REDUCTION_MODE); 1034 resultKeys.add(CaptureResult.REQUEST_PIPELINE_DEPTH); 1035 resultKeys.add(CaptureResult.SCALER_CROP_REGION); 1036 resultKeys.add(CaptureResult.SCALER_ROTATE_AND_CROP); 1037 resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME); 1038 resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION); 1039 resultKeys.add(CaptureResult.SENSOR_SENSITIVITY); 1040 resultKeys.add(CaptureResult.SENSOR_TIMESTAMP); 1041 resultKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT); 1042 resultKeys.add(CaptureResult.SENSOR_NOISE_PROFILE); 1043 resultKeys.add(CaptureResult.SENSOR_GREEN_SPLIT); 1044 resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_DATA); 1045 resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE); 1046 resultKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW); 1047 resultKeys.add(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL); 1048 resultKeys.add(CaptureResult.SENSOR_DYNAMIC_WHITE_LEVEL); 1049 resultKeys.add(CaptureResult.SENSOR_PIXEL_MODE); 1050 resultKeys.add(CaptureResult.SENSOR_RAW_BINNING_FACTOR_USED); 1051 resultKeys.add(CaptureResult.SHADING_MODE); 1052 resultKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE); 1053 resultKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE); 1054 resultKeys.add(CaptureResult.STATISTICS_FACES); 1055 resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP); 1056 resultKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER); 1057 resultKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP); 1058 resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP_MODE); 1059 resultKeys.add(CaptureResult.STATISTICS_OIS_DATA_MODE); 1060 resultKeys.add(CaptureResult.STATISTICS_OIS_SAMPLES); 1061 resultKeys.add(CaptureResult.TONEMAP_CURVE); 1062 resultKeys.add(CaptureResult.TONEMAP_MODE); 1063 resultKeys.add(CaptureResult.TONEMAP_GAMMA); 1064 resultKeys.add(CaptureResult.TONEMAP_PRESET_CURVE); 1065 resultKeys.add(CaptureResult.BLACK_LEVEL_LOCK); 1066 resultKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR); 1067 resultKeys.add(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID); 1068 resultKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE); 1069 1070 return resultKeys; 1071 } 1072 1073 /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ 1074 * End generated code 1075 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/ 1076 } 1077