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