Use mime type for image extension

This CL uses the mime type to determine the best image extension when saving
an image.

BUG=690355

Review-Url: https://codereview.chromium.org/2687873002
Cr-Commit-Position: refs/heads/master@{#449365}
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index b201040..f287d477 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -16,6 +16,7 @@
 
 #include "base/base64.h"
 #include "base/command_line.h"
+#include "base/files/file_path.h"
 #include "base/format_macros.h"
 #include "base/i18n/rtl.h"
 #include "base/ios/block_types.h"
@@ -185,6 +186,7 @@
 #include "ios/web/public/web_thread.h"
 #import "ios/web/web_state/ui/crw_web_controller.h"
 #import "net/base/mac/url_conversions.h"
+#include "net/base/mime_util.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "net/ssl/ssl_info.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -677,11 +679,12 @@
 // Induces an intentional crash in the browser process.
 - (void)induceBrowserCrash;
 // Saves the image or display error message, based on privacy settings.
-- (void)managePermissionAndSaveImage:(NSData*)data;
+- (void)managePermissionAndSaveImage:(NSData*)data
+                   withFileExtension:(NSString*)fileExtension;
 // Saves the image. In order to keep the metadata of the image, the image is
 // saved as a temporary file on disk then saved in photos.
 // This should be called on FILE thread.
-- (void)saveImage:(NSData*)data;
+- (void)saveImage:(NSData*)data withFileExtension:(NSString*)fileExtension;
 // Called when Chrome has been denied access to the photos or videos and the
 // user can change it.
 // Shows a privacy alert on the main queue, allowing the user to go to Chrome's
@@ -2991,7 +2994,8 @@
   DCHECK(url.is_valid());
   base::WeakNSObject<BrowserViewController> weakSelf(self);
   const GURL image_source_url = url;
-  image_fetcher::IOSImageDataFetcherCallback callback = ^(NSData* data) {
+  image_fetcher::IOSImageDataFetcherCallback callback = ^(
+      NSData* data, const image_fetcher::RequestMetadata& metadata) {
     DCHECK(data);
     dispatch_async(dispatch_get_main_queue(), ^{
       [weakSelf searchByImageData:data atURL:image_source_url];
@@ -3047,17 +3051,29 @@
               referrer:(const web::Referrer&)referrer {
   DCHECK(url.is_valid());
 
-  image_fetcher::IOSImageDataFetcherCallback callback = ^(NSData* data) {
+  image_fetcher::IOSImageDataFetcherCallback callback = ^(
+      NSData* data, const image_fetcher::RequestMetadata& metadata) {
     DCHECK(data);
 
-    [self managePermissionAndSaveImage:data];
+    base::FilePath::StringType extension;
+
+    bool extensionSuccess =
+        net::GetPreferredExtensionForMimeType(metadata.mime_type, &extension);
+    if (!extensionSuccess || extension.length() == 0) {
+      extension = "png";
+    }
+
+    NSString* fileExtension =
+        [@"." stringByAppendingString:base::SysUTF8ToNSString(extension)];
+    [self managePermissionAndSaveImage:data withFileExtension:fileExtension];
   };
   _imageFetcher->FetchImageDataWebpDecoded(
       url, callback, web::ReferrerHeaderValueForNavigation(url, referrer),
       web::PolicyForNavigation(url, referrer));
 }
 
-- (void)managePermissionAndSaveImage:(NSData*)data {
+- (void)managePermissionAndSaveImage:(NSData*)data
+                   withFileExtension:(NSString*)fileExtension {
   switch ([PHPhotoLibrary authorizationStatus]) {
     // User was never asked for permission to access photos.
     case PHAuthorizationStatusNotDetermined:
@@ -3065,7 +3081,8 @@
         // Call -saveImage again to check if chrome needs to display an error or
         // saves the image.
         if (status != PHAuthorizationStatusNotDetermined)
-          [self managePermissionAndSaveImage:data];
+          [self managePermissionAndSaveImage:data
+                           withFileExtension:fileExtension];
       }];
       break;
 
@@ -3085,18 +3102,18 @@
 
     // The application has permission to access the photos.
     default: {
-      web::WebThread::PostTask(web::WebThread::FILE, FROM_HERE,
-                               base::BindBlock(^{
-                                 [self saveImage:data];
-                               }));
+      web::WebThread::PostTask(
+          web::WebThread::FILE, FROM_HERE, base::BindBlock(^{
+            [self saveImage:data withFileExtension:fileExtension];
+          }));
       break;
     }
   }
 }
 
-- (void)saveImage:(NSData*)data {
+- (void)saveImage:(NSData*)data withFileExtension:(NSString*)fileExtension {
   NSString* fileName = [[[NSProcessInfo processInfo] globallyUniqueString]
-      stringByAppendingString:@".png"];
+      stringByAppendingString:fileExtension];
   NSURL* fileURL =
       [NSURL fileURLWithPath:[NSTemporaryDirectory()
                                  stringByAppendingPathComponent:fileName]];