| OLD | NEW |
| 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 NOTREACHED(); | 105 NOTREACHED(); |
| 106 } | 106 } |
| 107 }; | 107 }; |
| 108 #endif | 108 #endif |
| 109 | 109 |
| 110 // static | 110 // static |
| 111 PluginService* PluginService::GetInstance() { | 111 PluginService* PluginService::GetInstance() { |
| 112 return Singleton<PluginService>::get(); | 112 return Singleton<PluginService>::get(); |
| 113 } | 113 } |
| 114 | 114 |
| 115 PluginService::PluginService() | 115 PluginService::PluginService(webkit::npapi::PluginList* plugin_list) |
| 116 : ui_locale_( | 116 : plugin_list_(plugin_list), |
| 117 ui_locale_( |
| 117 content::GetContentClient()->browser()->GetApplicationLocale()), | 118 content::GetContentClient()->browser()->GetApplicationLocale()), |
| 118 filter_(NULL) { | 119 filter_(NULL) { |
| 119 webkit::npapi::PluginList::Singleton()->set_will_load_plugins_callback( | 120 if (!plugin_list_) |
| 121 plugin_list_ = webkit::npapi::PluginList::Singleton(); |
| 122 |
| 123 plugin_list_->set_will_load_plugins_callback( |
| 120 base::Bind(&WillLoadPluginsCallback)); | 124 base::Bind(&WillLoadPluginsCallback)); |
| 121 | 125 |
| 122 RegisterPepperPlugins(); | 126 RegisterPepperPlugins(); |
| 123 | 127 |
| 124 // Load any specified on the command line as well. | 128 // Load any specified on the command line as well. |
| 125 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 129 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 126 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin); | 130 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin); |
| 127 if (!path.empty()) | 131 if (!path.empty()) |
| 128 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path); | 132 plugin_list_->AddExtraPluginPath(path); |
| 129 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir); | 133 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir); |
| 130 if (!path.empty()) | 134 if (!path.empty()) |
| 131 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(path); | 135 plugin_list_->AddExtraPluginDir(path); |
| 132 | 136 |
| 133 #if defined(OS_MACOSX) | 137 #if defined(OS_MACOSX) |
| 134 // We need to know when the browser comes forward so we can bring modal plugin | 138 // We need to know when the browser comes forward so we can bring modal plugin |
| 135 // windows forward too. | 139 // windows forward too. |
| 136 registrar_.Add(this, content::NOTIFICATION_APP_ACTIVATED, | 140 registrar_.Add(this, content::NOTIFICATION_APP_ACTIVATED, |
| 137 content::NotificationService::AllSources()); | 141 content::NotificationService::AllSources()); |
| 138 #endif | 142 #endif |
| 139 } | 143 } |
| 140 | 144 |
| 141 PluginService::~PluginService() { | 145 PluginService::~PluginService() { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 179 } |
| 176 #elif defined(OS_POSIX) && !defined(OS_MACOSX) | 180 #elif defined(OS_POSIX) && !defined(OS_MACOSX) |
| 177 // The FilePathWatcher produces too many false positives on MacOS (access time | 181 // The FilePathWatcher produces too many false positives on MacOS (access time |
| 178 // updates?) which will lead to enforcing updates of the plugins way too often. | 182 // updates?) which will lead to enforcing updates of the plugins way too often. |
| 179 // On ChromeOS the user can't install plugins anyway and on Windows all | 183 // On ChromeOS the user can't install plugins anyway and on Windows all |
| 180 // important plugins register themselves in the registry so no need to do that. | 184 // important plugins register themselves in the registry so no need to do that. |
| 181 file_watcher_delegate_ = new PluginDirWatcherDelegate(); | 185 file_watcher_delegate_ = new PluginDirWatcherDelegate(); |
| 182 // Get the list of all paths for registering the FilePathWatchers | 186 // Get the list of all paths for registering the FilePathWatchers |
| 183 // that will track and if needed reload the list of plugins on runtime. | 187 // that will track and if needed reload the list of plugins on runtime. |
| 184 std::vector<FilePath> plugin_dirs; | 188 std::vector<FilePath> plugin_dirs; |
| 185 webkit::npapi::PluginList::Singleton()->GetPluginDirectories( | 189 plugin_list_->GetPluginDirectories(&plugin_dirs); |
| 186 &plugin_dirs); | |
| 187 | 190 |
| 188 for (size_t i = 0; i < plugin_dirs.size(); ++i) { | 191 for (size_t i = 0; i < plugin_dirs.size(); ++i) { |
| 189 // FilePathWatcher can not handle non-absolute paths under windows. | 192 // FilePathWatcher can not handle non-absolute paths under windows. |
| 190 // We don't watch for file changes in windows now but if this should ever | 193 // We don't watch for file changes in windows now but if this should ever |
| 191 // be extended to Windows these lines might save some time of debugging. | 194 // be extended to Windows these lines might save some time of debugging. |
| 192 #if defined(OS_WIN) | 195 #if defined(OS_WIN) |
| 193 if (!plugin_dirs[i].IsAbsolute()) | 196 if (!plugin_dirs[i].IsAbsolute()) |
| 194 continue; | 197 continue; |
| 195 #endif | 198 #endif |
| 196 FilePathWatcher* watcher = new FilePathWatcher(); | 199 FilePathWatcher* watcher = new FilePathWatcher(); |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 } | 424 } |
| 422 } | 425 } |
| 423 | 426 |
| 424 bool PluginService::GetPluginInfoArray( | 427 bool PluginService::GetPluginInfoArray( |
| 425 const GURL& url, | 428 const GURL& url, |
| 426 const std::string& mime_type, | 429 const std::string& mime_type, |
| 427 bool allow_wildcard, | 430 bool allow_wildcard, |
| 428 std::vector<webkit::WebPluginInfo>* plugins, | 431 std::vector<webkit::WebPluginInfo>* plugins, |
| 429 std::vector<std::string>* actual_mime_types) { | 432 std::vector<std::string>* actual_mime_types) { |
| 430 bool use_stale = false; | 433 bool use_stale = false; |
| 431 webkit::npapi::PluginList::Singleton()->GetPluginInfoArray( | 434 plugin_list_->GetPluginInfoArray( |
| 432 url, mime_type, allow_wildcard, &use_stale, plugins, actual_mime_types); | 435 url, mime_type, allow_wildcard, &use_stale, plugins, actual_mime_types); |
| 433 return use_stale; | 436 return use_stale; |
| 434 } | 437 } |
| 435 | 438 |
| 436 bool PluginService::GetPluginInfo(int render_process_id, | 439 bool PluginService::GetPluginInfo(int render_process_id, |
| 437 int render_view_id, | 440 int render_view_id, |
| 438 const content::ResourceContext& context, | 441 const content::ResourceContext& context, |
| 439 const GURL& url, | 442 const GURL& url, |
| 440 const GURL& page_url, | 443 const GURL& page_url, |
| 441 const std::string& mime_type, | 444 const std::string& mime_type, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 469 *actual_mime_type = mime_types[i]; | 472 *actual_mime_type = mime_types[i]; |
| 470 return true; | 473 return true; |
| 471 } | 474 } |
| 472 } | 475 } |
| 473 return false; | 476 return false; |
| 474 } | 477 } |
| 475 | 478 |
| 476 bool PluginService::GetPluginInfoByPath(const FilePath& plugin_path, | 479 bool PluginService::GetPluginInfoByPath(const FilePath& plugin_path, |
| 477 webkit::WebPluginInfo* info) { | 480 webkit::WebPluginInfo* info) { |
| 478 std::vector<webkit::WebPluginInfo> plugins; | 481 std::vector<webkit::WebPluginInfo> plugins; |
| 479 webkit::npapi::PluginList::Singleton()->GetPluginsIfNoRefreshNeeded( | 482 plugin_list_->GetPluginsIfNoRefreshNeeded(&plugins); |
| 480 &plugins); | |
| 481 | 483 |
| 482 for (std::vector<webkit::WebPluginInfo>::iterator it = plugins.begin(); | 484 for (std::vector<webkit::WebPluginInfo>::iterator it = plugins.begin(); |
| 483 it != plugins.end(); | 485 it != plugins.end(); |
| 484 ++it) { | 486 ++it) { |
| 485 if (it->path == plugin_path) { | 487 if (it->path == plugin_path) { |
| 486 *info = *it; | 488 *info = *it; |
| 487 return true; | 489 return true; |
| 488 } | 490 } |
| 489 } | 491 } |
| 490 | 492 |
| 491 return false; | 493 return false; |
| 492 } | 494 } |
| 493 | 495 |
| 494 void PluginService::RefreshPluginList() { | 496 void PluginService::RefreshPluginList() { |
| 495 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); | 497 plugin_list_->RefreshPlugins(); |
| 496 } | 498 } |
| 497 | 499 |
| 498 void PluginService::GetPlugins(const GetPluginsCallback& callback) { | 500 void PluginService::GetPlugins(const GetPluginsCallback& callback) { |
| 499 scoped_refptr<base::MessageLoopProxy> target_loop( | 501 scoped_refptr<base::MessageLoopProxy> target_loop( |
| 500 MessageLoop::current()->message_loop_proxy()); | 502 MessageLoop::current()->message_loop_proxy()); |
| 501 | 503 |
| 502 #if defined(OS_WIN) | 504 #if defined(OS_WIN) |
| 503 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 505 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 504 base::Bind(&PluginService::GetPluginsInternal, base::Unretained(this), | 506 base::Bind(&PluginService::GetPluginsInternal, base::Unretained(this), |
| 505 target_loop, callback)); | 507 target_loop, callback)); |
| 506 #else | 508 #else |
| 507 std::vector<webkit::WebPluginInfo> cached_plugins; | 509 std::vector<webkit::WebPluginInfo> cached_plugins; |
| 508 if (webkit::npapi::PluginList::Singleton()->GetPluginsIfNoRefreshNeeded( | 510 if (plugin_list_->GetPluginsIfNoRefreshNeeded(&cached_plugins)) { |
| 509 &cached_plugins)) { | |
| 510 // Can't assume the caller is reentrant. | 511 // Can't assume the caller is reentrant. |
| 511 target_loop->PostTask(FROM_HERE, | 512 target_loop->PostTask(FROM_HERE, |
| 512 base::Bind(&RunGetPluginsCallback, callback, cached_plugins)); | 513 base::Bind(&RunGetPluginsCallback, callback, cached_plugins)); |
| 513 } else { | 514 } else { |
| 514 // If we switch back to loading plugins in process, then we need to make | 515 // If we switch back to loading plugins in process, then we need to make |
| 515 // sure g_thread_init() gets called since plugins may call glib at load. | 516 // sure g_thread_init() gets called since plugins may call glib at load. |
| 516 if (!plugin_loader_.get()) | 517 if (!plugin_loader_.get()) |
| 517 plugin_loader_ = new PluginLoaderPosix; | 518 plugin_loader_ = new PluginLoaderPosix; |
| 518 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 519 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 519 base::Bind(&PluginLoaderPosix::LoadPlugins, plugin_loader_, | 520 base::Bind(&PluginLoaderPosix::LoadPlugins, plugin_loader_, |
| 520 target_loop, callback)); | 521 target_loop, callback)); |
| 521 } | 522 } |
| 522 #endif | 523 #endif |
| 523 } | 524 } |
| 524 | 525 |
| 525 void PluginService::GetPluginGroups(const GetPluginGroupsCallback& callback) { | 526 void PluginService::GetPluginGroups(const GetPluginGroupsCallback& callback) { |
| 526 GetPlugins(base::Bind(&GetPluginsForGroupsCallback, callback)); | 527 GetPlugins(base::Bind(&GetPluginsForGroupsCallback, callback)); |
| 527 } | 528 } |
| 528 | 529 |
| 529 void PluginService::GetPluginsInternal( | 530 void PluginService::GetPluginsInternal( |
| 530 base::MessageLoopProxy* target_loop, | 531 base::MessageLoopProxy* target_loop, |
| 531 const PluginService::GetPluginsCallback& callback) { | 532 const PluginService::GetPluginsCallback& callback) { |
| 532 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 533 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 533 | 534 |
| 534 std::vector<webkit::WebPluginInfo> plugins; | 535 std::vector<webkit::WebPluginInfo> plugins; |
| 535 webkit::npapi::PluginList::Singleton()->GetPlugins(&plugins); | 536 plugin_list_->GetPlugins(&plugins); |
| 536 | 537 |
| 537 target_loop->PostTask(FROM_HERE, | 538 target_loop->PostTask(FROM_HERE, |
| 538 base::Bind(&RunGetPluginsCallback, callback, plugins)); | 539 base::Bind(&RunGetPluginsCallback, callback, plugins)); |
| 539 } | 540 } |
| 540 | 541 |
| 541 void PluginService::OnWaitableEventSignaled( | 542 void PluginService::OnWaitableEventSignaled( |
| 542 base::WaitableEvent* waitable_event) { | 543 base::WaitableEvent* waitable_event) { |
| 543 #if defined(OS_WIN) | 544 #if defined(OS_WIN) |
| 544 if (waitable_event == hkcu_event_.get()) { | 545 if (waitable_event == hkcu_event_.get()) { |
| 545 hkcu_key_.StartWatching(); | 546 hkcu_key_.StartWatching(); |
| 546 } else { | 547 } else { |
| 547 hklm_key_.StartWatching(); | 548 hklm_key_.StartWatching(); |
| 548 } | 549 } |
| 549 | 550 |
| 550 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); | 551 plugin_list_->RefreshPlugins(); |
| 551 PurgePluginListCache(NULL, false); | 552 PurgePluginListCache(NULL, false); |
| 552 #else | 553 #else |
| 553 // This event should only get signaled on a Windows machine. | 554 // This event should only get signaled on a Windows machine. |
| 554 NOTREACHED(); | 555 NOTREACHED(); |
| 555 #endif // defined(OS_WIN) | 556 #endif // defined(OS_WIN) |
| 556 } | 557 } |
| 557 | 558 |
| 558 void PluginService::Observe(int type, | 559 void PluginService::Observe(int type, |
| 559 const content::NotificationSource& source, | 560 const content::NotificationSource& source, |
| 560 const content::NotificationDetails& details) { | 561 const content::NotificationDetails& details) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 576 RenderProcessHost* host = it.GetCurrentValue(); | 577 RenderProcessHost* host = it.GetCurrentValue(); |
| 577 if (!browser_context || host->browser_context() == browser_context) | 578 if (!browser_context || host->browser_context() == browser_context) |
| 578 host->Send(new ViewMsg_PurgePluginListCache(reload_pages)); | 579 host->Send(new ViewMsg_PurgePluginListCache(reload_pages)); |
| 579 } | 580 } |
| 580 } | 581 } |
| 581 | 582 |
| 582 void PluginService::RegisterPepperPlugins() { | 583 void PluginService::RegisterPepperPlugins() { |
| 583 // TODO(abarth): It seems like the PepperPluginRegistry should do this work. | 584 // TODO(abarth): It seems like the PepperPluginRegistry should do this work. |
| 584 PepperPluginRegistry::ComputeList(&ppapi_plugins_); | 585 PepperPluginRegistry::ComputeList(&ppapi_plugins_); |
| 585 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) { | 586 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) { |
| 586 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin( | 587 plugin_list_->RegisterInternalPlugin(ppapi_plugins_[i].ToWebPluginInfo()); |
| 587 ppapi_plugins_[i].ToWebPluginInfo()); | |
| 588 } | 588 } |
| 589 } | 589 } |
| 590 | 590 |
| 591 // There should generally be very few plugins so a brute-force search is fine. | 591 // There should generally be very few plugins so a brute-force search is fine. |
| 592 content::PepperPluginInfo* PluginService::GetRegisteredPpapiPluginInfo( | 592 content::PepperPluginInfo* PluginService::GetRegisteredPpapiPluginInfo( |
| 593 const FilePath& plugin_path) { | 593 const FilePath& plugin_path) { |
| 594 content::PepperPluginInfo* info = NULL; | 594 content::PepperPluginInfo* info = NULL; |
| 595 for (size_t i = 0; i < ppapi_plugins_.size(); i++) { | 595 for (size_t i = 0; i < ppapi_plugins_.size(); i++) { |
| 596 if (ppapi_plugins_[i].path == plugin_path) { | 596 if (ppapi_plugins_[i].path == plugin_path) { |
| 597 info = &ppapi_plugins_[i]; | 597 info = &ppapi_plugins_[i]; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 618 #if defined(OS_POSIX) && !defined(OS_MACOSX) | 618 #if defined(OS_POSIX) && !defined(OS_MACOSX) |
| 619 // static | 619 // static |
| 620 void PluginService::RegisterFilePathWatcher( | 620 void PluginService::RegisterFilePathWatcher( |
| 621 FilePathWatcher *watcher, | 621 FilePathWatcher *watcher, |
| 622 const FilePath& path, | 622 const FilePath& path, |
| 623 FilePathWatcher::Delegate* delegate) { | 623 FilePathWatcher::Delegate* delegate) { |
| 624 bool result = watcher->Watch(path, delegate); | 624 bool result = watcher->Watch(path, delegate); |
| 625 DCHECK(result); | 625 DCHECK(result); |
| 626 } | 626 } |
| 627 #endif | 627 #endif |
| OLD | NEW |