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