Skip to content

Commit

Permalink
[exo] Add initial support to 'chromium/x-web-custom-data' mime type
Browse files Browse the repository at this point in the history
This CL adds a initial support in Exo to chromium's custom data
mime types. Particularly, it also adds support to Ozone/Wayland
(ie Lacros) to make use of this support, and offer them, upon
request.

This CL is the basis for supporting "WebUI Tab Dragging" with
both touch and mouse to trigger work ChromeOS.

BUG=1236708

Change-Id: Ibf000ae32915f75b9bb959e49e70e4c480317c85
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3166178
Auto-Submit: Antonio Gomes <tonikitoo@igalia.com>
Reviewed-by: Mitsuru Oshima <oshima@chromium.org>
Reviewed-by: Nick Yamane <nickdiego@igalia.com>
Commit-Queue: Antonio Gomes <tonikitoo@igalia.com>
Cr-Commit-Position: refs/heads/main@{#924624}
  • Loading branch information
tonikitoo authored and Chromium LUCI CQ committed Sep 24, 2021
1 parent 814940b commit 6fdd023
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 16 deletions.
7 changes: 7 additions & 0 deletions components/exo/data_source.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ constexpr char kTextRTF[] = "text/rtf";
constexpr char kTextHTML[] = "text/html";
constexpr char kTextUriList[] = "text/uri-list";
constexpr char kApplicationOctetStream[] = "application/octet-stream";
constexpr char kWebCustomData[] = "chromium/x-web-custom-data";

constexpr char kUtfPrefix[] = "UTF";
constexpr char kEncoding16[] = "16";
Expand Down Expand Up @@ -259,13 +260,15 @@ void DataSource::GetDataForPreferredMimeTypes(
ReadDataCallback image_reader,
ReadDataCallback filenames_reader,
ReadFileContentsDataCallback file_contents_reader,
ReadDataCallback web_custom_data_reader,
base::RepeatingClosure failure_callback) {
std::string text_mime;
std::string rtf_mime;
std::string html_mime;
std::string image_mime;
std::string filenames_mime;
std::string file_contents_mime;
std::string web_custom_data_mime;

int text_rank = std::numeric_limits<int>::max();
int html_rank = std::numeric_limits<int>::max();
Expand Down Expand Up @@ -317,6 +320,8 @@ void DataSource::GetDataForPreferredMimeTypes(
filenames_mime = mime_type;
} else if (!GetApplicationOctetStreamName(mime_type).empty()) {
file_contents_mime = mime_type;
} else if (net::MatchesMimeType(std::string(kWebCustomData), mime_type)) {
web_custom_data_mime = mime_type;
}
}

Expand All @@ -338,6 +343,8 @@ void DataSource::GetDataForPreferredMimeTypes(
read_data_weak_ptr_factory_.GetWeakPtr(),
std::move(file_contents_reader)),
failure_callback);
ReadData(web_custom_data_mime, std::move(web_custom_data_reader),
failure_callback);
}

void DataSource::OnTextRead(ReadTextDataCallback callback,
Expand Down
13 changes: 8 additions & 5 deletions components/exo/data_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class DataSource {
public:
// The maximum number of different data types that will be read by
// GetDataForPreferredMimeTypes (plain text, RTF, HTML, image, text/uri-list,
// application/octet-stream).
static constexpr int kMaxDataTypes = 6;
// application/octet-stream, chromium/x-web-custom-data).
static constexpr int kMaxDataTypes = 7;

explicit DataSource(DataSourceDelegate* delegate);

Expand Down Expand Up @@ -71,12 +71,12 @@ class DataSource {

// Search the set of offered MIME types for the most preferred of each of the
// following categories: text/plain*, text/rtf, text/html*, image/*,
// text/uri-list. If any usable MIME types in a given category are available,
// the corresponding
// text/uri-list, chromium/x-web-custom-data. 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
// corresponding data. For any category that has no available MIME types,
// |failure_callback| is run. |failure_callback| may therefore be run as many
// as four times.
// as seven times.
using ReadDataCallback =
base::OnceCallback<void(const std::string&, const std::vector<uint8_t>&)>;
using ReadTextDataCallback =
Expand All @@ -85,13 +85,16 @@ class DataSource {
base::OnceCallback<void(const std::string&,
const base::FilePath&,
const std::vector<uint8_t>&)>;
using ReadWebCustomDataCallback =
base::OnceCallback<void(const std::string&, const std::vector<uint8_t>&)>;
void GetDataForPreferredMimeTypes(
ReadTextDataCallback text_reader,
ReadDataCallback rtf_reader,
ReadTextDataCallback html_reader,
ReadDataCallback image_reader,
ReadDataCallback filenames_reader,
ReadFileContentsDataCallback file_contents_reader,
ReadDataCallback web_custom_data_reader,
base::RepeatingClosure failure_callback);

void ReadDataForTesting(const std::string& mime_type,
Expand Down
42 changes: 33 additions & 9 deletions components/exo/data_source_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,30 @@ void CheckFileContentsMimeType(const FileContents& file_contents,
std::move(counter).Run();
}

void CheckWebCustomDataMimeType(const std::string& expected,
base::OnceClosure counter,
const std::string& mime_type,
const std::vector<uint8_t>& data) {
EXPECT_FALSE(mime_type.empty());
EXPECT_EQ(expected, mime_type);
std::move(counter).Run();
}

void IncrementFailureCounter(std::atomic_int* failure_count,
base::RepeatingClosure counter) {
++(*failure_count);
std::move(counter).Run();
}

void CheckMimeTypesReceived(DataSource* data_source,
const std::string& text_mime,
const std::string& rtf_mime,
const std::string& html_mime,
const std::string& image_mime,
const std::string& filenames_mime,
const FileContents& file_contents) {
void CheckMimeTypesReceived(
DataSource* data_source,
const std::string& text_mime,
const std::string& rtf_mime,
const std::string& html_mime,
const std::string& image_mime,
const std::string& filenames_mime,
const FileContents& file_contents,
const std::string& web_custom_data_mime = std::string()) {
base::RunLoop run_loop;
base::RepeatingClosure counter =
base::BarrierClosure(DataSource::kMaxDataTypes, run_loop.QuitClosure());
Expand All @@ -106,12 +117,15 @@ void CheckMimeTypesReceived(DataSource* data_source,
base::BindOnce(&CheckMimeType, image_mime, counter),
base::BindOnce(&CheckMimeType, filenames_mime, counter),
base::BindOnce(&CheckFileContentsMimeType, file_contents, counter),
base::BindOnce(&CheckWebCustomDataMimeType, web_custom_data_mime,
counter),
base::BindRepeating(&IncrementFailureCounter, &failure_count, counter));
run_loop.Run();

int expected_failure_count = 0;
for (const auto& mime_type : {text_mime, rtf_mime, html_mime, image_mime,
filenames_mime, file_contents.mime_type}) {
for (const auto& mime_type :
{text_mime, rtf_mime, html_mime, image_mime, filenames_mime,
file_contents.mime_type, web_custom_data_mime}) {
if (mime_type.empty())
++expected_failure_count;
}
Expand Down Expand Up @@ -339,5 +353,15 @@ TEST_F(DataSourceTest, OctetStreamWithQuotedName) {
{"application/octet-stream;name=\"t\\\\est\\\".jpg\"", "t\\est\".jpg"});
}

TEST_F(DataSourceTest, WebCustomDataMime) {
TestDataSourceDelegate delegate;
DataSource data_source(&delegate);
std::string web_custom_data_mime("chromium/x-web-custom-data");
data_source.Offer(web_custom_data_mime);

CheckMimeTypesReceived(&data_source, "", "", "", "", "", {},
web_custom_data_mime);
}

} // namespace
} // namespace exo
14 changes: 14 additions & 0 deletions components/exo/drag_drop_operation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "base/barrier_closure.h"
#include "base/check.h"
#include "base/pickle.h"
#include "base/strings/string_split.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/chromeos_buildflags.h"
Expand Down Expand Up @@ -226,6 +227,8 @@ DragDropOperation::DragDropOperation(
origin->window()),
base::BindOnce(&DragDropOperation::OnFileContentsRead,
weak_ptr_factory_.GetWeakPtr()),
base::BindOnce(&DragDropOperation::OnWebCustomDataRead,
weak_ptr_factory_.GetWeakPtr()),
counter_);
}

Expand Down Expand Up @@ -290,6 +293,17 @@ void DragDropOperation::OnFileContentsRead(const std::string& mime_type,
counter_.Run();
}

void DragDropOperation::OnWebCustomDataRead(const std::string& mime_type,
const std::vector<uint8_t>& data) {
DCHECK(os_exchange_data_);
base::Pickle pickle(reinterpret_cast<const char*>(data.data()), data.size());
os_exchange_data_->SetPickledData(
ui::ClipboardFormatType::WebCustomDataType(), pickle);

mime_type_ = mime_type;
counter_.Run();
}

void DragDropOperation::OnDragIconCaptured(const SkBitmap& icon_bitmap) {
DCHECK(icon_);

Expand Down
2 changes: 2 additions & 0 deletions components/exo/drag_drop_operation.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class DragDropOperation : public DataSourceObserver,
void OnFileContentsRead(const std::string& mime_type,
const base::FilePath& filename,
const std::vector<uint8_t>& data);
void OnWebCustomDataRead(const std::string& mime_type,
const std::vector<uint8_t>& data);

void ScheduleStartDragDropOperation();

Expand Down
15 changes: 14 additions & 1 deletion components/exo/seat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,10 @@ void Seat::SetSelection(DataSource* source) {
data_read_callback),
base::BindOnce(&Seat::OnFilenamesRead, weak_ptr_factory_.GetWeakPtr(),
endpoint_type, writer, data_read_callback),
DataSource::ReadFileContentsDataCallback(), data_read_callback);
DataSource::ReadFileContentsDataCallback(),
base::BindOnce(&Seat::OnWebCustomDataRead, weak_ptr_factory_.GetWeakPtr(),
writer, data_read_callback),
data_read_callback);
}

class Seat::RefCountedScopedClipboardWriter
Expand Down Expand Up @@ -249,6 +252,16 @@ void Seat::OnFilenamesRead(
std::move(callback).Run();
}

void Seat::OnWebCustomDataRead(
scoped_refptr<RefCountedScopedClipboardWriter> writer,
base::OnceClosure callback,
const std::string& mime_type,
const std::vector<uint8_t>& data) {
NOTREACHED()
<< "Seat does not support custom data mime types for selections.";
std::move(callback).Run();
}

void Seat::OnAllReadsFinished(
scoped_refptr<RefCountedScopedClipboardWriter> writer) {
// We need to destroy the ScopedClipboardWriter in this call, before
Expand Down
5 changes: 5 additions & 0 deletions components/exo/seat.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ class Seat : public aura::client::FocusChangeObserver,
base::OnceClosure callback,
const std::string& mime_type,
const std::vector<uint8_t>& data);
void OnWebCustomDataRead(
scoped_refptr<RefCountedScopedClipboardWriter> writer,
base::OnceClosure callback,
const std::string& mime_type,
const std::vector<uint8_t>& data);

void OnAllReadsFinished(
scoped_refptr<RefCountedScopedClipboardWriter> writer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ bool WaylandDataDragController::StartSession(const OSExchangeData& data,
return false;
}

// Create new new data source and offers |data|.
// Create new data source and offers |data|.
SetOfferedExchangeDataProvider(data);
data_source_ = data_device_manager_->CreateSource(this);
data_source_->Offer(GetOfferedExchangeDataProvider()->BuildMimeTypesList());
Expand Down
10 changes: 10 additions & 0 deletions ui/ozone/platform/wayland/host/wayland_exchange_data_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ int MimeTypeToFormat(const std::string& mime_type) {
return OSExchangeData::HTML;
if (base::StartsWith(mime_type, ui::kMimeTypeOctetStream))
return OSExchangeData::FILE_CONTENTS;
if (mime_type == ui::kMimeTypeWebCustomData)
return OSExchangeData::PICKLED_DATA;
return 0;
}

Expand Down Expand Up @@ -259,6 +261,14 @@ bool WaylandExchangeDataProvider::ExtractData(const std::string& mime_type,
out_content->append(base::UTF16ToUTF8(data));
return true;
}
if (HasCustomFormat(ui::ClipboardFormatType::WebCustomDataType())) {
base::Pickle pickle;
GetPickledData(ui::ClipboardFormatType::WebCustomDataType(), &pickle);
*out_content = std::string(reinterpret_cast<const char*>(pickle.data()),
pickle.size());
return true;
}

return false;
}

Expand Down

0 comments on commit 6fdd023

Please sign in to comment.