diff options
author | Derek Sollenberger <djsollen@google.com> | 2012-09-21 08:19:05 -0400 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2012-09-21 08:19:05 -0400 |
commit | cd77583ed336d10c5625933a565dcadf51705c61 (patch) | |
tree | 0ce7aa50801a206c8d745e7b6df2892aeb0e3ad7 /graphics | |
parent | 7b6ec1f6fd4f2858063d2d441b6118ac22da5569 (diff) | |
download | frameworks_base-cd77583ed336d10c5625933a565dcadf51705c61.zip frameworks_base-cd77583ed336d10c5625933a565dcadf51705c61.tar.gz frameworks_base-cd77583ed336d10c5625933a565dcadf51705c61.tar.bz2 |
Ensure that the decoder is thread-safe.
This prevents issues where one thread recycles the decoder while another
thread is in the process of checking the decoder's status or in the process
of decoding a region.
bug: 6880937
Change-Id: I7f755bf2149d03594e528ca79c536713b1447a55
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/java/android/graphics/BitmapRegionDecoder.java | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java index c1d3407..b38d107 100644 --- a/graphics/java/android/graphics/BitmapRegionDecoder.java +++ b/graphics/java/android/graphics/BitmapRegionDecoder.java @@ -36,6 +36,9 @@ import java.io.InputStream; public final class BitmapRegionDecoder { private int mNativeBitmapRegionDecoder; private boolean mRecycled; + // ensures that the native decoder object exists and that only one decode can + // occur at a time. + private final Object mNativeLock = new Object(); /** * Create a BitmapRegionDecoder from the specified byte array. @@ -179,24 +182,30 @@ public final class BitmapRegionDecoder { * decoded. */ public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) { - checkRecycled("decodeRegion called on recycled region decoder"); - if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= getWidth() - || rect.top >= getHeight()) - throw new IllegalArgumentException("rectangle is outside the image"); - return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, options); + synchronized (mNativeLock) { + checkRecycled("decodeRegion called on recycled region decoder"); + if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= getWidth() + || rect.top >= getHeight()) + throw new IllegalArgumentException("rectangle is outside the image"); + return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, options); + } } /** Returns the original image's width */ public int getWidth() { - checkRecycled("getWidth called on recycled region decoder"); - return nativeGetWidth(mNativeBitmapRegionDecoder); + synchronized (mNativeLock) { + checkRecycled("getWidth called on recycled region decoder"); + return nativeGetWidth(mNativeBitmapRegionDecoder); + } } /** Returns the original image's height */ public int getHeight() { - checkRecycled("getHeight called on recycled region decoder"); - return nativeGetHeight(mNativeBitmapRegionDecoder); + synchronized (mNativeLock) { + checkRecycled("getHeight called on recycled region decoder"); + return nativeGetHeight(mNativeBitmapRegionDecoder); + } } /** @@ -210,9 +219,11 @@ public final class BitmapRegionDecoder { * memory when there are no more references to this region decoder. */ public void recycle() { - if (!mRecycled) { - nativeClean(mNativeBitmapRegionDecoder); - mRecycled = true; + synchronized (mNativeLock) { + if (!mRecycled) { + nativeClean(mNativeBitmapRegionDecoder); + mRecycled = true; + } } } |