Merge "media: Update ImageReader to remove MaxImagesAcquiredException" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5cf86aa756
@@ -12350,8 +12350,8 @@ package android.media {
|
||||
}
|
||||
|
||||
public class ImageReader implements java.lang.AutoCloseable {
|
||||
method public android.media.Image acquireLatestImage() throws android.media.ImageReader.MaxImagesAcquiredException;
|
||||
method public android.media.Image acquireNextImage() throws android.media.ImageReader.MaxImagesAcquiredException;
|
||||
method public android.media.Image acquireLatestImage();
|
||||
method public android.media.Image acquireNextImage();
|
||||
method public void close();
|
||||
method public int getHeight();
|
||||
method public int getImageFormat();
|
||||
@@ -12362,13 +12362,6 @@ package android.media {
|
||||
method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
|
||||
}
|
||||
|
||||
public static class ImageReader.MaxImagesAcquiredException extends java.lang.Exception {
|
||||
ctor public ImageReader.MaxImagesAcquiredException();
|
||||
ctor public ImageReader.MaxImagesAcquiredException(java.lang.String);
|
||||
ctor public ImageReader.MaxImagesAcquiredException(java.lang.String, java.lang.Throwable);
|
||||
ctor public ImageReader.MaxImagesAcquiredException(java.lang.Throwable);
|
||||
}
|
||||
|
||||
public static abstract interface ImageReader.OnImageAvailableListener {
|
||||
method public abstract void onImageAvailable(android.media.ImageReader);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.VirtualDisplay;
|
||||
import android.media.Image;
|
||||
import android.media.ImageReader;
|
||||
import android.media.ImageReader.MaxImagesAcquiredException;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -427,9 +426,6 @@ public class VirtualDisplayTest extends AndroidTestCase {
|
||||
image.close();
|
||||
}
|
||||
}
|
||||
} catch (MaxImagesAcquiredException e) {
|
||||
// We should never try to consume more buffers than maxImages.
|
||||
throw new IllegalStateException(e);
|
||||
} finally {
|
||||
mImageReaderLock.unlock();
|
||||
}
|
||||
|
||||
@@ -40,8 +40,7 @@ import java.lang.AutoCloseable;
|
||||
* availability of new Images once
|
||||
* {@link ImageReader#getMaxImages the maximum outstanding image count} is
|
||||
* reached. When this happens, the function acquiring new Images will typically
|
||||
* throw a
|
||||
* {@link ImageReader.MaxImagesAcquiredException MaxImagesAcquiredException}.</p>
|
||||
* throw an {@link IllegalStateException}.</p>
|
||||
*
|
||||
* @see ImageReader
|
||||
*/
|
||||
|
||||
@@ -49,43 +49,20 @@ import java.nio.ByteOrder;
|
||||
public class ImageReader implements AutoCloseable {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This exception is thrown when the user of an {@link ImageReader} tries to acquire a new
|
||||
* {@link Image} when the maximum number of {@link Image Images} have already been acquired.
|
||||
* The maximum number is determined by the {@code maxBuffers} argument of
|
||||
* {@link ImageReader#newInstance newInstance}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* To recover from this exception, release existing {@link Image images} back to the
|
||||
* reader with {@link Image#close}.
|
||||
* </p>
|
||||
*
|
||||
* @see Image#close
|
||||
* @see ImageReader#acquireLatestImage
|
||||
* @see ImageReader#acquireNextImage
|
||||
* Returned by nativeImageSetup when acquiring the image was successful.
|
||||
*/
|
||||
public static class MaxImagesAcquiredException extends Exception {
|
||||
/**
|
||||
* Suppress Eclipse warnings
|
||||
*/
|
||||
private static final long serialVersionUID = 761231231236L;
|
||||
|
||||
public MaxImagesAcquiredException() {
|
||||
}
|
||||
|
||||
public MaxImagesAcquiredException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public MaxImagesAcquiredException(String message, Throwable throwable) {
|
||||
super(message, throwable);
|
||||
}
|
||||
|
||||
public MaxImagesAcquiredException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
}
|
||||
private static final int ACQUIRE_SUCCESS = 0;
|
||||
/**
|
||||
* Returned by nativeImageSetup when we couldn't acquire the buffer,
|
||||
* because there were no buffers available to acquire.
|
||||
*/
|
||||
private static final int ACQUIRE_NO_BUFS = 1;
|
||||
/**
|
||||
* Returned by nativeImageSetup when we couldn't acquire the buffer
|
||||
* because the consumer has already acquired {@maxImages} and cannot
|
||||
* acquire more than that.
|
||||
*/
|
||||
private static final int ACQUIRE_MAX_IMAGES = 2;
|
||||
|
||||
/**
|
||||
* <p>Create a new reader for images of the desired size and format.</p>
|
||||
@@ -195,7 +172,7 @@ public class ImageReader implements AutoCloseable {
|
||||
* </p>
|
||||
*
|
||||
* <p>Attempting to acquire more than {@code maxImages} concurrently will result in the
|
||||
* acquire function throwing a {@link MaxImagesAcquiredException}. Furthermore,
|
||||
* acquire function throwing a {@link IllegalStateException}. Furthermore,
|
||||
* while the max number of images have been acquired by the ImageReader user, the producer
|
||||
* enqueueing additional images may stall until at least one image has been released. </p>
|
||||
*
|
||||
@@ -243,26 +220,26 @@ public class ImageReader implements AutoCloseable {
|
||||
* {@code (maxImages - currentAcquiredImages < 2)} will not discard as expected.
|
||||
* </p>
|
||||
* <p>
|
||||
* This operation will fail by throwing an {@link MaxImagesAcquiredException} if
|
||||
* This operation will fail by throwing an {@link IllegalStateException} if
|
||||
* {@code maxImages} have been acquired with {@link #acquireLatestImage} or
|
||||
* {@link #acquireNextImage}. In particular a sequence of {@link #acquireLatestImage}
|
||||
* calls greater than {@link #getMaxImages} without calling {@link Image#close} in-between
|
||||
* will exhaust the underlying queue. At such a time, {@link MaxImagesAcquiredException}
|
||||
* will exhaust the underlying queue. At such a time, {@link IllegalStateException}
|
||||
* will be thrown until more images are
|
||||
* released with {@link Image#close}.
|
||||
* </p>
|
||||
*
|
||||
* @return latest frame of image data, or {@code null} if no image data is available.
|
||||
* @throws MaxImagesAcquiredException if too many images are currently acquired
|
||||
* @throws IllegalStateException if too many images are currently acquired
|
||||
*/
|
||||
public Image acquireLatestImage() throws MaxImagesAcquiredException {
|
||||
public Image acquireLatestImage() {
|
||||
Image image = acquireNextImage();
|
||||
if (image == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
for (;;) {
|
||||
Image next = acquireNextImageNoThrow();
|
||||
Image next = acquireNextImageNoThrowISE();
|
||||
if (next == null) {
|
||||
Image result = image;
|
||||
image = null;
|
||||
@@ -278,12 +255,48 @@ public class ImageReader implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
private Image acquireNextImageNoThrow() {
|
||||
try {
|
||||
return acquireNextImage();
|
||||
} catch (MaxImagesAcquiredException ex) {
|
||||
return null;
|
||||
/**
|
||||
* Don't throw IllegalStateException if there are too many images acquired.
|
||||
*
|
||||
* @return Image if acquiring succeeded, or null otherwise.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public Image acquireNextImageNoThrowISE() {
|
||||
SurfaceImage si = new SurfaceImage();
|
||||
return acquireNextSurfaceImage(si) == ACQUIRE_SUCCESS ? si : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to acquire the next image from the underlying native implementation.
|
||||
*
|
||||
* <p>
|
||||
* Note that unexpected failures will throw at the JNI level.
|
||||
* </p>
|
||||
*
|
||||
* @param si A blank SurfaceImage.
|
||||
* @return One of the {@code ACQUIRE_*} codes that determine success or failure.
|
||||
*
|
||||
* @see #ACQUIRE_MAX_IMAGES
|
||||
* @see #ACQUIRE_NO_BUFS
|
||||
* @see #ACQUIRE_SUCCESS
|
||||
*/
|
||||
private int acquireNextSurfaceImage(SurfaceImage si) {
|
||||
|
||||
int status = nativeImageSetup(si);
|
||||
|
||||
switch (status) {
|
||||
case ACQUIRE_SUCCESS:
|
||||
si.createSurfacePlanes();
|
||||
si.setImageValid(true);
|
||||
case ACQUIRE_NO_BUFS:
|
||||
case ACQUIRE_MAX_IMAGES:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Unknown nativeImageSetup return code " + status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,28 +314,36 @@ public class ImageReader implements AutoCloseable {
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This operation will fail by throwing an {@link MaxImagesAcquiredException} if
|
||||
* This operation will fail by throwing an {@link IllegalStateException} if
|
||||
* {@code maxImages} have been acquired with {@link #acquireNextImage} or
|
||||
* {@link #acquireLatestImage}. In particular a sequence of {@link #acquireNextImage} or
|
||||
* {@link #acquireLatestImage} calls greater than {@link #getMaxImages maxImages} without
|
||||
* calling {@link Image#close} in-between will exhaust the underlying queue. At such a time,
|
||||
* {@link MaxImagesAcquiredException} will be thrown until more images are released with
|
||||
* {@link IllegalStateException} will be thrown until more images are released with
|
||||
* {@link Image#close}.
|
||||
* </p>
|
||||
*
|
||||
* @return a new frame of image data, or {@code null} if no image data is available.
|
||||
* @throws MaxImagesAcquiredException if {@code maxImages} images are currently acquired
|
||||
* @throws IllegalStateException if {@code maxImages} images are currently acquired
|
||||
* @see #acquireLatestImage
|
||||
*/
|
||||
public Image acquireNextImage() throws MaxImagesAcquiredException {
|
||||
public Image acquireNextImage() {
|
||||
SurfaceImage si = new SurfaceImage();
|
||||
if (nativeImageSetup(si)) {
|
||||
// create SurfacePlane objects
|
||||
si.createSurfacePlanes();
|
||||
si.setImageValid(true);
|
||||
return si;
|
||||
int status = acquireNextSurfaceImage(si);
|
||||
|
||||
switch (status) {
|
||||
case ACQUIRE_SUCCESS:
|
||||
return si;
|
||||
case ACQUIRE_NO_BUFS:
|
||||
return null;
|
||||
case ACQUIRE_MAX_IMAGES:
|
||||
throw new IllegalStateException(
|
||||
String.format(
|
||||
"maxImages (%d) has already been acquired, " +
|
||||
"call #close before acquiring more.", mMaxImages));
|
||||
default:
|
||||
throw new AssertionError("Unknown nativeImageSetup return code " + status);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -658,7 +679,15 @@ public class ImageReader implements AutoCloseable {
|
||||
private synchronized native void nativeClose();
|
||||
private synchronized native void nativeReleaseImage(Image i);
|
||||
private synchronized native Surface nativeGetSurface();
|
||||
private synchronized native boolean nativeImageSetup(Image i);
|
||||
|
||||
/**
|
||||
* @return A return code {@code ACQUIRE_*}
|
||||
*
|
||||
* @see #ACQUIRE_SUCCESS
|
||||
* @see #ACQUIRE_NO_BUFS
|
||||
* @see #ACQUIRE_MAX_IMAGES
|
||||
*/
|
||||
private synchronized native int nativeImageSetup(Image i);
|
||||
|
||||
/**
|
||||
* We use a class initializer to allow the native code to cache some
|
||||
|
||||
@@ -43,13 +43,16 @@
|
||||
|
||||
using namespace android;
|
||||
|
||||
static const char* const MaxImagesAcquiredException =
|
||||
"android/media/ImageReader$MaxImagesAcquiredException";
|
||||
|
||||
enum {
|
||||
IMAGE_READER_MAX_NUM_PLANES = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
ACQUIRE_SUCCESS = 0,
|
||||
ACQUIRE_NO_BUFFERS = 1,
|
||||
ACQUIRE_MAX_IMAGES = 2,
|
||||
};
|
||||
|
||||
static struct {
|
||||
jfieldID mNativeContext;
|
||||
jmethodID postEventFromNative;
|
||||
@@ -685,14 +688,14 @@ static void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image)
|
||||
ctx->returnLockedBuffer(buffer);
|
||||
}
|
||||
|
||||
static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
|
||||
static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz,
|
||||
jobject image)
|
||||
{
|
||||
ALOGV("%s:", __FUNCTION__);
|
||||
JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz);
|
||||
if (ctx == NULL) {
|
||||
jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
CpuConsumer* consumer = ctx->getCpuConsumer();
|
||||
@@ -700,27 +703,22 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
|
||||
if (buffer == NULL) {
|
||||
ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than"
|
||||
" maxImages buffers");
|
||||
jniThrowException(env, MaxImagesAcquiredException,
|
||||
"Too many outstanding images, close existing images"
|
||||
" to be able to acquire more.");
|
||||
return false;
|
||||
return ACQUIRE_MAX_IMAGES;
|
||||
}
|
||||
status_t res = consumer->lockNextBuffer(buffer);
|
||||
if (res != NO_ERROR) {
|
||||
if (res != BAD_VALUE /*no buffers*/) {
|
||||
if (res == NOT_ENOUGH_DATA) {
|
||||
jniThrowException(env, MaxImagesAcquiredException,
|
||||
"Too many outstanding images, close existing images"
|
||||
" to be able to acquire more.");
|
||||
return ACQUIRE_MAX_IMAGES;
|
||||
} else {
|
||||
ALOGE("%s Fail to lockNextBuffer with error: %d ",
|
||||
__FUNCTION__, res);
|
||||
jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
|
||||
jniThrowExceptionFmt(env, "java/lang/AssertionError",
|
||||
"Unknown error (%d) when we tried to lock buffer.",
|
||||
res);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return ACQUIRE_NO_BUFFERS;
|
||||
}
|
||||
|
||||
// Check if the left-top corner of the crop rect is origin, we currently assume this point is
|
||||
@@ -730,7 +728,7 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
|
||||
ALOGE("crop left: %d, top = %d", lt.x, lt.y);
|
||||
jniThrowException(env, "java/lang/UnsupportedOperationException",
|
||||
"crop left top corner need to at origin");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check if the producer buffer configurations match what ImageReader configured.
|
||||
@@ -759,6 +757,7 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
|
||||
jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
|
||||
"Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d",
|
||||
outputWidth, outputHeight, imageReaderWidth, imageReaderHeight);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->getBufferFormat() != buffer->format) {
|
||||
@@ -775,14 +774,14 @@ static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
|
||||
buffer->format, ctx->getBufferFormat());
|
||||
jniThrowException(env, "java/lang/UnsupportedOperationException",
|
||||
msg.string());
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
// Set SurfaceImage instance member variables
|
||||
Image_setBuffer(env, image, buffer);
|
||||
env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp,
|
||||
static_cast<jlong>(buffer->timestamp));
|
||||
|
||||
return true;
|
||||
return ACQUIRE_SUCCESS;
|
||||
}
|
||||
|
||||
static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz)
|
||||
@@ -853,7 +852,7 @@ static JNINativeMethod gImageReaderMethods[] = {
|
||||
{"nativeInit", "(Ljava/lang/Object;IIII)V", (void*)ImageReader_init },
|
||||
{"nativeClose", "()V", (void*)ImageReader_close },
|
||||
{"nativeReleaseImage", "(Landroid/media/Image;)V", (void*)ImageReader_imageRelease },
|
||||
{"nativeImageSetup", "(Landroid/media/Image;)Z", (void*)ImageReader_imageSetup },
|
||||
{"nativeImageSetup", "(Landroid/media/Image;)I", (void*)ImageReader_imageSetup },
|
||||
{"nativeGetSurface", "()Landroid/view/Surface;", (void*)ImageReader_getSurface },
|
||||
};
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.media.Image;
|
||||
import android.media.Image.Plane;
|
||||
import android.media.ImageReader;
|
||||
import android.media.ImageReader.OnImageAvailableListener;
|
||||
import android.media.ImageReader.MaxImagesAcquiredException;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
@@ -67,7 +66,6 @@ public class ImageReaderTest extends AndroidTestCase {
|
||||
{
|
||||
mock(Plane.class);
|
||||
mock(OnImageAvailableListener.class);
|
||||
mock(MaxImagesAcquiredException.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -83,8 +81,9 @@ public class ImageReaderTest extends AndroidTestCase {
|
||||
* Return null when there is nothing in the image queue.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImageEmpty() throws MaxImagesAcquiredException {
|
||||
public void testGetLatestImageEmpty() {
|
||||
when(mReader.acquireNextImage()).thenReturn(null);
|
||||
when(mReader.acquireNextImageNoThrowISE()).thenReturn(null);
|
||||
assertEquals(null, mReader.acquireLatestImage());
|
||||
}
|
||||
|
||||
@@ -92,8 +91,9 @@ public class ImageReaderTest extends AndroidTestCase {
|
||||
* Return the last image from the image queue, close up the rest.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImage1() throws MaxImagesAcquiredException {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1).thenReturn(null);
|
||||
public void testGetLatestImage1() {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1);
|
||||
when(mReader.acquireNextImageNoThrowISE()).thenReturn(null);
|
||||
assertEquals(mImage1, mReader.acquireLatestImage());
|
||||
verify(mImage1, never()).close();
|
||||
}
|
||||
@@ -102,8 +102,9 @@ public class ImageReaderTest extends AndroidTestCase {
|
||||
* Return the last image from the image queue, close up the rest.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImage2() throws MaxImagesAcquiredException {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1).thenReturn(mImage2).thenReturn(null);
|
||||
public void testGetLatestImage2() {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1);
|
||||
when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).thenReturn(null);
|
||||
assertEquals(mImage2, mReader.acquireLatestImage());
|
||||
verify(mImage1, atLeastOnce()).close();
|
||||
verify(mImage2, never()).close();
|
||||
@@ -113,10 +114,11 @@ public class ImageReaderTest extends AndroidTestCase {
|
||||
* Return the last image from the image queue, close up the rest.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImage3() throws MaxImagesAcquiredException {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1).thenReturn(mImage2).
|
||||
thenReturn(mImage3).
|
||||
thenReturn(null);
|
||||
public void testGetLatestImage3() {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1);
|
||||
when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).
|
||||
thenReturn(mImage3).
|
||||
thenReturn(null);
|
||||
assertEquals(mImage3, mReader.acquireLatestImage());
|
||||
verify(mImage1, atLeastOnce()).close();
|
||||
verify(mImage2, atLeastOnce()).close();
|
||||
@@ -124,64 +126,27 @@ public class ImageReaderTest extends AndroidTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return null if get a MaxImagesAcquiredException with no images in the queue.
|
||||
* Return null if get a IllegalStateException with no images in the queue.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImageTooManyBuffersAcquiredEmpty() throws MaxImagesAcquiredException {
|
||||
when(mReader.acquireNextImage()).thenThrow(new MaxImagesAcquiredException());
|
||||
public void testGetLatestImageTooManyBuffersAcquiredEmpty() {
|
||||
when(mReader.acquireNextImage()).thenThrow(new IllegalStateException());
|
||||
try {
|
||||
mReader.acquireLatestImage();
|
||||
fail("Expected MaxImagesAcquiredException to be thrown");
|
||||
} catch(MaxImagesAcquiredException e) {
|
||||
fail("Expected IllegalStateException to be thrown");
|
||||
} catch(IllegalStateException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last image before we get a MaxImagesAcquiredException. Close up the rest.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImageTooManyBuffersAcquired1() throws MaxImagesAcquiredException {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1).
|
||||
thenThrow(new MaxImagesAcquiredException());
|
||||
assertEquals(mImage1, mReader.acquireLatestImage());
|
||||
verify(mImage1, never()).close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last image before we get a MaxImagesAcquiredException. Close up the rest.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImageTooManyBuffersAcquired2() throws MaxImagesAcquiredException {
|
||||
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1).thenReturn(mImage2).
|
||||
thenThrow(new MaxImagesAcquiredException());
|
||||
assertEquals(mImage2, mReader.acquireLatestImage());
|
||||
verify(mImage1, atLeastOnce()).close();
|
||||
verify(mImage2, never()).close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last image before we get a MaxImagesAcquiredException. Close up the rest.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImageTooManyBuffersAcquired3() throws MaxImagesAcquiredException {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1).thenReturn(mImage2).
|
||||
thenReturn(mImage3).
|
||||
thenThrow(new MaxImagesAcquiredException());
|
||||
assertEquals(mImage3, mReader.acquireLatestImage());
|
||||
verify(mImage1, atLeastOnce()).close();
|
||||
verify(mImage2, atLeastOnce()).close();
|
||||
verify(mImage3, never()).close();
|
||||
}
|
||||
|
||||
/**
|
||||
* All images are cleaned up when we get an unexpected Error.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImageExceptionalError() throws MaxImagesAcquiredException {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1).thenReturn(mImage2).
|
||||
thenReturn(mImage3).
|
||||
thenThrow(new OutOfMemoryError());
|
||||
public void testGetLatestImageExceptionalError() {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1);
|
||||
when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).
|
||||
thenReturn(mImage3).
|
||||
thenThrow(new OutOfMemoryError());
|
||||
try {
|
||||
mReader.acquireLatestImage();
|
||||
fail("Impossible");
|
||||
@@ -197,10 +162,12 @@ public class ImageReaderTest extends AndroidTestCase {
|
||||
* All images are cleaned up when we get an unexpected RuntimeException.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testGetLatestImageExceptionalRuntime() throws MaxImagesAcquiredException {
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1).thenReturn(mImage2).
|
||||
thenReturn(mImage3).
|
||||
thenThrow(new RuntimeException());
|
||||
public void testGetLatestImageExceptionalRuntime() {
|
||||
|
||||
when(mReader.acquireNextImage()).thenReturn(mImage1);
|
||||
when(mReader.acquireNextImageNoThrowISE()).thenReturn(mImage2).
|
||||
thenReturn(mImage3).
|
||||
thenThrow(new RuntimeException());
|
||||
try {
|
||||
mReader.acquireLatestImage();
|
||||
fail("Impossible");
|
||||
|
||||
Reference in New Issue
Block a user