• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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