Commit ba05b80c authored by Joel Hockey's avatar Joel Hockey Committed by Commit Bot

Support text/uri-list for file drag and drop in exo

Bug: 1144138

Change-Id: I57414924c9b09d100af6b6fa2b1f713310104209
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2504447
Commit-Queue: Joel Hockey <joelhockey@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824178}
parent ad5753fd
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/pickle.h" #include "base/pickle.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#include "components/exo/data_offer_delegate.h" #include "components/exo/data_offer_delegate.h"
#include "components/exo/data_offer_observer.h" #include "components/exo/data_offer_observer.h"
#include "components/exo/file_helper.h" #include "components/exo/file_helper.h"
#include "net/base/filename_util.h"
#include "third_party/skia/include/core/SkEncodedImageFormat.h" #include "third_party/skia/include/core/SkEncodedImageFormat.h"
#include "third_party/skia/include/core/SkImageEncoder.h" #include "third_party/skia/include/core/SkImageEncoder.h"
#include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/core/SkStream.h"
...@@ -38,6 +40,7 @@ constexpr char kTextMimeTypeUtf16[] = "text/plain;charset=utf-16"; ...@@ -38,6 +40,7 @@ constexpr char kTextMimeTypeUtf16[] = "text/plain;charset=utf-16";
constexpr char kTextHtmlMimeTypeUtf8[] = "text/html;charset=utf-8"; constexpr char kTextHtmlMimeTypeUtf8[] = "text/html;charset=utf-8";
constexpr char kTextHtmlMimeTypeUtf16[] = "text/html;charset=utf-16"; constexpr char kTextHtmlMimeTypeUtf16[] = "text/html;charset=utf-16";
constexpr char kTextRtfMimeType[] = "text/rtf"; constexpr char kTextRtfMimeType[] = "text/rtf";
constexpr char kTextUriListMimeType[] = "text/uri-list";
constexpr char kImagePngMimeType[] = "image/png"; constexpr char kImagePngMimeType[] = "image/png";
constexpr char kUriListSeparator[] = "\r\n"; constexpr char kUriListSeparator[] = "\r\n";
...@@ -263,6 +266,22 @@ void DataOffer::SetDropData(FileHelper* file_helper, ...@@ -263,6 +266,22 @@ void DataOffer::SetDropData(FileHelper* file_helper,
const ui::OSExchangeData& data) { const ui::OSExchangeData& data) {
DCHECK_EQ(0u, data_callbacks_.size()); DCHECK_EQ(0u, data_callbacks_.size());
std::string filenames_content;
// TODO(crbug.com/1144138): If we are dropping this in a VM, we must
// translate paths, and share paths at the time when data is received.
if (data.HasFile()) {
std::vector<ui::FileInfo> files;
std::vector<std::string> lines;
data.GetFilenames(&files);
for (const auto& file : files)
lines.emplace_back(net::FilePathToFileURL(file.path).spec());
filenames_content = base::JoinString(lines, kUriListSeparator);
data_callbacks_.emplace(
kTextUriListMimeType,
AsyncSend(base::RefCountedString::TakeString(&filenames_content)));
delegate_->OnOffer(kTextUriListMimeType);
}
const std::string uri_list_mime_type = file_helper->GetMimeTypeForUriList(); const std::string uri_list_mime_type = file_helper->GetMimeTypeForUriList();
base::string16 url_list_string; base::string16 url_list_string;
if (GetUrlListFromDataFile(file_helper, data, &url_list_string)) { if (GetUrlListFromDataFile(file_helper, data, &url_list_string)) {
......
...@@ -308,9 +308,9 @@ TEST_F(DataOfferTest, ReceiveUriList) { ...@@ -308,9 +308,9 @@ TEST_F(DataOfferTest, ReceiveUriList) {
ASSERT_TRUE(base::CreatePipe(&read_pipe, &write_pipe)); ASSERT_TRUE(base::CreatePipe(&read_pipe, &write_pipe));
data_offer.Receive("text/uri-list", std::move(write_pipe)); data_offer.Receive("text/uri-list", std::move(write_pipe));
base::string16 result; std::string result;
ASSERT_TRUE(ReadString16(std::move(read_pipe), &result)); ASSERT_TRUE(ReadString(std::move(read_pipe), &result));
EXPECT_EQ(base::ASCIIToUTF16("file:///test/downloads/file"), result); EXPECT_EQ("file:///test/downloads/file", result);
} }
TEST_F(DataOfferTest, ReceiveUriListFromPickle_ReceiveBeforeUrlIsResolved) { TEST_F(DataOfferTest, ReceiveUriListFromPickle_ReceiveBeforeUrlIsResolved) {
......
...@@ -31,6 +31,7 @@ namespace { ...@@ -31,6 +31,7 @@ namespace {
constexpr char kTextPlain[] = "text/plain"; constexpr char kTextPlain[] = "text/plain";
constexpr char kTextRTF[] = "text/rtf"; constexpr char kTextRTF[] = "text/rtf";
constexpr char kTextHTML[] = "text/html"; constexpr char kTextHTML[] = "text/html";
constexpr char kTextUriList[] = "text/uri-list";
constexpr char kUtfPrefix[] = "UTF"; constexpr char kUtfPrefix[] = "UTF";
constexpr char kEncoding16[] = "16"; constexpr char kEncoding16[] = "16";
...@@ -240,8 +241,9 @@ void DataSource::GetDataForPreferredMimeTypes( ...@@ -240,8 +241,9 @@ void DataSource::GetDataForPreferredMimeTypes(
ReadDataCallback rtf_reader, ReadDataCallback rtf_reader,
ReadTextDataCallback html_reader, ReadTextDataCallback html_reader,
ReadDataCallback image_reader, ReadDataCallback image_reader,
ReadDataCallback filenames_reader,
base::RepeatingClosure failure_callback) { base::RepeatingClosure failure_callback) {
std::string text_mime, rtf_mime, html_mime, image_mime; std::string text_mime, rtf_mime, html_mime, image_mime, filenames_mime;
int text_rank = std::numeric_limits<int>::max(); int text_rank = std::numeric_limits<int>::max();
int html_rank = std::numeric_limits<int>::max(); int html_rank = std::numeric_limits<int>::max();
...@@ -286,6 +288,11 @@ void DataSource::GetDataForPreferredMimeTypes( ...@@ -286,6 +288,11 @@ void DataSource::GetDataForPreferredMimeTypes(
image_mime = mime_type; image_mime = mime_type;
image_rank = new_rank; image_rank = new_rank;
} }
} else if (net::MatchesMimeType(std::string(kTextUriList), mime_type)) {
if (filenames_reader.is_null())
continue;
filenames_mime = mime_type;
} }
} }
...@@ -301,6 +308,7 @@ void DataSource::GetDataForPreferredMimeTypes( ...@@ -301,6 +308,7 @@ void DataSource::GetDataForPreferredMimeTypes(
std::move(html_reader)), std::move(html_reader)),
failure_callback); failure_callback);
ReadData(image_mime, std::move(image_reader), failure_callback); ReadData(image_mime, std::move(image_reader), failure_callback);
ReadData(filenames_mime, std::move(filenames_reader), failure_callback);
} }
void DataSource::OnTextRead(ReadTextDataCallback callback, void DataSource::OnTextRead(ReadTextDataCallback callback,
......
...@@ -60,8 +60,9 @@ class DataSource { ...@@ -60,8 +60,9 @@ class DataSource {
void DndFinished(); void DndFinished();
// Search the set of offered MIME types for the most preferred of each of the // Search the set of offered MIME types for the most preferred of each of the
// following categories: text/plain*, text/rtf, text/html*, image/*. If any // following categories: text/plain*, text/rtf, text/html*, image/*,
// usable MIME types in a given category are available, the corresponding // text/uri-list. If any usable MIME types in a given category are available,
// the corresponding
// |*_reader| input callback will be called with the best one and the // |*_reader| input callback will be called with the best one and the
// corresponding data. For any category that has no available MIME types, // corresponding data. For any category that has no available MIME types,
// |failure_callback| is run. |failure_callback| may therefore be run as many // |failure_callback| is run. |failure_callback| may therefore be run as many
...@@ -74,6 +75,7 @@ class DataSource { ...@@ -74,6 +75,7 @@ class DataSource {
ReadDataCallback rtf_reader, ReadDataCallback rtf_reader,
ReadTextDataCallback html_reader, ReadTextDataCallback html_reader,
ReadDataCallback image_reader, ReadDataCallback image_reader,
ReadDataCallback filenames_reader,
base::RepeatingClosure failure_callback); base::RepeatingClosure failure_callback);
void ReadDataForTesting(const std::string& mime_type, void ReadDataForTesting(const std::string& mime_type,
......
...@@ -68,11 +68,12 @@ void IncrementCounter(base::RepeatingClosure counter) { ...@@ -68,11 +68,12 @@ void IncrementCounter(base::RepeatingClosure counter) {
std::move(counter).Run(); std::move(counter).Run();
} }
void CheckMimeTypesRecieved(DataSource* data_source, void CheckMimeTypesReceived(DataSource* data_source,
const std::string& text_mime, const std::string& text_mime,
const std::string& rtf_mime, const std::string& rtf_mime,
const std::string& html_mime, const std::string& html_mime,
const std::string& image_mime) { const std::string& image_mime,
const std::string& filenames_mime) {
base::RunLoop run_loop; base::RunLoop run_loop;
base::RepeatingClosure counter = base::RepeatingClosure counter =
base::BarrierClosure(4, run_loop.QuitClosure()); base::BarrierClosure(4, run_loop.QuitClosure());
...@@ -81,6 +82,7 @@ void CheckMimeTypesRecieved(DataSource* data_source, ...@@ -81,6 +82,7 @@ void CheckMimeTypesRecieved(DataSource* data_source,
base::BindOnce(&CheckMimeType, rtf_mime, counter), base::BindOnce(&CheckMimeType, rtf_mime, counter),
base::BindOnce(&CheckTextMimeType, html_mime, counter), base::BindOnce(&CheckTextMimeType, html_mime, counter),
base::BindOnce(&CheckMimeType, image_mime, counter), base::BindOnce(&CheckMimeType, image_mime, counter),
base::BindOnce(&CheckMimeType, filenames_mime, counter),
base::BindRepeating(&IncrementCounter, counter)); base::BindRepeating(&IncrementCounter, counter));
run_loop.Run(); run_loop.Run();
} }
...@@ -170,11 +172,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeUTF16) { ...@@ -170,11 +172,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeUTF16) {
data_source.Offer("text/html;charset=UTF-16"); data_source.Offer("text/html;charset=UTF-16");
data_source.Offer("text/html;charset=utf-8"); data_source.Offer("text/html;charset=utf-8");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source, &data_source,
"text/plain;charset=utf-16", "text/plain;charset=utf-16",
"", "",
"text/html;charset=UTF-16", "text/html;charset=UTF-16",
"",
""); "");
} }
...@@ -186,11 +189,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeUTF16LE) { ...@@ -186,11 +189,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeUTF16LE) {
data_source.Offer("text/html;charset=utf16le"); data_source.Offer("text/html;charset=utf16le");
data_source.Offer("text/html;charset=utf-8"); data_source.Offer("text/html;charset=utf-8");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source, &data_source,
"text/plain;charset=utf-16le", "text/plain;charset=utf-16le",
"", "",
"text/html;charset=utf16le", "text/html;charset=utf16le",
"",
""); "");
} }
...@@ -202,11 +206,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeUTF16BE) { ...@@ -202,11 +206,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeUTF16BE) {
data_source.Offer("text/html;charset=UTF16be"); data_source.Offer("text/html;charset=UTF16be");
data_source.Offer("text/html;charset=utf-8"); data_source.Offer("text/html;charset=utf-8");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source, &data_source,
"text/plain;charset=utf-16be", "text/plain;charset=utf-16be",
"", "",
"text/html;charset=UTF16be", "text/html;charset=UTF16be",
"",
""); "");
} }
...@@ -218,11 +223,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeUTFToOther) { ...@@ -218,11 +223,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeUTFToOther) {
data_source.Offer("text/html;charset=utf-8"); data_source.Offer("text/html;charset=utf-8");
data_source.Offer("text/html;charset=iso-8859-1"); data_source.Offer("text/html;charset=iso-8859-1");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source, &data_source,
"text/plain;charset=utf-8", "text/plain;charset=utf-8",
"", "",
"text/html;charset=utf-8", "text/html;charset=utf-8",
"",
""); "");
} }
...@@ -232,11 +238,12 @@ TEST_F(DataSourceTest, RecogniseUTF8Legaccy) { ...@@ -232,11 +238,12 @@ TEST_F(DataSourceTest, RecogniseUTF8Legaccy) {
data_source.Offer("UTF8_STRING"); data_source.Offer("UTF8_STRING");
data_source.Offer("text/plain;charset=iso-8859-1"); data_source.Offer("text/plain;charset=iso-8859-1");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source, &data_source,
"UTF8_STRING", "UTF8_STRING",
"", "",
"", "",
"",
""); "");
} }
...@@ -248,11 +255,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeOtherToAscii) { ...@@ -248,11 +255,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeOtherToAscii) {
data_source.Offer("text/html;charset=iso-8859-1"); data_source.Offer("text/html;charset=iso-8859-1");
data_source.Offer("text/html;charset=ascii"); data_source.Offer("text/html;charset=ascii");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source, &data_source,
"text/plain;charset=iso-8859-1", "text/plain;charset=iso-8859-1",
"", "",
"text/html;charset=iso-8859-1", "text/html;charset=iso-8859-1",
"",
""); "");
} }
...@@ -264,11 +272,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeOtherToUnspecified) { ...@@ -264,11 +272,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeOtherToUnspecified) {
data_source.Offer("text/html;charset=iso-8859-1"); data_source.Offer("text/html;charset=iso-8859-1");
data_source.Offer("text/html"); data_source.Offer("text/html");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source, &data_source,
"text/plain;charset=iso-8859-1", "text/plain;charset=iso-8859-1",
"", "",
"text/html;charset=iso-8859-1", "text/html;charset=iso-8859-1",
"",
""); "");
} }
...@@ -277,11 +286,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeRTF) { ...@@ -277,11 +286,12 @@ TEST_F(DataSourceTest, PreferredMimeTypeRTF) {
DataSource data_source(&delegate); DataSource data_source(&delegate);
data_source.Offer("text/rtf"); data_source.Offer("text/rtf");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source, &data_source,
"", "",
"text/rtf", "text/rtf",
"", "",
"",
""); "");
} }
...@@ -291,12 +301,13 @@ TEST_F(DataSourceTest, PreferredMimeTypeBitmapToPNG) { ...@@ -291,12 +301,13 @@ TEST_F(DataSourceTest, PreferredMimeTypeBitmapToPNG) {
data_source.Offer("image/bmp"); data_source.Offer("image/bmp");
data_source.Offer("image/png"); data_source.Offer("image/png");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source, &data_source,
"", "",
"", "",
"", "",
"image/bmp"); "image/bmp",
"");
} }
TEST_F(DataSourceTest, PreferredMimeTypePNGToJPEG) { TEST_F(DataSourceTest, PreferredMimeTypePNGToJPEG) {
...@@ -306,12 +317,27 @@ TEST_F(DataSourceTest, PreferredMimeTypePNGToJPEG) { ...@@ -306,12 +317,27 @@ TEST_F(DataSourceTest, PreferredMimeTypePNGToJPEG) {
data_source.Offer("image/jpeg"); data_source.Offer("image/jpeg");
data_source.Offer("image/jpg"); data_source.Offer("image/jpg");
CheckMimeTypesRecieved( CheckMimeTypesReceived(
&data_source,
"",
"",
"",
"image/png",
"");
}
TEST_F(DataSourceTest, PreferredMimeTypeTextUriList) {
TestDataSourceDelegate delegate;
DataSource data_source(&delegate);
data_source.Offer("text/uri-list");
CheckMimeTypesReceived(
&data_source, &data_source,
"", "",
"", "",
"", "",
"image/png"); "",
"text/uri-list");
} }
} // namespace } // namespace
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/barrier_closure.h" #include "base/barrier_closure.h"
#include "base/check.h" #include "base/check.h"
#include "base/strings/string_split.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "components/exo/data_offer.h" #include "components/exo/data_offer.h"
#include "components/exo/data_source.h" #include "components/exo/data_source.h"
...@@ -16,6 +17,7 @@ ...@@ -16,6 +17,7 @@
#include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/common/frame_sinks/copy_output_result.h"
#include "ui/aura/client/drag_drop_client.h" #include "ui/aura/client/drag_drop_client.h"
#include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/file_info/file_info.h"
#include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/display/display.h" #include "ui/display/display.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
...@@ -23,6 +25,7 @@ ...@@ -23,6 +25,7 @@
#include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/transform_util.h" #include "ui/gfx/transform_util.h"
#include "url/gurl.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "ash/drag_drop/drag_drop_controller.h" #include "ash/drag_drop/drag_drop_controller.h"
...@@ -146,7 +149,10 @@ DragDropOperation::DragDropOperation(DataSource* source, ...@@ -146,7 +149,10 @@ DragDropOperation::DragDropOperation(DataSource* source,
DataSource::ReadDataCallback(), DataSource::ReadDataCallback(),
base::BindOnce(&DragDropOperation::OnHTMLRead, base::BindOnce(&DragDropOperation::OnHTMLRead,
weak_ptr_factory_.GetWeakPtr()), weak_ptr_factory_.GetWeakPtr()),
DataSource::ReadDataCallback(), counter_); DataSource::ReadDataCallback(),
base::BindOnce(&DragDropOperation::OnFilenamesRead,
weak_ptr_factory_.GetWeakPtr()),
counter_);
if (icon) { if (icon) {
origin_->get()->window()->AddChild(host_window()); origin_->get()->window()->AddChild(host_window());
...@@ -193,6 +199,28 @@ void DragDropOperation::OnHTMLRead(const std::string& mime_type, ...@@ -193,6 +199,28 @@ void DragDropOperation::OnHTMLRead(const std::string& mime_type,
counter_.Run(); counter_.Run();
} }
void DragDropOperation::OnFilenamesRead(const std::string& mime_type,
const std::vector<uint8_t>& data) {
DCHECK(os_exchange_data_);
std::string lines(data.begin(), data.end());
std::vector<ui::FileInfo> filenames;
for (const base::StringPiece& line : base::SplitStringPiece(
lines, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
if (line[0] == '#')
continue;
GURL url(line);
// TODO(crbug.com/1144138): We must translate the path if this was received
// from a VM. E.g. if this was from crostini as
// file:///home/username/file.txt, we translate to
// file:///media/fuse/crostini_<hash>_termina_penguin/file.txt.
filenames.emplace_back(
ui::FileInfo(base::FilePath(url.path()), base::FilePath()));
}
os_exchange_data_->SetFilenames(std::move(filenames));
mime_type_ = mime_type;
counter_.Run();
}
void DragDropOperation::OnSurfaceCommit() { void DragDropOperation::OnSurfaceCommit() {
SurfaceTreeHost::OnSurfaceCommit(); SurfaceTreeHost::OnSurfaceCommit();
......
...@@ -96,6 +96,8 @@ class DragDropOperation : public DataSourceObserver, ...@@ -96,6 +96,8 @@ class DragDropOperation : public DataSourceObserver,
void OnTextRead(const std::string& mime_type, base::string16 data); void OnTextRead(const std::string& mime_type, base::string16 data);
void OnHTMLRead(const std::string& mime_type, base::string16 data); void OnHTMLRead(const std::string& mime_type, base::string16 data);
void OnFilenamesRead(const std::string& mime_type,
const std::vector<uint8_t>& data);
void ScheduleStartDragDropOperation(); void ScheduleStartDragDropOperation();
......
...@@ -153,6 +153,8 @@ void Seat::SetSelection(DataSource* source) { ...@@ -153,6 +153,8 @@ void Seat::SetSelection(DataSource* source) {
data_read_callback), data_read_callback),
base::BindOnce(&Seat::OnImageRead, weak_ptr_factory_.GetWeakPtr(), writer, base::BindOnce(&Seat::OnImageRead, weak_ptr_factory_.GetWeakPtr(), writer,
data_read_callback), data_read_callback),
base::BindOnce(&Seat::OnFilenamesRead, weak_ptr_factory_.GetWeakPtr(),
writer, data_read_callback),
data_read_callback); data_read_callback);
} }
...@@ -220,6 +222,14 @@ void Seat::OnImageDecoded(base::OnceClosure callback, ...@@ -220,6 +222,14 @@ void Seat::OnImageDecoded(base::OnceClosure callback,
} }
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
void Seat::OnFilenamesRead(
scoped_refptr<RefCountedScopedClipboardWriter> writer,
base::OnceClosure callback,
const std::string& mime_type,
const std::vector<uint8_t>& data) {
std::move(callback).Run();
}
void Seat::OnAllReadsFinished( void Seat::OnAllReadsFinished(
scoped_refptr<RefCountedScopedClipboardWriter> writer) { scoped_refptr<RefCountedScopedClipboardWriter> writer) {
// We need to destroy the ScopedClipboardWriter in this call, before // We need to destroy the ScopedClipboardWriter in this call, before
......
...@@ -38,8 +38,8 @@ class Surface; ...@@ -38,8 +38,8 @@ class Surface;
class XkbTracker; class XkbTracker;
// The maximum number of different data types that we will write to the // The maximum number of different data types that we will write to the
// clipboard (plain text, RTF, HTML, image) // clipboard (plain text, RTF, HTML, image, text/uri-list)
constexpr int kMaxClipboardDataTypes = 4; constexpr int kMaxClipboardDataTypes = 5;
// Seat object represent a group of input devices such as keyboard, pointer and // Seat object represent a group of input devices such as keyboard, pointer and
// touch devices and keeps track of input focus. // touch devices and keeps track of input focus.
...@@ -158,6 +158,10 @@ class Seat : public aura::client::FocusChangeObserver, ...@@ -158,6 +158,10 @@ class Seat : public aura::client::FocusChangeObserver,
scoped_refptr<RefCountedScopedClipboardWriter> writer, scoped_refptr<RefCountedScopedClipboardWriter> writer,
const SkBitmap& bitmap); const SkBitmap& bitmap);
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
void OnFilenamesRead(scoped_refptr<RefCountedScopedClipboardWriter> writer,
base::OnceClosure callback,
const std::string& mime_type,
const std::vector<uint8_t>& data);
void OnAllReadsFinished( void OnAllReadsFinished(
scoped_refptr<RefCountedScopedClipboardWriter> writer); scoped_refptr<RefCountedScopedClipboardWriter> writer);
......
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