1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.hardware.camera2.cts.testcases; 18 19 import static android.hardware.camera2.cts.CameraTestUtils.CAMERA_CLOSE_TIMEOUT_MS; 20 import static android.hardware.camera2.cts.CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS; 21 import static android.hardware.camera2.cts.CameraTestUtils.PREVIEW_SIZE_BOUND; 22 import static android.hardware.camera2.cts.CameraTestUtils.assertNotNull; 23 import static android.hardware.camera2.cts.CameraTestUtils.checkSessionConfigurationSupported; 24 import static android.hardware.camera2.cts.CameraTestUtils.fail; 25 import static android.hardware.camera2.cts.CameraTestUtils.getPreviewSizeBound; 26 import static android.hardware.camera2.cts.CameraTestUtils.getSupportedPreviewSizes; 27 import static android.hardware.camera2.cts.CameraTestUtils.getSupportedStillSizes; 28 import static android.hardware.camera2.cts.CameraTestUtils.getSupportedVideoSizes; 29 30 import static com.android.ex.camera2.blocking.BlockingStateCallback.STATE_CLOSED; 31 32 import android.content.Context; 33 import android.graphics.ColorSpace; 34 import android.graphics.Rect; 35 import android.hardware.camera2.CameraCaptureSession; 36 import android.hardware.camera2.CameraCaptureSession.CaptureCallback; 37 import android.hardware.camera2.CameraCharacteristics; 38 import android.hardware.camera2.CameraDevice; 39 import android.hardware.camera2.CaptureRequest; 40 import android.hardware.camera2.cts.Camera2ParameterizedTestCase; 41 import android.hardware.camera2.cts.CameraTestUtils; 42 import android.hardware.camera2.cts.helpers.CameraErrorCollector; 43 import android.hardware.camera2.cts.helpers.StaticMetadata; 44 import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel; 45 import android.hardware.camera2.params.InputConfiguration; 46 import android.hardware.camera2.params.OutputConfiguration; 47 import android.hardware.camera2.params.SessionConfiguration; 48 import android.media.Image; 49 import android.media.Image.Plane; 50 import android.media.ImageReader; 51 import android.os.Handler; 52 import android.os.HandlerThread; 53 import android.util.Log; 54 import android.util.Size; 55 import android.view.Surface; 56 import android.view.WindowManager; 57 58 import com.android.ex.camera2.blocking.BlockingSessionCallback; 59 import com.android.ex.camera2.blocking.BlockingStateCallback; 60 61 import java.io.File; 62 import java.nio.ByteBuffer; 63 import java.util.ArrayList; 64 import java.util.Arrays; 65 import java.util.HashMap; 66 import java.util.List; 67 68 // TODO: Can we de-duplicate this with Camera2AndroidBasicTestCase keeping in mind CtsVerifier ? 69 public class Camera2AndroidTestCase extends Camera2ParameterizedTestCase { 70 private static final String TAG = "Camera2AndroidTestCase"; 71 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); 72 73 // Default capture size: VGA size is required by CDD. 74 protected static final Size DEFAULT_CAPTURE_SIZE = new Size(640, 480); 75 protected static final int CAPTURE_WAIT_TIMEOUT_MS = 7000; 76 77 protected CameraDevice mCamera; 78 protected CameraCaptureSession mCameraSession; 79 protected BlockingSessionCallback mCameraSessionListener; 80 protected BlockingStateCallback mCameraListener; 81 // include both standalone camera IDs and "hidden" physical camera IDs 82 protected String[] mAllCameraIds; 83 protected HashMap<String, StaticMetadata> mAllStaticInfo; 84 protected ImageReader mReader; 85 protected Surface mReaderSurface; 86 protected Handler mHandler; 87 protected HandlerThread mHandlerThread; 88 protected StaticMetadata mStaticInfo; 89 protected CameraErrorCollector mCollector; 90 protected List<Size> mOrderedPreviewSizes; // In descending order. 91 protected List<Size> mOrderedVideoSizes; // In descending order. 92 protected List<Size> mOrderedStillSizes; // In descending order. 93 protected String mDebugFileNameBase; 94 95 protected WindowManager mWindowManager; 96 97 /** 98 * Set up the camera2 test case required environments, including CameraManager, 99 * HandlerThread, Camera IDs, and CameraStateCallback etc. 100 */ 101 @Override setUp()102 public void setUp() throws Exception { 103 setUp(false); 104 } 105 106 /** 107 * Set up the camera2 test case required environments, including CameraManager, 108 * HandlerThread, Camera IDs, and CameraStateCallback etc. 109 * @param useAll whether all camera ids are to be used for system camera tests 110 */ setUp(boolean useAll)111 public void setUp(boolean useAll) throws Exception { 112 super.setUp(useAll); 113 mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 114 115 mHandlerThread = new HandlerThread(TAG); 116 mHandlerThread.start(); 117 mHandler = new Handler(mHandlerThread.getLooper()); 118 mCameraListener = new BlockingStateCallback(); 119 mCollector = new CameraErrorCollector(); 120 121 File filesDir = mContext.getExternalFilesDir(null); 122 if (filesDir == null || mContext.getPackageManager().isInstantApp()) { 123 filesDir = mContext.getFilesDir(); 124 } 125 126 mDebugFileNameBase = filesDir.getPath(); 127 128 mAllStaticInfo = new HashMap<String, StaticMetadata>(); 129 List<String> hiddenPhysicalIds = new ArrayList<>(); 130 for (String cameraId : mCameraIdsUnderTest) { 131 CameraCharacteristics props = mCameraManager.getCameraCharacteristics(cameraId); 132 StaticMetadata staticMetadata = new StaticMetadata(props, 133 CheckLevel.ASSERT, /*collector*/null); 134 mAllStaticInfo.put(cameraId, staticMetadata); 135 136 for (String physicalId : props.getPhysicalCameraIds()) { 137 if (!Arrays.asList(mCameraIdsUnderTest).contains(physicalId) && 138 !hiddenPhysicalIds.contains(physicalId)) { 139 hiddenPhysicalIds.add(physicalId); 140 props = mCameraManager.getCameraCharacteristics(physicalId); 141 staticMetadata = new StaticMetadata( 142 mCameraManager.getCameraCharacteristics(physicalId), 143 CheckLevel.ASSERT, /*collector*/null); 144 mAllStaticInfo.put(physicalId, staticMetadata); 145 } 146 } 147 } 148 mAllCameraIds = new String[mCameraIdsUnderTest.length + hiddenPhysicalIds.size()]; 149 System.arraycopy(mCameraIdsUnderTest, 0, mAllCameraIds, 0, mCameraIdsUnderTest.length); 150 for (int i = 0; i < hiddenPhysicalIds.size(); i++) { 151 mAllCameraIds[mCameraIdsUnderTest.length + i] = hiddenPhysicalIds.get(i); 152 } 153 } 154 155 @Override tearDown()156 public void tearDown() throws Exception { 157 try { 158 if (mHandlerThread != null) { 159 mHandlerThread.quitSafely(); 160 } 161 mHandler = null; 162 closeDefaultImageReader(); 163 164 if (mCollector != null) { 165 mCollector.verify(); 166 } 167 } catch (Throwable e) { 168 // When new Exception(e) is used, exception info will be printed twice. 169 throw new Exception(e.getMessage()); 170 } finally { 171 super.tearDown(); 172 } 173 } 174 175 /** 176 * Start capture with given {@link #CaptureRequest}. 177 * 178 * @param request The {@link #CaptureRequest} to be captured. 179 * @param repeating If the capture is single capture or repeating. 180 * @param listener The {@link #CaptureCallback} camera device used to notify callbacks. 181 * @param handler The handler camera device used to post callbacks. 182 */ startCapture(CaptureRequest request, boolean repeating, CaptureCallback listener, Handler handler)183 protected void startCapture(CaptureRequest request, boolean repeating, 184 CaptureCallback listener, Handler handler) throws Exception { 185 if (VERBOSE) Log.v(TAG, "Starting capture from device"); 186 187 if (repeating) { 188 mCameraSession.setRepeatingRequest(request, listener, handler); 189 } else { 190 mCameraSession.capture(request, listener, handler); 191 } 192 } 193 194 /** 195 * Stop the current active capture. 196 * 197 * @param fast When it is true, {@link CameraDevice#flush} is called, the stop capture 198 * could be faster. 199 */ stopCapture(boolean fast)200 protected void stopCapture(boolean fast) throws Exception { 201 if (VERBOSE) Log.v(TAG, "Stopping capture"); 202 203 if (fast) { 204 /** 205 * Flush is useful for canceling long exposure single capture, it also could help 206 * to make the streaming capture stop sooner. 207 */ 208 mCameraSession.abortCaptures(); 209 mCameraSessionListener.getStateWaiter(). 210 waitForState(BlockingSessionCallback.SESSION_READY, CAMERA_IDLE_TIMEOUT_MS); 211 } else { 212 mCameraSession.close(); 213 mCameraSessionListener.getStateWaiter(). 214 waitForState(BlockingSessionCallback.SESSION_CLOSED, CAMERA_IDLE_TIMEOUT_MS); 215 } 216 } 217 218 /** 219 * Open a {@link #CameraDevice camera device} and get the StaticMetadata for a given camera id. 220 * The default mCameraListener is used to wait for states. 221 * 222 * @param cameraId The id of the camera device to be opened. 223 */ openDevice(String cameraId)224 protected void openDevice(String cameraId) throws Exception { 225 openDevice(cameraId, /*overrideToPortrait*/false, mCameraListener); 226 } 227 228 /** 229 * Open a {@link #CameraDevice} and get the StaticMetadata for a given camera id and listener. 230 * 231 * @param cameraId The id of the camera device to be opened. 232 * @param listener The {@link #BlockingStateCallback} used to wait for states. 233 */ openDevice(String cameraId, BlockingStateCallback listener)234 protected void openDevice(String cameraId, BlockingStateCallback listener) throws Exception { 235 openDevice(cameraId, /*overrideToPortrait*/false, listener); 236 } 237 238 /** 239 * Open a {@link #CameraDevice} and get the StaticMetadata for a given camera id and listener. 240 * 241 * @param cameraId The id of the camera device to be opened. 242 * @param overrideToPortrait Whether to enable the landscape-to-portrait override 243 */ openDevice(String cameraId, boolean overrideToPortrait)244 protected void openDevice(String cameraId, boolean overrideToPortrait) throws Exception { 245 openDevice(cameraId, overrideToPortrait, mCameraListener); 246 } 247 248 /** 249 * Open a {@link #CameraDevice} and get the StaticMetadata for a given camera id and listener. 250 * 251 * @param cameraId The id of the camera device to be opened. 252 * @param overrideToPortrait Whether to enable the landscape-to-portrait override 253 * @param listener The {@link #BlockingStateCallback} used to wait for states. 254 */ openDevice(String cameraId, boolean overrideToPortrait, BlockingStateCallback listener)255 protected void openDevice(String cameraId, boolean overrideToPortrait, 256 BlockingStateCallback listener) throws Exception { 257 mCamera = CameraTestUtils.openCamera( 258 mCameraManager, cameraId, overrideToPortrait, listener, mHandler); 259 mCollector.setCameraId(cameraId); 260 mStaticInfo = mAllStaticInfo.get(cameraId); 261 if (mStaticInfo.isColorOutputSupported()) { 262 mOrderedPreviewSizes = getSupportedPreviewSizes( 263 cameraId, mCameraManager, 264 getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND)); 265 mOrderedVideoSizes = getSupportedVideoSizes(cameraId, mCameraManager, PREVIEW_SIZE_BOUND); 266 mOrderedStillSizes = getSupportedStillSizes(cameraId, mCameraManager, null); 267 } 268 269 if (VERBOSE) { 270 Log.v(TAG, "Camera " + cameraId + " is opened"); 271 } 272 } 273 274 /** 275 * Create a {@link #CameraCaptureSession} using the currently open camera. 276 * 277 * @param outputSurfaces The set of output surfaces to configure for this session 278 */ createSession(List<Surface> outputSurfaces)279 protected void createSession(List<Surface> outputSurfaces) throws Exception { 280 mCameraSessionListener = new BlockingSessionCallback(); 281 mCameraSession = CameraTestUtils.configureCameraSession(mCamera, outputSurfaces, 282 mCameraSessionListener, mHandler); 283 } 284 285 /** 286 * Create a reprocessable {@link #CameraCaptureSession} using the currently open camera. 287 * 288 * @param inputConfiguration The inputConfiguration for this session 289 * @param outputSurfaces The set of output surfaces to configure for this session 290 */ createReprocessableSession(InputConfiguration inputConfig, List<Surface> outputSurfaces)291 protected void createReprocessableSession(InputConfiguration inputConfig, 292 List<Surface> outputSurfaces) throws Exception { 293 mCameraSessionListener = new BlockingSessionCallback(); 294 mCameraSession = CameraTestUtils.configureReprocessableCameraSession( 295 mCamera, inputConfig, outputSurfaces, mCameraSessionListener, mHandler); 296 } 297 298 /** 299 * Create a {@link #CameraCaptureSession} using the currently open camera with 300 * OutputConfigurations. 301 * 302 * @param outputConfigs The set of output configurations for this session 303 */ createSessionByConfigs(List<OutputConfiguration> outputConfigs)304 protected void createSessionByConfigs(List<OutputConfiguration> outputConfigs) throws Exception { 305 mCameraSessionListener = new BlockingSessionCallback(); 306 mCameraSession = CameraTestUtils.configureCameraSessionWithConfig(mCamera, outputConfigs, 307 mCameraSessionListener, mHandler); 308 } 309 310 /** 311 * Create a {@link #CameraCaptureSession} using the currently open camera with 312 * OutputConfigurations and a ColorSpace. 313 * 314 * @param outputConfigs The set of output configurations for this session 315 * @param colorSpace The color space for this session 316 */ createSessionByConfigsAndColorSpace(List<OutputConfiguration> outputConfigs, ColorSpace.Named colorSpace)317 protected void createSessionByConfigsAndColorSpace(List<OutputConfiguration> outputConfigs, 318 ColorSpace.Named colorSpace) throws Exception { 319 mCameraSessionListener = new BlockingSessionCallback(); 320 mCameraSession = CameraTestUtils.configureCameraSessionWithColorSpace(mCamera, 321 outputConfigs, mCameraSessionListener, mHandler, colorSpace); 322 } 323 324 /** 325 * Close a {@link #CameraDevice camera device} and clear the associated StaticInfo field for a 326 * given camera id. The default mCameraListener is used to wait for states. 327 * <p> 328 * This function must be used along with the {@link #openDevice} for the 329 * same camera id. 330 * </p> 331 * 332 * @param cameraId The id of the {@link #CameraDevice camera device} to be closed. 333 */ closeDevice(String cameraId)334 protected void closeDevice(String cameraId) { 335 closeDevice(cameraId, mCameraListener); 336 } 337 338 /** 339 * Close a {@link #CameraDevice camera device} and clear the associated StaticInfo field for a 340 * given camera id and listener. 341 * <p> 342 * This function must be used along with the {@link #openDevice} for the 343 * same camera id. 344 * </p> 345 * 346 * @param cameraId The id of the camera device to be closed. 347 * @param listener The BlockingStateCallback used to wait for states. 348 */ closeDevice(String cameraId, BlockingStateCallback listener)349 protected void closeDevice(String cameraId, BlockingStateCallback listener) { 350 if (mCamera != null) { 351 if (!cameraId.equals(mCamera.getId())) { 352 throw new IllegalStateException("Try to close a device that is not opened yet"); 353 } 354 mCamera.close(); 355 listener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS); 356 mCamera = null; 357 mCameraSession = null; 358 mCameraSessionListener = null; 359 mStaticInfo = null; 360 mOrderedPreviewSizes = null; 361 mOrderedVideoSizes = null; 362 mOrderedStillSizes = null; 363 364 if (VERBOSE) { 365 Log.v(TAG, "Camera " + cameraId + " is closed"); 366 } 367 } 368 } 369 370 /** 371 * Create an {@link ImageReader} object and get the surface. 372 * <p> 373 * This function creates {@link ImageReader} object and surface, then assign 374 * to the default {@link mReader} and {@link mReaderSurface}. It closes the 375 * current default active {@link ImageReader} if it exists. 376 * </p> 377 * 378 * @param size The size of this ImageReader to be created. 379 * @param format The format of this ImageReader to be created 380 * @param maxNumImages The max number of images that can be acquired 381 * simultaneously. 382 * @param listener The listener used by this ImageReader to notify 383 * callbacks. 384 */ createDefaultImageReader(Size size, int format, int maxNumImages, ImageReader.OnImageAvailableListener listener)385 protected void createDefaultImageReader(Size size, int format, int maxNumImages, 386 ImageReader.OnImageAvailableListener listener) throws Exception { 387 closeDefaultImageReader(); 388 389 mReader = createImageReader(size, format, maxNumImages, listener); 390 mReaderSurface = mReader.getSurface(); 391 if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString()); 392 } 393 394 /** 395 * Create an {@link ImageReader} object and get the surface. 396 * <p> 397 * This function creates {@link ImageReader} object and surface, then assign 398 * to the default {@link mReader} and {@link mReaderSurface}. It closes the 399 * current default active {@link ImageReader} if it exists. 400 * </p> 401 * 402 * @param size The size of this ImageReader to be created. 403 * @param format The format of this ImageReader to be created 404 * @param maxNumImages The max number of images that can be acquired 405 * simultaneously. 406 * @param usage The usage flag of the ImageReader 407 * @param listener The listener used by this ImageReader to notify 408 * callbacks. 409 */ createDefaultImageReader(Size size, int format, int maxNumImages, long usage, ImageReader.OnImageAvailableListener listener)410 protected void createDefaultImageReader(Size size, int format, int maxNumImages, long usage, 411 ImageReader.OnImageAvailableListener listener) throws Exception { 412 closeDefaultImageReader(); 413 414 mReader = createImageReader(size, format, maxNumImages, usage, listener); 415 mReaderSurface = mReader.getSurface(); 416 if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString()); 417 } 418 419 /** 420 * Create an {@link ImageReader} object. 421 * 422 * <p>This function creates image reader object for given format, maxImages, and size.</p> 423 * 424 * @param size The size of this ImageReader to be created. 425 * @param format The format of this ImageReader to be created 426 * @param maxNumImages The max number of images that can be acquired simultaneously. 427 * @param listener The listener used by this ImageReader to notify callbacks. 428 */ 429 createImageReader(Size size, int format, int maxNumImages, ImageReader.OnImageAvailableListener listener)430 protected ImageReader createImageReader(Size size, int format, int maxNumImages, 431 ImageReader.OnImageAvailableListener listener) throws Exception { 432 433 ImageReader reader = null; 434 reader = ImageReader.newInstance(size.getWidth(), size.getHeight(), 435 format, maxNumImages); 436 437 reader.setOnImageAvailableListener(listener, mHandler); 438 if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString()); 439 return reader; 440 } 441 442 /** 443 * Create an {@link ImageReader} object. 444 * 445 * <p>This function creates image reader object for given format, maxImages, usage and size.</p> 446 * 447 * @param size The size of this ImageReader to be created. 448 * @param format The format of this ImageReader to be created 449 * @param maxNumImages The max number of images that can be acquired simultaneously. 450 * @param usage The usage flag of the ImageReader 451 * @param listener The listener used by this ImageReader to notify callbacks. 452 */ 453 createImageReader(Size size, int format, int maxNumImages, long usage, ImageReader.OnImageAvailableListener listener)454 protected ImageReader createImageReader(Size size, int format, int maxNumImages, long usage, 455 ImageReader.OnImageAvailableListener listener) throws Exception { 456 ImageReader reader = null; 457 reader = ImageReader.newInstance(size.getWidth(), size.getHeight(), 458 format, maxNumImages, usage); 459 460 reader.setOnImageAvailableListener(listener, mHandler); 461 if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString()); 462 return reader; 463 } 464 465 /** 466 * Close the pending images then close current default {@link ImageReader} object. 467 */ closeDefaultImageReader()468 protected void closeDefaultImageReader() { 469 closeImageReader(mReader); 470 mReader = null; 471 mReaderSurface = null; 472 } 473 474 /** 475 * Close an image reader instance. 476 * 477 * @param reader 478 */ closeImageReader(ImageReader reader)479 protected void closeImageReader(ImageReader reader) { 480 if (reader != null) { 481 try { 482 // Close all possible pending images first. 483 Image image = reader.acquireLatestImage(); 484 if (image != null) { 485 image.close(); 486 } 487 } finally { 488 reader.close(); 489 reader = null; 490 } 491 } 492 } 493 checkImageReaderSessionConfiguration(String msg)494 protected void checkImageReaderSessionConfiguration(String msg) throws Exception { 495 checkImageReaderSessionConfiguration(msg, /*physicalCameraId*/null); 496 } 497 checkImageReaderSessionConfiguration(String msg, String physicalCameraId)498 protected void checkImageReaderSessionConfiguration(String msg, String physicalCameraId) 499 throws Exception { 500 List<OutputConfiguration> outputConfigs = new ArrayList<OutputConfiguration>(); 501 OutputConfiguration config = new OutputConfiguration(mReaderSurface); 502 if (physicalCameraId != null) { 503 config.setPhysicalCameraId(physicalCameraId); 504 } 505 outputConfigs.add(config); 506 checkSessionConfigurationSupported(mCamera, mHandler, outputConfigs, /*inputConfig*/ null, 507 SessionConfiguration.SESSION_REGULAR, /*expectedResult*/ true, msg); 508 } 509 prepareCaptureRequest()510 protected CaptureRequest prepareCaptureRequest() throws Exception { 511 return prepareCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 512 } 513 prepareCaptureRequest(int template)514 protected CaptureRequest prepareCaptureRequest(int template) throws Exception { 515 List<Surface> outputSurfaces = new ArrayList<Surface>(); 516 Surface surface = mReader.getSurface(); 517 assertNotNull("Fail to get surface from ImageReader", surface); 518 outputSurfaces.add(surface); 519 return prepareCaptureRequestForSurfaces(outputSurfaces, template) 520 .build(); 521 } 522 prepareCaptureRequestForSurfaces(List<Surface> surfaces, int template)523 protected CaptureRequest.Builder prepareCaptureRequestForSurfaces(List<Surface> surfaces, 524 int template) 525 throws Exception { 526 createSession(surfaces); 527 528 CaptureRequest.Builder captureBuilder = 529 mCamera.createCaptureRequest(template); 530 assertNotNull("Fail to get captureRequest", captureBuilder); 531 for (Surface surface : surfaces) { 532 captureBuilder.addTarget(surface); 533 } 534 535 return captureBuilder; 536 } 537 prepareCaptureRequestBuilderWithConfig( List<OutputConfiguration> outputConfigs, int template)538 protected CaptureRequest.Builder prepareCaptureRequestBuilderWithConfig( 539 List<OutputConfiguration> outputConfigs, int template) throws Exception { 540 CaptureRequest.Builder captureBuilder = 541 mCamera.createCaptureRequest(template); 542 assertNotNull("Fail to get captureRequest", captureBuilder); 543 for (OutputConfiguration config : outputConfigs) { 544 for (Surface s : config.getSurfaces()) { 545 captureBuilder.addTarget(s); 546 } 547 } 548 return captureBuilder; 549 } 550 prepareCaptureRequestForConfigs( List<OutputConfiguration> outputConfigs, int template)551 protected CaptureRequest.Builder prepareCaptureRequestForConfigs( 552 List<OutputConfiguration> outputConfigs, int template) throws Exception { 553 createSessionByConfigs(outputConfigs); 554 return prepareCaptureRequestBuilderWithConfig(outputConfigs, template); 555 } 556 prepareCaptureRequestForColorSpace( List<OutputConfiguration> outputConfigs, int template, ColorSpace.Named colorSpace)557 protected CaptureRequest.Builder prepareCaptureRequestForColorSpace( 558 List<OutputConfiguration> outputConfigs, int template, ColorSpace.Named colorSpace) 559 throws Exception { 560 createSessionByConfigsAndColorSpace(outputConfigs, colorSpace); 561 return prepareCaptureRequestBuilderWithConfig(outputConfigs, template); 562 } 563 564 /** 565 * Test the invalid Image access: accessing a closed image must result in 566 * {@link IllegalStateException}. 567 * 568 * @param closedImage The closed image. 569 * @param closedBuffer The ByteBuffer from a closed Image. buffer invalid 570 * access will be skipped if it is null. 571 */ imageInvalidAccessTestAfterClose(Image closedImage, Plane closedPlane, ByteBuffer closedBuffer)572 protected void imageInvalidAccessTestAfterClose(Image closedImage, 573 Plane closedPlane, ByteBuffer closedBuffer) { 574 if (closedImage == null) { 575 throw new IllegalArgumentException(" closedImage must be non-null"); 576 } 577 if (closedBuffer != null && !closedBuffer.isDirect()) { 578 throw new IllegalArgumentException("The input ByteBuffer should be direct ByteBuffer"); 579 } 580 581 if (closedPlane != null) { 582 // Plane#getBuffer test 583 try { 584 closedPlane.getBuffer(); // An ISE should be thrown here. 585 fail("Image should throw IllegalStateException when calling getBuffer" 586 + " after the image is closed"); 587 } catch (IllegalStateException e) { 588 // Expected. 589 } 590 591 // Plane#getPixelStride test 592 try { 593 closedPlane.getPixelStride(); // An ISE should be thrown here. 594 fail("Image should throw IllegalStateException when calling getPixelStride" 595 + " after the image is closed"); 596 } catch (IllegalStateException e) { 597 // Expected. 598 } 599 600 // Plane#getRowStride test 601 try { 602 closedPlane.getRowStride(); // An ISE should be thrown here. 603 fail("Image should throw IllegalStateException when calling getRowStride" 604 + " after the image is closed"); 605 } catch (IllegalStateException e) { 606 // Expected. 607 } 608 } 609 610 // ByteBuffer access test 611 if (closedBuffer != null) { 612 try { 613 closedBuffer.get(); // An ISE should be thrown here. 614 fail("Image should throw IllegalStateException when accessing a byte buffer" 615 + " after the image is closed"); 616 } catch (IllegalStateException e) { 617 // Expected. 618 } 619 } 620 621 // Image#getFormat test 622 try { 623 closedImage.getFormat(); 624 fail("Image should throw IllegalStateException when calling getFormat" 625 + " after the image is closed"); 626 } catch (IllegalStateException e) { 627 // Expected. 628 } 629 630 // Image#getWidth test 631 try { 632 closedImage.getWidth(); 633 fail("Image should throw IllegalStateException when calling getWidth" 634 + " after the image is closed"); 635 } catch (IllegalStateException e) { 636 // Expected. 637 } 638 639 // Image#getHeight test 640 try { 641 closedImage.getHeight(); 642 fail("Image should throw IllegalStateException when calling getHeight" 643 + " after the image is closed"); 644 } catch (IllegalStateException e) { 645 // Expected. 646 } 647 648 // Image#getTimestamp test 649 try { 650 closedImage.getTimestamp(); 651 fail("Image should throw IllegalStateException when calling getTimestamp" 652 + " after the image is closed"); 653 } catch (IllegalStateException e) { 654 // Expected. 655 } 656 657 // Image#getTimestamp test 658 try { 659 closedImage.getTimestamp(); 660 fail("Image should throw IllegalStateException when calling getTimestamp" 661 + " after the image is closed"); 662 } catch (IllegalStateException e) { 663 // Expected. 664 } 665 666 // Image#getCropRect test 667 try { 668 closedImage.getCropRect(); 669 fail("Image should throw IllegalStateException when calling getCropRect" 670 + " after the image is closed"); 671 } catch (IllegalStateException e) { 672 // Expected. 673 } 674 675 // Image#setCropRect test 676 try { 677 Rect rect = new Rect(); 678 closedImage.setCropRect(rect); 679 fail("Image should throw IllegalStateException when calling setCropRect" 680 + " after the image is closed"); 681 } catch (IllegalStateException e) { 682 // Expected. 683 } 684 685 // Image#getPlanes test 686 try { 687 closedImage.getPlanes(); 688 fail("Image should throw IllegalStateException when calling getPlanes" 689 + " after the image is closed"); 690 } catch (IllegalStateException e) { 691 // Expected. 692 } 693 } 694 } 695