am 4b26247e: Merge "Change to stream decoding mode if the file descriptor cannot support seek." into honeycomb

* commit '4b26247e8b45850afc78e414a7007266dbdc5d18':
  Change to stream decoding mode if the file descriptor cannot support seek.
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index e47d91c..491a388 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -517,6 +517,11 @@
     }
 }
 
+static jboolean nativeIsSeekable(JNIEnv* env, jobject, jobject fileDescriptor) {
+    jint descriptor = env->GetIntField(fileDescriptor, gFileDescriptor_descriptor);
+    return ::lseek64(descriptor, 0, SEEK_CUR) != -1 ? JNI_TRUE : JNI_FALSE;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 static JNINativeMethod gMethods[] = {
@@ -546,6 +551,11 @@
     },
 
     {   "nativeSetDefaultConfig", "(I)V", (void*)nativeSetDefaultConfig },
+
+    {   "nativeIsSeekable",
+        "(Ljava/io/FileDescriptor;)Z",
+        (void*)nativeIsSeekable
+    },
 };
 
 static JNINativeMethod gOptionsMethods[] = {
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index dd6bf19..cffee5f 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -564,11 +564,22 @@
      * @return the decoded bitmap, or null
      */
     public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
-        Bitmap bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
-        if (bm == null && opts != null && opts.inBitmap != null) {
-            throw new IllegalArgumentException("Problem decoding into existing bitmap");
+        if (nativeIsSeekable(fd)) {
+            Bitmap bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
+            if (bm == null && opts != null && opts.inBitmap != null) {
+                throw new IllegalArgumentException("Problem decoding into existing bitmap");
+            }
+            return finishDecode(bm, outPadding, opts);
+        } else {
+            FileInputStream fis = new FileInputStream(fd);
+            try {
+                return decodeStream(fis, outPadding, opts);
+            } finally {
+                try {
+                    fis.close();
+                } catch (Throwable t) {/* ignore */}
+            }
         }
-        return finishDecode(bm, outPadding, opts);
     }
 
     /**
@@ -615,4 +626,5 @@
     private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
             int length, Options opts);
     private static native byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad);
+    private static native boolean nativeIsSeekable(FileDescriptor fd);
 }