Skip to content

Commit cd77583

Browse files
committed
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
1 parent 7b6ec1f commit cd77583

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

graphics/java/android/graphics/BitmapRegionDecoder.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
public final class BitmapRegionDecoder {
3737
private int mNativeBitmapRegionDecoder;
3838
private boolean mRecycled;
39+
// ensures that the native decoder object exists and that only one decode can
40+
// occur at a time.
41+
private final Object mNativeLock = new Object();
3942

4043
/**
4144
* Create a BitmapRegionDecoder from the specified byte array.
@@ -179,24 +182,30 @@ private BitmapRegionDecoder(int decoder) {
179182
* decoded.
180183
*/
181184
public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) {
182-
checkRecycled("decodeRegion called on recycled region decoder");
183-
if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= getWidth()
184-
|| rect.top >= getHeight())
185-
throw new IllegalArgumentException("rectangle is outside the image");
186-
return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top,
187-
rect.right - rect.left, rect.bottom - rect.top, options);
185+
synchronized (mNativeLock) {
186+
checkRecycled("decodeRegion called on recycled region decoder");
187+
if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= getWidth()
188+
|| rect.top >= getHeight())
189+
throw new IllegalArgumentException("rectangle is outside the image");
190+
return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top,
191+
rect.right - rect.left, rect.bottom - rect.top, options);
192+
}
188193
}
189194

190195
/** Returns the original image's width */
191196
public int getWidth() {
192-
checkRecycled("getWidth called on recycled region decoder");
193-
return nativeGetWidth(mNativeBitmapRegionDecoder);
197+
synchronized (mNativeLock) {
198+
checkRecycled("getWidth called on recycled region decoder");
199+
return nativeGetWidth(mNativeBitmapRegionDecoder);
200+
}
194201
}
195202

196203
/** Returns the original image's height */
197204
public int getHeight() {
198-
checkRecycled("getHeight called on recycled region decoder");
199-
return nativeGetHeight(mNativeBitmapRegionDecoder);
205+
synchronized (mNativeLock) {
206+
checkRecycled("getHeight called on recycled region decoder");
207+
return nativeGetHeight(mNativeBitmapRegionDecoder);
208+
}
200209
}
201210

202211
/**
@@ -210,9 +219,11 @@ public int getHeight() {
210219
* memory when there are no more references to this region decoder.
211220
*/
212221
public void recycle() {
213-
if (!mRecycled) {
214-
nativeClean(mNativeBitmapRegionDecoder);
215-
mRecycled = true;
222+
synchronized (mNativeLock) {
223+
if (!mRecycled) {
224+
nativeClean(mNativeBitmapRegionDecoder);
225+
mRecycled = true;
226+
}
216227
}
217228
}
218229

0 commit comments

Comments
 (0)