blob: f55dcfa9534f27cf7ce36df70878fba964cfd4dc [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/mojo/drag_mojom_traits.h"
#include "base/check.h"
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_refptr.h"
#include "base/notreached.h"
#include "base/optional.h"
#include "base/strings/string16.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/network/public/mojom/referrer_policy.mojom-shared.h"
#include "third_party/blink/public/mojom/file_system_access/file_system_access_data_transfer_token.mojom-blink.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace mojo {
// static
WTF::String StructTraits<
blink::mojom::DragItemStringDataView,
blink::WebDragData::Item>::string_type(blink::WebDragData::Item item) {
return item.string_type;
}
// static
WTF::String
StructTraits<blink::mojom::DragItemStringDataView, blink::WebDragData::Item>::
string_data(const blink::WebDragData::Item& item) {
return item.string_data;
}
// static
WTF::String StructTraits<
blink::mojom::DragItemStringDataView,
blink::WebDragData::Item>::title(const blink::WebDragData::Item& item) {
return item.title;
}
// static
base::Optional<blink::KURL> StructTraits<
blink::mojom::DragItemStringDataView,
blink::WebDragData::Item>::base_url(const blink::WebDragData::Item& item) {
if (item.base_url.IsNull())
return base::nullopt;
return item.base_url;
}
// static
bool StructTraits<
blink::mojom::DragItemStringDataView,
blink::WebDragData::Item>::Read(blink::mojom::DragItemStringDataView data,
blink::WebDragData::Item* out) {
blink::WebDragData::Item item;
WTF::String string_type, string_data, title;
base::Optional<blink::KURL> url;
if (!data.ReadStringType(&string_type) ||
!data.ReadStringData(&string_data) || !data.ReadTitle(&title) ||
!data.ReadBaseUrl(&url))
return false;
item.storage_type = blink::WebDragData::Item::kStorageTypeString;
item.string_type = string_type;
item.string_data = string_data;
item.title = title;
item.base_url = url.value_or(blink::KURL());
*out = std::move(item);
return true;
}
// static
base::FilePath StructTraits<
blink::mojom::DataTransferFileDataView,
blink::WebDragData::Item>::path(const blink::WebDragData::Item& item) {
return WebStringToFilePath(item.filename_data);
}
// static
base::FilePath
StructTraits<blink::mojom::DataTransferFileDataView, blink::WebDragData::Item>::
display_name(const blink::WebDragData::Item& item) {
return WebStringToFilePath(item.display_name_data);
}
// static
bool StructTraits<
blink::mojom::DataTransferFileDataView,
blink::WebDragData::Item>::Read(blink::mojom::DataTransferFileDataView data,
blink::WebDragData::Item* out) {
blink::WebDragData::Item item;
base::FilePath filename_data, display_name_data;
if (!data.ReadPath(&filename_data) ||
!data.ReadDisplayName(&display_name_data))
return false;
item.storage_type = blink::WebDragData::Item::kStorageTypeFilename;
item.filename_data = blink::FilePathToWebString(filename_data);
item.display_name_data = blink::FilePathToWebString(display_name_data);
mojo::PendingRemote<::blink::mojom::blink::FileSystemAccessDataTransferToken>
file_system_access_token(
data.TakeFileSystemAccessToken<mojo::PendingRemote<
::blink::mojom::blink::FileSystemAccessDataTransferToken>>());
item.file_system_access_entry =
base::MakeRefCounted<::blink::FileSystemAccessDropData>(
std::move(file_system_access_token));
*out = std::move(item);
return true;
}
// static
mojo_base::BigBuffer StructTraits<
blink::mojom::DragItemBinaryDataView,
blink::WebDragData::Item>::data(const blink::WebDragData::Item& item) {
mojo_base::BigBuffer buffer(item.binary_data.size());
item.binary_data.ForEachSegment([&buffer](const char* segment,
size_t segment_size,
size_t segment_offset) {
std::copy(segment, segment + segment_size, buffer.data() + segment_offset);
return true;
});
return buffer;
}
// static
blink::KURL
StructTraits<blink::mojom::DragItemBinaryDataView, blink::WebDragData::Item>::
source_url(const blink::WebDragData::Item& item) {
return item.binary_data_source_url;
}
// static
base::FilePath
StructTraits<blink::mojom::DragItemBinaryDataView, blink::WebDragData::Item>::
filename_extension(const blink::WebDragData::Item& item) {
return WebStringToFilePath(item.binary_data_filename_extension);
}
// static
WTF::String
StructTraits<blink::mojom::DragItemBinaryDataView, blink::WebDragData::Item>::
content_disposition(const blink::WebDragData::Item& item) {
return item.binary_data_content_disposition;
}
// static
bool StructTraits<
blink::mojom::DragItemBinaryDataView,
blink::WebDragData::Item>::Read(blink::mojom::DragItemBinaryDataView data,
blink::WebDragData::Item* out) {
// storage_type == kBinary should not happen when dragging into Blink.
NOTREACHED();
return true;
}
// static
blink::KURL StructTraits<
blink::mojom::DragItemFileSystemFileDataView,
blink::WebDragData::Item>::url(const blink::WebDragData::Item& item) {
return item.file_system_url;
}
// static
int64_t StructTraits<
blink::mojom::DragItemFileSystemFileDataView,
blink::WebDragData::Item>::size(const blink::WebDragData::Item& item) {
return item.file_system_file_size;
}
// static
WTF::String StructTraits<blink::mojom::DragItemFileSystemFileDataView,
blink::WebDragData::Item>::
file_system_id(const blink::WebDragData::Item& item) {
DCHECK(item.file_system_id.IsNull());
return item.file_system_id;
}
// static
mojo::PendingRemote<blink::mojom::blink::FileSystemAccessDataTransferToken>
StructTraits<blink::mojom::DataTransferFileDataView, blink::WebDragData::Item>::
file_system_access_token(const blink::WebDragData::Item& item) {
// Should never have to send a transfer token information from the renderer
// to the browser.
DCHECK(!item.file_system_access_entry);
return mojo::NullRemote();
}
// static
bool StructTraits<blink::mojom::DragItemFileSystemFileDataView,
blink::WebDragData::Item>::
Read(blink::mojom::DragItemFileSystemFileDataView data,
blink::WebDragData::Item* out) {
blink::WebDragData::Item item;
blink::KURL file_system_url;
WTF::String file_system_id;
if (!data.ReadUrl(&file_system_url) ||
!data.ReadFileSystemId(&file_system_id))
return false;
item.storage_type = blink::WebDragData::Item::kStorageTypeFileSystemFile;
item.file_system_url = file_system_url;
item.file_system_file_size = data.size();
item.file_system_id = file_system_id;
*out = std::move(item);
return true;
}
// static
bool UnionTraits<blink::mojom::DragItemDataView, blink::WebDragData::Item>::
Read(blink::mojom::DragItemDataView data, blink::WebDragData::Item* out) {
blink::WebDragData::Item item;
switch (data.tag()) {
case blink::mojom::DragItemDataView::Tag::STRING:
return data.ReadString(out);
case blink::mojom::DragItemDataView::Tag::FILE:
return data.ReadFile(out);
case blink::mojom::DragItemDataView::Tag::BINARY:
return data.ReadBinary(out);
case blink::mojom::DragItemDataView::Tag::FILE_SYSTEM_FILE:
return data.ReadFileSystemFile(out);
}
NOTREACHED();
return false;
}
// static
blink::mojom::DragItemDataView::Tag
UnionTraits<blink::mojom::DragItemDataView, blink::WebDragData::Item>::GetTag(
const blink::WebDragData::Item& item) {
switch (item.storage_type) {
case blink::WebDragData::Item::kStorageTypeString:
return blink::mojom::DragItemDataView::Tag::STRING;
case blink::WebDragData::Item::kStorageTypeFilename:
return blink::mojom::DragItemDataView::Tag::FILE;
case blink::WebDragData::Item::kStorageTypeBinaryData:
return blink::mojom::DragItemDataView::Tag::BINARY;
case blink::WebDragData::Item::kStorageTypeFileSystemFile:
return blink::mojom::DragItemDataView::Tag::FILE_SYSTEM_FILE;
}
NOTREACHED();
return blink::mojom::DragItemDataView::Tag::STRING;
}
// static
blink::WebVector<blink::WebDragData::Item>
StructTraits<blink::mojom::DragDataDataView, blink::WebDragData>::items(
const blink::WebDragData& drag_data) {
return drag_data.Items();
}
// static
WTF::String StructTraits<blink::mojom::DragDataDataView, blink::WebDragData>::
file_system_id(const blink::WebDragData& drag_data) {
// Only used when dragging into Blink.
DCHECK(drag_data.FilesystemId().IsNull());
return drag_data.FilesystemId();
}
// static
network::mojom::ReferrerPolicy StructTraits<
blink::mojom::DragDataDataView,
blink::WebDragData>::referrer_policy(const blink::WebDragData& drag_data) {
return drag_data.ReferrerPolicy();
}
// static
bool StructTraits<blink::mojom::DragDataDataView, blink::WebDragData>::Read(
blink::mojom::DragDataDataView data,
blink::WebDragData* out) {
blink::WebVector<blink::WebDragData::Item> items;
WTF::String file_system_id;
network::mojom::ReferrerPolicy referrer_policy;
if (!data.ReadItems(&items) || !data.ReadFileSystemId(&file_system_id) ||
!data.ReadReferrerPolicy(&referrer_policy))
return false;
blink::WebDragData drag_data;
drag_data.SetItems(std::move(items));
drag_data.SetFilesystemId(file_system_id);
drag_data.SetReferrerPolicy(referrer_policy);
*out = std::move(drag_data);
return true;
}
} // namespace mojo