Rename onException to onPartialImage
Bug: 63909536
Test: CTS: I8d1672180d8325ae1caf44f0bbf41036b94e6253
In ImageDecoder. The goal is to tell the client that there is a partial
image (which they can use if the callback returns true) and also allow
them to know why the image is partial.
Change how the return value is handled. Instead of returning null, which
is inconsistent with the rest of ImageDecoder, throw the Exception.
Change-Id: I56c38a624c978aa6e6d00fc927b5e355bf9c718a
diff --git a/core/jni/android/graphics/ImageDecoder.cpp b/core/jni/android/graphics/ImageDecoder.cpp
index c237564..ec03f82 100644
--- a/core/jni/android/graphics/ImageDecoder.cpp
+++ b/core/jni/android/graphics/ImageDecoder.cpp
@@ -46,7 +46,7 @@
static jmethodID gPoint_constructorMethodID;
static jmethodID gIncomplete_constructorMethodID;
static jmethodID gCorrupt_constructorMethodID;
-static jmethodID gCallback_onExceptionMethodID;
+static jmethodID gCallback_onPartialImageMethodID;
static jmethodID gPostProcess_postProcessMethodID;
static jmethodID gCanvas_constructorMethodID;
static jmethodID gCanvas_releaseMethodID;
@@ -276,7 +276,7 @@
SkAndroidCodec::AndroidOptions options;
options.fSampleSize = sampleSize;
auto result = codec->getAndroidPixels(decodeInfo, bm.getPixels(), bm.rowBytes(), &options);
- jobject jexception = env->ExceptionOccurred();
+ jthrowable jexception = env->ExceptionOccurred();
if (jexception) {
env->ExceptionClear();
}
@@ -287,12 +287,14 @@
break;
case SkCodec::kIncompleteInput:
if (jcallback && !jexception) {
- jexception = env->NewObject(gIncomplete_class, gIncomplete_constructorMethodID);
+ jexception = (jthrowable) env->NewObject(gIncomplete_class,
+ gIncomplete_constructorMethodID);
}
break;
case SkCodec::kErrorInInput:
if (jcallback && !jexception) {
- jexception = env->NewObject(gCorrupt_class, gCorrupt_constructorMethodID);
+ jexception = (jthrowable) env->NewObject(gCorrupt_class,
+ gCorrupt_constructorMethodID);
}
break;
default:
@@ -303,9 +305,14 @@
}
if (jexception) {
- // FIXME: Do not provide a way for the client to force the method to return null.
- if (!env->CallBooleanMethod(jcallback, gCallback_onExceptionMethodID, jexception) ||
- env->ExceptionCheck()) {
+ bool throwException = !env->CallBooleanMethod(jcallback, gCallback_onPartialImageMethodID,
+ jexception);
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
+
+ if (throwException) {
+ env->Throw(jexception);
return nullptr;
}
}
@@ -512,7 +519,7 @@
{ "nCreate", "([BII)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateByteArray },
{ "nCreate", "(Ljava/io/InputStream;[B)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateInputStream },
{ "nCreate", "(Ljava/io/FileDescriptor;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateFd },
- { "nDecodeBitmap", "(JLandroid/graphics/ImageDecoder$OnExceptionListener;Landroid/graphics/PostProcess;IILandroid/graphics/Rect;ZIZZZ)Landroid/graphics/Bitmap;",
+ { "nDecodeBitmap", "(JLandroid/graphics/ImageDecoder$OnPartialImageListener;Landroid/graphics/PostProcess;IILandroid/graphics/Rect;ZIZZZ)Landroid/graphics/Bitmap;",
(void*) ImageDecoder_nDecodeBitmap },
{ "nGetSampledSize","(JI)Landroid/graphics/Point;", (void*) ImageDecoder_nGetSampledSize },
{ "nGetPadding", "(JLandroid/graphics/Rect;)V", (void*) ImageDecoder_nGetPadding },
@@ -533,8 +540,8 @@
gCorrupt_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/ImageDecoder$CorruptException"));
gCorrupt_constructorMethodID = GetMethodIDOrDie(env, gCorrupt_class, "<init>", "()V");
- jclass callback_class = FindClassOrDie(env, "android/graphics/ImageDecoder$OnExceptionListener");
- gCallback_onExceptionMethodID = GetMethodIDOrDie(env, callback_class, "onException", "(Ljava/io/IOException;)Z");
+ jclass callback_class = FindClassOrDie(env, "android/graphics/ImageDecoder$OnPartialImageListener");
+ gCallback_onPartialImageMethodID = GetMethodIDOrDie(env, callback_class, "onPartialImage", "(Ljava/io/IOException;)Z");
jclass postProcess_class = FindClassOrDie(env, "android/graphics/PostProcess");
gPostProcess_postProcessMethodID = GetMethodIDOrDie(env, postProcess_class, "postProcess", "(Landroid/graphics/Canvas;II)I");
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 94b219a..419e2b7 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -239,7 +239,7 @@
};
/**
- * Supplied to onException if the provided data is incomplete.
+ * Supplied to onPartialImage if the provided data is incomplete.
*
* Will never be thrown by ImageDecoder.
*
@@ -252,7 +252,7 @@
*
* May be thrown if there is nothing to display.
*
- * If supplied to onException, there may be a correct partial image to
+ * If supplied to onPartialImage, there may be a correct partial image to
* display.
*/
public static class CorruptException extends IOException {};
@@ -275,17 +275,21 @@
/**
* Optional listener supplied to the ImageDecoder.
*/
- public static interface OnExceptionListener {
+ public static interface OnPartialImageListener {
/**
- * Called when there is a problem in the stream or in the data.
- * FIXME: Report how much of the image has been decoded?
+ * Called when there is only a partial image to display.
*
- * @param e IOException containing information about the error.
- * @return True to create and return a {@link Drawable}/
- * {@link Bitmap} with partial data. False to return
- * {@code null}. True is the default.
+ * If the input is incomplete or contains an error, this listener lets
+ * the client know that and allows them to optionally bypass the rest
+ * of the decode/creation process.
+ *
+ * @param e IOException containing information about the error that
+ * interrupted the decode.
+ * @return True (which is the default) to create and return a
+ * {@link Drawable}/{@link Bitmap} with partial data. False to
+ * abort the decode and throw the {@link java.io.IOException}.
*/
- public boolean onException(IOException e);
+ public boolean onPartialImage(IOException e);
};
// Fields
@@ -302,8 +306,8 @@
private boolean mAsAlphaMask = false;
private Rect mCropRect;
- private PostProcess mPostProcess;
- private OnExceptionListener mOnExceptionListener;
+ private PostProcess mPostProcess;
+ private OnPartialImageListener mOnPartialImageListener;
// Objects for interacting with the input.
private InputStream mInputStream;
@@ -557,13 +561,13 @@
}
/**
- * Set (replace) the {@link OnExceptionListener} on this object.
+ * Set (replace) the {@link OnPartialImageListener} on this object.
*
* Will be called if there is an error in the input. Without one, a
* partial {@link Bitmap} will be created.
*/
- public void setOnExceptionListener(OnExceptionListener l) {
- mOnExceptionListener = l;
+ public void setOnPartialImageListener(OnPartialImageListener l) {
+ mOnPartialImageListener = l;
}
/**
@@ -712,7 +716,7 @@
}
Bitmap bm = nDecodeBitmap(decoder.mNativePtr,
- decoder.mOnExceptionListener,
+ decoder.mOnPartialImageListener,
decoder.mPostProcess,
decoder.mDesiredWidth,
decoder.mDesiredHeight,
@@ -722,13 +726,6 @@
false, // mRequireUnpremultiplied
decoder.mPreferRamOverQuality,
decoder.mAsAlphaMask);
- if (bm == null) {
- // FIXME: bm should never be null. Currently a return value
- // of false from onException will result in bm being null. What
- // is the right API to choose to discard partial Bitmaps?
- return null;
- }
-
Resources res = src.getResources();
if (res == null) {
bm.setDensity(Bitmap.DENSITY_NONE);
@@ -786,7 +783,7 @@
decoder.checkState();
return nDecodeBitmap(decoder.mNativePtr,
- decoder.mOnExceptionListener,
+ decoder.mOnPartialImageListener,
decoder.mPostProcess,
decoder.mDesiredWidth,
decoder.mDesiredHeight,
@@ -821,7 +818,7 @@
private static native ImageDecoder nCreate(FileDescriptor fd) throws IOException;
@NonNull
private static native Bitmap nDecodeBitmap(long nativePtr,
- OnExceptionListener listener,
+ OnPartialImageListener listener,
PostProcess postProcess,
int width, int height,
Rect cropRect, boolean mutable,