diff options
| author | 2016-02-23 17:47:44 -0800 | |
|---|---|---|
| committer | 2016-02-23 17:54:30 -0800 | |
| commit | 8e694e3b494b0fc857dcd981c57687ecea543c02 (patch) | |
| tree | e3849d3c4b29d18685696db387d48fc87e9d59fe | |
| parent | c7a1b095a8f380b29f3f5108dd3e72f4898176b1 (diff) | |
ImageReader: skip callback when image reader is being closed
The application could acquire images in onImageAvailable callback when
the ImageReader is being closed. We need some protection here to avoid
application crash.
Change-Id: Ie5be8450048c0cfd78e5a7e27befe4de425d79f3
| -rw-r--r-- | media/java/android/media/ImageReader.java | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java index 397ab15c5aba..c08f4bf0eb19 100644 --- a/media/java/android/media/ImageReader.java +++ b/media/java/android/media/ImageReader.java @@ -153,6 +153,7 @@ public class ImageReader implements AutoCloseable { mSurface = nativeGetSurface(); + mIsReaderValid = true; // Estimate the native buffer allocation size and register it so it gets accounted for // during GC. Note that this doesn't include the buffers required by the buffer queue // itself and the buffers requested by the producer. @@ -326,7 +327,11 @@ public class ImageReader implements AutoCloseable { */ private int acquireNextSurfaceImage(SurfaceImage si) { synchronized (mCloseLock) { - int status = nativeImageSetup(si); + // A null image will eventually be returned if ImageReader is already closed. + int status = ACQUIRE_NO_BUFS; + if (mIsReaderValid) { + status = nativeImageSetup(si); + } switch (status) { case ACQUIRE_SUCCESS: @@ -498,6 +503,7 @@ public class ImageReader implements AutoCloseable { * acquire operations. */ synchronized (mCloseLock) { + mIsReaderValid = false; for (Image image : mAcquiredImages) { image.close(); } @@ -613,6 +619,7 @@ public class ImageReader implements AutoCloseable { private final Object mListenerLock = new Object(); private final Object mCloseLock = new Object(); + private boolean mIsReaderValid = false; private OnImageAvailableListener mListener; private ListenerHandler mListenerHandler; // Keep track of the successfully acquired Images. This need to be thread safe as the images @@ -638,7 +645,14 @@ public class ImageReader implements AutoCloseable { synchronized (mListenerLock) { listener = mListener; } - if (listener != null) { + + // It's dangerous to fire onImageAvailable() callback when the ImageReader is being + // closed, as application could acquire next image in the onImageAvailable() callback. + boolean isReaderValid = false; + synchronized (mCloseLock) { + isReaderValid = mIsReaderValid; + } + if (listener != null && isReaderValid) { listener.onImageAvailable(ImageReader.this); } } |