Commit 217890eb authored by scottmg@chromium.org's avatar scottmg@chromium.org

Add CF_HDROP path for dragging on Win Aura

This ports the PrepareDragForDownload path over from the native windows
code path. This makes dragging files to explorer from, for example, gmail
save the content of the file, rather than a link, or the thumbnail
image.

(This needs to be merged to 32, so attempted to keep it semi-localized.)

BUG=332579,333320
R=ben@chromium.org

Review URL: https://codereview.chromium.org/135393002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244355 0039d316-1c4b-4281-b951-d872f2087c98
parent d44b5d26
......@@ -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 @@ 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 =
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 +1436,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|.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment