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 // Tested in RobustnessTest.java stream use case test. 608 waiverKeys.add(CaptureResult.SCALER_RAW_CROP_REGION); 609 // Only present in certain tonemap mode. Test in CaptureRequestTest. 610 waiverKeys.add(CaptureResult.TONEMAP_CURVE); 611 waiverKeys.add(CaptureResult.TONEMAP_GAMMA); 612 waiverKeys.add(CaptureResult.TONEMAP_PRESET_CURVE); 613 // Only present when test pattern mode is SOLID_COLOR. 614 // TODO: verify this key in test pattern test later 615 waiverKeys.add(CaptureResult.SENSOR_TEST_PATTERN_DATA); 616 // Only present when STATISTICS_LENS_SHADING_MAP_MODE is ON 617 waiverKeys.add(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP); 618 // Only present when STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES is ON 619 waiverKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP); 620 // Only present when face detection is on 621 waiverKeys.add(CaptureResult.STATISTICS_FACES); 622 // Only present in reprocessing capture result. 623 waiverKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR); 624 625 // LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID not required if key is not supported. 626 if (!staticInfo.isLogicalMultiCamera() || 627 !staticInfo.isActivePhysicalCameraIdSupported()) { 628 waiverKeys.add(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID); 629 } 630 631 //Keys not required if RAW is not supported 632 if (!staticInfo.isCapabilitySupported( 633 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) { 634 waiverKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT); 635 waiverKeys.add(CaptureResult.SENSOR_GREEN_SPLIT); 636 waiverKeys.add(CaptureResult.SENSOR_NOISE_PROFILE); 637 } else if (staticInfo.isMonochromeCamera()) { 638 waiverKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT); 639 waiverKeys.add(CaptureResult.SENSOR_GREEN_SPLIT); 640 } 641 642 boolean calibrationReported = staticInfo.areKeysAvailable( 643 CameraCharacteristics.LENS_POSE_ROTATION, 644 CameraCharacteristics.LENS_POSE_TRANSLATION, 645 CameraCharacteristics.LENS_INTRINSIC_CALIBRATION); 646 647 // If any of distortion coefficients is reported in CameraCharacteristics, HAL must 648 // also report (one of) them in CaptureResult 649 boolean distortionReported = 650 staticInfo.areKeysAvailable( 651 CameraCharacteristics.LENS_RADIAL_DISTORTION) || 652 staticInfo.areKeysAvailable( 653 CameraCharacteristics.LENS_DISTORTION); 654 655 //Keys for lens distortion correction 656 boolean distortionCorrectionSupported = staticInfo.isDistortionCorrectionSupported(); 657 if (!distortionCorrectionSupported) { 658 waiverKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE); 659 } 660 661 boolean mustReportDistortion = true; 662 // These keys must present on either DEPTH or distortion correction devices 663 if (!staticInfo.isCapabilitySupported( 664 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) && 665 !distortionCorrectionSupported && 666 !distortionReported) { 667 mustReportDistortion = false; 668 waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION); 669 waiverKeys.add(CaptureResult.LENS_DISTORTION); 670 } else { 671 // Radial distortion doesn't need to be present for new devices, or old devices that 672 // opt in the new lens distortion tag. 673 CameraCharacteristics c = staticInfo.getCharacteristics(); 674 if (Build.VERSION.DEVICE_INITIAL_SDK_INT > Build.VERSION_CODES.O_MR1 || 675 c.get(CameraCharacteristics.LENS_DISTORTION) != null) { 676 waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION); 677 } 678 } 679 680 // Calibration keys must exist for 681 // - DEPTH capable devices 682 // - Devices that reports calibration keys in static metadata 683 // - Devices that reports lens distortion keys in static metadata 684 if (!staticInfo.isCapabilitySupported( 685 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) && 686 !calibrationReported && !mustReportDistortion) { 687 waiverKeys.add(CaptureResult.LENS_POSE_ROTATION); 688 waiverKeys.add(CaptureResult.LENS_POSE_TRANSLATION); 689 waiverKeys.add(CaptureResult.LENS_INTRINSIC_CALIBRATION); 690 } 691 692 // Waived if RAW output is not supported 693 int[] outputFormats = staticInfo.getAvailableFormats( 694 StaticMetadata.StreamDirection.Output); 695 boolean supportRaw = false; 696 for (int format : outputFormats) { 697 if (format == ImageFormat.RAW_SENSOR || format == ImageFormat.RAW10 || 698 format == ImageFormat.RAW12 || format == ImageFormat.RAW_PRIVATE) { 699 supportRaw = true; 700 break; 701 } 702 } 703 if (!supportRaw) { 704 waiverKeys.add(CaptureResult.CONTROL_POST_RAW_SENSITIVITY_BOOST); 705 } 706 707 // Waived if MONOCHROME capability 708 if (staticInfo.isMonochromeCamera()) { 709 waiverKeys.add(CaptureResult.COLOR_CORRECTION_MODE); 710 waiverKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM); 711 waiverKeys.add(CaptureResult.COLOR_CORRECTION_GAINS); 712 } 713 714 if (staticInfo.getAeMaxRegionsChecked() == 0) { 715 waiverKeys.add(CaptureResult.CONTROL_AE_REGIONS); 716 } 717 if (staticInfo.getAwbMaxRegionsChecked() == 0) { 718 waiverKeys.add(CaptureResult.CONTROL_AWB_REGIONS); 719 } 720 if (staticInfo.getAfMaxRegionsChecked() == 0) { 721 waiverKeys.add(CaptureResult.CONTROL_AF_REGIONS); 722 } 723 724 // Keys for dynamic black/white levels 725 if (!staticInfo.isOpticalBlackRegionSupported()) { 726 waiverKeys.add(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL); 727 waiverKeys.add(CaptureResult.SENSOR_DYNAMIC_WHITE_LEVEL); 728 } 729 730 if (!staticInfo.isEnableZslSupported()) { 731 waiverKeys.add(CaptureResult.CONTROL_ENABLE_ZSL); 732 } 733 734 if (!staticInfo.isAfSceneChangeSupported()) { 735 waiverKeys.add(CaptureResult.CONTROL_AF_SCENE_CHANGE); 736 } 737 738 if (!staticInfo.isOisDataModeSupported()) { 739 waiverKeys.add(CaptureResult.STATISTICS_OIS_DATA_MODE); 740 waiverKeys.add(CaptureResult.STATISTICS_OIS_SAMPLES); 741 } 742 743 if (staticInfo.getAvailableExtendedSceneModeCapsChecked().length == 0) { 744 waiverKeys.add(CaptureResult.CONTROL_EXTENDED_SCENE_MODE); 745 } 746 747 if (!staticInfo.isRotateAndCropSupported()) { 748 waiverKeys.add(CaptureResult.SCALER_ROTATE_AND_CROP); 749 } 750 751 if (!staticInfo.isSettingsOverrideSupported()) { 752 waiverKeys.add(CaptureResult.CONTROL_SETTINGS_OVERRIDE); 753 } 754 755 if (staticInfo.isHardwareLevelAtLeastFull()) { 756 return waiverKeys; 757 } 758 759 /* 760 * Hardware Level = LIMITED or LEGACY 761 */ 762 // Key not present if certain control is not supported 763 if (!staticInfo.isColorCorrectionSupported()) { 764 waiverKeys.add(CaptureResult.COLOR_CORRECTION_GAINS); 765 waiverKeys.add(CaptureResult.COLOR_CORRECTION_MODE); 766 waiverKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM); 767 } 768 769 if (!staticInfo.isManualColorAberrationControlSupported()) { 770 waiverKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE); 771 } 772 773 if (!staticInfo.isManualToneMapSupported()) { 774 waiverKeys.add(CaptureResult.TONEMAP_MODE); 775 } 776 777 if (!staticInfo.isEdgeModeControlSupported()) { 778 waiverKeys.add(CaptureResult.EDGE_MODE); 779 } 780 781 if (!staticInfo.isHotPixelMapModeControlSupported()) { 782 waiverKeys.add(CaptureResult.HOT_PIXEL_MODE); 783 } 784 785 if (!staticInfo.isNoiseReductionModeControlSupported()) { 786 waiverKeys.add(CaptureResult.NOISE_REDUCTION_MODE); 787 } 788 789 if (!staticInfo.isManualLensShadingMapSupported()) { 790 waiverKeys.add(CaptureResult.SHADING_MODE); 791 } 792 793 //Keys not required if neither MANUAL_SENSOR nor READ_SENSOR_SETTINGS is supported 794 if (!staticInfo.isCapabilitySupported( 795 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR) && 796 !staticInfo.isCapabilitySupported( 797 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS)) { 798 waiverKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME); 799 waiverKeys.add(CaptureResult.SENSOR_SENSITIVITY); 800 waiverKeys.add(CaptureResult.LENS_FOCUS_DISTANCE); 801 waiverKeys.add(CaptureResult.LENS_APERTURE); 802 } 803 804 if (!staticInfo.isCapabilitySupported( 805 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) { 806 waiverKeys.add(CaptureResult.SENSOR_FRAME_DURATION); 807 waiverKeys.add(CaptureResult.BLACK_LEVEL_LOCK); 808 waiverKeys.add(CaptureResult.LENS_FOCUS_RANGE); 809 waiverKeys.add(CaptureResult.LENS_STATE); 810 waiverKeys.add(CaptureResult.LENS_FILTER_DENSITY); 811 } 812 813 if (staticInfo.isHardwareLevelLimited() && staticInfo.isColorOutputSupported()) { 814 return waiverKeys; 815 } 816 817 /* 818 * Hardware Level = EXTERNAL 819 */ 820 if (staticInfo.isExternalCamera()) { 821 waiverKeys.add(CaptureResult.LENS_FOCAL_LENGTH); 822 waiverKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE); 823 waiverKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW); 824 } 825 826 if (staticInfo.isExternalCamera() && staticInfo.isColorOutputSupported()) { 827 return waiverKeys; 828 } 829 830 /* 831 * Hardware Level = LEGACY or no regular output is supported 832 */ 833 waiverKeys.add(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER); 834 waiverKeys.add(CaptureResult.CONTROL_AE_STATE); 835 waiverKeys.add(CaptureResult.CONTROL_AWB_STATE); 836 waiverKeys.add(CaptureResult.FLASH_STATE); 837 waiverKeys.add(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE); 838 waiverKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW); 839 waiverKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP_MODE); 840 waiverKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER); 841 waiverKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE); 842 waiverKeys.add(CaptureResult.CONTROL_AE_TARGET_FPS_RANGE); 843 waiverKeys.add(CaptureResult.CONTROL_AF_TRIGGER); 844 845 if (staticInfo.isHardwareLevelLegacy()) { 846 return waiverKeys; 847 } 848 849 /* 850 * Regular output not supported, only depth, waive color-output-related keys 851 */ 852 waiverKeys.add(CaptureResult.CONTROL_SCENE_MODE); 853 waiverKeys.add(CaptureResult.CONTROL_EFFECT_MODE); 854 waiverKeys.add(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE); 855 waiverKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE); 856 waiverKeys.add(CaptureResult.NOISE_REDUCTION_MODE); 857 waiverKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE); 858 waiverKeys.add(CaptureResult.CONTROL_AE_ANTIBANDING_MODE); 859 waiverKeys.add(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION); 860 waiverKeys.add(CaptureResult.CONTROL_AE_LOCK); 861 waiverKeys.add(CaptureResult.CONTROL_AE_MODE); 862 waiverKeys.add(CaptureResult.CONTROL_AF_MODE); 863 waiverKeys.add(CaptureResult.CONTROL_AWB_MODE); 864 waiverKeys.add(CaptureResult.CONTROL_AWB_LOCK); 865 waiverKeys.add(CaptureResult.CONTROL_ZOOM_RATIO); 866 waiverKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE); 867 waiverKeys.add(CaptureResult.FLASH_MODE); 868 waiverKeys.add(CaptureResult.SCALER_CROP_REGION); 869 waiverKeys.add(CaptureResult.SCALER_ROTATE_AND_CROP); 870 871 return waiverKeys; 872 } 873 874 /** 875 * A capture listener implementation for collecting both partial and total results. 876 * 877 * <p> This is not a full-blown class and has some implicit assumptions. The class groups 878 * capture results by capture request, so the user must guarantee each request this listener 879 * is listening is unique. This class is not thread safe, so don't attach an instance object 880 * with multiple handlers.</p> 881 * */ 882 private static class TotalAndPartialResultListener 883 extends CameraCaptureSession.CaptureCallback { 884 static final int ERROR_DUPLICATED_REQUEST = 1 << 0; 885 static final int ERROR_WRONG_CALLBACK_ORDER = 1 << 1; 886 887 private final LinkedBlockingQueue<Pair<TotalCaptureResult, List<CaptureResult>> > mQueue = 888 new LinkedBlockingQueue<>(); 889 private final HashMap<CaptureRequest, List<CaptureResult>> mPartialResultsMap = 890 new HashMap<CaptureRequest, List<CaptureResult>>(); 891 private final HashSet<CaptureRequest> completedRequests = new HashSet<>(); 892 private int errorCode = 0; 893 894 @Override onCaptureStarted( CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber)895 public void onCaptureStarted( 896 CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) 897 { 898 checkCallbackOrder(request); 899 createMapEntryIfNecessary(request); 900 } 901 902 @Override onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result)903 public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, 904 TotalCaptureResult result) { 905 try { 906 List<CaptureResult> partialResultsList = mPartialResultsMap.get(request); 907 if (partialResultsList == null) { 908 Log.w(TAG, "onCaptureCompleted: unknown request"); 909 } 910 mQueue.put(new Pair<TotalCaptureResult, List<CaptureResult>>( 911 result, partialResultsList)); 912 mPartialResultsMap.remove(request); 913 boolean newEntryAdded = completedRequests.add(request); 914 if (!newEntryAdded) { 915 Integer frame = (Integer) request.getTag(); 916 Log.e(TAG, "Frame " + frame + "ERROR_DUPLICATED_REQUEST"); 917 errorCode |= ERROR_DUPLICATED_REQUEST; 918 } 919 } catch (InterruptedException e) { 920 throw new UnsupportedOperationException( 921 "Can't handle InterruptedException in onCaptureCompleted"); 922 } 923 } 924 925 @Override onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult)926 public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, 927 CaptureResult partialResult) { 928 createMapEntryIfNecessary(request); 929 List<CaptureResult> partialResultsList = mPartialResultsMap.get(request); 930 partialResultsList.add(partialResult); 931 } 932 createMapEntryIfNecessary(CaptureRequest request)933 private void createMapEntryIfNecessary(CaptureRequest request) { 934 if (!mPartialResultsMap.containsKey(request)) { 935 // create a new entry in the map 936 mPartialResultsMap.put(request, new ArrayList<CaptureResult>()); 937 } 938 } 939 checkCallbackOrder(CaptureRequest request)940 private void checkCallbackOrder(CaptureRequest request) { 941 if (completedRequests.contains(request)) { 942 Integer frame = (Integer) request.getTag(); 943 Log.e(TAG, "Frame " + frame + "ERROR_WRONG_CALLBACK_ORDER"); 944 errorCode |= ERROR_WRONG_CALLBACK_ORDER; 945 } 946 } 947 getCaptureResultPairs(long timeout)948 public Pair<TotalCaptureResult, List<CaptureResult>> getCaptureResultPairs(long timeout) { 949 try { 950 Pair<TotalCaptureResult, List<CaptureResult>> result = 951 mQueue.poll(timeout, TimeUnit.MILLISECONDS); 952 assertNotNull("Wait for a capture result timed out in " + timeout + "ms", result); 953 return result; 954 } catch (InterruptedException e) { 955 throw new UnsupportedOperationException("Unhandled interrupted exception", e); 956 } 957 } 958 getErrorCode()959 public int getErrorCode() { 960 return errorCode; 961 } 962 } 963 964 // Returns true if `result` has timestamp `sensorTimestamp` when queried from the NDK via 965 // ACameraMetadata_fromCameraMetadata(). validateACameraMetadataFromCameraMetadataCriticalTagsNative( CaptureResult result, long sensorTimestamp)966 private static native boolean validateACameraMetadataFromCameraMetadataCriticalTagsNative( 967 CaptureResult result, long sensorTimestamp); 968 969 // First stash a native ACameraMetadata created from a capture result, then compare the stored value 970 // to the passed-in timestamp. stashACameraMetadataFromCameraMetadataNative(CaptureResult result)971 private static native boolean stashACameraMetadataFromCameraMetadataNative(CaptureResult result); validateStashedACameraMetadataFromCameraMetadataNative(long timestamp)972 private static native boolean validateStashedACameraMetadataFromCameraMetadataNative(long timestamp); 973 974 /** 975 * TODO: Use CameraCharacteristics.getAvailableCaptureResultKeys() once we can filter out 976 * @hide keys. 977 * 978 */ 979 980 /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ 981 * The key entries below this point are generated from metadata 982 * definitions in /system/media/camera/docs. Do not modify by hand or 983 * modify the comment blocks at the start or end. 984 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/ 985 getAllCaptureResultKeys()986 private static List<CaptureResult.Key<?>> getAllCaptureResultKeys() { 987 ArrayList<CaptureResult.Key<?>> resultKeys = new ArrayList<CaptureResult.Key<?>>(); 988 resultKeys.add(CaptureResult.COLOR_CORRECTION_MODE); 989 resultKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM); 990 resultKeys.add(CaptureResult.COLOR_CORRECTION_GAINS); 991 resultKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE); 992 resultKeys.add(CaptureResult.CONTROL_AE_ANTIBANDING_MODE); 993 resultKeys.add(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION); 994 resultKeys.add(CaptureResult.CONTROL_AE_LOCK); 995 resultKeys.add(CaptureResult.CONTROL_AE_MODE); 996 resultKeys.add(CaptureResult.CONTROL_AE_REGIONS); 997 resultKeys.add(CaptureResult.CONTROL_AE_TARGET_FPS_RANGE); 998 resultKeys.add(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER); 999 resultKeys.add(CaptureResult.CONTROL_AF_MODE); 1000 resultKeys.add(CaptureResult.CONTROL_AF_REGIONS); 1001 resultKeys.add(CaptureResult.CONTROL_AF_TRIGGER); 1002 resultKeys.add(CaptureResult.CONTROL_AWB_LOCK); 1003 resultKeys.add(CaptureResult.CONTROL_AWB_MODE); 1004 resultKeys.add(CaptureResult.CONTROL_AWB_REGIONS); 1005 resultKeys.add(CaptureResult.CONTROL_CAPTURE_INTENT); 1006 resultKeys.add(CaptureResult.CONTROL_EFFECT_MODE); 1007 resultKeys.add(CaptureResult.CONTROL_MODE); 1008 resultKeys.add(CaptureResult.CONTROL_SCENE_MODE); 1009 resultKeys.add(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE); 1010 resultKeys.add(CaptureResult.CONTROL_AE_STATE); 1011 resultKeys.add(CaptureResult.CONTROL_AF_STATE); 1012 resultKeys.add(CaptureResult.CONTROL_AWB_STATE); 1013 resultKeys.add(CaptureResult.CONTROL_POST_RAW_SENSITIVITY_BOOST); 1014 resultKeys.add(CaptureResult.CONTROL_ENABLE_ZSL); 1015 resultKeys.add(CaptureResult.CONTROL_AF_SCENE_CHANGE); 1016 resultKeys.add(CaptureResult.CONTROL_EXTENDED_SCENE_MODE); 1017 resultKeys.add(CaptureResult.CONTROL_ZOOM_RATIO); 1018 resultKeys.add(CaptureResult.CONTROL_SETTINGS_OVERRIDE); 1019 resultKeys.add(CaptureResult.CONTROL_AUTOFRAMING); 1020 resultKeys.add(CaptureResult.CONTROL_AUTOFRAMING_STATE); 1021 resultKeys.add(CaptureResult.EDGE_MODE); 1022 resultKeys.add(CaptureResult.FLASH_MODE); 1023 resultKeys.add(CaptureResult.FLASH_STATE); 1024 resultKeys.add(CaptureResult.HOT_PIXEL_MODE); 1025 resultKeys.add(CaptureResult.JPEG_GPS_LOCATION); 1026 resultKeys.add(CaptureResult.JPEG_ORIENTATION); 1027 resultKeys.add(CaptureResult.JPEG_QUALITY); 1028 resultKeys.add(CaptureResult.JPEG_THUMBNAIL_QUALITY); 1029 resultKeys.add(CaptureResult.JPEG_THUMBNAIL_SIZE); 1030 resultKeys.add(CaptureResult.LENS_APERTURE); 1031 resultKeys.add(CaptureResult.LENS_FILTER_DENSITY); 1032 resultKeys.add(CaptureResult.LENS_FOCAL_LENGTH); 1033 resultKeys.add(CaptureResult.LENS_FOCUS_DISTANCE); 1034 resultKeys.add(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE); 1035 resultKeys.add(CaptureResult.LENS_POSE_ROTATION); 1036 resultKeys.add(CaptureResult.LENS_POSE_TRANSLATION); 1037 resultKeys.add(CaptureResult.LENS_FOCUS_RANGE); 1038 resultKeys.add(CaptureResult.LENS_STATE); 1039 resultKeys.add(CaptureResult.LENS_INTRINSIC_CALIBRATION); 1040 resultKeys.add(CaptureResult.LENS_RADIAL_DISTORTION); 1041 resultKeys.add(CaptureResult.LENS_DISTORTION); 1042 resultKeys.add(CaptureResult.NOISE_REDUCTION_MODE); 1043 resultKeys.add(CaptureResult.REQUEST_PIPELINE_DEPTH); 1044 resultKeys.add(CaptureResult.SCALER_CROP_REGION); 1045 resultKeys.add(CaptureResult.SCALER_ROTATE_AND_CROP); 1046 resultKeys.add(CaptureResult.SCALER_RAW_CROP_REGION); 1047 resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME); 1048 resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION); 1049 resultKeys.add(CaptureResult.SENSOR_SENSITIVITY); 1050 resultKeys.add(CaptureResult.SENSOR_TIMESTAMP); 1051 resultKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT); 1052 resultKeys.add(CaptureResult.SENSOR_NOISE_PROFILE); 1053 resultKeys.add(CaptureResult.SENSOR_GREEN_SPLIT); 1054 resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_DATA); 1055 resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE); 1056 resultKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW); 1057 resultKeys.add(CaptureResult.SENSOR_DYNAMIC_BLACK_LEVEL); 1058 resultKeys.add(CaptureResult.SENSOR_DYNAMIC_WHITE_LEVEL); 1059 resultKeys.add(CaptureResult.SENSOR_PIXEL_MODE); 1060 resultKeys.add(CaptureResult.SENSOR_RAW_BINNING_FACTOR_USED); 1061 resultKeys.add(CaptureResult.SHADING_MODE); 1062 resultKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE); 1063 resultKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE); 1064 resultKeys.add(CaptureResult.STATISTICS_FACES); 1065 resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP); 1066 resultKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER); 1067 resultKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP); 1068 resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP_MODE); 1069 resultKeys.add(CaptureResult.STATISTICS_OIS_DATA_MODE); 1070 resultKeys.add(CaptureResult.STATISTICS_OIS_SAMPLES); 1071 resultKeys.add(CaptureResult.TONEMAP_CURVE); 1072 resultKeys.add(CaptureResult.TONEMAP_MODE); 1073 resultKeys.add(CaptureResult.TONEMAP_GAMMA); 1074 resultKeys.add(CaptureResult.TONEMAP_PRESET_CURVE); 1075 resultKeys.add(CaptureResult.BLACK_LEVEL_LOCK); 1076 resultKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR); 1077 resultKeys.add(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID); 1078 resultKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE); 1079 1080 return resultKeys; 1081 } 1082 1083 /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~ 1084 * End generated code 1085 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/ 1086 } 1087