Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(673)

Unified Diff: content/renderer/pepper/pepper_flash_clipboard_host.cc

Issue 11225021: Move flash clipboard to the new proxy and add custom format support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/pepper/pepper_flash_clipboard_host.cc
diff --git a/content/renderer/pepper/pepper_flash_clipboard_host.cc b/content/renderer/pepper/pepper_flash_clipboard_host.cc
new file mode 100644
index 0000000000000000000000000000000000000000..686d7f98f9ad567b45400480541aac8fc5cf9ea9
--- /dev/null
+++ b/content/renderer/pepper/pepper_flash_clipboard_host.cc
@@ -0,0 +1,339 @@
+// Copyright (c) 2012 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 "content/renderer/pepper/pepper_flash_clipboard_host.h"
+
+#include "base/pickle.h"
+#include "base/utf_string_conversions.h"
+#include "content/public/renderer/renderer_ppapi_host.h"
+#include "content/renderer/renderer_clipboard_client.h"
+#include "ipc/ipc_message_macros.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/private/ppb_flash_clipboard.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/resource_message_params.h"
+#include "webkit/glue/clipboard_client.h"
+#include "webkit/glue/scoped_clipboard_writer_glue.h"
+
+namespace content {
+
+namespace {
+
+const size_t kMaxClipboardWriteSize = 1000000;
+
+ui::Clipboard::Buffer ConvertClipboardType(uint32_t type) {
+ switch (type) {
+ case PP_FLASH_CLIPBOARD_TYPE_STANDARD:
+ return ui::Clipboard::BUFFER_STANDARD;
+ case PP_FLASH_CLIPBOARD_TYPE_SELECTION:
+ return ui::Clipboard::BUFFER_SELECTION;
+ }
+ NOTREACHED();
+ return ui::Clipboard::BUFFER_STANDARD;
+}
+
+// Functions to pack/unpack custom data from a pickle. See the header file for
+// more detail on custom formats in Pepper.
+// TODO(raymes): Currently pepper custom formats are stored in their own
+// native format type. However we should be able to store them in the same way
+// as "Web Custom" formats are. This would allow clipboard data to be shared
+// between pepper applications and web applications. However currently web apps
+// assume all data that is placed on the clipboard is UTF16 and pepper allows
+// arbitrary data so this change would require some reworking of the chrome
+// clipboard interface for custom data.
+bool JumpToFormatInPickle(const string16& format, PickleIterator* iter) {
+ uint64 size = 0;
+ if (!iter->ReadUInt64(&size))
+ return false;
+ for (uint64 i = 0; i < size; ++i) {
+ string16 stored_format;
+ if (!iter->ReadString16(&stored_format))
+ return false;
+ if (stored_format == format)
+ return true;
+ int skip_length;
+ if (!iter->ReadLength(&skip_length))
+ return false;
+ if (!iter->SkipBytes(skip_length))
+ return false;
+ }
+ return false;
+}
+
+bool IsFormatAvailableInPickle(const string16& format, const Pickle& pickle) {
+ PickleIterator iter(pickle);
+ return JumpToFormatInPickle(format, &iter);
+}
+
+std::string ReadDataFromPickle(const string16& format, const Pickle& pickle) {
+ std::string result;
+ PickleIterator iter(pickle);
+ if (!JumpToFormatInPickle(format, &iter) || !iter.ReadString(&result))
+ return std::string();
+ return result;
+}
+
+bool WriteDataToPickle(const std::map<string16, std::string>& data,
+ Pickle* pickle) {
+ pickle->WriteUInt64(data.size());
+ for (std::map<string16, std::string>::const_iterator it = data.begin();
+ it != data.end(); ++it) {
+ if (!pickle->WriteString16(it->first))
+ return false;
+ if (!pickle->WriteString(it->second))
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+PepperFlashClipboardHost::PepperFlashClipboardHost(
+ RendererPpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource)
+ : ResourceHost(host->GetPpapiHost(), instance, resource),
+ clipboard_client_(new RendererClipboardClient) {
+}
+
+PepperFlashClipboardHost::~PepperFlashClipboardHost() {
+}
+
+int32_t PepperFlashClipboardHost::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) {
+ IPC_BEGIN_MESSAGE_MAP(PepperFlashClipboardHost, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_FlashClipboard_RegisterCustomFormat,
+ OnMsgRegisterCustomFormat);
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_FlashClipboard_IsFormatAvailable,
+ OnMsgIsFormatAvailable);
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_FlashClipboard_ReadData,
+ OnMsgReadData);
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_FlashClipboard_WriteData,
+ OnMsgWriteData);
+ IPC_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperFlashClipboardHost::OnMsgRegisterCustomFormat(
+ ppapi::host::HostMessageContext* host_context,
+ const std::string& format_name) {
+ uint32_t format = custom_formats_.RegisterFormat(format_name);
+ if (format == PP_FLASH_CLIPBOARD_FORMAT_INVALID)
+ return PP_ERROR_FAILED;
+ host_context->reply_msg =
+ PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply(format);
+ return PP_OK;
+}
+
+int32_t PepperFlashClipboardHost::OnMsgIsFormatAvailable(
+ ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type,
+ uint32_t format) {
+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
+ NOTIMPLEMENTED();
+ return PP_ERROR_FAILED;
+ }
+
+ ui::Clipboard::Buffer buffer_type = ConvertClipboardType(clipboard_type);
+ bool available = false;
+ switch (format) {
+ case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
+ bool plain = clipboard_client_->IsFormatAvailable(
+ ui::Clipboard::GetPlainTextFormatType(), buffer_type);
+ bool plainw = clipboard_client_->IsFormatAvailable(
+ ui::Clipboard::GetPlainTextWFormatType(), buffer_type);
+ available = plain || plainw;
+ break;
+ }
+ case PP_FLASH_CLIPBOARD_FORMAT_HTML:
+ available = clipboard_client_->IsFormatAvailable(
+ ui::Clipboard::GetHtmlFormatType(), buffer_type);
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_RTF:
+ available = clipboard_client_->IsFormatAvailable(
+ ui::Clipboard::GetRtfFormatType(), buffer_type);
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
+ break;
+ default:
+ if (custom_formats_.IsFormatRegistered(format)) {
+ std::string format_name = custom_formats_.GetFormatName(format);
+ std::string clipboard_data;
+ clipboard_client_->ReadData(
+ ui::Clipboard::GetPepperCustomDataFormatType(), &clipboard_data);
+ Pickle pickle(clipboard_data.data(), clipboard_data.size());
+ available = IsFormatAvailableInPickle(UTF8ToUTF16(format_name), pickle);
+ }
+ break;
+ }
+
+ return available ? PP_OK : PP_ERROR_FAILED;
+}
+
+int32_t PepperFlashClipboardHost::OnMsgReadData(
+ ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type,
+ uint32_t format) {
+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
+ NOTIMPLEMENTED();
+ return PP_ERROR_FAILED;
+ }
+
+ ui::Clipboard::Buffer buffer_type = ConvertClipboardType(clipboard_type);
+ std::string clipboard_string;
+ int32_t result = PP_ERROR_FAILED;
+ switch (format) {
+ case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
+ if (clipboard_client_->IsFormatAvailable(
+ ui::Clipboard::GetPlainTextWFormatType(), buffer_type)) {
+ string16 text;
+ clipboard_client_->ReadText(buffer_type, &text);
+ if (!text.empty()) {
+ result = PP_OK;
+ clipboard_string = UTF16ToUTF8(text);
+ break;
+ }
+ }
+ // If the PlainTextW format isn't available or is empty, take the
+ // ASCII text format.
+ if (clipboard_client_->IsFormatAvailable(
+ ui::Clipboard::GetPlainTextFormatType(), buffer_type)) {
+ result = PP_OK;
+ clipboard_client_->ReadAsciiText(buffer_type, &clipboard_string);
+ }
+ break;
+ }
+ case PP_FLASH_CLIPBOARD_FORMAT_HTML: {
+ if (!clipboard_client_->IsFormatAvailable(
+ ui::Clipboard::GetHtmlFormatType(), buffer_type)) {
+ break;
+ }
+
+ string16 html;
+ GURL gurl;
+ uint32 fragment_start;
+ uint32 fragment_end;
+ clipboard_client_->ReadHTML(buffer_type, &html, &gurl, &fragment_start,
+ &fragment_end);
+ result = PP_OK;
+ clipboard_string = UTF16ToUTF8(
+ html.substr(fragment_start, fragment_end - fragment_start));
+ break;
+ }
+ case PP_FLASH_CLIPBOARD_FORMAT_RTF: {
+ if (!clipboard_client_->IsFormatAvailable(
+ ui::Clipboard::GetRtfFormatType(), buffer_type)) {
+ break;
+ }
+ result = PP_OK;
+ clipboard_client_->ReadRTF(buffer_type, &clipboard_string);
+ break;
+ }
+ case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
+ break;
+ default: {
+ if (custom_formats_.IsFormatRegistered(format)) {
+ string16 format_name = UTF8ToUTF16(
+ custom_formats_.GetFormatName(format));
+ std::string clipboard_data;
+ clipboard_client_->ReadData(
+ ui::Clipboard::GetPepperCustomDataFormatType(), &clipboard_data);
+ Pickle pickle(clipboard_data.data(), clipboard_data.size());
+ if (IsFormatAvailableInPickle(format_name, pickle)) {
+ result = PP_OK;
+ clipboard_string = ReadDataFromPickle(format_name, pickle);
+ }
+ }
+ break;
+ }
+ }
+
+ if (result == PP_OK) {
+ host_context->reply_msg =
+ PpapiPluginMsg_FlashClipboard_ReadDataReply(clipboard_string);
+ }
+ return result;
+}
+
+int32_t PepperFlashClipboardHost::OnMsgWriteData(
+ ppapi::host::HostMessageContext* host_context,
+ uint32_t clipboard_type,
+ const std::vector<uint32_t>& formats,
+ const std::vector<std::string>& data) {
+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
+ NOTIMPLEMENTED();
+ return PP_ERROR_FAILED;
+ }
+
+ DCHECK(formats.size() == data.size());
+ // If no formats are passed in clear the clipboard.
+ if (formats.size() == 0) {
+ clipboard_client_->Clear(ConvertClipboardType(clipboard_type));
+ return PP_OK;
+ }
+
+ webkit_glue::ScopedClipboardWriterGlue scw(clipboard_client_.get());
+ std::map<string16, std::string> custom_data_map;
+ int32_t res = PP_OK;
+ for (uint32_t i = 0; i < formats.size(); ++i) {
+ if (data[i].length() > kMaxClipboardWriteSize) {
+ res = PP_ERROR_NOSPACE;
+ break;
+ }
+
+ switch (formats[i]) {
+ case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT:
+ scw.WriteText(UTF8ToUTF16(data[i]));
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_HTML:
+ scw.WriteHTML(UTF8ToUTF16(data[i]), "");
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_RTF:
+ scw.WriteRTF(data[i]);
+ break;
+ case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
+ res = PP_ERROR_BADARGUMENT;
+ break;
+ default:
+ if (custom_formats_.IsFormatRegistered(formats[i])) {
+ std::string format_name = custom_formats_.GetFormatName(formats[i]);
+ custom_data_map[UTF8ToUTF16(format_name)] = data[i];
+ } else {
+ // Invalid format.
+ res = PP_ERROR_BADARGUMENT;
+ break;
+ }
+ }
+
+ if (res != PP_OK)
+ break;
+ }
+
+ if (custom_data_map.size() > 0) {
+ Pickle pickle;
+ if (WriteDataToPickle(custom_data_map, &pickle)) {
+ scw.WritePickledData(pickle,
+ ui::Clipboard::GetPepperCustomDataFormatType());
+ } else {
+ res = PP_ERROR_BADARGUMENT;
+ }
+ }
+
+ if (res != PP_OK) {
+ // Need to clear the objects so nothing is written.
+ scw.Reset();
+ }
+
+ return res;
+}
+
+} // namespace content
+
« no previous file with comments | « content/renderer/pepper/pepper_flash_clipboard_host.h ('k') | content/renderer/pepper/pepper_plugin_delegate_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698