summaryrefslogtreecommitdiffstats
path: root/mojo
diff options
context:
space:
mode:
authorerg <erg@chromium.org>2014-09-16 17:08:56 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-17 00:09:12 +0000
commitb69fbca034e3c2181e0a12cf02baec4de526bf25 (patch)
tree8bdb2d79438facc797c47f3a6ee483039e5afb02 /mojo
parent0d9398539d5a78e8025eeb1c92f9d396c946e105 (diff)
downloadchromium_src-b69fbca034e3c2181e0a12cf02baec4de526bf25.zip
chromium_src-b69fbca034e3c2181e0a12cf02baec4de526bf25.tar.gz
chromium_src-b69fbca034e3c2181e0a12cf02baec4de526bf25.tar.bz2
mojo: Create a basic clipboard.
This creates a basic clipboard interface and uses it from html_viewer. This is a minimal implementation and does not actually interact with the system clipboard. BUG=411039 First Committed: https://crrev.com/757286d8a2c778fe4622890140c9b9d2afd21063 Review URL: https://codereview.chromium.org/562483002 Cr-Commit-Position: refs/heads/master@{#295182}
Diffstat (limited to 'mojo')
-rw-r--r--mojo/BUILD.gn1
-rw-r--r--mojo/common/common_type_converters.cc16
-rw-r--r--mojo/common/common_type_converters.h15
-rw-r--r--mojo/common/common_type_converters_unittest.cc21
-rw-r--r--mojo/mojo.gyp2
-rw-r--r--mojo/mojo_services.gypi56
-rw-r--r--mojo/public/cpp/bindings/array.h3
-rw-r--r--mojo/services/BUILD.gn2
-rw-r--r--mojo/services/clipboard/BUILD.gn42
-rw-r--r--mojo/services/clipboard/DEPS4
-rw-r--r--mojo/services/clipboard/clipboard_standalone_impl.cc100
-rw-r--r--mojo/services/clipboard/clipboard_standalone_impl.h61
-rw-r--r--mojo/services/clipboard/clipboard_standalone_unittest.cc185
-rw-r--r--mojo/services/clipboard/main.cc45
-rw-r--r--mojo/services/html_viewer/BUILD.gn3
-rw-r--r--mojo/services/html_viewer/blink_basic_type_converters.cc10
-rw-r--r--mojo/services/html_viewer/blink_basic_type_converters.h4
-rw-r--r--mojo/services/html_viewer/blink_platform_impl.cc9
-rw-r--r--mojo/services/html_viewer/blink_platform_impl.h3
-rw-r--r--mojo/services/html_viewer/webclipboard_impl.cc222
-rw-r--r--mojo/services/html_viewer/webclipboard_impl.h48
-rw-r--r--mojo/services/public/interfaces/clipboard/BUILD.gn12
-rw-r--r--mojo/services/public/interfaces/clipboard/clipboard.mojom52
23 files changed, 916 insertions, 0 deletions
diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn
index c5b9683..276a4b9 100644
--- a/mojo/BUILD.gn
+++ b/mojo/BUILD.gn
@@ -37,6 +37,7 @@ group("tests") {
"//mojo/public/cpp/system/tests:mojo_public_system_unittests",
"//mojo/public/cpp/utility/tests:mojo_public_utility_unittests",
"//mojo/public/js/bindings/tests:mojo_js_unittests",
+ "//mojo/services/clipboard:mojo_clipboard_unittests",
"//mojo/services/public/cpp/surfaces/tests:mojo_surfaces_lib_unittests",
"//mojo/shell:mojo_shell_tests",
"//mojo/system:mojo_message_pipe_perftests",
diff --git a/mojo/common/common_type_converters.cc b/mojo/common/common_type_converters.cc
index ffc1907..114b409 100644
--- a/mojo/common/common_type_converters.cc
+++ b/mojo/common/common_type_converters.cc
@@ -46,4 +46,20 @@ GURL TypeConverter<GURL, String>::Convert(const String& input) {
return GURL(input.get());
}
+std::string TypeConverter<std::string, Array<uint8_t> >::Convert(
+ const Array<uint8_t>& input) {
+ if (input.is_null())
+ return std::string();
+
+ return std::string(reinterpret_cast<const char*>(&input.front()),
+ input.size());
+}
+
+Array<uint8_t> TypeConverter<Array<uint8_t>, std::string>::Convert(
+ const std::string& input) {
+ Array<uint8_t> result(input.size());
+ memcpy(&result.front(), input.c_str(), input.size());
+ return result.Pass();
+}
+
} // namespace mojo
diff --git a/mojo/common/common_type_converters.h b/mojo/common/common_type_converters.h
index 159325e..7b0260a 100644
--- a/mojo/common/common_type_converters.h
+++ b/mojo/common/common_type_converters.h
@@ -8,6 +8,7 @@
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
#include "mojo/common/mojo_common_export.h"
+#include "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/bindings/type_converter.h"
@@ -45,6 +46,20 @@ struct MOJO_COMMON_EXPORT TypeConverter<GURL, String> {
static GURL Convert(const String& input);
};
+// TODO(erg): In the very long term, we will want to remove conversion between
+// std::strings and arrays of unsigned bytes. However, there is too much code
+// across chrome which uses std::string as a bag of bytes that we probably
+// don't want to roll this function at each callsite.
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<std::string, Array<uint8_t> > {
+ static std::string Convert(const Array<uint8_t>& input);
+};
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<Array<uint8_t>, std::string> {
+ static Array<uint8_t> Convert(const std::string& input);
+};
+
} // namespace mojo
#endif // MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_
diff --git a/mojo/common/common_type_converters_unittest.cc b/mojo/common/common_type_converters_unittest.cc
index 314f180..f97be0a 100644
--- a/mojo/common/common_type_converters_unittest.cc
+++ b/mojo/common/common_type_converters_unittest.cc
@@ -84,6 +84,27 @@ TEST(CommonTypeConvertersTest, URL) {
ASSERT_EQ(0U, string_from_invalid.size());
}
+TEST(CommonTypeConvertersTest, ArrayUint8ToStdString) {
+ Array<uint8_t> data(4);
+ data[0] = 'd';
+ data[1] = 'a';
+ data[2] = 't';
+ data[3] = 'a';
+
+ EXPECT_EQ("data", data.To<std::string>());
+}
+
+TEST(CommonTypeConvertersTest, StdStringToArrayUint8) {
+ std::string input("data");
+ Array<uint8_t> data = Array<uint8_t>::From(input);
+
+ ASSERT_EQ(4ul, data.size());
+ EXPECT_EQ('d', data[0]);
+ EXPECT_EQ('a', data[1]);
+ EXPECT_EQ('t', data[2]);
+ EXPECT_EQ('a', data[3]);
+}
+
} // namespace test
} // namespace common
} // namespace mojo
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp
index 29a49f0..890af4e 100644
--- a/mojo/mojo.gyp
+++ b/mojo/mojo.gyp
@@ -29,6 +29,8 @@
'mojo_application_manager_unittests',
'mojo_apps_js_unittests',
'mojo_base.gyp:mojo_base',
+ 'mojo_clipboard',
+ 'mojo_clipboard_unittests',
'mojo_compositor_app',
'mojo_content_handler_demo',
'mojo_echo_client',
diff --git a/mojo/mojo_services.gypi b/mojo/mojo_services.gypi
index e775c00..4b68611 100644
--- a/mojo/mojo_services.gypi
+++ b/mojo/mojo_services.gypi
@@ -5,6 +5,59 @@
{
'targets': [
{
+ # GN version: //mojo/services/clipboard/
+ 'target_name': 'mojo_clipboard',
+ 'type': 'loadable_module',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ 'mojo_base.gyp:mojo_common_lib',
+ 'mojo_base.gyp:mojo_cpp_bindings',
+ 'mojo_base.gyp:mojo_utility',
+ 'mojo_base.gyp:mojo_application_chromium',
+ 'mojo_clipboard_bindings',
+ '<(mojo_system_for_loadable_module)',
+ ],
+ 'sources': [
+ 'services/clipboard/clipboard_standalone_impl.cc',
+ 'services/clipboard/clipboard_standalone_impl.h',
+ 'services/clipboard/main.cc',
+ ],
+ },
+ {
+ # GN version: //mojo/services/public/interfaces/clipboard
+ 'target_name': 'mojo_clipboard_bindings',
+ 'type': 'static_library',
+ 'sources': [
+ 'services/public/interfaces/clipboard/clipboard.mojom',
+ ],
+ 'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ],
+ 'dependencies': [
+ 'mojo_base.gyp:mojo_cpp_bindings',
+ ],
+ 'export_dependent_settings': [
+ 'mojo_base.gyp:mojo_cpp_bindings',
+ ],
+ },
+ {
+ # GN version: //mojo/services/clipboard:mojo_clipboard_unittests
+ 'target_name': 'mojo_clipboard_unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../base/base.gyp:test_support_base',
+ '../testing/gtest.gyp:gtest',
+ 'mojo_application_manager',
+ 'mojo_base.gyp:mojo_application_chromium',
+ 'mojo_base.gyp:mojo_run_all_unittests',
+ 'mojo_base.gyp:mojo_system_impl',
+ 'mojo_clipboard_bindings',
+ 'mojo_shell_test_support',
+ ],
+ 'sources': [
+ 'services/clipboard/clipboard_standalone_unittest.cc',
+ ],
+ },
+ {
# GN version: //mojo/services/html_viewer
'target_name': 'mojo_html_viewer',
'type': 'loadable_module',
@@ -23,6 +76,7 @@
'mojo_base.gyp:mojo_common_lib',
'mojo_base.gyp:mojo_cpp_bindings',
'mojo_base.gyp:mojo_utility',
+ 'mojo_clipboard_bindings',
'mojo_cc_support',
'mojo_content_handler_bindings',
'mojo_gpu_bindings',
@@ -47,6 +101,8 @@
'services/html_viewer/html_viewer.cc',
'services/html_viewer/html_document_view.cc',
'services/html_viewer/html_document_view.h',
+ 'services/html_viewer/webclipboard_impl.cc',
+ 'services/html_viewer/webclipboard_impl.h',
'services/html_viewer/webcookiejar_impl.cc',
'services/html_viewer/webcookiejar_impl.h',
'services/html_viewer/webmediaplayer_factory.cc',
diff --git a/mojo/public/cpp/bindings/array.h b/mojo/public/cpp/bindings/array.h
index 9b5aff8..0ef6261 100644
--- a/mojo/public/cpp/bindings/array.h
+++ b/mojo/public/cpp/bindings/array.h
@@ -68,6 +68,9 @@ class Array {
bool is_null() const { return is_null_; }
+ ConstRefType front() const { return vec_.front(); }
+ RefType front() { return vec_.front(); }
+
size_t size() const { return vec_.size(); }
ConstRefType at(size_t offset) const { return Traits::at(&vec_, offset); }
diff --git a/mojo/services/BUILD.gn b/mojo/services/BUILD.gn
index ae16a08..90988ab 100644
--- a/mojo/services/BUILD.gn
+++ b/mojo/services/BUILD.gn
@@ -6,10 +6,12 @@ import("//build/config/ui.gni")
group("services") {
deps = [
+ "//mojo/services/clipboard",
"//mojo/services/gles2:bindings",
"//mojo/services/html_viewer",
"//mojo/services/native_viewport",
"//mojo/services/network",
+ "//mojo/services/public/interfaces/clipboard",
"//mojo/services/public/interfaces/content_handler",
"//mojo/services/public/interfaces/geometry",
"//mojo/services/public/interfaces/input_events",
diff --git a/mojo/services/clipboard/BUILD.gn b/mojo/services/clipboard/BUILD.gn
new file mode 100644
index 0000000..5019a1a
--- /dev/null
+++ b/mojo/services/clipboard/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2014 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.
+
+# GYP version: mojo/mojo_services.gypi:mojo_clipboard
+component("clipboard") {
+ deps = [
+ "//base",
+ "//mojo/common",
+ "//mojo/environment:chromium",
+ "//mojo/public/c/system:for_component",
+ "//mojo/services/public/interfaces/clipboard",
+ "//ui/base",
+ ]
+
+ sources = [
+ "clipboard_standalone_impl.cc",
+ "clipboard_standalone_impl.h",
+ "main.cc",
+ ]
+}
+
+# GYP version: mojo/mojo_services.gypi:mojo_clipboard_unittests
+test("mojo_clipboard_unittests") {
+ deps = [
+ "//base",
+ "//base/test:test_support",
+ "//mojo/application",
+ "//mojo/application_manager",
+ "//mojo/common",
+ "//mojo/common/test:run_all_unittests",
+ "//mojo/environment:chromium",
+ "//mojo/services/public/interfaces/clipboard:clipboard",
+ "//mojo/shell:test_support",
+ "//mojo/system",
+ "//testing/gtest",
+ ]
+
+ sources = [
+ "clipboard_standalone_unittest.cc",
+ ]
+}
diff --git a/mojo/services/clipboard/DEPS b/mojo/services/clipboard/DEPS
new file mode 100644
index 0000000..79cfc5d
--- /dev/null
+++ b/mojo/services/clipboard/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+mojo/application",
+ "+mojo/services",
+]
diff --git a/mojo/services/clipboard/clipboard_standalone_impl.cc b/mojo/services/clipboard/clipboard_standalone_impl.cc
new file mode 100644
index 0000000..e1c7e2c
--- /dev/null
+++ b/mojo/services/clipboard/clipboard_standalone_impl.cc
@@ -0,0 +1,100 @@
+// Copyright (c) 2014 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 "mojo/services/clipboard/clipboard_standalone_impl.h"
+
+namespace mojo {
+
+typedef std::vector<uint8_t> ByteVector;
+
+// ClipboardData contains data copied to the Clipboard for a variety of formats.
+// It mostly just provides APIs to cleanly access and manipulate this data.
+class ClipboardStandaloneImpl::ClipboardData {
+ public:
+ ClipboardData() {}
+ ~ClipboardData() {}
+
+ std::vector<std::string> GetMimeTypes() const {
+ std::vector<std::string> types;
+ for (std::map<std::string, ByteVector>::const_iterator it =
+ data_types_.begin();
+ it != data_types_.end();
+ ++it) {
+ types.push_back(it->first);
+ }
+
+ return types;
+ }
+
+ void SetData(std::map<std::string, ByteVector>* data) {
+ std::swap(data_types_, *data);
+ }
+
+ bool GetData(const std::string& mime_type, ByteVector* data) const {
+ std::map<std::string, ByteVector>::const_iterator it =
+ data_types_.find(mime_type);
+ if (it != data_types_.end()) {
+ *data = it->second;
+ return true;
+ }
+
+ return false;
+ }
+
+ private:
+ std::map<std::string, ByteVector> data_types_;
+
+ DISALLOW_COPY_AND_ASSIGN(ClipboardData);
+};
+
+ClipboardStandaloneImpl::ClipboardStandaloneImpl() {
+ for (int i = 0; i < kNumClipboards; ++i) {
+ sequence_number_[i] = 0;
+ clipboard_state_[i].reset(new ClipboardData);
+ }
+}
+
+ClipboardStandaloneImpl::~ClipboardStandaloneImpl() {
+}
+
+void ClipboardStandaloneImpl::GetSequenceNumber(
+ Clipboard::Type clipboard_type,
+ const mojo::Callback<void(uint64_t)>& callback) {
+ callback.Run(sequence_number_[clipboard_type]);
+}
+
+void ClipboardStandaloneImpl::GetAvailableMimeTypes(
+ Clipboard::Type clipboard_type,
+ const mojo::Callback<void(mojo::Array<mojo::String>)>& callback) {
+ mojo::Array<mojo::String> types = mojo::Array<mojo::String>::From(
+ clipboard_state_[clipboard_type]->GetMimeTypes());
+ callback.Run(types.Pass());
+}
+
+void ClipboardStandaloneImpl::ReadMimeType(
+ Clipboard::Type clipboard_type,
+ const mojo::String& mime_type,
+ const mojo::Callback<void(mojo::Array<uint8_t>)>& callback) {
+ ByteVector mime_data;
+ if (clipboard_state_[clipboard_type]->GetData(
+ mime_type.To<std::string>(), &mime_data)) {
+ callback.Run(mojo::Array<uint8_t>::From(mime_data).Pass());
+ return;
+ }
+
+ callback.Run(mojo::Array<uint8_t>().Pass());
+}
+
+void ClipboardStandaloneImpl::WriteClipboardData(
+ Clipboard::Type clipboard_type,
+ mojo::Array<MimeTypePairPtr> data) {
+ std::map<std::string, ByteVector> mime_data;
+ for (size_t i = 0; i < data.size(); ++i)
+ mime_data[data[i]->mime_type] = data[i]->data;
+
+ sequence_number_[clipboard_type]++;
+ clipboard_state_[clipboard_type]->SetData(&mime_data);
+}
+
+} // namespace mojo
diff --git a/mojo/services/clipboard/clipboard_standalone_impl.h b/mojo/services/clipboard/clipboard_standalone_impl.h
new file mode 100644
index 0000000..6909c10
--- /dev/null
+++ b/mojo/services/clipboard/clipboard_standalone_impl.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2014 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.
+
+#ifndef MOJO_SERVICES_CLIPBOARD_CLIPBOARD_STANDALONE_IMPL_H_
+#define MOJO_SERVICES_CLIPBOARD_CLIPBOARD_STANDALONE_IMPL_H_
+
+#include <base/memory/scoped_ptr.h>
+#include <string>
+
+#include "mojo/services/public/interfaces/clipboard/clipboard.mojom.h"
+
+namespace mojo {
+
+// Stub clipboard implementation.
+//
+// Eventually, we'll actually want to interact with the system clipboard, but
+// that's hard today because the system clipboard is asynchronous (on X11), the
+// ui::Clipboard interface is synchronous (which is what we'd use), mojo is
+// asynchronous across processes, and the WebClipboard interface is synchronous
+// (which is at least tractable).
+class ClipboardStandaloneImpl : public InterfaceImpl<mojo::Clipboard> {
+ public:
+ // mojo::Clipboard exposes three possible clipboards.
+ static const int kNumClipboards = 3;
+
+ ClipboardStandaloneImpl();
+ virtual ~ClipboardStandaloneImpl();
+
+ // InterfaceImpl<mojo::Clipboard> implementation.
+ virtual void GetSequenceNumber(Clipboard::Type clipboard_type,
+ const mojo::Callback<void(uint64_t)>& callback)
+ MOJO_OVERRIDE;
+ virtual void GetAvailableMimeTypes(
+ Clipboard::Type clipboard_types,
+ const mojo::Callback<void(mojo::Array<mojo::String>)>& callback)
+ MOJO_OVERRIDE;
+ virtual void ReadMimeType(
+ Clipboard::Type clipboard_type,
+ const mojo::String& mime_type,
+ const mojo::Callback<void(mojo::Array<uint8_t>)>& callback)
+ MOJO_OVERRIDE;
+ virtual void WriteClipboardData(Clipboard::Type clipboard_type,
+ mojo::Array<MimeTypePairPtr> data)
+ MOJO_OVERRIDE;
+
+ private:
+ uint64_t sequence_number_[kNumClipboards];
+
+ // Internal struct which stores the current state of the clipboard.
+ class ClipboardData;
+
+ // The current clipboard state. This is what is read from.
+ scoped_ptr<ClipboardData> clipboard_state_[kNumClipboards];
+
+ DISALLOW_COPY_AND_ASSIGN(ClipboardStandaloneImpl);
+};
+
+} // namespace mojo
+
+#endif // MOJO_SERVICES_CLIPBOARD_CLIPBOARD_STANDALONE_IMPL_H_
diff --git a/mojo/services/clipboard/clipboard_standalone_unittest.cc b/mojo/services/clipboard/clipboard_standalone_unittest.cc
new file mode 100644
index 0000000..60838f1
--- /dev/null
+++ b/mojo/services/clipboard/clipboard_standalone_unittest.cc
@@ -0,0 +1,185 @@
+// Copyright (c) 2014 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 "base/at_exit.h"
+#include "base/bind.h"
+#include "mojo/common/common_type_converters.h"
+#include "mojo/services/public/interfaces/clipboard/clipboard.mojom.h"
+#include "mojo/shell/shell_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+void CopyUint64AndEndRunloop(uint64_t* output,
+ base::RunLoop* run_loop,
+ uint64_t input) {
+ *output = input;
+ run_loop->Quit();
+}
+
+void CopyStringAndEndRunloop(std::string* output,
+ bool* string_is_null,
+ base::RunLoop* run_loop,
+ const mojo::Array<uint8_t>& input) {
+ *string_is_null = input.is_null();
+ *output = input.is_null() ? "" : input.To<std::string>();
+ run_loop->Quit();
+}
+
+void CopyVectorStringAndEndRunloop(std::vector<std::string>* output,
+ base::RunLoop* run_loop,
+ const mojo::Array<mojo::String>& input) {
+ *output = input.To<std::vector<std::string> >();
+ run_loop->Quit();
+}
+
+const char* kUninitialized = "Uninitialized data";
+const char* kPlainTextData = "Some plain data";
+const char* kHtmlData = "<html>data</html>";
+
+} // namespace
+
+namespace mojo {
+namespace service {
+
+class ClipboardStandaloneTest : public testing::Test {
+ public:
+ ClipboardStandaloneTest() {}
+ virtual ~ClipboardStandaloneTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ test_helper_.Init();
+
+ test_helper_.application_manager()->ConnectToService(
+ GURL("mojo:mojo_clipboard"), &clipboard_);
+ }
+
+ uint64_t GetSequenceNumber() {
+ base::RunLoop run_loop;
+ uint64_t sequence_num = 999999;
+ clipboard_->GetSequenceNumber(
+ mojo::Clipboard::TYPE_COPY_PASTE,
+ base::Bind(&CopyUint64AndEndRunloop, &sequence_num, &run_loop));
+ run_loop.Run();
+ return sequence_num;
+ }
+
+ std::vector<std::string> GetAvailableFormatMimeTypes() {
+ base::RunLoop run_loop;
+ std::vector<std::string> types;
+ types.push_back(kUninitialized);
+ clipboard_->GetAvailableMimeTypes(
+ mojo::Clipboard::TYPE_COPY_PASTE,
+ base::Bind(&CopyVectorStringAndEndRunloop, &types, &run_loop));
+ run_loop.Run();
+ return types;
+ }
+
+ bool GetDataOfType(const std::string& mime_type, std::string* data) {
+ base::RunLoop run_loop;
+ bool is_null = false;
+ clipboard_->ReadMimeType(
+ mojo::Clipboard::TYPE_COPY_PASTE,
+ mime_type,
+ base::Bind(&CopyStringAndEndRunloop, data, &is_null, &run_loop));
+ run_loop.Run();
+ return !is_null;
+ }
+
+ void SetStringText(const std::string& data) {
+ Array<MimeTypePairPtr> mime_data;
+ MimeTypePairPtr text_data(MimeTypePair::New());
+ text_data->mime_type = mojo::Clipboard::MIME_TYPE_TEXT;
+ text_data->data = Array<uint8_t>::From(data).Pass();
+ mime_data.push_back(text_data.Pass());
+ clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE,
+ mime_data.Pass());
+ }
+
+ protected:
+ base::ShadowingAtExitManager at_exit_;
+ shell::ShellTestHelper test_helper_;
+
+ ClipboardPtr clipboard_;
+
+ DISALLOW_COPY_AND_ASSIGN(ClipboardStandaloneTest);
+};
+
+TEST_F(ClipboardStandaloneTest, EmptyClipboardOK) {
+ EXPECT_EQ(0ul, GetSequenceNumber());
+ EXPECT_TRUE(GetAvailableFormatMimeTypes().empty());
+ std::string data;
+ EXPECT_FALSE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
+}
+
+TEST_F(ClipboardStandaloneTest, CanReadBackText) {
+ std::string data;
+ EXPECT_FALSE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
+ EXPECT_EQ(0ul, GetSequenceNumber());
+
+ SetStringText(kPlainTextData);
+ EXPECT_EQ(1ul, GetSequenceNumber());
+
+ EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
+ EXPECT_EQ(kPlainTextData, data);
+}
+
+TEST_F(ClipboardStandaloneTest, CanSetMultipleDataTypesAtOnce) {
+ Array<MimeTypePairPtr> mime_data;
+ MimeTypePairPtr text_data(MimeTypePair::New());
+ text_data->mime_type = mojo::Clipboard::MIME_TYPE_TEXT;
+ text_data->data = Array<uint8_t>::From(std::string(kPlainTextData)).Pass();
+ mime_data.push_back(text_data.Pass());
+
+ MimeTypePairPtr html_data(MimeTypePair::New());
+ html_data->mime_type = mojo::Clipboard::MIME_TYPE_HTML;
+ html_data->data = Array<uint8_t>::From(std::string(kHtmlData)).Pass();
+ mime_data.push_back(html_data.Pass());
+
+ clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE,
+ mime_data.Pass());
+
+ EXPECT_EQ(1ul, GetSequenceNumber());
+
+ std::string data;
+ EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
+ EXPECT_EQ(kPlainTextData, data);
+ EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_HTML, &data));
+ EXPECT_EQ(kHtmlData, data);
+}
+
+TEST_F(ClipboardStandaloneTest, CanClearClipboardWithNull) {
+ std::string data;
+ SetStringText(kPlainTextData);
+ EXPECT_EQ(1ul, GetSequenceNumber());
+
+ EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
+ EXPECT_EQ(kPlainTextData, data);
+
+ Array<MimeTypePairPtr> mime_data;
+ clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE,
+ mime_data.Pass());
+
+ EXPECT_EQ(2ul, GetSequenceNumber());
+ EXPECT_FALSE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
+}
+
+TEST_F(ClipboardStandaloneTest, CanClearClipboardWithZeroArray) {
+ std::string data;
+ SetStringText(kPlainTextData);
+ EXPECT_EQ(1ul, GetSequenceNumber());
+
+ EXPECT_TRUE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
+ EXPECT_EQ(kPlainTextData, data);
+
+ Array<MimeTypePairPtr> mime_data(0);
+ clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE,
+ mime_data.Pass());
+
+ EXPECT_EQ(2ul, GetSequenceNumber());
+ EXPECT_FALSE(GetDataOfType(mojo::Clipboard::MIME_TYPE_TEXT, &data));
+}
+
+} // namespace service
+} // namespace mojo
diff --git a/mojo/services/clipboard/main.cc b/mojo/services/clipboard/main.cc
new file mode 100644
index 0000000..423aca0
--- /dev/null
+++ b/mojo/services/clipboard/main.cc
@@ -0,0 +1,45 @@
+// Copyright 2014 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 "base/at_exit.h"
+#include "base/base_paths.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
+#include "mojo/application/application_runner_chromium.h"
+#include "mojo/public/c/system/main.h"
+#include "mojo/public/cpp/application/application_connection.h"
+#include "mojo/public/cpp/application/application_delegate.h"
+#include "mojo/public/cpp/application/interface_factory.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/services/clipboard/clipboard_standalone_impl.h"
+
+class Delegate : public mojo::ApplicationDelegate,
+ public mojo::InterfaceFactory<mojo::Clipboard> {
+ public:
+ Delegate() {}
+ virtual ~Delegate() {}
+
+ // mojo::ApplicationDelegate implementation.
+ virtual bool ConfigureIncomingConnection(
+ mojo::ApplicationConnection* connection) OVERRIDE {
+ connection->AddService(this);
+ return true;
+ }
+
+ // mojo::InterfaceFactory<mojo::Clipboard> implementation.
+ virtual void Create(
+ mojo::ApplicationConnection* connection,
+ mojo::InterfaceRequest<mojo::Clipboard> request) OVERRIDE {
+ // TODO(erg): Write native implementations of the clipboard. For now, we
+ // just build a clipboard which doesn't interact with the system.
+ mojo::BindToRequest(new mojo::ClipboardStandaloneImpl(), &request);
+ }
+};
+
+MojoResult MojoMain(MojoHandle shell_handle) {
+ mojo::ApplicationRunnerChromium runner(new Delegate);
+ return runner.Run(shell_handle);
+}
diff --git a/mojo/services/html_viewer/BUILD.gn b/mojo/services/html_viewer/BUILD.gn
index 3e640b9..22246ab 100644
--- a/mojo/services/html_viewer/BUILD.gn
+++ b/mojo/services/html_viewer/BUILD.gn
@@ -18,6 +18,8 @@ shared_library("html_viewer") {
"html_viewer.cc",
"html_document_view.cc",
"html_document_view.h",
+ "webclipboard_impl.cc",
+ "webclipboard_impl.h",
"webcookiejar_impl.cc",
"webcookiejar_impl.h",
"webmediaplayer_factory.cc",
@@ -53,6 +55,7 @@ shared_library("html_viewer") {
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/utility",
"//mojo/services/public/cpp/view_manager",
+ "//mojo/services/public/interfaces/clipboard",
"//mojo/services/public/interfaces/content_handler",
"//mojo/services/public/interfaces/gpu",
"//mojo/services/public/interfaces/navigation",
diff --git a/mojo/services/html_viewer/blink_basic_type_converters.cc b/mojo/services/html_viewer/blink_basic_type_converters.cc
index 23b9e5f..eb52652 100644
--- a/mojo/services/html_viewer/blink_basic_type_converters.cc
+++ b/mojo/services/html_viewer/blink_basic_type_converters.cc
@@ -21,4 +21,14 @@ WebString TypeConverter<WebString, String>::Convert(const String& str) {
return WebString::fromUTF8(str.get());
}
+// static
+Array<uint8_t> TypeConverter<Array<uint8_t>, blink::WebString>::Convert(
+ const blink::WebString& input) {
+ std::string utf8 = input.utf8();
+ Array<uint8_t> result(utf8.size());
+ for (size_t i = 0; i < utf8.size(); ++i)
+ result[i] = utf8[i];
+ return result.Pass();
+}
+
} // namespace mojo
diff --git a/mojo/services/html_viewer/blink_basic_type_converters.h b/mojo/services/html_viewer/blink_basic_type_converters.h
index cb3b803..60ddeee 100644
--- a/mojo/services/html_viewer/blink_basic_type_converters.h
+++ b/mojo/services/html_viewer/blink_basic_type_converters.h
@@ -25,6 +25,10 @@ template<>
struct TypeConverter<blink::WebString, String> {
static blink::WebString Convert(const String& str);
};
+template <>
+struct TypeConverter<Array<uint8_t>, blink::WebString> {
+ static Array<uint8_t> Convert(const blink::WebString& input);
+};
template<typename T, typename U>
struct TypeConverter<Array<T>, blink::WebVector<U> > {
diff --git a/mojo/services/html_viewer/blink_platform_impl.cc b/mojo/services/html_viewer/blink_platform_impl.cc
index 1d19b83..315a850 100644
--- a/mojo/services/html_viewer/blink_platform_impl.cc
+++ b/mojo/services/html_viewer/blink_platform_impl.cc
@@ -11,6 +11,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "mojo/public/cpp/application/application_impl.h"
+#include "mojo/services/html_viewer/webclipboard_impl.h"
#include "mojo/services/html_viewer/webcookiejar_impl.h"
#include "mojo/services/html_viewer/websockethandle_impl.h"
#include "mojo/services/html_viewer/webthread_impl.h"
@@ -59,6 +60,10 @@ BlinkPlatformImpl::BlinkPlatformImpl(ApplicationImpl* app)
CookieStorePtr cookie_store;
network_service_->GetCookieStore(Get(&cookie_store));
cookie_jar_.reset(new WebCookieJarImpl(cookie_store.Pass()));
+
+ ClipboardPtr clipboard;
+ app->ConnectToService("mojo:mojo_clipboard", &clipboard);
+ clipboard_.reset(new WebClipboardImpl(clipboard.Pass()));
}
BlinkPlatformImpl::~BlinkPlatformImpl() {
@@ -68,6 +73,10 @@ blink::WebCookieJar* BlinkPlatformImpl::cookieJar() {
return cookie_jar_.get();
}
+blink::WebClipboard* BlinkPlatformImpl::clipboard() {
+ return clipboard_.get();
+}
+
blink::WebMimeRegistry* BlinkPlatformImpl::mimeRegistry() {
return &mime_registry_;
}
diff --git a/mojo/services/html_viewer/blink_platform_impl.h b/mojo/services/html_viewer/blink_platform_impl.h
index aeae757..522f98d 100644
--- a/mojo/services/html_viewer/blink_platform_impl.h
+++ b/mojo/services/html_viewer/blink_platform_impl.h
@@ -18,6 +18,7 @@
namespace mojo {
class ApplicationImpl;
+class WebClipboardImpl;
class WebCookieJarImpl;
class BlinkPlatformImpl : public blink::Platform {
@@ -27,6 +28,7 @@ class BlinkPlatformImpl : public blink::Platform {
// blink::Platform methods:
virtual blink::WebCookieJar* cookieJar();
+ virtual blink::WebClipboard* clipboard();
virtual blink::WebMimeRegistry* mimeRegistry();
virtual blink::WebThemeEngine* themeEngine();
virtual blink::WebString defaultLocale();
@@ -78,6 +80,7 @@ class BlinkPlatformImpl : public blink::Platform {
cc_blink::WebCompositorSupportImpl compositor_support_;
WebThemeEngineImpl theme_engine_;
scoped_ptr<WebCookieJarImpl> cookie_jar_;
+ scoped_ptr<WebClipboardImpl> clipboard_;
WebMimeRegistryImpl mime_registry_;
blink::WebScrollbarBehavior scrollbar_behavior_;
diff --git a/mojo/services/html_viewer/webclipboard_impl.cc b/mojo/services/html_viewer/webclipboard_impl.cc
new file mode 100644
index 0000000..94b16ca
--- /dev/null
+++ b/mojo/services/html_viewer/webclipboard_impl.cc
@@ -0,0 +1,222 @@
+// Copyright 2014 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 "mojo/services/html_viewer/webclipboard_impl.h"
+
+#include "base/bind.h"
+#include "mojo/services/html_viewer/blink_basic_type_converters.h"
+
+namespace mojo {
+namespace {
+
+void CopyUint64(uint64_t* output, uint64_t input) {
+ *output = input;
+}
+
+void CopyWebString(blink::WebString* output,
+ const mojo::Array<uint8_t>& input) {
+ // blink does not differentiate between the requested data type not existing
+ // and the empty string.
+ if (input.is_null()) {
+ output->reset();
+ } else {
+ *output = blink::WebString::fromUTF8(
+ reinterpret_cast<const char*>(&input.front()),
+ input.size());
+ }
+}
+
+void CopyURL(blink::WebURL* pageURL,
+ const mojo::Array<uint8_t>& input) {
+ if (input.is_null()) {
+ *pageURL = blink::WebURL();
+ } else {
+ *pageURL = GURL(std::string(reinterpret_cast<const char*>(&input.front()),
+ input.size()));
+ }
+}
+
+void CopyVectorString(std::vector<std::string>* output,
+ const Array<String>& input) {
+ *output = input.To<std::vector<std::string> >();
+}
+
+template <typename T, typename U>
+bool Contains(const std::vector<T>& v, const U& item) {
+ return std::find(v.begin(), v.end(), item) != v.end();
+}
+
+const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
+
+} // namespace
+
+WebClipboardImpl::WebClipboardImpl(ClipboardPtr clipboard)
+ : clipboard_(clipboard.Pass()) {
+}
+
+WebClipboardImpl::~WebClipboardImpl() {
+}
+
+uint64_t WebClipboardImpl::sequenceNumber(Buffer buffer) {
+ mojo::Clipboard::Type clipboard_type = ConvertBufferType(buffer);
+
+ uint64_t number = 0;
+ clipboard_->GetSequenceNumber(clipboard_type,
+ base::Bind(&CopyUint64, &number));
+
+ // Force this to be synchronous.
+ clipboard_.WaitForIncomingMethodCall();
+ return number;
+}
+
+bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
+ mojo::Clipboard::Type clipboard_type = ConvertBufferType(buffer);
+
+ std::vector<std::string> types;
+ clipboard_->GetAvailableMimeTypes(
+ clipboard_type, base::Bind(&CopyVectorString, &types));
+
+ // Force this to be synchronous.
+ clipboard_.WaitForIncomingMethodCall();
+
+ switch (format) {
+ case FormatPlainText:
+ return Contains(types, mojo::Clipboard::MIME_TYPE_TEXT);
+ case FormatHTML:
+ return Contains(types, mojo::Clipboard::MIME_TYPE_HTML);
+ case FormatSmartPaste:
+ return Contains(types, kMimeTypeWebkitSmartPaste);
+ case FormatBookmark:
+ // This might be difficult.
+ return false;
+ }
+
+ return false;
+}
+
+blink::WebVector<blink::WebString> WebClipboardImpl::readAvailableTypes(
+ Buffer buffer,
+ bool* containsFilenames) {
+ mojo::Clipboard::Type clipboard_type = ConvertBufferType(buffer);
+
+ std::vector<std::string> types;
+ clipboard_->GetAvailableMimeTypes(
+ clipboard_type, base::Bind(&CopyVectorString, &types));
+
+ // Force this to be synchronous.
+ clipboard_.WaitForIncomingMethodCall();
+
+ // AFAICT, every instance of setting containsFilenames is false.
+ *containsFilenames = false;
+
+ blink::WebVector<blink::WebString> output(types.size());
+ for (size_t i = 0; i < types.size(); ++i) {
+ output[i] = blink::WebString::fromUTF8(types[i]);
+ }
+
+ return output;
+}
+
+blink::WebString WebClipboardImpl::readPlainText(Buffer buffer) {
+ mojo::Clipboard::Type type = ConvertBufferType(buffer);
+
+ blink::WebString text;
+ clipboard_->ReadMimeType(
+ type, mojo::Clipboard::MIME_TYPE_TEXT, base::Bind(&CopyWebString, &text));
+
+ // Force this to be synchronous.
+ clipboard_.WaitForIncomingMethodCall();
+
+ return text;
+}
+
+blink::WebString WebClipboardImpl::readHTML(Buffer buffer,
+ blink::WebURL* pageURL,
+ unsigned* fragmentStart,
+ unsigned* fragmentEnd) {
+ mojo::Clipboard::Type type = ConvertBufferType(buffer);
+
+ blink::WebString html;
+ clipboard_->ReadMimeType(
+ type, mojo::Clipboard::MIME_TYPE_HTML, base::Bind(&CopyWebString, &html));
+ clipboard_.WaitForIncomingMethodCall();
+
+ *fragmentStart = 0;
+ *fragmentEnd = static_cast<unsigned>(html.length());
+
+ clipboard_->ReadMimeType(
+ type, mojo::Clipboard::MIME_TYPE_URL, base::Bind(&CopyURL, pageURL));
+ clipboard_.WaitForIncomingMethodCall();
+
+ return html;
+}
+
+blink::WebString WebClipboardImpl::readCustomData(
+ Buffer buffer,
+ const blink::WebString& mime_type) {
+ mojo::Clipboard::Type clipboard_type = ConvertBufferType(buffer);
+
+ blink::WebString data;
+ clipboard_->ReadMimeType(
+ clipboard_type, mime_type.utf8(), base::Bind(&CopyWebString, &data));
+
+ // Force this to be synchronous.
+ clipboard_.WaitForIncomingMethodCall();
+
+ return data;
+}
+
+void WebClipboardImpl::writePlainText(const blink::WebString& text) {
+ Array<MimeTypePairPtr> data;
+ MimeTypePairPtr text_data(MimeTypePair::New());
+ text_data->mime_type = mojo::Clipboard::MIME_TYPE_TEXT;
+ text_data->data = Array<uint8_t>::From(text).Pass();
+ data.push_back(text_data.Pass());
+
+ clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE, data.Pass());
+}
+
+void WebClipboardImpl::writeHTML(const blink::WebString& htmlText,
+ const blink::WebURL& url,
+ const blink::WebString& plainText,
+ bool writeSmartPaste) {
+ Array<MimeTypePairPtr> data;
+ MimeTypePairPtr text_data(MimeTypePair::New());
+ text_data->mime_type = mojo::Clipboard::MIME_TYPE_TEXT;
+ text_data->data = Array<uint8_t>::From(plainText).Pass();
+ data.push_back(text_data.Pass());
+
+ MimeTypePairPtr html_data(MimeTypePair::New());
+ text_data->mime_type = mojo::Clipboard::MIME_TYPE_HTML;
+ text_data->data = Array<uint8_t>::From(htmlText).Pass();
+ data.push_back(html_data.Pass());
+
+ MimeTypePairPtr url_data(MimeTypePair::New());
+ url_data->mime_type = mojo::Clipboard::MIME_TYPE_URL;
+ url_data->data = Array<uint8_t>::From(url.string()).Pass();
+ data.push_back(url_data.Pass());
+
+ if (writeSmartPaste) {
+ MimeTypePairPtr smart_paste(MimeTypePair::New());
+ url_data->mime_type = kMimeTypeWebkitSmartPaste;
+ url_data->data = Array<uint8_t>::From(blink::WebString()).Pass();
+ data.push_back(smart_paste.Pass());
+ }
+
+ clipboard_->WriteClipboardData(mojo::Clipboard::TYPE_COPY_PASTE, data.Pass());
+}
+
+mojo::Clipboard::Type WebClipboardImpl::ConvertBufferType(Buffer buffer) {
+ switch (buffer) {
+ case BufferStandard:
+ return mojo::Clipboard::TYPE_COPY_PASTE;
+ case BufferSelection:
+ return mojo::Clipboard::TYPE_SELECTION;
+ }
+
+ NOTREACHED();
+ return mojo::Clipboard::TYPE_COPY_PASTE;
+}
+
+} // namespace mojo
diff --git a/mojo/services/html_viewer/webclipboard_impl.h b/mojo/services/html_viewer/webclipboard_impl.h
new file mode 100644
index 0000000..0c307c5
--- /dev/null
+++ b/mojo/services/html_viewer/webclipboard_impl.h
@@ -0,0 +1,48 @@
+// Copyright 2014 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.
+
+#ifndef MOJO_SERVICES_HTML_VIEWER_WEBCLIPBOARD_IMPL_H_
+#define MOJO_SERVICES_HTML_VIEWER_WEBCLIPBOARD_IMPL_H_
+
+#include "mojo/services/public/interfaces/clipboard/clipboard.mojom.h"
+#include "third_party/WebKit/public/platform/WebClipboard.h"
+
+namespace mojo {
+
+class WebClipboardImpl : public blink::WebClipboard {
+ public:
+ WebClipboardImpl(ClipboardPtr clipboard);
+ virtual ~WebClipboardImpl();
+
+ // blink::WebClipboard methods:
+ virtual uint64_t sequenceNumber(Buffer);
+ virtual bool isFormatAvailable(Format, Buffer);
+ virtual blink::WebVector<blink::WebString> readAvailableTypes(
+ Buffer,
+ bool* containsFilenames);
+ virtual blink::WebString readPlainText(Buffer);
+ virtual blink::WebString readHTML(Buffer buffer,
+ blink::WebURL* pageURL,
+ unsigned* fragmentStart,
+ unsigned* fragmentEnd);
+ // TODO(erg): readImage()
+ virtual blink::WebString readCustomData(Buffer, const blink::WebString& type);
+ virtual void writePlainText(const blink::WebString&);
+ virtual void writeHTML(const blink::WebString& htmlText,
+ const blink::WebURL&,
+ const blink::WebString& plainText,
+ bool writeSmartPaste);
+
+ private:
+ // Changes webkit buffers to mojo Clipboard::Types.
+ mojo::Clipboard::Type ConvertBufferType(Buffer buffer);
+
+ ClipboardPtr clipboard_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebClipboardImpl);
+};
+
+} // namespace mojo
+
+#endif // MOJO_SERVICES_HTML_VIEWER_WEBCLIPBOARD_IMPL_H_
diff --git a/mojo/services/public/interfaces/clipboard/BUILD.gn b/mojo/services/public/interfaces/clipboard/BUILD.gn
new file mode 100644
index 0000000..65dd7d3
--- /dev/null
+++ b/mojo/services/public/interfaces/clipboard/BUILD.gn
@@ -0,0 +1,12 @@
+# Copyright 2014 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+# GYP version: mojo/mojo_services.gypi:mojo_clipboard_bindings
+mojom("clipboard") {
+ sources = [
+ "clipboard.mojom",
+ ]
+}
diff --git a/mojo/services/public/interfaces/clipboard/clipboard.mojom b/mojo/services/public/interfaces/clipboard/clipboard.mojom
new file mode 100644
index 0000000..c1e1be4
--- /dev/null
+++ b/mojo/services/public/interfaces/clipboard/clipboard.mojom
@@ -0,0 +1,52 @@
+// Copyright 2014 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.
+
+module mojo {
+
+// A wrapper type which is just a Key/Value pair. Workaround until we get
+// proper maps in mojom.
+struct MimeTypePair {
+ string mime_type;
+ uint8[] data;
+};
+
+interface Clipboard {
+ enum Type {
+ COPY_PASTE = 0,
+ SELECTION = 1,
+ DRAG = 2
+ };
+
+ // Mime type constants
+ const string MIME_TYPE_TEXT = "text/plain";
+ const string MIME_TYPE_HTML = "text/html";
+ const string MIME_TYPE_URL = "text/url";
+
+ // Returns a sequence number which uniquely identifies clipboard state.
+ // Clients are able to assume that the clipboard contents are unchanged as
+ // long as this number has not changed. This number is monotonically
+ // increasing, is increased when the clipboard state changes, and is
+ // provided by Windows, Linux, and Mac.
+ GetSequenceNumber(Type clipboard_type) => (uint64 sequence);
+
+ // Returns the available mime types. (Note: the chrome interface has a
+ // |contains_filenames| parameter here, but it appears to always be set
+ // to false.)
+ GetAvailableMimeTypes(Type clipboard_types) => (string[] types);
+
+ // Returns the data associated with a Mime type, returning NULL if that data
+ // doesn't exist. Note: because of the inherit raciness of clipboard access,
+ // this may return NULL even if you just verified that it exists with
+ // GetAvailableFormatMimeTypes(). We don't want to provide one API to return
+ // the entire clipboard state because the combined size of the clipboard can
+ // be megabytes, especially when image data is involved.
+ ReadMimeType(Type clipboard_type, string mime_type) => (uint8[]? data);
+
+ // Writes a set of mime types to the clipboard. This will increment the
+ // sequence number. In the case of an empty or NULL list, this will just
+ // clear the clipboard.
+ WriteClipboardData(Type clipboard_type, MimeTypePair[]? data);
+};
+
+} // module mojo