Commit 757286d8 authored by erg's avatar erg Committed by Commit bot

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

Review URL: https://codereview.chromium.org/562483002

Cr-Commit-Position: refs/heads/master@{#295143}
parent db519299
......@@ -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",
......
......@@ -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
......@@ -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_
......@@ -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
......@@ -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',
......
......@@ -4,6 +4,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',
......@@ -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',
......
......@@ -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); }
......
......@@ -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",
......
# 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/system.gni")
# GYP version: mojo/mojo_services.gypi:mojo_clipboard
component("clipboard") {
deps = [
"//base",
"//mojo/common",
"//mojo/environment:chromium",
"//mojo/services/public/interfaces/clipboard",
"//ui/base",
] + mojo_system_for_component
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",
]
}
include_rules = [
"+mojo/application",
"+mojo/services",
]
// 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
// 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_
// 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
// 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);
}
......@@ -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",
......
......@@ -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
......@@ -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> > {
......
......@@ -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_;
}
......
......@@ -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_;
......
// 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
// 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_
# 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",
]
}
// 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
......@@ -41,6 +41,7 @@
"browser_tests",
"content_browsertests",
"mojo_apps_js_unittests",
"mojo_clipboard_unittests",
"mojo_common_unittests",
"mojo_js_unittests",
"mojo_public_bindings_unittests",
......@@ -96,6 +97,7 @@
"browser_tests",
"content_browsertests",
"mojo_apps_js_unittests",
"mojo_clipboard_unittests",
"mojo_common_unittests",
"mojo_js_unittests",
"mojo_public_bindings_unittests",
......@@ -151,6 +153,7 @@
"browser_tests",
"content_browsertests",
"mojo_apps_js_unittests",
"mojo_clipboard_unittests",
"mojo_common_unittests",
"mojo_js_unittests",
"mojo_public_bindings_unittests",
......@@ -206,6 +209,7 @@
"browser_tests",
"content_browsertests",
"mojo_apps_js_unittests",
"mojo_clipboard_unittests",
"mojo_common_unittests",
"mojo_js_unittests",
"mojo_public_bindings_unittests",
......@@ -251,6 +255,7 @@
"media_unittests",
"message_center_unittests",
"mojo_apps_js_unittests",
"mojo_clipboard_unittests",
"mojo_common_unittests",
"mojo_js_unittests",
"mojo_public_bindings_unittests",
......
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