diff options
author | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-23 12:19:48 +0000 |
---|---|---|
committer | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-23 12:19:48 +0000 |
commit | 60ed95ffb41e79246d05381837b1fa386dd8a7a6 (patch) | |
tree | 837d4c110cfbac551a8df8bec09ffa730df6c4c2 | |
parent | 5206ae88cd5b226471a304c7f5b2740a6a7bfe79 (diff) | |
download | chromium_src-60ed95ffb41e79246d05381837b1fa386dd8a7a6.zip chromium_src-60ed95ffb41e79246d05381837b1fa386dd8a7a6.tar.gz chromium_src-60ed95ffb41e79246d05381837b1fa386dd8a7a6.tar.bz2 |
Support drag and drop of files with filesystem: URL
Filter filesystem files in RenderViewHostImpl::OnStartDragging.
Create isolated filesystem for each filesystem file in RenderViewHostImpl::DragTargetDragEnter.
Add file_system_files to content::DropData.
Wire information from blink::WebDragData to ui::OSExchangeData.
blink::WebDragData -[drop_data_builder.cc]-> content::DropData -[web_contents_view_aura.cc]-> ui::OSExchangeData
Wire information from ui::OSExchangeData to blink::WebDragData.
ui::OSExchangeData -[web_contents_view_aura.cc]-> content::DropData -[render_view_impl.cc]-> blink::WebDragData
BUG=126766
Review URL: https://codereview.chromium.org/242643004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@265616 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/browser/renderer_host/render_view_host_impl.cc | 36 | ||||
-rw-r--r-- | content/browser/web_contents/web_contents_view_aura.cc | 58 | ||||
-rw-r--r-- | content/common/drag_traits.h | 6 | ||||
-rw-r--r-- | content/public/common/drop_data.h | 11 | ||||
-rw-r--r-- | content/renderer/drop_data_builder.cc | 9 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 11 |
6 files changed, 129 insertions, 2 deletions
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 40bb8a4..ac03ecc 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -62,6 +62,7 @@ #include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_widget_host_iterator.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/user_metrics.h" #include "content/public/common/bindings_policy.h" #include "content/public/common/content_constants.h" @@ -775,6 +776,28 @@ void RenderViewHostImpl::DragTargetDragEnter( } filtered_data.filesystem_id = base::UTF8ToUTF16(filesystem_id); + fileapi::FileSystemContext* file_system_context = + BrowserContext::GetStoragePartition( + GetProcess()->GetBrowserContext(), + GetSiteInstance())->GetFileSystemContext(); + for (size_t i = 0; i < filtered_data.file_system_files.size(); ++i) { + fileapi::FileSystemURL file_system_url = + file_system_context->CrackURL(filtered_data.file_system_files[i].url); + + std::string register_name; + std::string filesystem_id = isolated_context->RegisterFileSystemForPath( + file_system_url.type(), file_system_url.path(), ®ister_name); + policy->GrantReadFileSystem(renderer_id, filesystem_id); + + // Note: We are using the origin URL provided by the sender here. It may be + // different from the receiver's. + filtered_data.file_system_files[i].url = GURL( + fileapi::GetIsolatedFileSystemRootURIString( + file_system_url.origin(), + filesystem_id, + std::string()).append(register_name)); + } + Send(new DragMsg_TargetDragEnter(GetRoutingID(), filtered_data, client_pt, screen_pt, operations_allowed, key_modifiers)); @@ -1324,6 +1347,19 @@ void RenderViewHostImpl::OnStartDragging( if (policy->CanReadFile(GetProcess()->GetID(), it->path)) filtered_data.filenames.push_back(*it); } + + fileapi::FileSystemContext* file_system_context = + BrowserContext::GetStoragePartition( + GetProcess()->GetBrowserContext(), + GetSiteInstance())->GetFileSystemContext(); + filtered_data.file_system_files.clear(); + for (size_t i = 0; i < drop_data.file_system_files.size(); ++i) { + fileapi::FileSystemURL file_system_url = + file_system_context->CrackURL(drop_data.file_system_files[i].url); + if (policy->CanReadFileSystemFile(GetProcess()->GetID(), file_system_url)) + filtered_data.file_system_files.push_back(drop_data.file_system_files[i]); + } + float scale = ui::GetImageScale(GetScaleFactorForView(GetView())); gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, scale)); view->StartDragging(filtered_data, drag_operations_mask, image, diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index 9062d5d..2d77af7 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc @@ -294,6 +294,54 @@ void PrepareDragForDownload( } #endif // defined(OS_WIN) +// Returns the CustomFormat to store file system files. +const ui::OSExchangeData::CustomFormat& GetFileSystemFileCustomFormat() { + static const char kFormatString[] = "chromium/x-file-system-files"; + CR_DEFINE_STATIC_LOCAL(ui::OSExchangeData::CustomFormat, + format, + (ui::Clipboard::GetFormatType(kFormatString))); + return format; +} + +// Writes file system files to the pickle. +void WriteFileSystemFilesToPickle( + const std::vector<DropData::FileSystemFileInfo>& file_system_files, + Pickle* pickle) { + pickle->WriteUInt64(file_system_files.size()); + for (size_t i = 0; i < file_system_files.size(); ++i) { + pickle->WriteString(file_system_files[i].url.spec()); + pickle->WriteInt64(file_system_files[i].size); + } +} + +// Reads file system files from the pickle. +bool ReadFileSystemFilesFromPickle( + const Pickle& pickle, + std::vector<DropData::FileSystemFileInfo>* file_system_files) { + PickleIterator iter(pickle); + + uint64 num_files = 0; + if (!pickle.ReadUInt64(&iter, &num_files)) + return false; + file_system_files->resize(num_files); + + for (uint64 i = 0; i < num_files; ++i) { + std::string url_string; + int64 size = 0; + if (!pickle.ReadString(&iter, &url_string) || + !pickle.ReadInt64(&iter, &size)) + return false; + + GURL url(url_string); + if (!url.is_valid()) + return false; + + (*file_system_files)[i].url = url; + (*file_system_files)[i].size = size; + } + return true; +} + // Utility to fill a ui::OSExchangeDataProvider object from DropData. void PrepareDragData(const DropData& drop_data, ui::OSExchangeData::Provider* provider, @@ -320,6 +368,11 @@ void PrepareDragData(const DropData& drop_data, provider->SetHtml(drop_data.html.string(), drop_data.html_base_url); if (!drop_data.filenames.empty()) provider->SetFilenames(drop_data.filenames); + if (!drop_data.file_system_files.empty()) { + Pickle pickle; + WriteFileSystemFilesToPickle(drop_data.file_system_files, &pickle); + provider->SetPickledData(GetFileSystemFileCustomFormat(), pickle); + } if (!drop_data.custom_data.empty()) { Pickle pickle; ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle); @@ -357,6 +410,11 @@ void PrepareDropData(DropData* drop_data, const ui::OSExchangeData& data) { data.GetFilenames(&drop_data->filenames); Pickle pickle; + std::vector<DropData::FileSystemFileInfo> file_system_files; + if (data.GetPickledData(GetFileSystemFileCustomFormat(), &pickle) && + ReadFileSystemFilesFromPickle(pickle, &file_system_files)) + drop_data->file_system_files = file_system_files; + if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), &pickle)) ui::ReadCustomDataIntoMap( pickle.data(), pickle.size(), &drop_data->custom_data); diff --git a/content/common/drag_traits.h b/content/common/drag_traits.h index 5b78528..fa8d358 100644 --- a/content/common/drag_traits.h +++ b/content/common/drag_traits.h @@ -27,6 +27,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::DropData) IPC_STRUCT_TRAITS_MEMBER(referrer_policy) IPC_STRUCT_TRAITS_MEMBER(filenames) IPC_STRUCT_TRAITS_MEMBER(filesystem_id) + IPC_STRUCT_TRAITS_MEMBER(file_system_files) IPC_STRUCT_TRAITS_MEMBER(text) IPC_STRUCT_TRAITS_MEMBER(html) IPC_STRUCT_TRAITS_MEMBER(html_base_url) @@ -35,6 +36,11 @@ IPC_STRUCT_TRAITS_BEGIN(content::DropData) IPC_STRUCT_TRAITS_MEMBER(custom_data) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(content::DropData::FileSystemFileInfo) + IPC_STRUCT_TRAITS_MEMBER(url) + IPC_STRUCT_TRAITS_MEMBER(size) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(content::DragEventSourceInfo) IPC_STRUCT_TRAITS_MEMBER(event_location) IPC_STRUCT_TRAITS_MEMBER(event_source) diff --git a/content/public/common/drop_data.h b/content/public/common/drop_data.h index 91628bf..3bc08df 100644 --- a/content/public/common/drop_data.h +++ b/content/public/common/drop_data.h @@ -22,6 +22,14 @@ namespace content { struct CONTENT_EXPORT DropData { + struct FileSystemFileInfo { + FileSystemFileInfo() : size(0) {} + ~FileSystemFileInfo() {} + + GURL url; + int64 size; + }; + DropData(); ~DropData(); @@ -47,6 +55,9 @@ struct CONTENT_EXPORT DropData { // Isolated filesystem ID for the files being dragged on the webview. base::string16 filesystem_id; + // User is dragging files specified with filesystem: URLs. + std::vector<FileSystemFileInfo> file_system_files; + // User is dragging plain text into the webview. base::NullableString16 text; diff --git a/content/renderer/drop_data_builder.cc b/content/renderer/drop_data_builder.cc index 14b4dcd..395c2b5 100644 --- a/content/renderer/drop_data_builder.cc +++ b/content/renderer/drop_data_builder.cc @@ -59,8 +59,13 @@ DropData DropDataBuilder::Build(const WebDragData& drag_data) { base::FilePath::FromUTF16Unsafe(item.filenameData), base::FilePath::FromUTF16Unsafe(item.displayNameData))); break; - default: // TODO(hashimoto): Remove this "default". - NOTREACHED(); + case WebDragData::Item::StorageTypeFileSystemFile: { + DropData::FileSystemFileInfo info; + info.url = item.fileSystemURL; + info.size = item.fileSystemFileSize; + result.file_system_files.push_back(info); + break; + } } } diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 96226f8..0b363d1 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -611,6 +611,17 @@ WebDragData DropDataToWebDragData(const DropData& drop_data) { item_list.push_back(item); } + for (std::vector<DropData::FileSystemFileInfo>::const_iterator it = + drop_data.file_system_files.begin(); + it != drop_data.file_system_files.end(); + ++it) { + WebDragData::Item item; + item.storageType = WebDragData::Item::StorageTypeFileSystemFile; + item.fileSystemURL = it->url; + item.fileSystemFileSize = it->size; + item_list.push_back(item); + } + for (std::map<base::string16, base::string16>::const_iterator it = drop_data.custom_data.begin(); it != drop_data.custom_data.end(); |