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