Chromium Code Reviews| Index: content/browser/web_contents/web_contents_view_aura.cc |
| diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc |
| index 6825fc677a477bd6ccf6747a37a4d362370b4035..6cacaacf75d8cfef930b368a12992da83afb1779 100644 |
| --- a/content/browser/web_contents/web_contents_view_aura.cc |
| +++ b/content/browser/web_contents/web_contents_view_aura.cc |
| @@ -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,75 @@ void PrepareDragForFileContents(const DropData& drop_data, |
| } |
| 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 = |
|
Ben Goodger (Google)
2014/01/11 05:01:47
nit: nl above
scottmg
2014/01/11 05:02:46
Done.
|
| + 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. |
| @@ -1368,7 +1435,7 @@ void WebContentsViewAura::StartDragging( |
| 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|. |