| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.hardware.camera2.cts.testcases; |
| |
| import static android.hardware.camera2.cts.CameraTestUtils.*; |
| import static com.android.ex.camera2.blocking.BlockingStateCallback.*; |
| |
| import android.content.Context; |
| import android.graphics.Rect; |
| |
| import android.hardware.camera2.cts.CameraTestUtils; |
| import android.hardware.camera2.CameraCaptureSession; |
| import android.hardware.camera2.CameraCaptureSession.CaptureCallback; |
| import android.hardware.camera2.CameraCharacteristics; |
| import android.hardware.camera2.CameraDevice; |
| import android.hardware.camera2.CameraManager; |
| import android.hardware.camera2.CaptureRequest; |
| import android.hardware.camera2.params.OutputConfiguration; |
| import android.hardware.camera2.params.SessionConfiguration; |
| import android.util.Size; |
| import android.hardware.camera2.cts.helpers.CameraErrorCollector; |
| import android.hardware.camera2.cts.helpers.StaticMetadata; |
| import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel; |
| import android.media.Image; |
| import android.media.Image.Plane; |
| import android.media.ImageReader; |
| import android.os.Bundle; |
| import android.os.Handler; |
| import android.os.HandlerThread; |
| import android.util.Log; |
| import android.view.Surface; |
| import android.view.WindowManager; |
| |
| import androidx.test.InstrumentationRegistry; |
| |
| import com.android.ex.camera2.blocking.BlockingSessionCallback; |
| import com.android.ex.camera2.blocking.BlockingStateCallback; |
| |
| import org.junit.rules.ExternalResource; |
| |
| import java.io.File; |
| import java.nio.ByteBuffer; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.List; |
| |
| public class Camera2AndroidTestRule extends ExternalResource { |
| private static final String TAG = "Camera2AndroidBasicTestCase"; |
| private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); |
| |
| // Default capture size: VGA size is required by CDD. |
| protected static final Size DEFAULT_CAPTURE_SIZE = new Size(640, 480); |
| protected static final int CAPTURE_WAIT_TIMEOUT_MS = 5000; |
| |
| private CameraManager mCameraManager; |
| private CameraDevice mCamera; |
| private CameraCaptureSession mCameraSession; |
| private BlockingSessionCallback mCameraSessionListener; |
| private BlockingStateCallback mCameraListener; |
| private String[] mCameraIdsUnderTest; |
| // include both standalone camera IDs and "hidden" physical camera IDs |
| private String[] mAllCameraIds; |
| private HashMap<String, StaticMetadata> mAllStaticInfo; |
| private ImageReader mReader; |
| private Surface mReaderSurface; |
| private Handler mHandler; |
| private HandlerThread mHandlerThread; |
| private StaticMetadata mStaticInfo; |
| private CameraErrorCollector mCollector; |
| private List<Size> mOrderedPreviewSizes; // In descending order. |
| private List<Size> mOrderedVideoSizes; // In descending order. |
| private List<Size> mOrderedStillSizes; // In descending order. |
| private String mDebugFileNameBase; |
| |
| private WindowManager mWindowManager; |
| private Context mContext; |
| |
| private static final String CAMERA_ID_INSTR_ARG_KEY = "camera-id"; |
| private static final Bundle mBundle = InstrumentationRegistry.getArguments(); |
| private static final String mOverrideCameraId = mBundle.getString(CAMERA_ID_INSTR_ARG_KEY); |
| |
| public Camera2AndroidTestRule(Context context) { |
| mContext = context; |
| } |
| |
| public Context getContext() { |
| return mContext; |
| } |
| |
| public String[] getCameraIdsUnderTest() { |
| return mCameraIdsUnderTest; |
| } |
| |
| public StaticMetadata getStaticInfo() { |
| return mStaticInfo; |
| } |
| |
| public CameraManager getCameraManager() { |
| return mCameraManager; |
| } |
| |
| public void setStaticInfo(StaticMetadata staticInfo) { |
| mStaticInfo = staticInfo; |
| } |
| |
| public CameraCaptureSession getCameraSession() { |
| return mCameraSession; |
| } |
| |
| public CameraDevice getCamera() { |
| return mCamera; |
| } |
| |
| public void setCamera(CameraDevice camera) { |
| mCamera = camera; |
| } |
| |
| public void setCameraSession(CameraCaptureSession session) { |
| mCameraSession = session; |
| } |
| |
| public BlockingStateCallback getCameraListener() { |
| return mCameraListener; |
| } |
| |
| public BlockingSessionCallback getCameraSessionListener() { |
| return mCameraSessionListener; |
| } |
| |
| public Handler getHandler() { |
| return mHandler; |
| } |
| |
| public void setCameraSessionListener(BlockingSessionCallback listener) { |
| mCameraSessionListener = listener; |
| } |
| |
| public ImageReader getReader() { |
| return mReader; |
| } |
| |
| public HashMap<String, StaticMetadata> getAllStaticInfo() { |
| return mAllStaticInfo; |
| } |
| |
| public List<Size> getOrderedPreviewSizes() { |
| return mOrderedPreviewSizes; |
| } |
| |
| public List<Size> getOrderedStillSizes() { |
| return mOrderedStillSizes; |
| } |
| |
| public Surface getReaderSurface() { |
| return mReaderSurface; |
| } |
| |
| public void setOrderedPreviewSizes(List<Size> sizes) { |
| mOrderedPreviewSizes = sizes; |
| } |
| |
| public WindowManager getWindowManager() { |
| return mWindowManager; |
| } |
| |
| public CameraErrorCollector getCollector() { |
| return mCollector; |
| } |
| |
| private String[] deriveCameraIdsUnderTest() throws Exception { |
| String[] idsUnderTest = mCameraManager.getCameraIdListNoLazy(); |
| assertNotNull("Camera ids shouldn't be null", idsUnderTest); |
| if (mOverrideCameraId != null) { |
| if (Arrays.asList(idsUnderTest).contains(mOverrideCameraId)) { |
| idsUnderTest = new String[]{mOverrideCameraId}; |
| } else { |
| idsUnderTest = new String[]{}; |
| } |
| } |
| |
| return idsUnderTest; |
| } |
| |
| /** |
| * Set up the camera2 test case required environments, including CameraManager, |
| * HandlerThread, Camera IDs, and CameraStateCallback etc. |
| */ |
| @Override |
| public void before() throws Exception { |
| Log.v(TAG, "Set up..."); |
| mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE); |
| assertNotNull("Can't connect to camera manager!", mCameraManager); |
| mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); |
| /** |
| * Workaround for mockito and JB-MR2 incompatibility |
| * |
| * Avoid java.lang.IllegalArgumentException: dexcache == null |
| * https://code.google.com/p/dexmaker/issues/detail?id=2 |
| */ |
| System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString()); |
| |
| mCameraIdsUnderTest = deriveCameraIdsUnderTest(); |
| mHandlerThread = new HandlerThread(TAG); |
| mHandlerThread.start(); |
| mHandler = new Handler(mHandlerThread.getLooper()); |
| mCameraListener = new BlockingStateCallback(); |
| mCollector = new CameraErrorCollector(); |
| |
| File filesDir = mContext.getPackageManager().isInstantApp() |
| ? mContext.getFilesDir() |
| : mContext.getExternalFilesDir(null); |
| |
| mDebugFileNameBase = filesDir.getPath(); |
| |
| mAllStaticInfo = new HashMap<String, StaticMetadata>(); |
| List<String> hiddenPhysicalIds = new ArrayList<>(); |
| for (String cameraId : mCameraIdsUnderTest) { |
| CameraCharacteristics props = mCameraManager.getCameraCharacteristics(cameraId); |
| StaticMetadata staticMetadata = new StaticMetadata(props, |
| CheckLevel.ASSERT, /*collector*/null); |
| mAllStaticInfo.put(cameraId, staticMetadata); |
| |
| for (String physicalId : props.getPhysicalCameraIds()) { |
| if (!Arrays.asList(mCameraIdsUnderTest).contains(physicalId) && |
| !hiddenPhysicalIds.contains(physicalId)) { |
| hiddenPhysicalIds.add(physicalId); |
| props = mCameraManager.getCameraCharacteristics(physicalId); |
| staticMetadata = new StaticMetadata( |
| mCameraManager.getCameraCharacteristics(physicalId), |
| CheckLevel.ASSERT, /*collector*/null); |
| mAllStaticInfo.put(physicalId, staticMetadata); |
| } |
| } |
| } |
| mAllCameraIds = new String[mCameraIdsUnderTest.length + hiddenPhysicalIds.size()]; |
| System.arraycopy(mCameraIdsUnderTest, 0, mAllCameraIds, 0, mCameraIdsUnderTest.length); |
| for (int i = 0; i < hiddenPhysicalIds.size(); i++) { |
| mAllCameraIds[mCameraIdsUnderTest.length + i] = hiddenPhysicalIds.get(i); |
| } |
| } |
| |
| @Override |
| public void after() { |
| Log.v(TAG, "Tear down..."); |
| if (mCameraManager != null) { |
| try { |
| String[] cameraIdsPostTest = deriveCameraIdsUnderTest(); |
| Log.i(TAG, "Camera ids in setup:" + Arrays.toString(mCameraIdsUnderTest)); |
| Log.i(TAG, "Camera ids in tearDown:" + Arrays.toString(cameraIdsPostTest)); |
| assertTrue( |
| "Number of cameras changed from " + mCameraIdsUnderTest.length + " to " + |
| cameraIdsPostTest.length, |
| mCameraIdsUnderTest.length == cameraIdsPostTest.length); |
| mHandlerThread.quitSafely(); |
| mHandler = null; |
| closeDefaultImageReader(); |
| mCollector.verify(); |
| } catch (Throwable e) { |
| // When new Exception(e) is used, exception info will be printed twice. |
| throw new RuntimeException(e.getMessage()); |
| } |
| } |
| } |
| |
| /** |
| * Start capture with given {@link #CaptureRequest}. |
| * |
| * @param request The {@link #CaptureRequest} to be captured. |
| * @param repeating If the capture is single capture or repeating. |
| * @param listener The {@link #CaptureCallback} camera device used to notify callbacks. |
| * @param handler The handler camera device used to post callbacks. |
| */ |
| public void startCapture(CaptureRequest request, boolean repeating, |
| CaptureCallback listener, Handler handler) throws Exception { |
| if (VERBOSE) Log.v(TAG, "Starting capture from device"); |
| |
| if (repeating) { |
| mCameraSession.setRepeatingRequest(request, listener, handler); |
| } else { |
| mCameraSession.capture(request, listener, handler); |
| } |
| } |
| |
| /** |
| * Stop the current active capture. |
| * |
| * @param fast When it is true, {@link CameraDevice#flush} is called, the stop capture |
| * could be faster. |
| */ |
| public void stopCapture(boolean fast) throws Exception { |
| if (VERBOSE) Log.v(TAG, "Stopping capture"); |
| |
| if (fast) { |
| /** |
| * Flush is useful for canceling long exposure single capture, it also could help |
| * to make the streaming capture stop sooner. |
| */ |
| mCameraSession.abortCaptures(); |
| mCameraSessionListener.getStateWaiter(). |
| waitForState(BlockingSessionCallback.SESSION_READY, CAMERA_IDLE_TIMEOUT_MS); |
| } else { |
| mCameraSession.close(); |
| mCameraSessionListener.getStateWaiter(). |
| waitForState(BlockingSessionCallback.SESSION_CLOSED, CAMERA_IDLE_TIMEOUT_MS); |
| } |
| } |
| |
| /** |
| * Open a {@link #CameraDevice camera device} and get the StaticMetadata for a given camera id. |
| * The default mCameraListener is used to wait for states. |
| * |
| * @param cameraId The id of the camera device to be opened. |
| */ |
| public void openDevice(String cameraId) throws Exception { |
| openDevice(cameraId, mCameraListener); |
| } |
| |
| /** |
| * Open a {@link #CameraDevice} and get the StaticMetadata for a given camera id and listener. |
| * |
| * @param cameraId The id of the camera device to be opened. |
| * @param listener The {@link #BlockingStateCallback} used to wait for states. |
| */ |
| public void openDevice(String cameraId, BlockingStateCallback listener) throws Exception { |
| mCamera = CameraTestUtils.openCamera( |
| mCameraManager, cameraId, listener, mHandler); |
| mCollector.setCameraId(cameraId); |
| mStaticInfo = mAllStaticInfo.get(cameraId); |
| if (mStaticInfo.isColorOutputSupported()) { |
| mOrderedPreviewSizes = getSupportedPreviewSizes( |
| cameraId, mCameraManager, |
| getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND)); |
| mOrderedVideoSizes = getSupportedVideoSizes(cameraId, mCameraManager, PREVIEW_SIZE_BOUND); |
| mOrderedStillSizes = getSupportedStillSizes(cameraId, mCameraManager, null); |
| } |
| |
| if (VERBOSE) { |
| Log.v(TAG, "Camera " + cameraId + " is opened"); |
| } |
| } |
| |
| /** |
| * Create a {@link #CameraCaptureSession} using the currently open camera. |
| * |
| * @param outputSurfaces The set of output surfaces to configure for this session |
| */ |
| public void createSession(List<Surface> outputSurfaces) throws Exception { |
| mCameraSessionListener = new BlockingSessionCallback(); |
| mCameraSession = CameraTestUtils.configureCameraSession(mCamera, outputSurfaces, |
| mCameraSessionListener, mHandler); |
| } |
| |
| /** |
| * Create a {@link #CameraCaptureSession} using the currently open camera with |
| * OutputConfigurations. |
| * |
| * @param outputSurfaces The set of output surfaces to configure for this session |
| */ |
| public void createSessionByConfigs(List<OutputConfiguration> outputConfigs) throws Exception { |
| mCameraSessionListener = new BlockingSessionCallback(); |
| mCameraSession = CameraTestUtils.configureCameraSessionWithConfig(mCamera, outputConfigs, |
| mCameraSessionListener, mHandler); |
| } |
| |
| /** |
| * Close a {@link #CameraDevice camera device} and clear the associated StaticInfo field for a |
| * given camera id. The default mCameraListener is used to wait for states. |
| * <p> |
| * This function must be used along with the {@link #openDevice} for the |
| * same camera id. |
| * </p> |
| * |
| * @param cameraId The id of the {@link #CameraDevice camera device} to be closed. |
| */ |
| public void closeDevice(String cameraId) { |
| closeDevice(cameraId, mCameraListener); |
| } |
| |
| /** |
| * Close a {@link #CameraDevice camera device} and clear the associated StaticInfo field for a |
| * given camera id and listener. |
| * <p> |
| * This function must be used along with the {@link #openDevice} for the |
| * same camera id. |
| * </p> |
| * |
| * @param cameraId The id of the camera device to be closed. |
| * @param listener The BlockingStateCallback used to wait for states. |
| */ |
| public void closeDevice(String cameraId, BlockingStateCallback listener) { |
| if (mCamera != null) { |
| if (!cameraId.equals(mCamera.getId())) { |
| throw new IllegalStateException("Try to close a device that is not opened yet"); |
| } |
| mCamera.close(); |
| listener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS); |
| mCamera = null; |
| mCameraSession = null; |
| mCameraSessionListener = null; |
| mStaticInfo = null; |
| mOrderedPreviewSizes = null; |
| mOrderedVideoSizes = null; |
| mOrderedStillSizes = null; |
| |
| if (VERBOSE) { |
| Log.v(TAG, "Camera " + cameraId + " is closed"); |
| } |
| } |
| } |
| |
| /** |
| * Create an {@link ImageReader} object and get the surface. |
| * <p> |
| * This function creates {@link ImageReader} object and surface, then assign |
| * to the default {@link mReader} and {@link mReaderSurface}. It closes the |
| * current default active {@link ImageReader} if it exists. |
| * </p> |
| * |
| * @param size The size of this ImageReader to be created. |
| * @param format The format of this ImageReader to be created |
| * @param maxNumImages The max number of images that can be acquired |
| * simultaneously. |
| * @param listener The listener used by this ImageReader to notify |
| * callbacks. |
| */ |
| public void createDefaultImageReader(Size size, int format, int maxNumImages, |
| ImageReader.OnImageAvailableListener listener) throws Exception { |
| closeDefaultImageReader(); |
| |
| mReader = createImageReader(size, format, maxNumImages, listener); |
| mReaderSurface = mReader.getSurface(); |
| if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString()); |
| } |
| |
| /** |
| * Create an {@link ImageReader} object and get the surface. |
| * <p> |
| * This function creates {@link ImageReader} object and surface, then assign |
| * to the default {@link mReader} and {@link mReaderSurface}. It closes the |
| * current default active {@link ImageReader} if it exists. |
| * </p> |
| * |
| * @param size The size of this ImageReader to be created. |
| * @param format The format of this ImageReader to be created |
| * @param maxNumImages The max number of images that can be acquired |
| * simultaneously. |
| * @param usage The usage flag of the ImageReader |
| * @param listener The listener used by this ImageReader to notify |
| * callbacks. |
| */ |
| public void createDefaultImageReader(Size size, int format, int maxNumImages, long usage, |
| ImageReader.OnImageAvailableListener listener) throws Exception { |
| closeDefaultImageReader(); |
| |
| mReader = createImageReader(size, format, maxNumImages, usage, listener); |
| mReaderSurface = mReader.getSurface(); |
| if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString()); |
| } |
| |
| /** |
| * Create an {@link ImageReader} object. |
| * |
| * <p>This function creates image reader object for given format, maxImages, and size.</p> |
| * |
| * @param size The size of this ImageReader to be created. |
| * @param format The format of this ImageReader to be created |
| * @param maxNumImages The max number of images that can be acquired simultaneously. |
| * @param listener The listener used by this ImageReader to notify callbacks. |
| */ |
| |
| public ImageReader createImageReader(Size size, int format, int maxNumImages, |
| ImageReader.OnImageAvailableListener listener) throws Exception { |
| |
| ImageReader reader = null; |
| reader = ImageReader.newInstance(size.getWidth(), size.getHeight(), |
| format, maxNumImages); |
| |
| reader.setOnImageAvailableListener(listener, mHandler); |
| if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString()); |
| return reader; |
| } |
| |
| /** |
| * Create an {@link ImageReader} object. |
| * |
| * <p>This function creates image reader object for given format, maxImages, usage and size.</p> |
| * |
| * @param size The size of this ImageReader to be created. |
| * @param format The format of this ImageReader to be created |
| * @param maxNumImages The max number of images that can be acquired simultaneously. |
| * @param usage The usage flag of the ImageReader |
| * @param listener The listener used by this ImageReader to notify callbacks. |
| */ |
| |
| public ImageReader createImageReader(Size size, int format, int maxNumImages, long usage, |
| ImageReader.OnImageAvailableListener listener) throws Exception { |
| ImageReader reader = null; |
| reader = ImageReader.newInstance(size.getWidth(), size.getHeight(), |
| format, maxNumImages, usage); |
| |
| reader.setOnImageAvailableListener(listener, mHandler); |
| if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString()); |
| return reader; |
| } |
| |
| /** |
| * Close the pending images then close current default {@link ImageReader} object. |
| */ |
| public void closeDefaultImageReader() { |
| closeImageReader(mReader); |
| mReader = null; |
| mReaderSurface = null; |
| } |
| |
| /** |
| * Close an image reader instance. |
| * |
| * @param reader |
| */ |
| public void closeImageReader(ImageReader reader) { |
| if (reader != null) { |
| try { |
| // Close all possible pending images first. |
| Image image = reader.acquireLatestImage(); |
| if (image != null) { |
| image.close(); |
| } |
| } finally { |
| reader.close(); |
| reader = null; |
| } |
| } |
| } |
| |
| public void checkImageReaderSessionConfiguration(String msg) throws Exception { |
| List<OutputConfiguration> outputConfigs = new ArrayList<OutputConfiguration>(); |
| outputConfigs.add(new OutputConfiguration(mReaderSurface)); |
| |
| checkSessionConfigurationSupported(mCamera, mHandler, outputConfigs, /*inputConfig*/ null, |
| SessionConfiguration.SESSION_REGULAR, /*expectedResult*/ true, msg); |
| } |
| |
| public CaptureRequest prepareCaptureRequest() throws Exception { |
| return prepareCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); |
| } |
| |
| public CaptureRequest prepareCaptureRequest(int template) throws Exception { |
| List<Surface> outputSurfaces = new ArrayList<Surface>(); |
| Surface surface = mReader.getSurface(); |
| assertNotNull("Fail to get surface from ImageReader", surface); |
| outputSurfaces.add(surface); |
| return prepareCaptureRequestForSurfaces(outputSurfaces, template) |
| .build(); |
| } |
| |
| public CaptureRequest.Builder prepareCaptureRequestForSurfaces(List<Surface> surfaces, |
| int template) |
| throws Exception { |
| createSession(surfaces); |
| |
| CaptureRequest.Builder captureBuilder = |
| mCamera.createCaptureRequest(template); |
| assertNotNull("Fail to get captureRequest", captureBuilder); |
| for (Surface surface : surfaces) { |
| captureBuilder.addTarget(surface); |
| } |
| |
| return captureBuilder; |
| } |
| |
| public CaptureRequest.Builder prepareCaptureRequestForConfigs( |
| List<OutputConfiguration> outputConfigs, int template) throws Exception { |
| createSessionByConfigs(outputConfigs); |
| |
| CaptureRequest.Builder captureBuilder = |
| mCamera.createCaptureRequest(template); |
| assertNotNull("Fail to get captureRequest", captureBuilder); |
| for (OutputConfiguration config : outputConfigs) { |
| for (Surface s : config.getSurfaces()) { |
| captureBuilder.addTarget(s); |
| } |
| } |
| |
| return captureBuilder; |
| } |
| |
| /** |
| * Test the invalid Image access: accessing a closed image must result in |
| * {@link IllegalStateException}. |
| * |
| * @param closedImage The closed image. |
| * @param closedBuffer The ByteBuffer from a closed Image. buffer invalid |
| * access will be skipped if it is null. |
| */ |
| public void imageInvalidAccessTestAfterClose(Image closedImage, |
| Plane closedPlane, ByteBuffer closedBuffer) { |
| if (closedImage == null) { |
| throw new IllegalArgumentException(" closedImage must be non-null"); |
| } |
| if (closedBuffer != null && !closedBuffer.isDirect()) { |
| throw new IllegalArgumentException("The input ByteBuffer should be direct ByteBuffer"); |
| } |
| |
| if (closedPlane != null) { |
| // Plane#getBuffer test |
| try { |
| closedPlane.getBuffer(); // An ISE should be thrown here. |
| fail("Image should throw IllegalStateException when calling getBuffer" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| |
| // Plane#getPixelStride test |
| try { |
| closedPlane.getPixelStride(); // An ISE should be thrown here. |
| fail("Image should throw IllegalStateException when calling getPixelStride" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| |
| // Plane#getRowStride test |
| try { |
| closedPlane.getRowStride(); // An ISE should be thrown here. |
| fail("Image should throw IllegalStateException when calling getRowStride" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| } |
| |
| // ByteBuffer access test |
| if (closedBuffer != null) { |
| try { |
| closedBuffer.get(); // An ISE should be thrown here. |
| fail("Image should throw IllegalStateException when accessing a byte buffer" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| } |
| |
| // Image#getFormat test |
| try { |
| closedImage.getFormat(); |
| fail("Image should throw IllegalStateException when calling getFormat" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| |
| // Image#getWidth test |
| try { |
| closedImage.getWidth(); |
| fail("Image should throw IllegalStateException when calling getWidth" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| |
| // Image#getHeight test |
| try { |
| closedImage.getHeight(); |
| fail("Image should throw IllegalStateException when calling getHeight" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| |
| // Image#getTimestamp test |
| try { |
| closedImage.getTimestamp(); |
| fail("Image should throw IllegalStateException when calling getTimestamp" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| |
| // Image#getTimestamp test |
| try { |
| closedImage.getTimestamp(); |
| fail("Image should throw IllegalStateException when calling getTimestamp" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| |
| // Image#getCropRect test |
| try { |
| closedImage.getCropRect(); |
| fail("Image should throw IllegalStateException when calling getCropRect" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| |
| // Image#setCropRect test |
| try { |
| Rect rect = new Rect(); |
| closedImage.setCropRect(rect); |
| fail("Image should throw IllegalStateException when calling setCropRect" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| |
| // Image#getPlanes test |
| try { |
| closedImage.getPlanes(); |
| fail("Image should throw IllegalStateException when calling getPlanes" |
| + " after the image is closed"); |
| } catch (IllegalStateException e) { |
| // Expected. |
| } |
| } |
| } |