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