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

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

Powered by Google App Engine
This is Rietveld 408576698