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

Side by Side Diff: chrome/plugin/chrome_plugin_host.cc

Issue 6576020: Remove Gears from Chrome (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: ready to review Created 9 years, 10 months 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) 2011 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 "chrome/plugin/chrome_plugin_host.h"
6
7 #include "base/command_line.h"
8 #include "base/file_path.h"
9 #include "base/file_util.h"
10 #include "base/message_loop.h"
11 #include "base/process_util.h"
12 #include "base/utf_string_conversions.h"
13 #include "base/string_split.h"
14 #include "chrome/common/child_process.h"
15 #include "chrome/common/chrome_constants.h"
16 #include "chrome/common/chrome_plugin_lib.h"
17 #include "chrome/common/chrome_plugin_util.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/plugin_messages.h"
20 #include "chrome/common/resource_dispatcher.h"
21 #include "chrome/plugin/plugin_thread.h"
22 #include "chrome/plugin/webplugin_proxy.h"
23 #include "net/base/data_url.h"
24 #include "net/base/io_buffer.h"
25 #include "net/base/upload_data.h"
26 #include "net/http/http_response_headers.h"
27 #include "webkit/appcache/appcache_interfaces.h"
28 #include "webkit/plugins/npapi/plugin_instance.h"
29 #include "webkit/glue/resource_loader_bridge.h"
30 #include "webkit/glue/resource_type.h"
31 #include "webkit/glue/webkit_glue.h"
32
33 namespace {
34
35 using webkit_glue::ResourceLoaderBridge;
36 using webkit_glue::ResourceResponseInfo;
37
38 static MessageLoop* g_plugin_thread_message_loop;
39
40 // This class manages a network request made by the plugin, handling the
41 // data as it comes in from the ResourceLoaderBridge and is requested by the
42 // plugin.
43 // NOTE: All methods must be called on the Plugin thread.
44 class PluginRequestHandlerProxy
45 : public PluginHelper, public ResourceLoaderBridge::Peer {
46 public:
47 static PluginRequestHandlerProxy* FromCPRequest(CPRequest* request) {
48 return ScopableCPRequest::GetData<PluginRequestHandlerProxy*>(request);
49 }
50
51 PluginRequestHandlerProxy(ChromePluginLib* plugin,
52 ScopableCPRequest* cprequest)
53 : PluginHelper(plugin),
54 cprequest_(cprequest),
55 sync_(false),
56 response_data_offset_(0),
57 completed_(false),
58 read_buffer_(NULL),
59 read_buffer_size_(0) {
60 load_flags_ = PluginResponseUtils::CPLoadFlagsToNetFlags(0);
61 cprequest_->data = this; // see FromCPRequest().
62 }
63
64 ~PluginRequestHandlerProxy() {
65 if (bridge_.get() && !completed_) {
66 bridge_->Cancel();
67 }
68 }
69
70 // ResourceLoaderBridge::Peer
71 virtual void OnUploadProgress(uint64 position, uint64 size) {
72 CPRR_UploadProgressFunc upload_progress =
73 plugin_->functions().response_funcs->upload_progress;
74 if (upload_progress)
75 upload_progress(cprequest_.get(), position, size);
76 }
77
78 virtual bool OnReceivedRedirect(
79 const GURL& new_url,
80 const ResourceResponseInfo& info,
81 bool* has_new_first_party_for_cookies,
82 GURL* new_first_party_for_cookies) {
83 plugin_->functions().response_funcs->received_redirect(
84 cprequest_.get(), new_url.spec().c_str());
85 // TODO(wtc): should we return a new first party for cookies URL?
86 *has_new_first_party_for_cookies = false;
87 return true;
88 }
89
90 virtual void OnReceivedResponse(
91 const ResourceResponseInfo& info,
92 bool content_filtered) {
93 response_headers_ = info.headers;
94 plugin_->functions().response_funcs->start_completed(
95 cprequest_.get(), CPERR_SUCCESS);
96 }
97
98 virtual void OnDownloadedData(int len) {
99 }
100
101 virtual void OnReceivedData(const char* data, int len) {
102 response_data_.append(data, len);
103 if (read_buffer_) {
104 // If we had an asynchronous operation pending, read into that buffer
105 // and inform the plugin.
106 int rv = Read(read_buffer_, read_buffer_size_);
107 DCHECK(rv != CPERR_IO_PENDING);
108 read_buffer_ = NULL;
109 plugin_->functions().response_funcs->read_completed(
110 cprequest_.get(), rv);
111 }
112 }
113
114 virtual void OnCompletedRequest(const net::URLRequestStatus& status,
115 const std::string& security_info,
116 const base::Time& completion_time) {
117 completed_ = true;
118
119 if (!status.is_success()) {
120 // TODO(mpcomplete): better error codes
121 // Inform the plugin, calling the right function depending on whether
122 // we got the start_completed event or not.
123 if (response_headers_) {
124 plugin_->functions().response_funcs->start_completed(
125 cprequest_.get(), CPERR_FAILURE);
126 } else {
127 plugin_->functions().response_funcs->read_completed(
128 cprequest_.get(), CPERR_FAILURE);
129 }
130 } else if (read_buffer_) {
131 // The plugin was waiting for more data. Inform him we're done.
132 read_buffer_ = NULL;
133 plugin_->functions().response_funcs->read_completed(
134 cprequest_.get(), CPERR_SUCCESS);
135 }
136 }
137
138 void set_extra_headers(const std::string& headers) {
139 extra_headers_ = headers;
140 }
141 void set_load_flags(uint32 flags) {
142 load_flags_ = flags;
143 }
144 void set_sync(bool sync) {
145 sync_ = sync;
146 }
147 void AppendDataToUpload(const char* bytes, int bytes_len) {
148 upload_content_.push_back(net::UploadData::Element());
149 upload_content_.back().SetToBytes(bytes, bytes_len);
150 }
151
152 void AppendFileToUpload(const FilePath &filepath) {
153 AppendFileRangeToUpload(filepath, 0, kuint64max);
154 }
155
156 void AppendFileRangeToUpload(const FilePath &filepath,
157 uint64 offset, uint64 length) {
158 upload_content_.push_back(net::UploadData::Element());
159 upload_content_.back().SetToFilePathRange(filepath, offset, length,
160 base::Time());
161 }
162
163 CPError Start(int renderer_id, int render_view_id) {
164 webkit_glue::ResourceLoaderBridge::RequestInfo request_info;
165 request_info.method = cprequest_->method;
166 request_info.url = GURL(cprequest_->url);
167 request_info.first_party_for_cookies =
168 GURL(cprequest_->url); // TODO(jackson): policy url?
169 request_info.referrer = GURL(); // TODO(mpcomplete): referrer?
170 request_info.headers = extra_headers_;
171 request_info.load_flags = load_flags_;
172 request_info.requestor_pid = base::GetCurrentProcId();
173 request_info.request_type = ResourceType::OBJECT;
174 request_info.request_context = cprequest_->context;
175 request_info.appcache_host_id = appcache::kNoHostId;
176 request_info.routing_id = MSG_ROUTING_CONTROL;
177 bridge_.reset(
178 PluginThread::current()->resource_dispatcher()->CreateBridge(
179 request_info,
180 renderer_id,
181 render_view_id));
182 if (!bridge_.get())
183 return CPERR_FAILURE;
184
185 for (size_t i = 0; i < upload_content_.size(); ++i) {
186 switch (upload_content_[i].type()) {
187 case net::UploadData::TYPE_BYTES: {
188 const std::vector<char>& bytes = upload_content_[i].bytes();
189 bridge_->AppendDataToUpload(&bytes[0],
190 static_cast<int>(bytes.size()));
191 break;
192 }
193 case net::UploadData::TYPE_FILE: {
194 bridge_->AppendFileRangeToUpload(
195 upload_content_[i].file_path(),
196 upload_content_[i].file_range_offset(),
197 upload_content_[i].file_range_length(),
198 upload_content_[i].expected_file_modification_time());
199 break;
200 }
201 default: {
202 NOTREACHED() << "Unknown UploadData::Element type";
203 }
204 }
205 }
206
207 if (sync_) {
208 ResourceLoaderBridge::SyncLoadResponse response;
209 bridge_->SyncLoad(&response);
210 response_headers_ = response.headers;
211 response_data_ = response.data;
212 completed_ = true;
213 return response.status.is_success() ? CPERR_SUCCESS : CPERR_FAILURE;
214 } else {
215 if (!bridge_->Start(this)) {
216 bridge_.reset();
217 return CPERR_FAILURE;
218 }
219 return CPERR_IO_PENDING;
220 }
221 }
222
223 int GetResponseInfo(CPResponseInfoType type, void* buf, uint32 buf_size) {
224 return PluginResponseUtils::GetResponseInfo(
225 response_headers_, type, buf, buf_size);
226 }
227
228 int Read(void* buf, uint32 buf_size) {
229 uint32 avail =
230 static_cast<uint32>(response_data_.size()) - response_data_offset_;
231 uint32 count = buf_size;
232 if (count > avail)
233 count = avail;
234
235 if (count) {
236 // Data is ready now.
237 memcpy(buf, &response_data_[0] + response_data_offset_, count);
238 response_data_offset_ += count;
239 } else if (!completed_) {
240 read_buffer_ = buf;
241 read_buffer_size_ = buf_size;
242 DCHECK(!sync_);
243 return CPERR_IO_PENDING;
244 }
245
246 if (response_data_.size() == response_data_offset_) {
247 // Simple optimization for large requests. Generally the consumer will
248 // read the data faster than it comes in, so we can clear our buffer
249 // any time it has all been read.
250 response_data_.clear();
251 response_data_offset_ = 0;
252 }
253
254 read_buffer_ = NULL;
255 return count;
256 }
257
258 private:
259 scoped_ptr<ScopableCPRequest> cprequest_;
260 scoped_ptr<ResourceLoaderBridge> bridge_;
261 std::vector<net::UploadData::Element> upload_content_;
262 std::string extra_headers_;
263 uint32 load_flags_;
264 bool sync_;
265
266 scoped_refptr<net::HttpResponseHeaders> response_headers_;
267 std::string response_data_;
268 size_t response_data_offset_;
269 bool completed_;
270 void* read_buffer_;
271 uint32 read_buffer_size_;
272 };
273
274 //
275 // Generic functions
276 //
277
278 void STDCALL CPB_SetKeepProcessAlive(CPID id, CPBool keep_alive) {
279 CHECK(ChromePluginLib::IsPluginThread());
280 static bool g_keep_process_alive = false;
281 bool desired_value = keep_alive ? true : false; // smash to bool
282 if (desired_value != g_keep_process_alive) {
283 g_keep_process_alive = desired_value;
284 if (g_keep_process_alive)
285 ChildProcess::current()->AddRefProcess();
286 else
287 ChildProcess::current()->ReleaseProcess();
288 }
289 }
290
291 CPError STDCALL CPB_GetCookies(CPID id, CPBrowsingContext context,
292 const char* url, char** cookies) {
293 CHECK(ChromePluginLib::IsPluginThread());
294 std::string cookies_str;
295
296 WebPluginProxy* webplugin = WebPluginProxy::FromCPBrowsingContext(context);
297 // There are two contexts in which we can be asked for cookies:
298 // 1. From a script context. webplugin will be non-NULL.
299 // 2. From a global browser context (think: Gears UpdateTask). webplugin will
300 // be NULL and context will (loosely) represent a browser Profile.
301 // In case 1, we *must* route through the renderer process, otherwise we race
302 // with renderer script that may have set cookies. In case 2, we are running
303 // out-of-band with script, so we don't need to stay in sync with any
304 // particular renderer.
305 // See http://b/issue?id=1487502.
306 if (webplugin) {
307 cookies_str = webplugin->GetCookies(GURL(url), GURL(url));
308 } else {
309 PluginThread::current()->Send(
310 new PluginProcessHostMsg_GetCookies(context, GURL(url), &cookies_str));
311 }
312
313 *cookies = CPB_StringDup(CPB_Alloc, cookies_str);
314 return CPERR_SUCCESS;
315 }
316
317 CPError STDCALL CPB_ShowHtmlDialogModal(
318 CPID id, CPBrowsingContext context, const char* url, int width, int height,
319 const char* json_arguments, char** json_retval) {
320 CHECK(ChromePluginLib::IsPluginThread());
321
322 WebPluginProxy* webplugin = WebPluginProxy::FromCPBrowsingContext(context);
323 if (!webplugin)
324 return CPERR_INVALID_PARAMETER;
325
326 std::string retval_str;
327 webplugin->ShowModalHTMLDialog(
328 GURL(url), width, height, json_arguments, &retval_str);
329 *json_retval = CPB_StringDup(CPB_Alloc, retval_str);
330 return CPERR_SUCCESS;
331 }
332
333 CPError STDCALL CPB_ShowHtmlDialog(
334 CPID id, CPBrowsingContext context, const char* url, int width, int height,
335 const char* json_arguments, void* plugin_context) {
336 // TODO(mpcomplete): support non-modal dialogs.
337 return CPERR_FAILURE;
338 }
339
340 CPError STDCALL CPB_GetDragData(
341 CPID id, CPBrowsingContext context, struct NPObject* event, bool add_data,
342 int32 *identity, int32 *event_id, char **drag_type, char **drag_data) {
343 CHECK(ChromePluginLib::IsPluginThread());
344
345 *identity = *event_id = 0;
346 WebPluginProxy* webplugin = WebPluginProxy::FromCPBrowsingContext(context);
347 if (!event || !webplugin)
348 return CPERR_INVALID_PARAMETER;
349
350 std::string type_str, data_str;
351 if (!webplugin->GetDragData(event, add_data,
352 identity, event_id, &type_str, &data_str)) {
353 return CPERR_FAILURE;
354 }
355
356 if (add_data)
357 *drag_data = CPB_StringDup(CPB_Alloc, data_str);
358 *drag_type = CPB_StringDup(CPB_Alloc, type_str);
359 return CPERR_SUCCESS;
360 }
361
362 CPError STDCALL CPB_SetDropEffect(
363 CPID id, CPBrowsingContext context, struct NPObject* event, int effect) {
364 CHECK(ChromePluginLib::IsPluginThread());
365
366 WebPluginProxy* webplugin = WebPluginProxy::FromCPBrowsingContext(context);
367 if (!event || !webplugin)
368 return CPERR_INVALID_PARAMETER;
369
370 if (webplugin->SetDropEffect(event, effect))
371 return CPERR_SUCCESS;
372 return CPERR_FAILURE;
373 }
374
375 CPError STDCALL CPB_AllowFileDrop(
376 CPID id, CPBrowsingContext context, const char* file_drag_data) {
377 CHECK(ChromePluginLib::IsPluginThread());
378
379 WebPluginProxy* webplugin = WebPluginProxy::FromCPBrowsingContext(context);
380 if (!webplugin || !file_drag_data)
381 return CPERR_INVALID_PARAMETER;
382
383 const int renderer = webplugin->GetRendererId();
384 if (renderer == -1)
385 return CPERR_FAILURE;
386
387 static const char kDelimiter('\b');
388 std::vector<std::string> files;
389 base::SplitStringDontTrim(file_drag_data, kDelimiter, &files);
390
391 bool allowed = false;
392 if (!PluginThread::current()->Send(
393 new PluginProcessHostMsg_AccessFiles(renderer, files, &allowed))) {
394 return CPERR_FAILURE;
395 }
396
397 if (allowed)
398 return CPERR_SUCCESS;
399 return CPERR_FAILURE;
400 }
401
402 CPError STDCALL CPB_GetCommandLineArguments(
403 CPID id, CPBrowsingContext context, const char* url, char** arguments) {
404 CHECK(ChromePluginLib::IsPluginThread());
405 std::string arguments_str;
406 CPError rv = CPB_GetCommandLineArgumentsCommon(url, &arguments_str);
407 if (rv == CPERR_SUCCESS)
408 *arguments = CPB_StringDup(CPB_Alloc, arguments_str);
409 return rv;
410 }
411
412 CPBrowsingContext STDCALL CPB_GetBrowsingContextFromNPP(NPP npp) {
413 if (!npp)
414 return CPERR_INVALID_PARAMETER;
415
416 webkit::npapi::PluginInstance* instance =
417 static_cast<webkit::npapi::PluginInstance *>(npp->ndata);
418 WebPluginProxy* webplugin =
419 static_cast<WebPluginProxy*>(instance->webplugin());
420
421 return webplugin->GetCPBrowsingContext();
422 }
423
424 int STDCALL CPB_GetBrowsingContextInfo(
425 CPID id, CPBrowsingContext context, CPBrowsingContextInfoType type,
426 void* buf, uint32 buf_size) {
427 CHECK(ChromePluginLib::IsPluginThread());
428
429 #if defined(OS_WIN)
430 switch (type) {
431 case CPBROWSINGCONTEXT_DATA_DIR_PTR: {
432 if (buf_size < sizeof(char*))
433 return sizeof(char*);
434
435 FilePath path = CommandLine::ForCurrentProcess()->
436 GetSwitchValuePath(switches::kPluginDataDir);
437 DCHECK(!path.empty());
438 std::string retval = WideToUTF8(
439 path.Append(chrome::kChromePluginDataDirname).value());
440 *static_cast<char**>(buf) = CPB_StringDup(CPB_Alloc, retval);
441
442 return CPERR_SUCCESS;
443 }
444 case CPBROWSINGCONTEXT_UI_LOCALE_PTR: {
445 if (buf_size < sizeof(char*))
446 return sizeof(char*);
447
448 std::string retval = webkit_glue::GetWebKitLocale();
449 *static_cast<char**>(buf) = CPB_StringDup(CPB_Alloc, retval);
450 return CPERR_SUCCESS;
451 }
452 }
453 #else
454 // TODO(aa): this code is only used by Gears, which we are removing.
455 NOTREACHED();
456 #endif
457
458 return CPERR_FAILURE;
459 }
460
461 CPError STDCALL CPB_AddUICommand(CPID id, int command) {
462 // Not implemented in the plugin process
463 return CPERR_FAILURE;
464 }
465
466 CPError STDCALL CPB_HandleCommand(
467 CPID id, CPBrowsingContext context, int command, void *data) {
468 // Not implemented in the plugin process
469 return CPERR_FAILURE;
470 }
471
472 //
473 // Functions related to network interception
474 //
475
476 void STDCALL CPB_EnableRequestIntercept(
477 CPID id, const char** schemes, uint32 num_schemes) {
478 // We ignore requests by the plugin to intercept from this process. That's
479 // handled in the browser process.
480 }
481
482 void STDCALL CPRR_ReceivedRedirect(CPRequest* request, const char* new_url) {
483 NOTREACHED() << "Network interception should not happen in plugin process.";
484 }
485
486 void STDCALL CPRR_StartCompleted(CPRequest* request, CPError result) {
487 NOTREACHED() << "Network interception should not happen in plugin process.";
488 }
489
490 void STDCALL CPRR_ReadCompleted(CPRequest* request, int bytes_read) {
491 NOTREACHED() << "Network interception should not happen in plugin process.";
492 }
493
494 void STDCALL CPRR_UploadProgress(CPRequest* request, uint64 pos, uint64 size) {
495 NOTREACHED() << "Network interception should not happen in plugin process.";
496 }
497
498 //
499 // Functions related to serving network requests to the plugin
500 //
501
502 CPError STDCALL CPB_CreateRequest(CPID id, CPBrowsingContext context,
503 const char* method, const char* url,
504 CPRequest** request) {
505 CHECK(ChromePluginLib::IsPluginThread());
506 ChromePluginLib* plugin = ChromePluginLib::FromCPID(id);
507 CHECK(plugin);
508
509 ScopableCPRequest* cprequest = new ScopableCPRequest(url, method, context);
510 new PluginRequestHandlerProxy(plugin, cprequest);
511
512 *request = cprequest;
513 return CPERR_SUCCESS;
514 }
515
516 CPError STDCALL CPR_StartRequest(CPRequest* request) {
517 CHECK(ChromePluginLib::IsPluginThread());
518 PluginRequestHandlerProxy* handler =
519 PluginRequestHandlerProxy::FromCPRequest(request);
520 CHECK(handler);
521
522 int renderer_id = -1;
523 int render_view_id = -1;
524
525 WebPluginProxy* webplugin = WebPluginProxy::FromCPBrowsingContext(
526 request->context);
527 if (webplugin) {
528 renderer_id = webplugin->GetRendererId();
529 if (renderer_id == -1)
530 return CPERR_FAILURE;
531
532 render_view_id = webplugin->host_render_view_routing_id();
533 if (render_view_id == -1)
534 return CPERR_FAILURE;
535 }
536
537 return handler->Start(renderer_id, render_view_id);
538 }
539
540 void STDCALL CPR_EndRequest(CPRequest* request, CPError reason) {
541 CHECK(ChromePluginLib::IsPluginThread());
542 PluginRequestHandlerProxy* handler =
543 PluginRequestHandlerProxy::FromCPRequest(request);
544 delete handler;
545 }
546
547 void STDCALL CPR_SetExtraRequestHeaders(CPRequest* request,
548 const char* headers) {
549 CHECK(ChromePluginLib::IsPluginThread());
550 PluginRequestHandlerProxy* handler =
551 PluginRequestHandlerProxy::FromCPRequest(request);
552 CHECK(handler);
553 handler->set_extra_headers(headers);
554 }
555
556 void STDCALL CPR_SetRequestLoadFlags(CPRequest* request, uint32 flags) {
557 CHECK(ChromePluginLib::IsPluginThread());
558 PluginRequestHandlerProxy* handler =
559 PluginRequestHandlerProxy::FromCPRequest(request);
560 CHECK(handler);
561
562 if (flags & CPREQUESTLOAD_SYNCHRONOUS) {
563 handler->set_sync(true);
564 }
565
566 uint32 net_flags = PluginResponseUtils::CPLoadFlagsToNetFlags(flags);
567 handler->set_load_flags(net_flags);
568 }
569
570 void STDCALL CPR_AppendDataToUpload(CPRequest* request, const char* bytes,
571 int bytes_len) {
572 CHECK(ChromePluginLib::IsPluginThread());
573 PluginRequestHandlerProxy* handler =
574 PluginRequestHandlerProxy::FromCPRequest(request);
575 CHECK(handler);
576 handler->AppendDataToUpload(bytes, bytes_len);
577 }
578
579 CPError STDCALL CPR_AppendFileToUpload(CPRequest* request, const char* filepath,
580 uint64 offset, uint64 length) {
581 CHECK(ChromePluginLib::IsPluginThread());
582 PluginRequestHandlerProxy* handler =
583 PluginRequestHandlerProxy::FromCPRequest(request);
584 CHECK(handler);
585
586 if (!length) length = kuint64max;
587 std::wstring wfilepath(UTF8ToWide(filepath));
588 handler->AppendFileRangeToUpload(FilePath::FromWStringHack(wfilepath), offset,
589 length);
590 return CPERR_SUCCESS;
591 }
592
593 int STDCALL CPR_GetResponseInfo(CPRequest* request, CPResponseInfoType type,
594 void* buf, uint32 buf_size) {
595 CHECK(ChromePluginLib::IsPluginThread());
596 PluginRequestHandlerProxy* handler =
597 PluginRequestHandlerProxy::FromCPRequest(request);
598 CHECK(handler);
599 return handler->GetResponseInfo(type, buf, buf_size);
600 }
601
602 int STDCALL CPR_Read(CPRequest* request, void* buf, uint32 buf_size) {
603 CHECK(ChromePluginLib::IsPluginThread());
604 PluginRequestHandlerProxy* handler =
605 PluginRequestHandlerProxy::FromCPRequest(request);
606 CHECK(handler);
607 return handler->Read(buf, buf_size);
608 }
609
610
611 CPBool STDCALL CPB_IsPluginProcessRunning(CPID id) {
612 CHECK(ChromePluginLib::IsPluginThread());
613 return true;
614 }
615
616 CPProcessType STDCALL CPB_GetProcessType(CPID id) {
617 CHECK(ChromePluginLib::IsPluginThread());
618 return CP_PROCESS_PLUGIN;
619 }
620
621 CPError STDCALL CPB_SendMessage(CPID id, const void *data, uint32 data_len) {
622 CHECK(ChromePluginLib::IsPluginThread());
623 const uint8* data_ptr = static_cast<const uint8*>(data);
624 std::vector<uint8> v(data_ptr, data_ptr + data_len);
625 if (!PluginThread::current()->Send(new PluginProcessHostMsg_PluginMessage(v)))
626 return CPERR_FAILURE;
627
628 return CPERR_SUCCESS;
629 }
630
631 CPError STDCALL CPB_SendSyncMessage(CPID id, const void *data, uint32 data_len,
632 void **retval, uint32 *retval_len) {
633 CHECK(ChromePluginLib::IsPluginThread());
634 const uint8* data_ptr = static_cast<const uint8*>(data);
635 std::vector<uint8> v(data_ptr, data_ptr + data_len);
636 std::vector<uint8> r;
637 if (!PluginThread::current()->Send(
638 new PluginProcessHostMsg_PluginSyncMessage(v, &r))) {
639 return CPERR_FAILURE;
640 }
641
642 if (r.size()) {
643 *retval_len = static_cast<uint32>(r.size());
644 *retval = CPB_Alloc(*retval_len);
645 memcpy(*retval, &(r.at(0)), r.size());
646 } else {
647 *retval = NULL;
648 *retval_len = 0;
649 }
650
651 return CPERR_SUCCESS;
652 }
653
654 CPError STDCALL CPB_PluginThreadAsyncCall(CPID id,
655 void (*func)(void *),
656 void *user_data) {
657 g_plugin_thread_message_loop->PostTask(
658 FROM_HERE, NewRunnableFunction(func, user_data));
659
660 return CPERR_SUCCESS;
661 }
662
663 CPError STDCALL CPB_OpenFileDialog(CPID id,
664 CPBrowsingContext context,
665 bool multiple_files,
666 const char *title,
667 const char *filter,
668 void *user_data) {
669 NOTREACHED() <<
670 "Open file dialog should only be called from the renderer process.";
671
672 return CPERR_FAILURE;
673 }
674
675 } // namespace
676
677 CPBrowserFuncs* GetCPBrowserFuncsForPlugin() {
678 static CPBrowserFuncs browser_funcs;
679 static CPRequestFuncs request_funcs;
680 static CPResponseFuncs response_funcs;
681 static bool initialized = false;
682 if (!initialized) {
683 initialized = true;
684
685 g_plugin_thread_message_loop = PluginThread::current()->message_loop();
686
687 browser_funcs.size = sizeof(browser_funcs);
688 browser_funcs.version = CP_VERSION;
689 browser_funcs.enable_request_intercept = CPB_EnableRequestIntercept;
690 browser_funcs.create_request = CPB_CreateRequest;
691 browser_funcs.get_cookies = CPB_GetCookies;
692 browser_funcs.alloc = CPB_Alloc;
693 browser_funcs.free = CPB_Free;
694 browser_funcs.set_keep_process_alive = CPB_SetKeepProcessAlive;
695 browser_funcs.show_html_dialog = CPB_ShowHtmlDialog;
696 browser_funcs.show_html_dialog_modal = CPB_ShowHtmlDialogModal;
697 browser_funcs.is_plugin_process_running = CPB_IsPluginProcessRunning;
698 browser_funcs.get_process_type = CPB_GetProcessType;
699 browser_funcs.send_message = CPB_SendMessage;
700 browser_funcs.get_browsing_context_from_npp = CPB_GetBrowsingContextFromNPP;
701 browser_funcs.get_browsing_context_info = CPB_GetBrowsingContextInfo;
702 browser_funcs.get_command_line_arguments = CPB_GetCommandLineArguments;
703 browser_funcs.add_ui_command = CPB_AddUICommand;
704 browser_funcs.handle_command = CPB_HandleCommand;
705 browser_funcs.send_sync_message = CPB_SendSyncMessage;
706 browser_funcs.plugin_thread_async_call = CPB_PluginThreadAsyncCall;
707 browser_funcs.open_file_dialog = CPB_OpenFileDialog;
708 browser_funcs.get_drag_data = CPB_GetDragData;
709 browser_funcs.set_drop_effect = CPB_SetDropEffect;
710 browser_funcs.allow_file_drop = CPB_AllowFileDrop;
711
712 browser_funcs.request_funcs = &request_funcs;
713 browser_funcs.response_funcs = &response_funcs;
714
715 request_funcs.size = sizeof(request_funcs);
716 request_funcs.start_request = CPR_StartRequest;
717 request_funcs.end_request = CPR_EndRequest;
718 request_funcs.set_extra_request_headers = CPR_SetExtraRequestHeaders;
719 request_funcs.set_request_load_flags = CPR_SetRequestLoadFlags;
720 request_funcs.append_data_to_upload = CPR_AppendDataToUpload;
721 request_funcs.get_response_info = CPR_GetResponseInfo;
722 request_funcs.read = CPR_Read;
723 request_funcs.append_file_to_upload = CPR_AppendFileToUpload;
724
725 response_funcs.size = sizeof(response_funcs);
726 response_funcs.received_redirect = CPRR_ReceivedRedirect;
727 response_funcs.start_completed = CPRR_StartCompleted;
728 response_funcs.read_completed = CPRR_ReadCompleted;
729 response_funcs.upload_progress = CPRR_UploadProgress;
730 }
731
732 return &browser_funcs;
733 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698