pepper_flash_clipboard_message_filter.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// Use of this source code is governed by a BSD-style license that can be
3ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// found in the LICENSE file.
4ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
5ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h"
6ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
7ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "base/pickle.h"
8ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "base/strings/utf_string_conversions.h"
9ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "content/public/browser/browser_thread.h"
10ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ipc/ipc_message.h"
11ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ipc/ipc_message_macros.h"
12ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ppapi/c/pp_errors.h"
13ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ppapi/c/private/ppb_flash_clipboard.h"
14ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ppapi/host/dispatch_host_message.h"
15ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ppapi/host/host_message_context.h"
16ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ppapi/host/ppapi_host.h"
17ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ppapi/proxy/ppapi_messages.h"
18ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ppapi/proxy/resource_message_params.h"
19ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "ui/base/clipboard/scoped_clipboard_writer.h"
20ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
21ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectusing content::BrowserThread;
22ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
23ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectnamespace chrome {
24ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
2594442ad4107000e6d49f9b85a46a591495a57632Selim Gurunnamespace {
2694442ad4107000e6d49f9b85a46a591495a57632Selim Gurun
27ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectconst size_t kMaxClipboardWriteSize = 1000000;
28ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
29ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectui::Clipboard::Buffer ConvertClipboardType(uint32_t type) {
30ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  switch (type) {
31ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    case PP_FLASH_CLIPBOARD_TYPE_STANDARD:
32ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      return ui::Clipboard::BUFFER_STANDARD;
3394442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    case PP_FLASH_CLIPBOARD_TYPE_SELECTION:
34ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      return ui::Clipboard::BUFFER_SELECTION;
35ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
36ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  NOTREACHED();
37ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return ui::Clipboard::BUFFER_STANDARD;
38ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
39ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
4094442ad4107000e6d49f9b85a46a591495a57632Selim Gurun// Functions to pack/unpack custom data from a pickle. See the header file for
41ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// more detail on custom formats in Pepper.
42ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// TODO(raymes): Currently pepper custom formats are stored in their own
43ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// native format type. However we should be able to store them in the same way
44ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// as "Web Custom" formats are. This would allow clipboard data to be shared
45ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// between pepper applications and web applications. However currently web apps
46ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// assume all data that is placed on the clipboard is UTF16 and pepper allows
4794442ad4107000e6d49f9b85a46a591495a57632Selim Gurun// arbitrary data so this change would require some reworking of the chrome
48ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project// clipboard interface for custom data.
49ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectbool JumpToFormatInPickle(const string16& format, PickleIterator* iter) {
50ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  uint64 size = 0;
51ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (!iter->ReadUInt64(&size))
52ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return false;
53ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  for (uint64 i = 0; i < size; ++i) {
5494442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    string16 stored_format;
55ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (!iter->ReadString16(&stored_format))
56ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      return false;
57ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (stored_format == format)
58ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      return true;
59ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int skip_length;
60ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (!iter->ReadLength(&skip_length))
6194442ad4107000e6d49f9b85a46a591495a57632Selim Gurun      return false;
62ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (!iter->SkipBytes(skip_length))
63ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      return false;
64ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
65ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return false;
66ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
67ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
68ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectbool IsFormatAvailableInPickle(const string16& format, const Pickle& pickle) {
69ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  PickleIterator iter(pickle);
70ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return JumpToFormatInPickle(format, &iter);
71ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
72ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
73ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstd::string ReadDataFromPickle(const string16& format, const Pickle& pickle) {
74ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  std::string result;
75ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  PickleIterator iter(pickle);
76ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (!JumpToFormatInPickle(format, &iter) || !iter.ReadString(&result))
77ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return std::string();
78ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return result;
79ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
80ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
81ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectbool WriteDataToPickle(const std::map<string16, std::string>& data,
82ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                       Pickle* pickle) {
83ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  pickle->WriteUInt64(data.size());
84ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  for (std::map<string16, std::string>::const_iterator it = data.begin();
85ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project       it != data.end(); ++it) {
86ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (!pickle->WriteString16(it->first))
87ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      return false;
88ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (!pickle->WriteString(it->second))
89ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      return false;
90ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
91ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return true;
92ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
93ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
94ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}  // namespace
95ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
96ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectPepperFlashClipboardMessageFilter::PepperFlashClipboardMessageFilter() {
97ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
98ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
99ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectPepperFlashClipboardMessageFilter::~PepperFlashClipboardMessageFilter() {
100ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
101ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
102ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectscoped_refptr<base::TaskRunner>
103ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectPepperFlashClipboardMessageFilter::OverrideTaskRunnerForMessage(
104ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    const IPC::Message& msg) {
105ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  // Clipboard writes should always occur on the UI thread due to the
106ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  // restrictions of various platform APIs. In general, the clipboard is not
107ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  // thread-safe, so all clipboard calls should be serviced from the UI thread.
108ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (msg.type() == PpapiHostMsg_FlashClipboard_WriteData::ID)
109ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
110ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
111ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  // Windows needs clipboard reads to be serviced from the IO thread because
112ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  // these are sync IPCs which can result in deadlocks with plugins if serviced
113ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  // from the UI thread. Note that Windows clipboard calls ARE thread-safe so it
114ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  // is ok for reads and writes to be serviced from different threads.
115ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#if !defined(OS_WIN)
116ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
117ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#else
118ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
119ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
120ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
121ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
122ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint32_t PepperFlashClipboardMessageFilter::OnResourceMessageReceived(
123ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    const IPC::Message& msg,
124ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ppapi::host::HostMessageContext* context) {
125ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  IPC_BEGIN_MESSAGE_MAP(PepperFlashClipboardMessageFilter, msg)
126ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
127ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        PpapiHostMsg_FlashClipboard_RegisterCustomFormat,
128ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        OnMsgRegisterCustomFormat);
129ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
130ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        PpapiHostMsg_FlashClipboard_IsFormatAvailable,
131ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        OnMsgIsFormatAvailable);
132ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
133ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        PpapiHostMsg_FlashClipboard_ReadData,
134ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        OnMsgReadData);
135ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
136ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        PpapiHostMsg_FlashClipboard_WriteData,
137ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        OnMsgWriteData);
138ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  IPC_END_MESSAGE_MAP()
139ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return PP_ERROR_FAILED;
140ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
141ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
142ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint32_t PepperFlashClipboardMessageFilter::OnMsgRegisterCustomFormat(
143ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ppapi::host::HostMessageContext* host_context,
14460a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    const std::string& format_name) {
14560a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  uint32_t format = custom_formats_.RegisterFormat(format_name);
14660a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  if (format == PP_FLASH_CLIPBOARD_FORMAT_INVALID)
147ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return PP_ERROR_FAILED;
148ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  host_context->reply_msg =
14960a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply(format);
15060a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  return PP_OK;
15160a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott}
152ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
153ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint32_t PepperFlashClipboardMessageFilter::OnMsgIsFormatAvailable(
154ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ppapi::host::HostMessageContext* host_context,
155ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    uint32_t clipboard_type,
15660a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    uint32_t format) {
157ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
158ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    NOTIMPLEMENTED();
159ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return PP_ERROR_FAILED;
160ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
161ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
162ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
163ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  ui::Clipboard::Buffer buffer_type = ConvertClipboardType(clipboard_type);
164ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  bool available = false;
165ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  switch (format) {
166ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
167ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      bool plain = clipboard->IsFormatAvailable(
168ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          ui::Clipboard::GetPlainTextFormatType(), buffer_type);
169ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      bool plainw = clipboard->IsFormatAvailable(
170ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          ui::Clipboard::GetPlainTextWFormatType(), buffer_type);
171ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      available = plain || plainw;
172ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
173ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
174ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    case PP_FLASH_CLIPBOARD_FORMAT_HTML:
175ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      available = clipboard->IsFormatAvailable(
176ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          ui::Clipboard::GetHtmlFormatType(), buffer_type);
177ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
178ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    case PP_FLASH_CLIPBOARD_FORMAT_RTF:
179ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      available = clipboard->IsFormatAvailable(
180ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          ui::Clipboard::GetRtfFormatType(), buffer_type);
181ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
182ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
183ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
184ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    default:
185ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      if (custom_formats_.IsFormatRegistered(format)) {
186ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        std::string format_name = custom_formats_.GetFormatName(format);
187ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        std::string clipboard_data;
188ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        clipboard->ReadData(
189ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project            ui::Clipboard::GetPepperCustomDataFormatType(), &clipboard_data);
190ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        Pickle pickle(clipboard_data.data(), clipboard_data.size());
191ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        available = IsFormatAvailableInPickle(UTF8ToUTF16(format_name), pickle);
192ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      }
193ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
194ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
19560a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott
19660a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  return available ? PP_OK : PP_ERROR_FAILED;
19760a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott}
19860a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott
19960a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scottint32_t PepperFlashClipboardMessageFilter::OnMsgReadData(
20060a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    ppapi::host::HostMessageContext* host_context,
20160a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    uint32_t clipboard_type,
20260a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    uint32_t format) {
20360a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
20460a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    NOTIMPLEMENTED();
20560a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    return PP_ERROR_FAILED;
20660a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  }
20760a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott
20860a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
20960a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  ui::Clipboard::Buffer buffer_type = ConvertClipboardType(clipboard_type);
21060a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  std::string clipboard_string;
21160a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  int32_t result = PP_ERROR_FAILED;
21260a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott  switch (format) {
21360a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
21460a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      if (clipboard->IsFormatAvailable(
21560a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott          ui::Clipboard::GetPlainTextWFormatType(), buffer_type)) {
21660a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott        string16 text;
21760a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott        clipboard->ReadText(buffer_type, &text);
21860a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott        if (!text.empty()) {
21960a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott          result = PP_OK;
22060a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott          clipboard_string = UTF16ToUTF8(text);
22160a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott          break;
22260a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott        }
22360a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      }
22460a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      // If the PlainTextW format isn't available or is empty, take the
22560a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      // ASCII text format.
22660a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      if (clipboard->IsFormatAvailable(
22760a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott          ui::Clipboard::GetPlainTextFormatType(), buffer_type)) {
22860a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott        result = PP_OK;
22960a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott        clipboard->ReadAsciiText(buffer_type, &clipboard_string);
23060a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      }
23160a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      break;
23260a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    }
23360a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott    case PP_FLASH_CLIPBOARD_FORMAT_HTML: {
23460a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      if (!clipboard->IsFormatAvailable(
23560a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott          ui::Clipboard::GetHtmlFormatType(), buffer_type)) {
23660a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott        break;
23760a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott      }
23860a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott
239ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      string16 html;
240ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      std::string url;
241ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      uint32 fragment_start;
242ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      uint32 fragment_end;
243ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      clipboard->ReadHTML(buffer_type, &html, &url, &fragment_start,
244ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                                  &fragment_end);
245ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      result = PP_OK;
246ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      clipboard_string = UTF16ToUTF8(
247ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          html.substr(fragment_start, fragment_end - fragment_start));
248ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
249ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
250ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    case PP_FLASH_CLIPBOARD_FORMAT_RTF: {
251ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      if (!clipboard->IsFormatAvailable(
252ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          ui::Clipboard::GetRtfFormatType(), buffer_type)) {
253ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        break;
254ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      }
255ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      result = PP_OK;
256ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      clipboard->ReadRTF(buffer_type, &clipboard_string);
257ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
258ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
259ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
260ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
261ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    default: {
262ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      if (custom_formats_.IsFormatRegistered(format)) {
263ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        string16 format_name = UTF8ToUTF16(
264ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project            custom_formats_.GetFormatName(format));
265ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        std::string clipboard_data;
266ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        clipboard->ReadData(
267ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project            ui::Clipboard::GetPepperCustomDataFormatType(), &clipboard_data);
268ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        Pickle pickle(clipboard_data.data(), clipboard_data.size());
269ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        if (IsFormatAvailableInPickle(format_name, pickle)) {
270ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          result = PP_OK;
271ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          clipboard_string = ReadDataFromPickle(format_name, pickle);
272ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        }
273ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      }
274ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
275ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
276ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
277ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
278ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (result == PP_OK) {
279ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    host_context->reply_msg =
280ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        PpapiPluginMsg_FlashClipboard_ReadDataReply(clipboard_string);
281ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
282ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return result;
283ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
284ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
285ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint32_t PepperFlashClipboardMessageFilter::OnMsgWriteData(
286ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ppapi::host::HostMessageContext* host_context,
287ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    uint32_t clipboard_type,
288ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    const std::vector<uint32_t>& formats,
289ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    const std::vector<std::string>& data) {
290ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
291ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    NOTIMPLEMENTED();
292ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return PP_ERROR_FAILED;
293ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
294ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (formats.size() != data.size())
295ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return PP_ERROR_FAILED;
296ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
297ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
298ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  ui::Clipboard::Buffer buffer_type = ConvertClipboardType(clipboard_type);
299ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  // If no formats are passed in clear the clipboard.
300ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (formats.size() == 0) {
301ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    clipboard->Clear(buffer_type);
302ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return PP_OK;
303ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
304ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
305ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  ui::ScopedClipboardWriter scw(clipboard, buffer_type);
306ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  std::map<string16, std::string> custom_data_map;
307ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  int32_t res = PP_OK;
308ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  for (uint32_t i = 0; i < formats.size(); ++i) {
309ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (data[i].length() > kMaxClipboardWriteSize) {
310ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      res = PP_ERROR_NOSPACE;
311ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
312ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
313ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
314ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    switch (formats[i]) {
315ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT:
316ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        scw.WriteText(UTF8ToUTF16(data[i]));
317ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        break;
318ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      case PP_FLASH_CLIPBOARD_FORMAT_HTML:
319ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        scw.WriteHTML(UTF8ToUTF16(data[i]), std::string());
320ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        break;
321ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      case PP_FLASH_CLIPBOARD_FORMAT_RTF:
322ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        scw.WriteRTF(data[i]);
323ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        break;
324ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
325ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        res = PP_ERROR_BADARGUMENT;
326ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        break;
327ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      default:
328ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        if (custom_formats_.IsFormatRegistered(formats[i])) {
329ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          std::string format_name = custom_formats_.GetFormatName(formats[i]);
330ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          custom_data_map[UTF8ToUTF16(format_name)] = data[i];
331ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        } else {
332ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          // Invalid format.
333ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          res = PP_ERROR_BADARGUMENT;
334ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project          break;
335ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        }
336ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
337ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
338ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res != PP_OK)
339ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      break;
340ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
341ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
342ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (custom_data_map.size() > 0) {
343ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    Pickle pickle;
344ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (WriteDataToPickle(custom_data_map, &pickle)) {
345ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      scw.WritePickledData(pickle,
346ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                           ui::Clipboard::GetPepperCustomDataFormatType());
347ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else {
348ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project      res = PP_ERROR_BADARGUMENT;
349ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
350ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
351ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
352ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  if (res != PP_OK) {
353ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    // Need to clear the objects so nothing is written.
354ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    scw.Reset();
355ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  }
356ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
357ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project  return res;
358ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
359ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
360ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}  // namespace chrome
361ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project