Henrique Ferreiro | 0bb413bf | 2020-09-17 13:37:54 | [diff] [blame^] | 1 | // Copyright 2020 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "content/browser/renderer_host/drop_data_util.h" |
| 6 | |
| 7 | #include <string> |
| 8 | #include <utility> |
| 9 | #include <vector> |
| 10 | |
| 11 | #include "base/files/file_path.h" |
| 12 | #include "base/strings/utf_string_conversions.h" |
| 13 | #include "content/browser/native_file_system/native_file_system_manager_impl.h" |
| 14 | #include "content/public/common/drop_data.h" |
| 15 | #include "mojo/public/cpp/bindings/pending_remote.h" |
| 16 | #include "services/network/public/mojom/referrer_policy.mojom-shared.h" |
| 17 | #include "third_party/blink/public/mojom/native_file_system/native_file_system_drag_drop_token.mojom.h" |
| 18 | #include "third_party/blink/public/mojom/page/drag.mojom.h" |
| 19 | #include "ui/base/clipboard/clipboard_constants.h" |
| 20 | #include "ui/base/dragdrop/file_info/file_info.h" |
| 21 | #include "url/gurl.h" |
| 22 | |
| 23 | namespace content { |
| 24 | |
| 25 | blink::mojom::DragDataPtr DropDataToDragData( |
| 26 | const DropData& drop_data, |
| 27 | NativeFileSystemManagerImpl* native_file_system_manager, |
| 28 | int child_id) { |
| 29 | // These fields are currently unused when dragging into Blink. |
| 30 | DCHECK(drop_data.download_metadata.empty()); |
| 31 | DCHECK(drop_data.file_contents.empty()); |
| 32 | DCHECK(drop_data.file_contents_content_disposition.empty()); |
| 33 | |
| 34 | std::vector<blink::mojom::DragItemPtr> items; |
| 35 | if (drop_data.text) { |
| 36 | blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New(); |
| 37 | item->string_type = ui::kMimeTypeText; |
| 38 | item->string_data = *drop_data.text; |
| 39 | items.push_back(blink::mojom::DragItem::NewString(std::move(item))); |
| 40 | } |
| 41 | if (!drop_data.url.is_empty()) { |
| 42 | blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New(); |
| 43 | item->string_type = ui::kMimeTypeURIList; |
| 44 | item->string_data = base::UTF8ToUTF16(drop_data.url.spec()); |
| 45 | item->title = drop_data.url_title; |
| 46 | items.push_back(blink::mojom::DragItem::NewString(std::move(item))); |
| 47 | } |
| 48 | if (drop_data.html) { |
| 49 | blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New(); |
| 50 | item->string_type = ui::kMimeTypeHTML; |
| 51 | item->string_data = *drop_data.html; |
| 52 | item->base_url = drop_data.html_base_url; |
| 53 | items.push_back(blink::mojom::DragItem::NewString(std::move(item))); |
| 54 | } |
| 55 | for (const ui::FileInfo& file : drop_data.filenames) { |
| 56 | blink::mojom::DragItemFilePtr item = blink::mojom::DragItemFile::New(); |
| 57 | item->path = file.path; |
| 58 | item->display_name = file.display_name; |
| 59 | mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> |
| 60 | pending_token; |
| 61 | native_file_system_manager->CreateNativeFileSystemDragDropToken( |
| 62 | file.path, child_id, pending_token.InitWithNewPipeAndPassReceiver()); |
| 63 | item->native_file_system_token = std::move(pending_token); |
| 64 | items.push_back(blink::mojom::DragItem::NewFile(std::move(item))); |
| 65 | } |
| 66 | for (const content::DropData::FileSystemFileInfo& file_system_file : |
| 67 | drop_data.file_system_files) { |
| 68 | blink::mojom::DragItemFileSystemFilePtr item = |
| 69 | blink::mojom::DragItemFileSystemFile::New(); |
| 70 | item->url = file_system_file.url; |
| 71 | item->size = file_system_file.size; |
| 72 | item->file_system_id = file_system_file.filesystem_id; |
| 73 | items.push_back(blink::mojom::DragItem::NewFileSystemFile(std::move(item))); |
| 74 | } |
| 75 | for (const std::pair<base::string16, base::string16> data : |
| 76 | drop_data.custom_data) { |
| 77 | blink::mojom::DragItemStringPtr item = blink::mojom::DragItemString::New(); |
| 78 | item->string_type = base::UTF16ToUTF8(data.first); |
| 79 | item->string_data = data.second; |
| 80 | items.push_back(blink::mojom::DragItem::NewString(std::move(item))); |
| 81 | } |
| 82 | |
| 83 | return blink::mojom::DragData::New(std::move(items), |
| 84 | base::UTF16ToUTF8(drop_data.filesystem_id), |
| 85 | drop_data.referrer_policy); |
| 86 | } |
| 87 | |
| 88 | DropData DragDataToDropData(const blink::mojom::DragData& drag_data) { |
| 89 | DropData result; |
| 90 | |
| 91 | for (const blink::mojom::DragItemPtr& item : drag_data.items) { |
| 92 | switch (item->which()) { |
| 93 | case blink::mojom::DragItemDataView::Tag::STRING: { |
| 94 | const blink::mojom::DragItemStringPtr& string_item = item->get_string(); |
| 95 | std::string str_type = string_item->string_type; |
| 96 | if (str_type == ui::kMimeTypeText) { |
| 97 | result.text = string_item->string_data; |
| 98 | } else if (str_type == ui::kMimeTypeURIList) { |
| 99 | result.url = GURL(string_item->string_data); |
| 100 | if (string_item->title) |
| 101 | result.url_title = *string_item->title; |
| 102 | } else if (str_type == ui::kMimeTypeDownloadURL) { |
| 103 | result.download_metadata = string_item->string_data; |
| 104 | result.referrer_policy = drag_data.referrer_policy; |
| 105 | } else if (str_type == ui::kMimeTypeHTML) { |
| 106 | result.html = string_item->string_data; |
| 107 | if (string_item->base_url) |
| 108 | result.html_base_url = *string_item->base_url; |
| 109 | } else { |
| 110 | result.custom_data.emplace( |
| 111 | base::UTF8ToUTF16(string_item->string_type), |
| 112 | string_item->string_data); |
| 113 | } |
| 114 | break; |
| 115 | } |
| 116 | case blink::mojom::DragItemDataView::Tag::BINARY: { |
| 117 | DCHECK(result.file_contents.empty()); |
| 118 | |
| 119 | const blink::mojom::DragItemBinaryPtr& binary_item = item->get_binary(); |
| 120 | result.file_contents.reserve(binary_item->data.size()); |
| 121 | result.file_contents_source_url = binary_item->source_url; |
| 122 | result.file_contents_filename_extension = |
| 123 | binary_item->filename_extension.value(); |
| 124 | if (binary_item->content_disposition) { |
| 125 | result.file_contents_content_disposition = |
| 126 | *binary_item->content_disposition; |
| 127 | } |
| 128 | break; |
| 129 | } |
| 130 | case blink::mojom::DragItemDataView::Tag::FILE: { |
| 131 | const blink::mojom::DragItemFilePtr& file_item = item->get_file(); |
| 132 | // TODO(varunjain): This only works on chromeos. Support win/mac/gtk. |
| 133 | result.filenames.emplace_back(file_item->path, file_item->display_name); |
| 134 | break; |
| 135 | } |
| 136 | case blink::mojom::DragItemDataView::Tag::FILE_SYSTEM_FILE: { |
| 137 | const blink::mojom::DragItemFileSystemFilePtr& file_system_file_item = |
| 138 | item->get_file_system_file(); |
| 139 | DropData::FileSystemFileInfo info; |
| 140 | info.url = file_system_file_item->url; |
| 141 | info.size = file_system_file_item->size; |
| 142 | info.filesystem_id = file_system_file_item->file_system_id; |
| 143 | result.file_system_files.push_back(std::move(info)); |
| 144 | break; |
| 145 | } |
| 146 | } |
| 147 | } |
| 148 | return result; |
| 149 | } |
| 150 | |
| 151 | } // namespace content |