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

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

Powered by Google App Engine
This is Rietveld 408576698