Bug 990642 - Try harder to find an extension to use when sharing images. r=mfinkle, a=lsblakk
authorWes Johnston <wjohnston@mozilla.com>
Mon, 12 May 2014 10:13:45 -0700
changeset 193409 4fa8558dd82750f605d043a902305e92c6fde717
parent 193408 f3247e4fa37d49188b9ebb7ba07a58dfe144aeb2
child 193410 ea269bc194685fb129990de5324a51684bf4bfa6
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, lsblakk
bugs990642
milestone30.0
Bug 990642 - Try harder to find an extension to use when sharing images. r=mfinkle, a=lsblakk
mobile/android/base/GeckoAppShell.java
mobile/android/base/widget/GeckoActionProvider.java
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -104,16 +104,17 @@ import android.util.Log;
 import android.view.ContextThemeWrapper;
 import android.view.HapticFeedbackConstants;
 import android.view.Surface;
 import android.view.SurfaceView;
 import android.view.TextureView;
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
 import android.webkit.MimeTypeMap;
+import android.webkit.URLUtil;
 import android.widget.AbsoluteLayout;
 import android.widget.Toast;
 
 public class GeckoAppShell
 {
     private static final String LOGTAG = "GeckoAppShell";
     private static final boolean LOGGING = false;
 
@@ -2634,47 +2635,63 @@ public class GeckoAppShell
 
         if (dir == null) {
             showImageShareFailureToast();
             return;
         }
 
         GeckoApp.deleteTempFiles();
 
+        String type = intent.getType();
         OutputStream os = null;
         try {
             // Create a temporary file for the image
-            final String type = intent.getType().replace("image/", "");
-            final File imageFile = File.createTempFile("image", "." + type, dir);
-            os = new FileOutputStream(imageFile);
-
             if (src.startsWith("data:")) {
-                int dataStart = src.indexOf(",");
+                final int dataStart = src.indexOf(",");
+
+                String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(type);
+
+                // If we weren't given an explicit mimetype, try to dig one out of the data uri.
+                if (TextUtils.isEmpty(extension) && dataStart > 5) {
+                    type = src.substring(5, dataStart).replace(";base64", "");
+                    extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(type);
+                }
+
+                final File imageFile = File.createTempFile("image", "." + extension, dir);
+                os = new FileOutputStream(imageFile);
+
                 byte[] buf = Base64.decode(src.substring(dataStart + 1), Base64.DEFAULT);
                 os.write(buf);
 
+                // Only alter the intent when we're sure everything has worked
                 intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
             } else {
                 InputStream is = null;
                 try {
                     final byte[] buf = new byte[2048];
                     final URL url = new URL(src);
+                    final String filename = URLUtil.guessFileName(src, null, type);
                     is = url.openStream();
 
+                    final File imageFile = new File(dir, filename);
+                    os = new FileOutputStream(imageFile);
+
                     int length;
                     while ((length = is.read(buf)) != -1) {
                         os.write(buf, 0, length);
                     }
 
+                    // Only alter the intent when we're sure everything has worked
                     intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
                 } finally {
                     safeStreamClose(is);
                 }
             }
         } catch(IOException ex) {
+            // If something went wrong, we'll just leave the intent un-changed
         } finally {
             safeStreamClose(os);
         }
     }
 
     // Don't fail silently, tell the user that we weren't able to share the image
     private static final void showImageShareFailureToast() {
         Toast toast = Toast.makeText(getContext(),
--- a/mobile/android/base/widget/GeckoActionProvider.java
+++ b/mobile/android/base/widget/GeckoActionProvider.java
@@ -1,15 +1,16 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.widget;
 
+import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.menu.MenuItemActionView;
 
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Drawable;
 import android.view.MenuItem;