| 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 |