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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/pepper/pepper_flash_clipboard_host.h"
6
7 #include "base/pickle.h"
8 #include "base/utf_string_conversions.h"
9 #include "content/public/renderer/renderer_ppapi_host.h"
10 #include "content/renderer/renderer_clipboard_client.h"
11 #include "ipc/ipc_message_macros.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/private/ppb_flash_clipboard.h"
14 #include "ppapi/host/dispatch_host_message.h"
15 #include "ppapi/host/ppapi_host.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/proxy/resource_message_params.h"
18 #include "webkit/glue/clipboard_client.h"
19 #include "webkit/glue/scoped_clipboard_writer_glue.h"
20
21 namespace content {
22
23 namespace {
24
25 const size_t kMaxClipboardWriteSize = 1000000;
26
27 ui::Clipboard::Buffer ConvertClipboardType(
28 uint32_t type) {
29 switch (type) {
30 case PP_FLASH_CLIPBOARD_TYPE_STANDARD:
31 return ui::Clipboard::BUFFER_STANDARD;
32 case PP_FLASH_CLIPBOARD_TYPE_SELECTION:
33 return ui::Clipboard::BUFFER_SELECTION;
34 }
35 NOTREACHED();
36 return ui::Clipboard::BUFFER_STANDARD;
37 }
38
39 // Functions to pack/unpack custom data from a pickle. See the header file for
40 // more detail on custom formats in Pepper.
41 // TODO(raymes): This code is very similar to the code in
dcheng 2012/10/29 20:26:29 We should probably address this sooner rather than
raymes 2012/10/29 23:30:00 I filed a bug and added a TODO. As discussed, I've
42 // ui/base/clipboard/custom_data_helper.cc except that it operates on custom
43 // data represented as std::strings rather than string16s. This could be unified
44 // by changing that code (and its uses) to read/write custom data as arbitrary
45 // bytes rather than string16s. This would also allow interoperability between
46 // the web clipboard and the pepper clipboard.
47 bool JumpToFormatInPickle(const string16& format, PickleIterator* iter) {
48 uint64 size = 0;
49 if (!iter->ReadUInt64(&size))
50 return false;
51 for (uint64 i = 0; i < size; ++i) {
52 string16 stored_format;
53 if (!iter->ReadString16(&stored_format))
54 return false;
55 if (stored_format == format)
56 return true;
57 int skip_length;
58 if (!iter->ReadLength(&skip_length))
59 return false;
60 if (!iter->SkipBytes(skip_length))
61 return false;
62 }
63 return false;
64 }
65
66 bool IsFormatAvailableInPickle(const string16& format, const Pickle& pickle) {
67 PickleIterator iter(pickle);
68 return JumpToFormatInPickle(format, &iter);
69 }
70
71 std::string ReadDataFromPickle(const string16& format, const Pickle& pickle) {
72 std::string result;
73 PickleIterator iter(pickle);
74 if (!JumpToFormatInPickle(format, &iter) || !iter.ReadString(&result))
75 return "";
dcheng 2012/10/29 20:26:29 std::string() is preferred over "".
raymes 2012/10/29 23:30:00 Done.
76 return result;
77 }
78
79 bool WriteDataToPickle(const std::map<string16, std::string>& data,
80 Pickle* pickle) {
81 pickle->WriteUInt64(data.size());
82 for (std::map<string16, std::string>::const_iterator it = data.begin();
83 it != data.end(); ++it) {
84 if (!pickle->WriteString16(it->first))
85 return false;
86 if (!pickle->WriteString(it->second))
87 return false;
88 }
89 return true;
90 }
91
92 } // namespace
93
94 PepperFlashClipboardHost::PepperFlashClipboardHost(
95 RendererPpapiHost* host,
96 PP_Instance instance,
97 PP_Resource resource)
98 : ResourceHost(host->GetPpapiHost(), instance, resource),
99 clipboard_client_(new RendererClipboardClient) {
100 }
101
102 PepperFlashClipboardHost::~PepperFlashClipboardHost() {
103 }
104
105 int32_t PepperFlashClipboardHost::OnResourceMessageReceived(
106 const IPC::Message& msg,
107 ppapi::host::HostMessageContext* context) {
108 IPC_BEGIN_MESSAGE_MAP(PepperFlashClipboardHost, msg)
109 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
110 PpapiHostMsg_FlashClipboard_RegisterCustomFormat,
111 OnMsgRegisterCustomFormat);
112 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
113 PpapiHostMsg_FlashClipboard_IsFormatAvailable,
114 OnMsgIsFormatAvailable);
115 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
116 PpapiHostMsg_FlashClipboard_ReadData,
117 OnMsgReadData);
118 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
119 PpapiHostMsg_FlashClipboard_WriteData,
120 OnMsgWriteData);
121 IPC_END_MESSAGE_MAP()
122 return PP_ERROR_FAILED;
123 }
124
125 int32_t PepperFlashClipboardHost::OnMsgRegisterCustomFormat(
126 ppapi::host::HostMessageContext* host_context,
127 const std::string& format_name) {
128 uint32_t format = custom_formats_.RegisterFormat(format_name);
129 if (format == PP_FLASH_CLIPBOARD_FORMAT_INVALID)
130 return PP_ERROR_FAILED;
131 host_context->reply_msg =
132 PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply(format);
133 return PP_OK;
134 }
135
136 int32_t PepperFlashClipboardHost::OnMsgIsFormatAvailable(
137 ppapi::host::HostMessageContext* host_context,
138 uint32_t clipboard_type,
139 uint32_t format) {
140 if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
141 NOTIMPLEMENTED();
142 return PP_ERROR_FAILED;
143 }
144
145 ui::Clipboard::Buffer buffer_type = ConvertClipboardType(clipboard_type);
146 bool available = false;
147 switch (format) {
148 case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
149 bool plain = clipboard_client_->IsFormatAvailable(
150 ui::Clipboard::GetPlainTextFormatType(), buffer_type);
151 bool plainw = clipboard_client_->IsFormatAvailable(
152 ui::Clipboard::GetPlainTextWFormatType(), buffer_type);
153 available = plain || plainw;
154 break;
155 }
156 case PP_FLASH_CLIPBOARD_FORMAT_HTML:
157 available = clipboard_client_->IsFormatAvailable(
158 ui::Clipboard::GetHtmlFormatType(), buffer_type);
159 break;
160 case PP_FLASH_CLIPBOARD_FORMAT_RTF:
161 available = clipboard_client_->IsFormatAvailable(
162 ui::Clipboard::GetRtfFormatType(), buffer_type);
163 break;
164 case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
165 break;
166 default:
167 if (custom_formats_.IsFormatRegistered(format)) {
168 std::string format_name = custom_formats_.GetFormatName(format);
169 std::string clipboard_data;
170 clipboard_client_->ReadData(
171 ui::Clipboard::GetWebCustomDataFormatType(), &clipboard_data);
172 Pickle pickle(clipboard_data.data(), clipboard_data.size());
173 available = IsFormatAvailableInPickle(UTF8ToUTF16(format_name), pickle);
174 }
175 break;
176 }
177
178 return available ? PP_OK : PP_ERROR_FAILED;
179 }
180
181 int32_t PepperFlashClipboardHost::OnMsgReadData(
182 ppapi::host::HostMessageContext* host_context,
183 uint32_t clipboard_type,
184 uint32_t format) {
185 if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
186 NOTIMPLEMENTED();
187 return PP_ERROR_FAILED;
188 }
189
190 ui::Clipboard::Buffer buffer_type = ConvertClipboardType(clipboard_type);
191 std::string clipboard_string;
192 int32_t result = PP_ERROR_FAILED;
193 switch (format) {
194 case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: {
195 if (clipboard_client_->IsFormatAvailable(
196 ui::Clipboard::GetPlainTextWFormatType(), buffer_type)) {
197 string16 text;
198 clipboard_client_->ReadText(buffer_type, &text);
199 if (!text.empty()) {
200 result = PP_OK;
201 clipboard_string = UTF16ToUTF8(text);
202 break;
203 }
204 }
205 // If the PlainTextW format isn't available or is empty, take the
206 // ASCII text format.
207 if (clipboard_client_->IsFormatAvailable(
208 ui::Clipboard::GetPlainTextFormatType(), buffer_type)) {
209 result = PP_OK;
210 clipboard_client_->ReadAsciiText(buffer_type, &clipboard_string);
211 }
212 break;
213 }
214 case PP_FLASH_CLIPBOARD_FORMAT_HTML: {
215 if (!clipboard_client_->IsFormatAvailable(
216 ui::Clipboard::GetHtmlFormatType(), buffer_type)) {
217 break;
218 }
219
220 string16 html;
221 GURL gurl;
222 uint32 fragment_start;
223 uint32 fragment_end;
224 clipboard_client_->ReadHTML(buffer_type, &html, &gurl, &fragment_start,
225 &fragment_end);
226 result = PP_OK;
227 clipboard_string = UTF16ToUTF8(
228 html.substr(fragment_start, fragment_end - fragment_start));
229 break;
230 }
231 case PP_FLASH_CLIPBOARD_FORMAT_RTF: {
232 if (!clipboard_client_->IsFormatAvailable(
233 ui::Clipboard::GetRtfFormatType(), buffer_type)) {
234 break;
235 }
236 result = PP_OK;
237 clipboard_client_->ReadRTF(buffer_type, &clipboard_string);
238 break;
239 }
240 case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
241 break;
242 default: {
243 if (custom_formats_.IsFormatRegistered(format)) {
244 string16 format_name = UTF8ToUTF16(
245 custom_formats_.GetFormatName(format));
246 std::string clipboard_data;
247 clipboard_client_->ReadData(
248 ui::Clipboard::GetWebCustomDataFormatType(), &clipboard_data);
249 Pickle pickle(clipboard_data.data(), clipboard_data.size());
250 if (IsFormatAvailableInPickle(format_name, pickle)) {
251 result = PP_OK;
252 clipboard_string = ReadDataFromPickle(format_name, pickle);
253 }
254 }
255 break;
256 }
257 }
258
259 if (result == PP_OK) {
260 host_context->reply_msg =
261 PpapiPluginMsg_FlashClipboard_ReadDataReply(clipboard_string);
262 }
263 return result;
264 }
265
266 int32_t PepperFlashClipboardHost::OnMsgWriteData(
267 ppapi::host::HostMessageContext* host_context,
268 uint32_t clipboard_type,
269 const std::vector<uint32_t>& formats,
270 const std::vector<std::string>& data) {
271 if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) {
272 NOTIMPLEMENTED();
273 return PP_ERROR_FAILED;
274 }
275
276 DCHECK(formats.size() == data.size());
277 // If no formats are passed in clear the clipboard.
278 if (formats.size() == 0) {
279 clipboard_client_->Clear(ConvertClipboardType(clipboard_type));
280 return PP_OK;
281 }
282
283 webkit_glue::ScopedClipboardWriterGlue scw(clipboard_client_.get());
284 std::map<string16, std::string> custom_data_map;
285 int32_t res = PP_OK;
286 for (uint32_t i = 0; i < formats.size(); ++i) {
287 if (data[i].length() > kMaxClipboardWriteSize) {
288 res = PP_ERROR_NOSPACE;
289 break;
290 }
291
292 switch (formats[i]) {
293 case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT:
294 scw.WriteText(UTF8ToUTF16(data[i]));
295 break;
296 case PP_FLASH_CLIPBOARD_FORMAT_HTML:
297 scw.WriteHTML(UTF8ToUTF16(data[i]), "");
298 break;
299 case PP_FLASH_CLIPBOARD_FORMAT_RTF:
300 scw.WriteRTF(data[i]);
301 break;
302 case PP_FLASH_CLIPBOARD_FORMAT_INVALID:
303 res = PP_ERROR_BADARGUMENT;
304 break;
305 default:
306 if (custom_formats_.IsFormatRegistered(formats[i])) {
307 std::string format_name = custom_formats_.GetFormatName(formats[i]);
308 custom_data_map[UTF8ToUTF16(format_name)] = data[i];
309 } else {
310 // Invalid format.
311 res = PP_ERROR_BADARGUMENT;
312 break;
313 }
314 }
315
316 if (res != PP_OK)
317 break;
318 }
319
320 if (custom_data_map.size() > 0) {
321 Pickle pickle;
322 if (WriteDataToPickle(custom_data_map, &pickle)) {
323 scw.WritePickledData(pickle,
324 ui::Clipboard::GetWebCustomDataFormatType());
325 } else {
326 res = PP_ERROR_BADARGUMENT;
327 }
328 }
329
330 if (res != PP_OK) {
331 // Need to clear the objects so nothing is written.
332 scw.Reset();
333 }
334
335 return res;
336 }
337
338 } // namespace content
339
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698