OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/child/npapi/plugin_instance.h" | 5 #include "content/child/npapi/plugin_instance.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 PluginInstance::PluginInstance(PluginLib* plugin, const std::string& mime_type) | 33 PluginInstance::PluginInstance(PluginLib* plugin, const std::string& mime_type) |
34 : plugin_(plugin), | 34 : plugin_(plugin), |
35 npp_(0), | 35 npp_(0), |
36 host_(PluginHost::Singleton()), | 36 host_(PluginHost::Singleton()), |
37 npp_functions_(plugin->functions()), | 37 npp_functions_(plugin->functions()), |
38 window_handle_(0), | 38 window_handle_(0), |
39 windowless_(false), | 39 windowless_(false), |
40 transparent_(true), | 40 transparent_(true), |
41 webplugin_(0), | 41 webplugin_(0), |
42 mime_type_(mime_type), | 42 mime_type_(mime_type), |
43 get_notify_data_(0), | |
44 use_mozilla_user_agent_(false), | 43 use_mozilla_user_agent_(false), |
45 #if defined (OS_MACOSX) | 44 #if defined (OS_MACOSX) |
46 #ifdef NP_NO_QUICKDRAW | 45 #ifdef NP_NO_QUICKDRAW |
47 drawing_model_(NPDrawingModelCoreGraphics), | 46 drawing_model_(NPDrawingModelCoreGraphics), |
48 #else | 47 #else |
49 drawing_model_(NPDrawingModelQuickDraw), | 48 drawing_model_(NPDrawingModelQuickDraw), |
50 #endif | 49 #endif |
51 #ifdef NP_NO_CARBON | 50 #ifdef NP_NO_CARBON |
52 event_model_(NPEventModelCocoa), | 51 event_model_(NPEventModelCocoa), |
53 #else | 52 #else |
54 event_model_(NPEventModelCarbon), | 53 event_model_(NPEventModelCarbon), |
55 #endif | 54 #endif |
56 currently_handled_event_(NULL), | 55 currently_handled_event_(NULL), |
57 #endif | 56 #endif |
58 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 57 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
59 load_manually_(false), | 58 load_manually_(false), |
60 in_close_streams_(false), | 59 in_close_streams_(false), |
61 next_timer_id_(1), | 60 next_timer_id_(1), |
62 next_notify_id_(0), | 61 next_range_request_id_(0) { |
63 next_range_request_id_(0), | |
64 handles_url_redirects_(false) { | |
65 npp_ = new NPP_t(); | 62 npp_ = new NPP_t(); |
66 npp_->ndata = 0; | 63 npp_->ndata = 0; |
67 npp_->pdata = 0; | 64 npp_->pdata = 0; |
68 | 65 |
69 if (mime_type_ == kFlashPluginSwfMimeType) | 66 if (mime_type_ == kFlashPluginSwfMimeType) |
70 transparent_ = false; | 67 transparent_ = false; |
71 | 68 |
72 memset(&zero_padding_, 0, sizeof(zero_padding_)); | 69 memset(&zero_padding_, 0, sizeof(zero_padding_)); |
73 } | 70 } |
74 | 71 |
75 PluginInstance::~PluginInstance() { | 72 PluginInstance::~PluginInstance() { |
76 CloseStreams(); | 73 CloseStreams(); |
77 | 74 |
78 if (npp_ != 0) { | 75 if (npp_ != 0) { |
79 delete npp_; | 76 delete npp_; |
80 npp_ = 0; | 77 npp_ = 0; |
81 } | 78 } |
82 | 79 |
83 if (plugin_.get()) | 80 if (plugin_.get()) |
84 plugin_->CloseInstance(); | 81 plugin_->CloseInstance(); |
85 } | 82 } |
86 | 83 |
87 PluginStreamUrl* PluginInstance::CreateStream(unsigned long resource_id, | 84 PluginStreamUrl* PluginInstance::CreateStream(unsigned long resource_id, |
88 const GURL& url, | 85 const GURL& url, |
89 const std::string& mime_type, | 86 const std::string& mime_type) { |
90 int notify_id) { | 87 PluginStreamUrl* stream = new PluginStreamUrl(resource_id, url, this); |
91 | |
92 bool notify; | |
93 void* notify_data; | |
94 GetNotifyData(notify_id, ¬ify, ¬ify_data); | |
95 PluginStreamUrl* stream = new PluginStreamUrl( | |
96 resource_id, url, this, notify, notify_data); | |
97 | |
98 AddStream(stream); | 88 AddStream(stream); |
99 return stream; | 89 return stream; |
100 } | 90 } |
101 | 91 |
102 void PluginInstance::AddStream(PluginStream* stream) { | 92 void PluginInstance::AddStream(PluginStream* stream) { |
103 open_streams_.push_back(make_scoped_refptr(stream)); | 93 open_streams_.push_back(make_scoped_refptr(stream)); |
104 } | 94 } |
105 | 95 |
106 void PluginInstance::RemoveStream(PluginStream* stream) { | 96 void PluginInstance::RemoveStream(PluginStream* stream) { |
107 if (in_close_streams_) | 97 if (in_close_streams_) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 char** const param_names, | 145 char** const param_names, |
156 char** const param_values, | 146 char** const param_values, |
157 int param_count, | 147 int param_count, |
158 bool load_manually) { | 148 bool load_manually) { |
159 load_manually_ = load_manually; | 149 load_manually_ = load_manually; |
160 unsigned short mode = load_manually_ ? NP_FULL : NP_EMBED; | 150 unsigned short mode = load_manually_ ? NP_FULL : NP_EMBED; |
161 npp_->ndata = this; | 151 npp_->ndata = this; |
162 | 152 |
163 NPError err = NPP_New(mode, param_count, | 153 NPError err = NPP_New(mode, param_count, |
164 const_cast<char **>(param_names), const_cast<char **>(param_values)); | 154 const_cast<char **>(param_names), const_cast<char **>(param_values)); |
165 | |
166 if (err == NPERR_NO_ERROR) { | |
167 handles_url_redirects_ = | |
168 ((npp_functions_->version >= NPVERS_HAS_URL_REDIRECT_HANDLING) && | |
169 (npp_functions_->urlredirectnotify)); | |
170 } | |
171 return err == NPERR_NO_ERROR; | 155 return err == NPERR_NO_ERROR; |
172 } | 156 } |
173 | 157 |
174 NPObject *PluginInstance::GetPluginScriptableObject() { | 158 NPObject *PluginInstance::GetPluginScriptableObject() { |
175 NPObject *value = NULL; | 159 NPObject *value = NULL; |
176 NPError error = NPP_GetValue(NPPVpluginScriptableNPObject, &value); | 160 NPError error = NPP_GetValue(NPPVpluginScriptableNPObject, &value); |
177 if (error != NPERR_NO_ERROR || value == NULL) | 161 if (error != NPERR_NO_ERROR || value == NULL) |
178 return NULL; | 162 return NULL; |
179 return value; | 163 return value; |
180 } | 164 } |
181 | 165 |
182 bool PluginInstance::GetFormValue(base::string16* value) { | 166 bool PluginInstance::GetFormValue(base::string16* value) { |
183 // Plugins will allocate memory for the return value by using NPN_MemAlloc(). | 167 // Plugins will allocate memory for the return value by using NPN_MemAlloc(). |
184 char *plugin_value = NULL; | 168 char *plugin_value = NULL; |
185 NPError error = NPP_GetValue(NPPVformValue, &plugin_value); | 169 NPError error = NPP_GetValue(NPPVformValue, &plugin_value); |
186 if (error != NPERR_NO_ERROR || !plugin_value) { | 170 if (error != NPERR_NO_ERROR || !plugin_value) { |
187 return false; | 171 return false; |
188 } | 172 } |
189 // Assumes the result is UTF8 text, as Firefox does. | 173 // Assumes the result is UTF8 text, as Firefox does. |
190 *value = base::UTF8ToUTF16(plugin_value); | 174 *value = base::UTF8ToUTF16(plugin_value); |
191 host_->host_functions()->memfree(plugin_value); | 175 host_->host_functions()->memfree(plugin_value); |
192 return true; | 176 return true; |
193 } | 177 } |
194 | 178 |
195 // WebPluginLoadDelegate methods | |
196 void PluginInstance::DidFinishLoadWithReason(const GURL& url, | |
197 NPReason reason, | |
198 int notify_id) { | |
199 bool notify; | |
200 void* notify_data; | |
201 GetNotifyData(notify_id, ¬ify, ¬ify_data); | |
202 if (!notify) { | |
203 NOTREACHED(); | |
204 return; | |
205 } | |
206 | |
207 NPP_URLNotify(url.spec().c_str(), reason, notify_data); | |
208 } | |
209 | |
210 unsigned PluginInstance::GetBackingTextureId() { | 179 unsigned PluginInstance::GetBackingTextureId() { |
211 // By default the plugin instance is not backed by an OpenGL texture. | 180 // By default the plugin instance is not backed by an OpenGL texture. |
212 return 0; | 181 return 0; |
213 } | 182 } |
214 | 183 |
215 // NPAPI methods | 184 // NPAPI methods |
216 NPError PluginInstance::NPP_New(unsigned short mode, | 185 NPError PluginInstance::NPP_New(unsigned short mode, |
217 short argc, | 186 short argc, |
218 char* argn[], | 187 char* argn[], |
219 char* argv[]) { | 188 char* argv[]) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 npp_functions_->asfile(npp_, stream, fname); | 288 npp_functions_->asfile(npp_, stream, fname); |
320 } | 289 } |
321 | 290 |
322 // Creating a temporary FilePath instance on the stack as the explicit | 291 // Creating a temporary FilePath instance on the stack as the explicit |
323 // FilePath constructor with StringType as an argument causes a compiler | 292 // FilePath constructor with StringType as an argument causes a compiler |
324 // error when invoked via vector push back. | 293 // error when invoked via vector push back. |
325 base::FilePath file_name = base::FilePath::FromUTF8Unsafe(fname); | 294 base::FilePath file_name = base::FilePath::FromUTF8Unsafe(fname); |
326 files_created_.push_back(file_name); | 295 files_created_.push_back(file_name); |
327 } | 296 } |
328 | 297 |
329 void PluginInstance::NPP_URLNotify(const char* url, | |
330 NPReason reason, | |
331 void* notifyData) { | |
332 DCHECK(npp_functions_ != 0); | |
333 DCHECK(npp_functions_->urlnotify != 0); | |
334 if (npp_functions_->urlnotify != 0) { | |
335 npp_functions_->urlnotify(npp_, url, reason, notifyData); | |
336 } | |
337 } | |
338 | |
339 NPError PluginInstance::NPP_GetValue(NPPVariable variable, void* value) { | 298 NPError PluginInstance::NPP_GetValue(NPPVariable variable, void* value) { |
340 DCHECK(npp_functions_ != 0); | 299 DCHECK(npp_functions_ != 0); |
341 // getvalue is NULL for Shockwave | 300 // getvalue is NULL for Shockwave |
342 if (npp_functions_->getvalue != 0) { | 301 if (npp_functions_->getvalue != 0) { |
343 return npp_functions_->getvalue(npp_, variable, value); | 302 return npp_functions_->getvalue(npp_, variable, value); |
344 } | 303 } |
345 return NPERR_INVALID_FUNCTABLE_ERROR; | 304 return NPERR_INVALID_FUNCTABLE_ERROR; |
346 } | 305 } |
347 | 306 |
348 NPError PluginInstance::NPP_SetValue(NPNVariable variable, void* value) { | 307 NPError PluginInstance::NPP_SetValue(NPNVariable variable, void* value) { |
(...skipping 15 matching lines...) Expand all Loading... |
364 | 323 |
365 bool PluginInstance::NPP_Print(NPPrint* platform_print) { | 324 bool PluginInstance::NPP_Print(NPPrint* platform_print) { |
366 DCHECK(npp_functions_ != 0); | 325 DCHECK(npp_functions_ != 0); |
367 if (npp_functions_->print != 0) { | 326 if (npp_functions_->print != 0) { |
368 npp_functions_->print(npp_, platform_print); | 327 npp_functions_->print(npp_, platform_print); |
369 return true; | 328 return true; |
370 } | 329 } |
371 return false; | 330 return false; |
372 } | 331 } |
373 | 332 |
374 void PluginInstance::NPP_URLRedirectNotify(const char* url, int32_t status, | |
375 void* notify_data) { | |
376 DCHECK(npp_functions_ != 0); | |
377 if (npp_functions_->urlredirectnotify != 0) { | |
378 npp_functions_->urlredirectnotify(npp_, url, status, notify_data); | |
379 } | |
380 } | |
381 | |
382 void PluginInstance::SendJavaScriptStream(const GURL& url, | 333 void PluginInstance::SendJavaScriptStream(const GURL& url, |
383 const std::string& result, | 334 const std::string& result, |
384 bool success, | 335 bool success) { |
385 int notify_id) { | |
386 bool notify; | |
387 void* notify_data; | |
388 GetNotifyData(notify_id, ¬ify, ¬ify_data); | |
389 | |
390 if (success) { | 336 if (success) { |
391 PluginStringStream *stream = | 337 PluginStringStream *stream = new PluginStringStream(this, url); |
392 new PluginStringStream(this, url, notify, notify_data); | |
393 AddStream(stream); | 338 AddStream(stream); |
394 stream->SendToPlugin(result, "text/html"); | 339 stream->SendToPlugin(result, "text/html"); |
395 } else { | |
396 // NOTE: Sending an empty stream here will crash MacroMedia | |
397 // Flash 9. Just send the URL Notify. | |
398 if (notify) | |
399 NPP_URLNotify(url.spec().c_str(), NPRES_DONE, notify_data); | |
400 } | 340 } |
401 } | 341 } |
402 | 342 |
403 void PluginInstance::DidReceiveManualResponse(const GURL& url, | 343 void PluginInstance::DidReceiveManualResponse(const GURL& url, |
404 const std::string& mime_type, | 344 const std::string& mime_type, |
405 const std::string& headers, | 345 const std::string& headers, |
406 uint32 expected_length, | 346 uint32 expected_length, |
407 uint32 last_modified) { | 347 uint32 last_modified) { |
408 DCHECK(load_manually_); | 348 DCHECK(load_manually_); |
409 | 349 |
410 plugin_data_stream_ = | 350 plugin_data_stream_ = |
411 CreateStream(static_cast<unsigned long>(-1), url, mime_type, 0); | 351 CreateStream(static_cast<unsigned long>(-1), url, mime_type); |
412 plugin_data_stream_->DidReceiveResponse(mime_type, headers, expected_length, | 352 plugin_data_stream_->DidReceiveResponse(mime_type, headers, expected_length, |
413 last_modified, true); | 353 last_modified, true); |
414 } | 354 } |
415 | 355 |
416 void PluginInstance::DidReceiveManualData(const char* buffer, int length) { | 356 void PluginInstance::DidReceiveManualData(const char* buffer, int length) { |
417 DCHECK(load_manually_); | 357 DCHECK(load_manually_); |
418 if (plugin_data_stream_.get() != NULL) { | 358 if (plugin_data_stream_.get() != NULL) { |
419 plugin_data_stream_->DidReceiveData(buffer, length, 0); | 359 plugin_data_stream_->DidReceiveData(buffer, length, 0); |
420 } | 360 } |
421 } | 361 } |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 } | 515 } |
576 } | 516 } |
577 } | 517 } |
578 NOTREACHED(); | 518 NOTREACHED(); |
579 } | 519 } |
580 | 520 |
581 void PluginInstance::RequestURL(const char* url, | 521 void PluginInstance::RequestURL(const char* url, |
582 const char* method, | 522 const char* method, |
583 const char* target, | 523 const char* target, |
584 const char* buf, | 524 const char* buf, |
585 unsigned int len, | 525 unsigned int len) { |
586 bool notify, | |
587 void* notify_data) { | |
588 int notify_id = 0; | |
589 if (notify) { | |
590 notify_id = ++next_notify_id_; | |
591 pending_requests_[notify_id] = notify_data; | |
592 } | |
593 | |
594 webplugin_->HandleURLRequest( | 526 webplugin_->HandleURLRequest( |
595 url, method, target, buf, len, notify_id, popups_allowed(), | 527 url, method, target, buf, len, popups_allowed(), false); |
596 notify ? handles_url_redirects_ : false); | |
597 } | 528 } |
598 | 529 |
599 bool PluginInstance::ConvertPoint(double source_x, double source_y, | 530 bool PluginInstance::ConvertPoint(double source_x, double source_y, |
600 NPCoordinateSpace source_space, | 531 NPCoordinateSpace source_space, |
601 double* dest_x, double* dest_y, | 532 double* dest_x, double* dest_y, |
602 NPCoordinateSpace dest_space) { | 533 NPCoordinateSpace dest_space) { |
603 #if defined(OS_MACOSX) | 534 #if defined(OS_MACOSX) |
604 CGRect main_display_bounds = CGDisplayBounds(CGMainDisplayID()); | 535 CGRect main_display_bounds = CGDisplayBounds(CGMainDisplayID()); |
605 | 536 |
606 double flipped_screen_x = source_x; | 537 double flipped_screen_x = source_x; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 *dest_x = target_x; | 590 *dest_x = target_x; |
660 if (dest_y) | 591 if (dest_y) |
661 *dest_y = target_y; | 592 *dest_y = target_y; |
662 return true; | 593 return true; |
663 #else | 594 #else |
664 NOTIMPLEMENTED(); | 595 NOTIMPLEMENTED(); |
665 return false; | 596 return false; |
666 #endif | 597 #endif |
667 } | 598 } |
668 | 599 |
669 void PluginInstance::GetNotifyData(int notify_id, | |
670 bool* notify, | |
671 void** notify_data) { | |
672 PendingRequestMap::iterator iter = pending_requests_.find(notify_id); | |
673 if (iter != pending_requests_.end()) { | |
674 *notify = true; | |
675 *notify_data = iter->second; | |
676 pending_requests_.erase(iter); | |
677 } else { | |
678 *notify = false; | |
679 *notify_data = NULL; | |
680 } | |
681 } | |
682 | |
683 void PluginInstance::URLRedirectResponse(bool allow, void* notify_data) { | |
684 // The notify_data passed in allows us to identify the matching stream. | |
685 std::vector<scoped_refptr<PluginStream> >::iterator stream_index; | |
686 for (stream_index = open_streams_.begin(); | |
687 stream_index != open_streams_.end(); ++stream_index) { | |
688 PluginStream* plugin_stream = stream_index->get(); | |
689 if (plugin_stream->notify_data() == notify_data) { | |
690 PluginStreamUrl* plugin_stream_url = | |
691 static_cast<PluginStreamUrl*>(plugin_stream); | |
692 plugin_stream_url->URLRedirectResponse(allow); | |
693 break; | |
694 } | |
695 } | |
696 } | |
697 | |
698 } // namespace content | 600 } // namespace content |
OLD | NEW |