Index: content/browser/web_contents/web_contents_view_aura.cc |
=================================================================== |
--- content/browser/web_contents/web_contents_view_aura.cc (revision 244560) |
+++ content/browser/web_contents/web_contents_view_aura.cc (working copy) |
@@ -6,8 +6,10 @@ |
#include "base/auto_reset.h" |
#include "base/command_line.h" |
+#include "base/file_util.h" |
#include "base/metrics/histogram.h" |
#include "base/strings/utf_string_conversions.h" |
+#include "content/browser/download/drag_download_util.h" |
#include "content/browser/frame_host/interstitial_page_impl.h" |
#include "content/browser/frame_host/navigation_entry_impl.h" |
#include "content/browser/renderer_host/dip_util.h" |
@@ -21,6 +23,7 @@ |
#include "content/browser/web_contents/aura/window_slider.h" |
#include "content/browser/web_contents/touch_editable_impl_aura.h" |
#include "content/browser/web_contents/web_contents_impl.h" |
+#include "content/public/browser/content_browser_client.h" |
#include "content/public/browser/notification_observer.h" |
#include "content/public/browser/notification_registrar.h" |
#include "content/public/browser/notification_source.h" |
@@ -33,6 +36,7 @@ |
#include "content/public/browser/web_contents_observer.h" |
#include "content/public/browser/web_contents_view_delegate.h" |
#include "content/public/browser/web_drag_dest_delegate.h" |
+#include "content/public/common/content_client.h" |
#include "content/public/common/content_switches.h" |
#include "content/public/common/drop_data.h" |
#include "net/base/net_util.h" |
@@ -256,12 +260,76 @@ |
} |
provider->SetFileContents(file_name, drop_data.file_contents); |
} |
+ |
+void PrepareDragForDownload( |
+ const DropData& drop_data, |
+ ui::OSExchangeData::Provider* provider, |
+ WebContentsImpl* web_contents) { |
+ const GURL& page_url = web_contents->GetLastCommittedURL(); |
+ const std::string& page_encoding = web_contents->GetEncoding(); |
+ |
+ // Parse the download metadata. |
+ base::string16 mime_type; |
+ base::FilePath file_name; |
+ GURL download_url; |
+ if (!ParseDownloadMetadata(drop_data.download_metadata, |
+ &mime_type, |
+ &file_name, |
+ &download_url)) |
+ return; |
+ |
+ // Generate the file name based on both mime type and proposed file name. |
+ std::string default_name = |
+ GetContentClient()->browser()->GetDefaultDownloadName(); |
+ base::FilePath generated_download_file_name = |
+ net::GenerateFileName(download_url, |
+ std::string(), |
+ std::string(), |
+ base::UTF16ToUTF8(file_name.value()), |
+ base::UTF16ToUTF8(mime_type), |
+ default_name); |
+ |
+ // http://crbug.com/332579 |
+ base::ThreadRestrictions::ScopedAllowIO allow_file_operations; |
+ |
+ base::FilePath temp_dir_path; |
+ if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_drag"), |
+ &temp_dir_path)) |
+ return; |
+ |
+ base::FilePath download_path = |
+ temp_dir_path.Append(generated_download_file_name); |
+ |
+ // We cannot know when the target application will be done using the temporary |
+ // file, so schedule it to be deleted after rebooting. |
+ base::DeleteFileAfterReboot(download_path); |
+ base::DeleteFileAfterReboot(temp_dir_path); |
+ |
+ // Provide the data as file (CF_HDROP). A temporary download file with the |
+ // Zone.Identifier ADS (Alternate Data Stream) attached will be created. |
+ scoped_refptr<DragDownloadFile> download_file = |
+ new DragDownloadFile( |
+ download_path, |
+ scoped_ptr<net::FileStream>(), |
+ download_url, |
+ Referrer(page_url, drop_data.referrer_policy), |
+ page_encoding, |
+ web_contents); |
+ ui::OSExchangeData::DownloadFileInfo file_download(base::FilePath(), |
+ download_file.get()); |
+ provider->SetDownloadFileInfo(file_download); |
+} |
#endif |
// Utility to fill a ui::OSExchangeDataProvider object from DropData. |
void PrepareDragData(const DropData& drop_data, |
- ui::OSExchangeData::Provider* provider) { |
+ ui::OSExchangeData::Provider* provider, |
+ WebContentsImpl* web_contents) { |
#if defined(OS_WIN) |
+ // Put download before file contents to prefer the download of a image over |
+ // its thumbnail link. |
+ if (!drop_data.download_metadata.empty()) |
+ PrepareDragForDownload(drop_data, provider, web_contents); |
// We set the file contents before the URL because the URL also sets file |
// contents (to a .URL shortcut). We want to prefer file content data over |
// a shortcut so we add it first. |
@@ -1367,7 +1435,7 @@ |
touch_editable_->EndTouchEditing(); |
ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider(); |
- PrepareDragData(drop_data, provider); |
+ PrepareDragData(drop_data, provider, web_contents_); |
ui::OSExchangeData data(provider); // takes ownership of |provider|. |