| 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/browser/plugin_service_impl.h" | 5 #include "content/browser/plugin_service_impl.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 26 matching lines...) Expand all Loading... |
| 37 #endif | 37 #endif |
| 38 | 38 |
| 39 #if defined(OS_POSIX) | 39 #if defined(OS_POSIX) |
| 40 #include "content/browser/plugin_loader_posix.h" | 40 #include "content/browser/plugin_loader_posix.h" |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 #if defined(OS_POSIX) && !defined(OS_OPENBSD) | 43 #if defined(OS_POSIX) && !defined(OS_OPENBSD) |
| 44 using ::base::files::FilePathWatcher; | 44 using ::base::files::FilePathWatcher; |
| 45 #endif | 45 #endif |
| 46 | 46 |
| 47 using content::BrowserThread; | 47 namespace content { |
| 48 using content::PepperPluginRegistry; | |
| 49 using content::PluginService; | |
| 50 using content::PluginServiceFilter; | |
| 51 | |
| 52 namespace { | 48 namespace { |
| 53 | 49 |
| 54 // Callback set on the PluginList to assert that plugin loading happens on the | 50 // Callback set on the PluginList to assert that plugin loading happens on the |
| 55 // correct thread. | 51 // correct thread. |
| 56 #if defined(OS_WIN) | 52 #if defined(OS_WIN) |
| 57 void WillLoadPluginsCallbackWin( | 53 void WillLoadPluginsCallbackWin( |
| 58 base::SequencedWorkerPool::SequenceToken token) { | 54 base::SequencedWorkerPool::SequenceToken token) { |
| 59 CHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( | 55 CHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( |
| 60 token)); | 56 token)); |
| 61 } | 57 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 77 #endif | 73 #endif |
| 78 #if defined(OS_POSIX) && !defined(OS_OPENBSD) | 74 #if defined(OS_POSIX) && !defined(OS_OPENBSD) |
| 79 // Delegate class for monitoring directories. | 75 // Delegate class for monitoring directories. |
| 80 class PluginDirWatcherDelegate : public FilePathWatcher::Delegate { | 76 class PluginDirWatcherDelegate : public FilePathWatcher::Delegate { |
| 81 virtual void OnFilePathChanged(const FilePath& path) OVERRIDE { | 77 virtual void OnFilePathChanged(const FilePath& path) OVERRIDE { |
| 82 VLOG(1) << "Watched path changed: " << path.value(); | 78 VLOG(1) << "Watched path changed: " << path.value(); |
| 83 // Make the plugin list update itself | 79 // Make the plugin list update itself |
| 84 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); | 80 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); |
| 85 BrowserThread::PostTask( | 81 BrowserThread::PostTask( |
| 86 BrowserThread::UI, FROM_HERE, | 82 BrowserThread::UI, FROM_HERE, |
| 87 base::Bind(&content::PluginService::PurgePluginListCache, | 83 base::Bind(&PluginService::PurgePluginListCache, |
| 88 static_cast<content::BrowserContext*>(NULL), false)); | 84 static_cast<BrowserContext*>(NULL), false)); |
| 89 } | 85 } |
| 90 | 86 |
| 91 virtual void OnFilePathError(const FilePath& path) OVERRIDE { | 87 virtual void OnFilePathError(const FilePath& path) OVERRIDE { |
| 92 // TODO(pastarmovj): Add some sensible error handling. Maybe silently | 88 // TODO(pastarmovj): Add some sensible error handling. Maybe silently |
| 93 // stopping the watcher would be enough. Or possibly restart it. | 89 // stopping the watcher would be enough. Or possibly restart it. |
| 94 NOTREACHED(); | 90 NOTREACHED(); |
| 95 } | 91 } |
| 96 | 92 |
| 97 protected: | 93 protected: |
| 98 virtual ~PluginDirWatcherDelegate() {} | 94 virtual ~PluginDirWatcherDelegate() {} |
| 99 }; | 95 }; |
| 100 #endif | 96 #endif |
| 101 | 97 |
| 102 namespace content { | |
| 103 // static | 98 // static |
| 104 PluginService* PluginService::GetInstance() { | 99 PluginService* PluginService::GetInstance() { |
| 105 return PluginServiceImpl::GetInstance(); | 100 return PluginServiceImpl::GetInstance(); |
| 106 } | 101 } |
| 107 | 102 |
| 108 void PluginService::PurgePluginListCache(BrowserContext* browser_context, | 103 void PluginService::PurgePluginListCache(BrowserContext* browser_context, |
| 109 bool reload_pages) { | 104 bool reload_pages) { |
| 110 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator(); | 105 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator(); |
| 111 !it.IsAtEnd(); it.Advance()) { | 106 !it.IsAtEnd(); it.Advance()) { |
| 112 RenderProcessHost* host = it.GetCurrentValue(); | 107 RenderProcessHost* host = it.GetCurrentValue(); |
| 113 if (!browser_context || host->GetBrowserContext() == browser_context) | 108 if (!browser_context || host->GetBrowserContext() == browser_context) |
| 114 host->Send(new ViewMsg_PurgePluginListCache(reload_pages)); | 109 host->Send(new ViewMsg_PurgePluginListCache(reload_pages)); |
| 115 } | 110 } |
| 116 } | 111 } |
| 117 | 112 |
| 118 } // namespace content | |
| 119 | |
| 120 // static | 113 // static |
| 121 PluginServiceImpl* PluginServiceImpl::GetInstance() { | 114 PluginServiceImpl* PluginServiceImpl::GetInstance() { |
| 122 return Singleton<PluginServiceImpl>::get(); | 115 return Singleton<PluginServiceImpl>::get(); |
| 123 } | 116 } |
| 124 | 117 |
| 125 PluginServiceImpl::PluginServiceImpl() | 118 PluginServiceImpl::PluginServiceImpl() |
| 126 : plugin_list_(NULL), filter_(NULL) { | 119 : plugin_list_(NULL), filter_(NULL) { |
| 127 } | 120 } |
| 128 | 121 |
| 129 PluginServiceImpl::~PluginServiceImpl() { | 122 PluginServiceImpl::~PluginServiceImpl() { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 148 plugin_list_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken(); | 141 plugin_list_token_ = BrowserThread::GetBlockingPool()->GetSequenceToken(); |
| 149 plugin_list_->set_will_load_plugins_callback( | 142 plugin_list_->set_will_load_plugins_callback( |
| 150 base::Bind(&WillLoadPluginsCallbackWin, plugin_list_token_)); | 143 base::Bind(&WillLoadPluginsCallbackWin, plugin_list_token_)); |
| 151 #else | 144 #else |
| 152 plugin_list_->set_will_load_plugins_callback( | 145 plugin_list_->set_will_load_plugins_callback( |
| 153 base::Bind(&WillLoadPluginsCallbackPosix)); | 146 base::Bind(&WillLoadPluginsCallbackPosix)); |
| 154 #endif | 147 #endif |
| 155 | 148 |
| 156 RegisterPepperPlugins(); | 149 RegisterPepperPlugins(); |
| 157 | 150 |
| 158 content::GetContentClient()->AddNPAPIPlugins(plugin_list_); | 151 GetContentClient()->AddNPAPIPlugins(plugin_list_); |
| 159 | 152 |
| 160 // Load any specified on the command line as well. | 153 // Load any specified on the command line as well. |
| 161 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 154 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 162 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin); | 155 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin); |
| 163 if (!path.empty()) | 156 if (!path.empty()) |
| 164 AddExtraPluginPath(path); | 157 AddExtraPluginPath(path); |
| 165 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir); | 158 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir); |
| 166 if (!path.empty()) | 159 if (!path.empty()) |
| 167 plugin_list_->AddExtraPluginDir(path); | 160 plugin_list_->AddExtraPluginDir(path); |
| 168 } | 161 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 const FilePath& profile_data_directory, | 269 const FilePath& profile_data_directory, |
| 277 PpapiPluginProcessHost::PluginClient* client) { | 270 PpapiPluginProcessHost::PluginClient* client) { |
| 278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 279 | 272 |
| 280 PpapiPluginProcessHost* plugin_host = | 273 PpapiPluginProcessHost* plugin_host = |
| 281 FindPpapiPluginProcess(plugin_path, profile_data_directory); | 274 FindPpapiPluginProcess(plugin_path, profile_data_directory); |
| 282 if (plugin_host) | 275 if (plugin_host) |
| 283 return plugin_host; | 276 return plugin_host; |
| 284 | 277 |
| 285 // Validate that the plugin is actually registered. | 278 // Validate that the plugin is actually registered. |
| 286 content::PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); | 279 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); |
| 287 if (!info) | 280 if (!info) |
| 288 return NULL; | 281 return NULL; |
| 289 | 282 |
| 290 // This plugin isn't loaded by any plugin process, so create a new process. | 283 // This plugin isn't loaded by any plugin process, so create a new process. |
| 291 return PpapiPluginProcessHost::CreatePluginHost( | 284 return PpapiPluginProcessHost::CreatePluginHost( |
| 292 *info, profile_data_directory, | 285 *info, profile_data_directory, |
| 293 client->GetResourceContext()->GetHostResolver()); | 286 client->GetResourceContext()->GetHostResolver()); |
| 294 } | 287 } |
| 295 | 288 |
| 296 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( | 289 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( |
| 297 const FilePath& plugin_path) { | 290 const FilePath& plugin_path) { |
| 298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 291 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 299 | 292 |
| 300 PpapiPluginProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path); | 293 PpapiPluginProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path); |
| 301 if (plugin_host) | 294 if (plugin_host) |
| 302 return plugin_host; | 295 return plugin_host; |
| 303 | 296 |
| 304 // Validate that the plugin is actually registered. | 297 // Validate that the plugin is actually registered. |
| 305 content::PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); | 298 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); |
| 306 if (!info) | 299 if (!info) |
| 307 return NULL; | 300 return NULL; |
| 308 | 301 |
| 309 // TODO(ddorwin): Uncomment once out of process is supported. | 302 // TODO(ddorwin): Uncomment once out of process is supported. |
| 310 // DCHECK(info->is_out_of_process); | 303 // DCHECK(info->is_out_of_process); |
| 311 | 304 |
| 312 // This broker isn't loaded by any broker process, so create a new process. | 305 // This broker isn't loaded by any broker process, so create a new process. |
| 313 return PpapiPluginProcessHost::CreateBrokerHost(*info); | 306 return PpapiPluginProcessHost::CreateBrokerHost(*info); |
| 314 } | 307 } |
| 315 | 308 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 params.resource_context); | 373 params.resource_context); |
| 381 } | 374 } |
| 382 | 375 |
| 383 void PluginServiceImpl::GetAllowedPluginForOpenChannelToPlugin( | 376 void PluginServiceImpl::GetAllowedPluginForOpenChannelToPlugin( |
| 384 int render_process_id, | 377 int render_process_id, |
| 385 int render_view_id, | 378 int render_view_id, |
| 386 const GURL& url, | 379 const GURL& url, |
| 387 const GURL& page_url, | 380 const GURL& page_url, |
| 388 const std::string& mime_type, | 381 const std::string& mime_type, |
| 389 PluginProcessHost::Client* client, | 382 PluginProcessHost::Client* client, |
| 390 content::ResourceContext* resource_context) { | 383 ResourceContext* resource_context) { |
| 391 webkit::WebPluginInfo info; | 384 webkit::WebPluginInfo info; |
| 392 bool allow_wildcard = true; | 385 bool allow_wildcard = true; |
| 393 bool found = GetPluginInfo( | 386 bool found = GetPluginInfo( |
| 394 render_process_id, render_view_id, resource_context, | 387 render_process_id, render_view_id, resource_context, |
| 395 url, page_url, mime_type, allow_wildcard, | 388 url, page_url, mime_type, allow_wildcard, |
| 396 NULL, &info, NULL); | 389 NULL, &info, NULL); |
| 397 FilePath plugin_path; | 390 FilePath plugin_path; |
| 398 if (found) | 391 if (found) |
| 399 plugin_path = info.path; | 392 plugin_path = info.path; |
| 400 | 393 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 431 std::vector<webkit::WebPluginInfo>* plugins, | 424 std::vector<webkit::WebPluginInfo>* plugins, |
| 432 std::vector<std::string>* actual_mime_types) { | 425 std::vector<std::string>* actual_mime_types) { |
| 433 bool use_stale = false; | 426 bool use_stale = false; |
| 434 plugin_list_->GetPluginInfoArray(url, mime_type, allow_wildcard, | 427 plugin_list_->GetPluginInfoArray(url, mime_type, allow_wildcard, |
| 435 &use_stale, plugins, actual_mime_types); | 428 &use_stale, plugins, actual_mime_types); |
| 436 return use_stale; | 429 return use_stale; |
| 437 } | 430 } |
| 438 | 431 |
| 439 bool PluginServiceImpl::GetPluginInfo(int render_process_id, | 432 bool PluginServiceImpl::GetPluginInfo(int render_process_id, |
| 440 int render_view_id, | 433 int render_view_id, |
| 441 content::ResourceContext* context, | 434 ResourceContext* context, |
| 442 const GURL& url, | 435 const GURL& url, |
| 443 const GURL& page_url, | 436 const GURL& page_url, |
| 444 const std::string& mime_type, | 437 const std::string& mime_type, |
| 445 bool allow_wildcard, | 438 bool allow_wildcard, |
| 446 bool* is_stale, | 439 bool* is_stale, |
| 447 webkit::WebPluginInfo* info, | 440 webkit::WebPluginInfo* info, |
| 448 std::string* actual_mime_type) { | 441 std::string* actual_mime_type) { |
| 449 std::vector<webkit::WebPluginInfo> plugins; | 442 std::vector<webkit::WebPluginInfo> plugins; |
| 450 std::vector<std::string> mime_types; | 443 std::vector<std::string> mime_types; |
| 451 bool stale = GetPluginInfoArray( | 444 bool stale = GetPluginInfoArray( |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 | 561 |
| 569 void PluginServiceImpl::RegisterPepperPlugins() { | 562 void PluginServiceImpl::RegisterPepperPlugins() { |
| 570 // TODO(abarth): It seems like the PepperPluginRegistry should do this work. | 563 // TODO(abarth): It seems like the PepperPluginRegistry should do this work. |
| 571 PepperPluginRegistry::ComputeList(&ppapi_plugins_); | 564 PepperPluginRegistry::ComputeList(&ppapi_plugins_); |
| 572 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) { | 565 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) { |
| 573 RegisterInternalPlugin(ppapi_plugins_[i].ToWebPluginInfo(), true); | 566 RegisterInternalPlugin(ppapi_plugins_[i].ToWebPluginInfo(), true); |
| 574 } | 567 } |
| 575 } | 568 } |
| 576 | 569 |
| 577 // There should generally be very few plugins so a brute-force search is fine. | 570 // There should generally be very few plugins so a brute-force search is fine. |
| 578 content::PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo( | 571 PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo( |
| 579 const FilePath& plugin_path) { | 572 const FilePath& plugin_path) { |
| 580 content::PepperPluginInfo* info = NULL; | 573 PepperPluginInfo* info = NULL; |
| 581 for (size_t i = 0; i < ppapi_plugins_.size(); i++) { | 574 for (size_t i = 0; i < ppapi_plugins_.size(); i++) { |
| 582 if (ppapi_plugins_[i].path == plugin_path) { | 575 if (ppapi_plugins_[i].path == plugin_path) { |
| 583 info = &ppapi_plugins_[i]; | 576 info = &ppapi_plugins_[i]; |
| 584 break; | 577 break; |
| 585 } | 578 } |
| 586 } | 579 } |
| 587 if (info) | 580 if (info) |
| 588 return info; | 581 return info; |
| 589 // We did not find the plugin in our list. But wait! the plugin can also | 582 // We did not find the plugin in our list. But wait! the plugin can also |
| 590 // be a latecomer, as it happens with pepper flash. This information | 583 // be a latecomer, as it happens with pepper flash. This information |
| 591 // can be obtained from the PluginList singleton and we can use it to | 584 // can be obtained from the PluginList singleton and we can use it to |
| 592 // construct it and add it to the list. This same deal needs to be done | 585 // construct it and add it to the list. This same deal needs to be done |
| 593 // in the renderer side in PepperPluginRegistry. | 586 // in the renderer side in PepperPluginRegistry. |
| 594 webkit::WebPluginInfo webplugin_info; | 587 webkit::WebPluginInfo webplugin_info; |
| 595 if (!GetPluginInfoByPath(plugin_path, &webplugin_info)) | 588 if (!GetPluginInfoByPath(plugin_path, &webplugin_info)) |
| 596 return NULL; | 589 return NULL; |
| 597 content::PepperPluginInfo new_pepper_info; | 590 PepperPluginInfo new_pepper_info; |
| 598 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info)) | 591 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info)) |
| 599 return NULL; | 592 return NULL; |
| 600 ppapi_plugins_.push_back(new_pepper_info); | 593 ppapi_plugins_.push_back(new_pepper_info); |
| 601 return &ppapi_plugins_[ppapi_plugins_.size() - 1]; | 594 return &ppapi_plugins_[ppapi_plugins_.size() - 1]; |
| 602 } | 595 } |
| 603 | 596 |
| 604 #if defined(OS_POSIX) && !defined(OS_OPENBSD) | 597 #if defined(OS_POSIX) && !defined(OS_OPENBSD) |
| 605 // static | 598 // static |
| 606 void PluginServiceImpl::RegisterFilePathWatcher( | 599 void PluginServiceImpl::RegisterFilePathWatcher( |
| 607 FilePathWatcher* watcher, | 600 FilePathWatcher* watcher, |
| 608 const FilePath& path, | 601 const FilePath& path, |
| 609 FilePathWatcher::Delegate* delegate) { | 602 FilePathWatcher::Delegate* delegate) { |
| 610 bool result = watcher->Watch(path, delegate); | 603 bool result = watcher->Watch(path, delegate); |
| 611 DCHECK(result); | 604 DCHECK(result); |
| 612 } | 605 } |
| 613 #endif | 606 #endif |
| 614 | 607 |
| 615 void PluginServiceImpl::SetFilter(content::PluginServiceFilter* filter) { | 608 void PluginServiceImpl::SetFilter(PluginServiceFilter* filter) { |
| 616 filter_ = filter; | 609 filter_ = filter; |
| 617 } | 610 } |
| 618 | 611 |
| 619 content::PluginServiceFilter* PluginServiceImpl::GetFilter() { | 612 PluginServiceFilter* PluginServiceImpl::GetFilter() { |
| 620 return filter_; | 613 return filter_; |
| 621 } | 614 } |
| 622 | 615 |
| 623 void PluginServiceImpl::ForcePluginShutdown(const FilePath& plugin_path) { | 616 void PluginServiceImpl::ForcePluginShutdown(const FilePath& plugin_path) { |
| 624 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 617 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 625 BrowserThread::PostTask( | 618 BrowserThread::PostTask( |
| 626 BrowserThread::IO, FROM_HERE, | 619 BrowserThread::IO, FROM_HERE, |
| 627 base::Bind(&PluginServiceImpl::ForcePluginShutdown, | 620 base::Bind(&PluginServiceImpl::ForcePluginShutdown, |
| 628 base::Unretained(this), plugin_path)); | 621 base::Unretained(this), plugin_path)); |
| 629 return; | 622 return; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 } | 701 } |
| 709 | 702 |
| 710 void PluginServiceImpl::GetInternalPlugins( | 703 void PluginServiceImpl::GetInternalPlugins( |
| 711 std::vector<webkit::WebPluginInfo>* plugins) { | 704 std::vector<webkit::WebPluginInfo>* plugins) { |
| 712 plugin_list_->GetInternalPlugins(plugins); | 705 plugin_list_->GetInternalPlugins(plugins); |
| 713 } | 706 } |
| 714 | 707 |
| 715 webkit::npapi::PluginList* PluginServiceImpl::GetPluginList() { | 708 webkit::npapi::PluginList* PluginServiceImpl::GetPluginList() { |
| 716 return plugin_list_; | 709 return plugin_list_; |
| 717 } | 710 } |
| 711 |
| 712 } // namespace content |
| OLD | NEW |