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

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: Ready for review 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
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 struct ForwardOpenChannelParams {
77 int render_process_id;
78 int render_view_id;
79 PluginProcessHost::Client* client;
80 const content::ResourceContext* resource_context;
81 };
82
76 #if defined(OS_POSIX) 83 #if defined(OS_POSIX)
77 // Utility child process client that manages the IPC for loading plugins out of 84 // Utility child process client that manages the IPC for loading plugins out of
78 // process. 85 // process.
79 class PluginLoaderClient : public UtilityProcessHost::Client { 86 class PluginLoaderClient : public UtilityProcessHost::Client {
80 public: 87 public:
81 // Meant to be called on the IO thread. Will invoke the callback on the target 88 // Meant to be called on the IO thread. Will invoke the callback on the target
82 // loop when the plugins have been loaded. 89 // loop when the plugins have been loaded.
83 static void LoadPluginsOutOfProcess( 90 static void LoadPluginsOutOfProcess(
84 base::MessageLoopProxy* target_loop, 91 base::MessageLoopProxy* target_loop,
85 const PluginService::GetPluginsCallback& callback) { 92 const PluginService::GetPluginsCallback& callback) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 324
318 PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess( 325 PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess(
319 const FilePath& plugin_path) { 326 const FilePath& plugin_path) {
320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
321 328
322 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); 329 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path);
323 if (plugin_host) 330 if (plugin_host)
324 return plugin_host; 331 return plugin_host;
325 332
326 webkit::WebPluginInfo info; 333 webkit::WebPluginInfo info;
327 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( 334 if (!GetPluginInfoByPath(plugin_path, &info)) {
328 plugin_path, &info)) {
329 return NULL; 335 return NULL;
330 } 336 }
331 337
332 // This plugin isn't loaded by any plugin process, so create a new process. 338 // This plugin isn't loaded by any plugin process, so create a new process.
333 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); 339 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost());
334 if (!new_host->Init(info, ui_locale_)) { 340 if (!new_host->Init(info, ui_locale_)) {
335 NOTREACHED(); // Init is not expected to fail. 341 NOTREACHED(); // Init is not expected to fail.
336 return NULL; 342 return NULL;
337 } 343 }
338 return new_host.release(); 344 return new_host.release();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 386
381 void PluginService::OpenChannelToNpapiPlugin( 387 void PluginService::OpenChannelToNpapiPlugin(
382 int render_process_id, 388 int render_process_id,
383 int render_view_id, 389 int render_view_id,
384 const GURL& url, 390 const GURL& url,
385 const GURL& page_url, 391 const GURL& page_url,
386 const std::string& mime_type, 392 const std::string& mime_type,
387 PluginProcessHost::Client* client) { 393 PluginProcessHost::Client* client) {
388 DCHECK(!ContainsKey(pending_plugin_clients_, client)); 394 DCHECK(!ContainsKey(pending_plugin_clients_, client));
389 pending_plugin_clients_.insert(client); 395 pending_plugin_clients_.insert(client);
390 // The PluginList::GetPluginInfo may need to load the plugins. Don't do it on 396
391 // the IO thread. 397 // Make sure plugins are loaded if necessary.
392 BrowserThread::PostTask( 398 ForwardOpenChannelParams params = {
393 BrowserThread::FILE, FROM_HERE, 399 render_process_id,
394 NewRunnableMethod( 400 render_view_id,
395 this, &PluginService::GetAllowedPluginForOpenChannelToPlugin, 401 client,
396 render_process_id, render_view_id, url, page_url, mime_type, 402 &client->GetResourceContext()
397 client, &client->GetResourceContext())); 403 };
404 GetPlugins(
405 base::Bind(&PluginService::ForwardGetAllowedPluginForOpenChannelToPlugin,
406 base::Unretained(this), params, url, page_url, mime_type));
398 } 407 }
399 408
400 void PluginService::OpenChannelToPpapiPlugin( 409 void PluginService::OpenChannelToPpapiPlugin(
401 const FilePath& path, 410 const FilePath& path,
402 PpapiPluginProcessHost::PluginClient* client) { 411 PpapiPluginProcessHost::PluginClient* client) {
403 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess( 412 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(
404 path, client); 413 path, client);
405 if (plugin_host) 414 if (plugin_host)
406 plugin_host->OpenChannelToPlugin(client); 415 plugin_host->OpenChannelToPlugin(client);
407 else // Send error. 416 else // Send error.
(...skipping 10 matching lines...) Expand all
418 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle()); 427 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle());
419 } 428 }
420 429
421 void PluginService::CancelOpenChannelToNpapiPlugin( 430 void PluginService::CancelOpenChannelToNpapiPlugin(
422 PluginProcessHost::Client* client) { 431 PluginProcessHost::Client* client) {
423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
424 DCHECK(ContainsKey(pending_plugin_clients_, client)); 433 DCHECK(ContainsKey(pending_plugin_clients_, client));
425 pending_plugin_clients_.erase(client); 434 pending_plugin_clients_.erase(client);
426 } 435 }
427 436
437 void PluginService::ForwardGetAllowedPluginForOpenChannelToPlugin(
438 const ForwardOpenChannelParams& params,
439 const GURL& url,
440 const GURL& page_url,
441 const std::string& mime_type,
442 const std::vector<webkit::WebPluginInfo>&) {
443 GetAllowedPluginForOpenChannelToPlugin(params.render_process_id,
444 params.render_view_id, url, page_url, mime_type, params.client,
445 params.resource_context);
446 }
447
428 void PluginService::GetAllowedPluginForOpenChannelToPlugin( 448 void PluginService::GetAllowedPluginForOpenChannelToPlugin(
429 int render_process_id, 449 int render_process_id,
430 int render_view_id, 450 int render_view_id,
431 const GURL& url, 451 const GURL& url,
432 const GURL& page_url, 452 const GURL& page_url,
433 const std::string& mime_type, 453 const std::string& mime_type,
434 PluginProcessHost::Client* client, 454 PluginProcessHost::Client* client,
435 const content::ResourceContext* resource_context) { 455 const content::ResourceContext* resource_context) {
436 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
437 DCHECK(resource_context);
438 webkit::WebPluginInfo info; 456 webkit::WebPluginInfo info;
439 bool allow_wildcard = true; 457 bool allow_wildcard = true;
440 bool found = GetPluginInfo( 458 bool found = GetPluginInfo(
441 render_process_id, render_view_id, *resource_context, 459 render_process_id, render_view_id, *resource_context,
442 url, page_url, mime_type, allow_wildcard, 460 url, page_url, mime_type, allow_wildcard,
443 NULL, &info, NULL); 461 NULL, &info, NULL);
444 FilePath plugin_path; 462 FilePath plugin_path;
445 if (found) 463 if (found)
446 plugin_path = info.path; 464 plugin_path = info.path;
447 465
448 // Now we jump back to the IO thread to finish opening the channel. 466 // Now we jump back to the IO thread to finish opening the channel.
449 BrowserThread::PostTask( 467 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
450 BrowserThread::IO, FROM_HERE, 468 base::Bind(&PluginService::FinishOpenChannelToPlugin,
451 NewRunnableMethod( 469 base::Unretained(this), plugin_path, client));
452 this, &PluginService::FinishOpenChannelToPlugin,
453 plugin_path, client));
454 } 470 }
455 471
456 void PluginService::FinishOpenChannelToPlugin( 472 void PluginService::FinishOpenChannelToPlugin(
457 const FilePath& plugin_path, 473 const FilePath& plugin_path,
458 PluginProcessHost::Client* client) { 474 PluginProcessHost::Client* client) {
459 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
460 476
461 // Make sure it hasn't been canceled yet. 477 // Make sure it hasn't been canceled yet.
462 if (!ContainsKey(pending_plugin_clients_, client)) 478 if (!ContainsKey(pending_plugin_clients_, client))
463 return; 479 return;
464 pending_plugin_clients_.erase(client); 480 pending_plugin_clients_.erase(client);
465 481
466 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess(plugin_path); 482 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess(plugin_path);
467 if (plugin_host) { 483 if (plugin_host) {
468 client->OnFoundPluginProcessHost(plugin_host); 484 client->OnFoundPluginProcessHost(plugin_host);
469 plugin_host->OpenChannelToPlugin(client); 485 plugin_host->OpenChannelToPlugin(client);
470 } else { 486 } else {
471 client->OnError(); 487 client->OnError();
472 } 488 }
473 } 489 }
474 490
491 bool PluginService::GetPluginInfoArray(
492 const GURL& url,
493 const std::string& mime_type,
494 bool allow_wildcard,
495 std::vector<webkit::WebPluginInfo>* plugins,
496 std::vector<std::string>* actual_mime_types) {
497 bool use_stale = false;
498 webkit::npapi::PluginList::Singleton()->GetPluginInfoArray(
499 url, mime_type, allow_wildcard, &use_stale, plugins, actual_mime_types);
500 return use_stale;
501 }
502
475 bool PluginService::GetPluginInfo(int render_process_id, 503 bool PluginService::GetPluginInfo(int render_process_id,
476 int render_view_id, 504 int render_view_id,
477 const content::ResourceContext& context, 505 const content::ResourceContext& context,
478 const GURL& url, 506 const GURL& url,
479 const GURL& page_url, 507 const GURL& page_url,
480 const std::string& mime_type, 508 const std::string& mime_type,
481 bool allow_wildcard, 509 bool allow_wildcard,
482 bool* use_stale, 510 bool* is_stale,
483 webkit::WebPluginInfo* info, 511 webkit::WebPluginInfo* info,
484 std::string* actual_mime_type) { 512 std::string* actual_mime_type) {
485 webkit::npapi::PluginList* plugin_list =
486 webkit::npapi::PluginList::Singleton();
487 // GetPluginInfoArray may need to load the plugins, so we need to be
488 // on the FILE thread.
489 DCHECK(use_stale || BrowserThread::CurrentlyOn(BrowserThread::FILE));
490 std::vector<webkit::WebPluginInfo> plugins; 513 std::vector<webkit::WebPluginInfo> plugins;
491 std::vector<std::string> mime_types; 514 std::vector<std::string> mime_types;
492 plugin_list->GetPluginInfoArray( 515 bool stale = GetPluginInfoArray(
493 url, mime_type, allow_wildcard, use_stale, &plugins, &mime_types); 516 url, mime_type, allow_wildcard, &plugins, &mime_types);
517 if (is_stale)
518 *is_stale = stale;
494 if (plugins.size() > 1 && 519 if (plugins.size() > 1 &&
495 plugins.back().path == 520 plugins.back().path ==
496 FilePath(webkit::npapi::kDefaultPluginLibraryName)) { 521 FilePath(webkit::npapi::kDefaultPluginLibraryName)) {
497 // If there is at least one plug-in handling the required MIME type (apart 522 // If there is at least one plug-in handling the required MIME type (apart
498 // from the default plug-in), we don't need the default plug-in. 523 // from the default plug-in), we don't need the default plug-in.
499 plugins.pop_back(); 524 plugins.pop_back();
500 } 525 }
501 526
502 for (size_t i = 0; i < plugins.size(); ++i) { 527 for (size_t i = 0; i < plugins.size(); ++i) {
503 if (!filter_ || filter_->ShouldUsePlugin(render_process_id, 528 if (!filter_ || filter_->ShouldUsePlugin(render_process_id,
504 render_view_id, 529 render_view_id,
505 &context, 530 &context,
506 url, 531 url,
507 page_url, 532 page_url,
508 &plugins[i])) { 533 &plugins[i])) {
509 *info = plugins[i]; 534 *info = plugins[i];
510 if (actual_mime_type) 535 if (actual_mime_type)
511 *actual_mime_type = mime_types[i]; 536 *actual_mime_type = mime_types[i];
512 return true; 537 return true;
513 } 538 }
514 } 539 }
515 return false; 540 return false;
516 } 541 }
517 542
543 bool PluginService::GetPluginInfoByPath(const FilePath& plugin_path,
544 webkit::WebPluginInfo* info) {
545 std::vector<webkit::WebPluginInfo> plugins;
546 webkit::npapi::PluginList::Singleton()->GetPluginsIfNoRefreshNeeded(
547 &plugins);
548
549 for (std::vector<webkit::WebPluginInfo>::iterator it = plugins.begin();
550 it != plugins.end();
551 ++it) {
552 if (it->path == plugin_path) {
553 *info = *it;
554 return true;
555 }
556 }
557
558 return false;
559 }
560
518 void PluginService::RefreshPluginList() { 561 void PluginService::RefreshPluginList() {
519 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); 562 webkit::npapi::PluginList::Singleton()->RefreshPlugins();
520 } 563 }
521 564
522 void PluginService::GetPlugins(const GetPluginsCallback& callback) { 565 void PluginService::GetPlugins(const GetPluginsCallback& callback) {
523 scoped_refptr<base::MessageLoopProxy> target_loop( 566 scoped_refptr<base::MessageLoopProxy> target_loop(
524 MessageLoop::current()->message_loop_proxy()); 567 MessageLoop::current()->message_loop_proxy());
525 568
526 #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX)) 569 #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX))
527 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 570 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 } 658 }
616 } 659 }
617 if (info) 660 if (info)
618 return info; 661 return info;
619 // We did not find the plugin in our list. But wait! the plugin can also 662 // We did not find the plugin in our list. But wait! the plugin can also
620 // be a latecomer, as it happens with pepper flash. This information 663 // be a latecomer, as it happens with pepper flash. This information
621 // can be obtained from the PluginList singleton and we can use it to 664 // can be obtained from the PluginList singleton and we can use it to
622 // construct it and add it to the list. This same deal needs to be done 665 // construct it and add it to the list. This same deal needs to be done
623 // in the renderer side in PepperPluginRegistry. 666 // in the renderer side in PepperPluginRegistry.
624 webkit::WebPluginInfo webplugin_info; 667 webkit::WebPluginInfo webplugin_info;
625 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( 668 if (!GetPluginInfoByPath(plugin_path, &webplugin_info))
626 plugin_path, &webplugin_info))
627 return NULL; 669 return NULL;
628 PepperPluginInfo new_pepper_info; 670 PepperPluginInfo new_pepper_info;
629 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info)) 671 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info))
630 return NULL; 672 return NULL;
631 ppapi_plugins_.push_back(new_pepper_info); 673 ppapi_plugins_.push_back(new_pepper_info);
632 return &ppapi_plugins_[ppapi_plugins_.size() - 1]; 674 return &ppapi_plugins_[ppapi_plugins_.size() - 1];
633 } 675 }
634 676
635 #if defined(OS_POSIX) && !defined(OS_MACOSX) 677 #if defined(OS_POSIX) && !defined(OS_MACOSX)
636 // static 678 // static
637 void PluginService::RegisterFilePathWatcher( 679 void PluginService::RegisterFilePathWatcher(
638 FilePathWatcher *watcher, 680 FilePathWatcher *watcher,
639 const FilePath& path, 681 const FilePath& path,
640 FilePathWatcher::Delegate* delegate) { 682 FilePathWatcher::Delegate* delegate) {
641 bool result = watcher->Watch(path, delegate); 683 bool result = watcher->Watch(path, delegate);
642 DCHECK(result); 684 DCHECK(result);
643 } 685 }
644 #endif 686 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698