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

Side by Side Diff: content/browser/plugin_service.cc

Issue 8071013: Finish moving plugin probing out of process. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 9 years, 2 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
« no previous file with comments | « content/browser/plugin_service.h ('k') | content/browser/plugin_service_filter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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/browser/plugin_service.h" 5 #include "content/browser/plugin_service.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/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/file_path.h" 10 #include "base/file_path.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 std::vector<webkit::npapi::PluginGroup> groups; 60 std::vector<webkit::npapi::PluginGroup> groups;
61 webkit::npapi::PluginList::Singleton()->GetPluginGroups(false, &groups); 61 webkit::npapi::PluginList::Singleton()->GetPluginGroups(false, &groups);
62 callback.Run(groups); 62 callback.Run(groups);
63 } 63 }
64 64
65 // Callback set on the PluginList to assert that plugin loading happens on the 65 // Callback set on the PluginList to assert that plugin loading happens on the
66 // correct thread. 66 // correct thread.
67 void WillLoadPluginsCallback() { 67 void WillLoadPluginsCallback() {
68 // TODO(rsesek): Change these to CHECKs. 68 // TODO(rsesek): Change these to CHECKs.
69 #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX)) 69 #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX))
70 LOG_IF(ERROR, !BrowserThread::CurrentlyOn(BrowserThread::FILE)); 70 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
71 #else 71 #else
72 LOG(ERROR) << "Plugin loading should happen out-of-process."; 72 CHECK(false) << "Plugin loading should happen out-of-process.";
73 #endif 73 #endif
74 } 74 }
75 75
76 #if defined(OS_POSIX) 76 #if defined(OS_POSIX)
77 // Utility child process client that manages the IPC for loading plugins out of 77 // Utility child process client that manages the IPC for loading plugins out of
78 // process. 78 // process.
79 class PluginLoaderClient : public UtilityProcessHost::Client { 79 class PluginLoaderClient : public UtilityProcessHost::Client {
80 public: 80 public:
81 // Meant to be called on the IO thread. Will invoke the callback on the target 81 // Meant to be called on the IO thread. Will invoke the callback on the target
82 // loop when the plugins have been loaded. 82 // loop when the plugins have been loaded.
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 317
318 PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess( 318 PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess(
319 const FilePath& plugin_path) { 319 const FilePath& plugin_path) {
320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
321 321
322 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); 322 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path);
323 if (plugin_host) 323 if (plugin_host)
324 return plugin_host; 324 return plugin_host;
325 325
326 webkit::WebPluginInfo info; 326 webkit::WebPluginInfo info;
327 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( 327 if (!GetPluginInfoByPath(plugin_path, &info)) {
328 plugin_path, &info)) {
329 return NULL; 328 return NULL;
330 } 329 }
331 330
332 // This plugin isn't loaded by any plugin process, so create a new process. 331 // This plugin isn't loaded by any plugin process, so create a new process.
333 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); 332 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost());
334 if (!new_host->Init(info, ui_locale_)) { 333 if (!new_host->Init(info, ui_locale_)) {
335 NOTREACHED(); // Init is not expected to fail. 334 NOTREACHED(); // Init is not expected to fail.
336 return NULL; 335 return NULL;
337 } 336 }
338 return new_host.release(); 337 return new_host.release();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 379
381 void PluginService::OpenChannelToNpapiPlugin( 380 void PluginService::OpenChannelToNpapiPlugin(
382 int render_process_id, 381 int render_process_id,
383 int render_view_id, 382 int render_view_id,
384 const GURL& url, 383 const GURL& url,
385 const GURL& page_url, 384 const GURL& page_url,
386 const std::string& mime_type, 385 const std::string& mime_type,
387 PluginProcessHost::Client* client) { 386 PluginProcessHost::Client* client) {
388 DCHECK(!ContainsKey(pending_plugin_clients_, client)); 387 DCHECK(!ContainsKey(pending_plugin_clients_, client));
389 pending_plugin_clients_.insert(client); 388 pending_plugin_clients_.insert(client);
390 // The PluginList::GetPluginInfo may need to load the plugins. Don't do it on 389
391 // the IO thread. 390 // Make sure plugins are loaded if necessary.
392 BrowserThread::PostTask( 391 content::PluginServiceFilterParams params = {
393 BrowserThread::FILE, FROM_HERE, 392 render_process_id,
394 NewRunnableMethod( 393 render_view_id,
395 this, &PluginService::GetAllowedPluginForOpenChannelToPlugin, 394 page_url,
396 render_process_id, render_view_id, url, page_url, mime_type, 395 &client->GetResourceContext()
397 client, &client->GetResourceContext())); 396 };
397 GetPlugins(
398 base::Bind(&PluginService::ForwardGetAllowedPluginForOpenChannelToPlugin,
399 base::Unretained(this), params, url, mime_type, client));
398 } 400 }
399 401
400 void PluginService::OpenChannelToPpapiPlugin( 402 void PluginService::OpenChannelToPpapiPlugin(
401 const FilePath& path, 403 const FilePath& path,
402 PpapiPluginProcessHost::PluginClient* client) { 404 PpapiPluginProcessHost::PluginClient* client) {
403 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess( 405 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(
404 path, client); 406 path, client);
405 if (plugin_host) 407 if (plugin_host)
406 plugin_host->OpenChannelToPlugin(client); 408 plugin_host->OpenChannelToPlugin(client);
407 else // Send error. 409 else // Send error.
(...skipping 10 matching lines...) Expand all
418 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle()); 420 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
419 } 421 }
420 422
421 void PluginService::CancelOpenChannelToNpapiPlugin( 423 void PluginService::CancelOpenChannelToNpapiPlugin(
422 PluginProcessHost::Client* client) { 424 PluginProcessHost::Client* client) {
423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
424 DCHECK(ContainsKey(pending_plugin_clients_, client)); 426 DCHECK(ContainsKey(pending_plugin_clients_, client));
425 pending_plugin_clients_.erase(client); 427 pending_plugin_clients_.erase(client);
426 } 428 }
427 429
430 void PluginService::ForwardGetAllowedPluginForOpenChannelToPlugin(
431 const content::PluginServiceFilterParams& params,
432 const GURL& url,
433 const std::string& mime_type,
434 PluginProcessHost::Client* client,
435 const std::vector<webkit::WebPluginInfo>&) {
436 GetAllowedPluginForOpenChannelToPlugin(params.render_process_id,
437 params.render_view_id, url, params.page_url, mime_type, client,
438 params.resource_context);
439 }
440
428 void PluginService::GetAllowedPluginForOpenChannelToPlugin( 441 void PluginService::GetAllowedPluginForOpenChannelToPlugin(
429 int render_process_id, 442 int render_process_id,
430 int render_view_id, 443 int render_view_id,
431 const GURL& url, 444 const GURL& url,
432 const GURL& page_url, 445 const GURL& page_url,
433 const std::string& mime_type, 446 const std::string& mime_type,
434 PluginProcessHost::Client* client, 447 PluginProcessHost::Client* client,
435 const content::ResourceContext* resource_context) { 448 const content::ResourceContext* resource_context) {
436 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
437 DCHECK(resource_context);
438 webkit::WebPluginInfo info; 449 webkit::WebPluginInfo info;
439 bool allow_wildcard = true; 450 bool allow_wildcard = true;
440 bool found = GetPluginInfo( 451 bool found = GetPluginInfo(
441 render_process_id, render_view_id, *resource_context, 452 render_process_id, render_view_id, *resource_context,
442 url, page_url, mime_type, allow_wildcard, 453 url, page_url, mime_type, allow_wildcard,
443 NULL, &info, NULL); 454 NULL, &info, NULL);
444 FilePath plugin_path; 455 FilePath plugin_path;
445 if (found) 456 if (found)
446 plugin_path = info.path; 457 plugin_path = info.path;
447 458
448 // Now we jump back to the IO thread to finish opening the channel. 459 // Now we jump back to the IO thread to finish opening the channel.
449 BrowserThread::PostTask( 460 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
450 BrowserThread::IO, FROM_HERE, 461 base::Bind(&PluginService::FinishOpenChannelToPlugin,
451 NewRunnableMethod( 462 base::Unretained(this), plugin_path, client));
452 this, &PluginService::FinishOpenChannelToPlugin,
453 plugin_path, client));
454 } 463 }
455 464
456 void PluginService::FinishOpenChannelToPlugin( 465 void PluginService::FinishOpenChannelToPlugin(
457 const FilePath& plugin_path, 466 const FilePath& plugin_path,
458 PluginProcessHost::Client* client) { 467 PluginProcessHost::Client* client) {
459 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
460 469
461 // Make sure it hasn't been canceled yet. 470 // Make sure it hasn't been canceled yet.
462 if (!ContainsKey(pending_plugin_clients_, client)) 471 if (!ContainsKey(pending_plugin_clients_, client))
463 return; 472 return;
(...skipping 20 matching lines...) Expand all
484 return use_stale; 493 return use_stale;
485 } 494 }
486 495
487 bool PluginService::GetPluginInfo(int render_process_id, 496 bool PluginService::GetPluginInfo(int render_process_id,
488 int render_view_id, 497 int render_view_id,
489 const content::ResourceContext& context, 498 const content::ResourceContext& context,
490 const GURL& url, 499 const GURL& url,
491 const GURL& page_url, 500 const GURL& page_url,
492 const std::string& mime_type, 501 const std::string& mime_type,
493 bool allow_wildcard, 502 bool allow_wildcard,
494 bool* use_stale, 503 bool* is_stale,
495 webkit::WebPluginInfo* info, 504 webkit::WebPluginInfo* info,
496 std::string* actual_mime_type) { 505 std::string* actual_mime_type) {
497 webkit::npapi::PluginList* plugin_list =
498 webkit::npapi::PluginList::Singleton();
499 // GetPluginInfoArray may need to load the plugins, so we need to be
500 // on the FILE thread.
501 DCHECK(use_stale || BrowserThread::CurrentlyOn(BrowserThread::FILE));
502 std::vector<webkit::WebPluginInfo> plugins; 506 std::vector<webkit::WebPluginInfo> plugins;
503 std::vector<std::string> mime_types; 507 std::vector<std::string> mime_types;
504 plugin_list->GetPluginInfoArray( 508 bool stale = GetPluginInfoArray(
505 url, mime_type, allow_wildcard, use_stale, &plugins, &mime_types); 509 url, mime_type, allow_wildcard, &plugins, &mime_types);
510 if (is_stale)
511 *is_stale = stale;
506 if (plugins.size() > 1 && 512 if (plugins.size() > 1 &&
507 plugins.back().path == 513 plugins.back().path ==
508 FilePath(webkit::npapi::kDefaultPluginLibraryName)) { 514 FilePath(webkit::npapi::kDefaultPluginLibraryName)) {
509 // If there is at least one plug-in handling the required MIME type (apart 515 // If there is at least one plug-in handling the required MIME type (apart
510 // from the default plug-in), we don't need the default plug-in. 516 // from the default plug-in), we don't need the default plug-in.
511 plugins.pop_back(); 517 plugins.pop_back();
512 } 518 }
513 519
514 for (size_t i = 0; i < plugins.size(); ++i) { 520 for (size_t i = 0; i < plugins.size(); ++i) {
515 if (!filter_ || filter_->ShouldUsePlugin(render_process_id, 521 if (!filter_ || filter_->ShouldUsePlugin(render_process_id,
516 render_view_id, 522 render_view_id,
517 &context, 523 &context,
518 url, 524 url,
519 page_url, 525 page_url,
520 &plugins[i])) { 526 &plugins[i])) {
521 *info = plugins[i]; 527 *info = plugins[i];
522 if (actual_mime_type) 528 if (actual_mime_type)
523 *actual_mime_type = mime_types[i]; 529 *actual_mime_type = mime_types[i];
524 return true; 530 return true;
525 } 531 }
526 } 532 }
527 return false; 533 return false;
528 } 534 }
529 535
536 bool PluginService::GetPluginInfoByPath(const FilePath& plugin_path,
537 webkit::WebPluginInfo* info) {
538 std::vector<webkit::WebPluginInfo> plugins;
539 webkit::npapi::PluginList::Singleton()->GetPluginsIfNoRefreshNeeded(
540 &plugins);
541
542 for (std::vector<webkit::WebPluginInfo>::iterator it = plugins.begin();
543 it != plugins.end();
544 ++it) {
545 if (it->path == plugin_path) {
546 *info = *it;
547 return true;
548 }
549 }
550
551 return false;
552 }
553
530 void PluginService::RefreshPluginList() { 554 void PluginService::RefreshPluginList() {
531 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); 555 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
532 } 556 }
533 557
534 void PluginService::GetPlugins(const GetPluginsCallback& callback) { 558 void PluginService::GetPlugins(const GetPluginsCallback& callback) {
535 scoped_refptr<base::MessageLoopProxy> target_loop( 559 scoped_refptr<base::MessageLoopProxy> target_loop(
536 MessageLoop::current()->message_loop_proxy()); 560 MessageLoop::current()->message_loop_proxy());
537 561
538 #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX)) 562 #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX))
539 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 563 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 } 651 }
628 } 652 }
629 if (info) 653 if (info)
630 return info; 654 return info;
631 // We did not find the plugin in our list. But wait! the plugin can also 655 // We did not find the plugin in our list. But wait! the plugin can also
632 // be a latecomer, as it happens with pepper flash. This information 656 // be a latecomer, as it happens with pepper flash. This information
633 // can be obtained from the PluginList singleton and we can use it to 657 // can be obtained from the PluginList singleton and we can use it to
634 // construct it and add it to the list. This same deal needs to be done 658 // construct it and add it to the list. This same deal needs to be done
635 // in the renderer side in PepperPluginRegistry. 659 // in the renderer side in PepperPluginRegistry.
636 webkit::WebPluginInfo webplugin_info; 660 webkit::WebPluginInfo webplugin_info;
637 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( 661 if (!GetPluginInfoByPath(plugin_path, &webplugin_info))
638 plugin_path, &webplugin_info))
639 return NULL; 662 return NULL;
640 PepperPluginInfo new_pepper_info; 663 PepperPluginInfo new_pepper_info;
641 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info)) 664 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info))
642 return NULL; 665 return NULL;
643 ppapi_plugins_.push_back(new_pepper_info); 666 ppapi_plugins_.push_back(new_pepper_info);
644 return &ppapi_plugins_[ppapi_plugins_.size() - 1]; 667 return &ppapi_plugins_[ppapi_plugins_.size() - 1];
645 } 668 }
646 669
647 #if defined(OS_POSIX) && !defined(OS_MACOSX) 670 #if defined(OS_POSIX) && !defined(OS_MACOSX)
648 // static 671 // static
649 void PluginService::RegisterFilePathWatcher( 672 void PluginService::RegisterFilePathWatcher(
650 FilePathWatcher *watcher, 673 FilePathWatcher *watcher,
651 const FilePath& path, 674 const FilePath& path,
652 FilePathWatcher::Delegate* delegate) { 675 FilePathWatcher::Delegate* delegate) {
653 bool result = watcher->Watch(path, delegate); 676 bool result = watcher->Watch(path, delegate);
654 DCHECK(result); 677 DCHECK(result);
655 } 678 }
656 #endif 679 #endif
OLDNEW
« no previous file with comments | « content/browser/plugin_service.h ('k') | content/browser/plugin_service_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698