Index: content/browser/plugin_service_impl.cc |
diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc |
index a5cb57737d5022949412acbf06dbc5e0d7a8f846..c81e19b6b234a1fcf979d52c6bd2d6a2d8e8fd8c 100644 |
--- a/content/browser/plugin_service_impl.cc |
+++ b/content/browser/plugin_service_impl.cc |
@@ -34,107 +34,26 @@ |
#include "content/public/common/process_type.h" |
#include "content/public/common/webplugininfo.h" |
-#if defined(OS_WIN) |
-#include "content/common/plugin_constants_win.h" |
-#include "ui/gfx/win/hwnd_util.h" |
-#endif |
- |
-#if defined(OS_POSIX) |
-#include "content/browser/plugin_loader_posix.h" |
-#endif |
- |
-#if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
-using ::base::FilePathWatcher; |
-#endif |
- |
namespace content { |
namespace { |
// This enum is used to collect Flash usage data. |
enum FlashUsage { |
- // Number of browser processes that have started at least one NPAPI Flash |
- // process during their lifetime. |
- START_NPAPI_FLASH_AT_LEAST_ONCE, |
// Number of browser processes that have started at least one PPAPI Flash |
// process during their lifetime. |
- START_PPAPI_FLASH_AT_LEAST_ONCE, |
+ START_PPAPI_FLASH_AT_LEAST_ONCE = 1, |
// Total number of browser processes. |
TOTAL_BROWSER_PROCESSES, |
FLASH_USAGE_ENUM_COUNT |
}; |
-enum NPAPIPluginStatus { |
- // Platform does not support NPAPI. |
- NPAPI_STATUS_UNSUPPORTED, |
- // Platform supports NPAPI and NPAPI is disabled. |
- NPAPI_STATUS_DISABLED, |
- // Platform supports NPAPI and NPAPI is enabled. |
- NPAPI_STATUS_ENABLED, |
- NPAPI_STATUS_ENUM_COUNT |
-}; |
- |
-bool LoadPluginListInProcess() { |
-#if defined(OS_WIN) |
- return true; |
-#else |
- // If on POSIX, we don't want to load the list of NPAPI plugins in-process as |
- // that causes instability. |
- |
- // Can't load the plugins on the utility thread when in single process mode |
- // since that requires GTK which can only be used on the main thread. |
- if (RenderProcessHost::run_renderer_in_process()) |
- return true; |
- |
- return !PluginService::GetInstance()->NPAPIPluginsSupported(); |
-#endif |
-} |
- |
// Callback set on the PluginList to assert that plugin loading happens on the |
// correct thread. |
void WillLoadPluginsCallback( |
base::SequencedWorkerPool::SequenceToken token) { |
- if (LoadPluginListInProcess()) { |
- CHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( |
- token)); |
- } else { |
- CHECK(false) << "Plugin loading should happen out-of-process."; |
- } |
-} |
- |
-#if defined(OS_MACOSX) |
-void NotifyPluginsOfActivation() { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- |
- for (PluginProcessHostIterator iter; !iter.Done(); ++iter) |
- iter->OnAppActivation(); |
-} |
-#endif |
- |
-#if defined(OS_POSIX) |
-#if !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
-void NotifyPluginDirChanged(const base::FilePath& path, bool error) { |
- if (error) { |
- // TODO(pastarmovj): Add some sensible error handling. Maybe silently |
- // stopping the watcher would be enough. Or possibly restart it. |
- NOTREACHED(); |
- return; |
- } |
- VLOG(1) << "Watched path changed: " << path.value(); |
- // Make the plugin list update itself |
- PluginList::Singleton()->RefreshPlugins(); |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&PluginService::PurgePluginListCache, |
- static_cast<BrowserContext*>(NULL), false)); |
+ CHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( |
+ token)); |
} |
-#endif // !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
- |
-void ForwardCallback(base::SingleThreadTaskRunner* target_task_runner, |
- const PluginService::GetPluginsCallback& callback, |
- const std::vector<WebPluginInfo>& plugins) { |
- target_task_runner->PostTask(FROM_HERE, base::Bind(callback, plugins)); |
-} |
-#endif // defined(OS_POSIX) |
} // namespace |
@@ -159,7 +78,7 @@ PluginServiceImpl* PluginServiceImpl::GetInstance() { |
} |
PluginServiceImpl::PluginServiceImpl() |
- : npapi_plugins_enabled_(false), filter_(NULL) { |
+ : filter_(NULL) { |
// Collect the total number of browser processes (which create |
// PluginServiceImpl objects, to be precise). The number is used to normalize |
// the number of processes which start at least one NPAPI/PPAPI Flash process. |
@@ -172,8 +91,6 @@ PluginServiceImpl::PluginServiceImpl() |
} |
PluginServiceImpl::~PluginServiceImpl() { |
- // Make sure no plugin channel requests have been leaked. |
- DCHECK(pending_plugin_clients_.empty()); |
} |
void PluginServiceImpl::Init() { |
@@ -182,80 +99,6 @@ void PluginServiceImpl::Init() { |
base::Bind(&WillLoadPluginsCallback, plugin_list_token_)); |
RegisterPepperPlugins(); |
- |
- // Load any specified on the command line as well. |
- const base::CommandLine* command_line = |
- base::CommandLine::ForCurrentProcess(); |
- base::FilePath path = |
- command_line->GetSwitchValuePath(switches::kLoadPlugin); |
- if (!path.empty()) |
- AddExtraPluginPath(path); |
- path = command_line->GetSwitchValuePath(switches::kExtraPluginDir); |
- if (!path.empty()) |
- PluginList::Singleton()->AddExtraPluginDir(path); |
- |
- if (command_line->HasSwitch(switches::kDisablePluginsDiscovery)) |
- PluginList::Singleton()->DisablePluginsDiscovery(); |
-} |
- |
-void PluginServiceImpl::StartWatchingPlugins() { |
- // Start watching for changes in the plugin list. This means watching |
- // for changes in the Windows registry keys and on both Windows and POSIX |
- // watch for changes in the paths that are expected to contain plugins. |
-#if defined(OS_WIN) |
- if (hkcu_key_.Create(HKEY_CURRENT_USER, |
- kRegistryMozillaPlugins, |
- KEY_NOTIFY) == ERROR_SUCCESS) { |
- base::win::RegKey::ChangeCallback callback = |
- base::Bind(&PluginServiceImpl::OnKeyChanged, base::Unretained(this), |
- base::Unretained(&hkcu_key_)); |
- hkcu_key_.StartWatching(callback); |
- } |
- if (hklm_key_.Create(HKEY_LOCAL_MACHINE, |
- kRegistryMozillaPlugins, |
- KEY_NOTIFY) == ERROR_SUCCESS) { |
- base::win::RegKey::ChangeCallback callback = |
- base::Bind(&PluginServiceImpl::OnKeyChanged, base::Unretained(this), |
- base::Unretained(&hklm_key_)); |
- hklm_key_.StartWatching(callback); |
- } |
-#endif |
-#if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
-// On ChromeOS the user can't install plugins anyway and on Windows all |
-// important plugins register themselves in the registry so no need to do that. |
- |
- // Get the list of all paths for registering the FilePathWatchers |
- // that will track and if needed reload the list of plugins on runtime. |
- std::vector<base::FilePath> plugin_dirs; |
- PluginList::Singleton()->GetPluginDirectories(&plugin_dirs); |
- |
- for (size_t i = 0; i < plugin_dirs.size(); ++i) { |
- // FilePathWatcher can not handle non-absolute paths under windows. |
- // We don't watch for file changes in windows now but if this should ever |
- // be extended to Windows these lines might save some time of debugging. |
-#if defined(OS_WIN) |
- if (!plugin_dirs[i].IsAbsolute()) |
- continue; |
-#endif |
- FilePathWatcher* watcher = new FilePathWatcher(); |
- VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value(); |
- BrowserThread::PostTask( |
- BrowserThread::FILE, FROM_HERE, |
- base::Bind(&PluginServiceImpl::RegisterFilePathWatcher, watcher, |
- plugin_dirs[i])); |
- file_watchers_.push_back(watcher); |
- } |
-#endif |
-} |
- |
-PluginProcessHost* PluginServiceImpl::FindNpapiPluginProcess( |
- const base::FilePath& plugin_path) { |
- for (PluginProcessHostIterator iter; !iter.Done(); ++iter) { |
- if (iter->info().path == plugin_path) |
- return *iter; |
- } |
- |
- return NULL; |
} |
PpapiPluginProcessHost* PluginServiceImpl::FindPpapiPluginProcess( |
@@ -280,46 +123,6 @@ PpapiPluginProcessHost* PluginServiceImpl::FindPpapiBrokerProcess( |
return NULL; |
} |
-PluginProcessHost* PluginServiceImpl::FindOrStartNpapiPluginProcess( |
- int render_process_id, |
- const base::FilePath& plugin_path) { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- |
- if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) |
- return NULL; |
- |
- PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); |
- if (plugin_host) |
- return plugin_host; |
- |
- WebPluginInfo info; |
- if (!GetPluginInfoByPath(plugin_path, &info)) { |
- return NULL; |
- } |
- |
- // Record when NPAPI Flash process is started for the first time. |
- static bool counted = false; |
- if (!counted && base::UTF16ToUTF8(info.name) == kFlashPluginName) { |
- counted = true; |
- UMA_HISTOGRAM_ENUMERATION("Plugin.FlashUsage", |
- START_NPAPI_FLASH_AT_LEAST_ONCE, |
- FLASH_USAGE_ENUM_COUNT); |
- } |
-#if defined(OS_CHROMEOS) |
- // TODO(ihf): Move to an earlier place once crbug.com/314301 is fixed. For now |
- // we still want Plugin.FlashUsage recorded if we end up here. |
- LOG(WARNING) << "Refusing to start npapi plugin on ChromeOS."; |
- return NULL; |
-#endif |
- // This plugin isn't loaded by any plugin process, so create a new process. |
- scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); |
- if (!new_host->Init(info)) { |
- NOTREACHED(); // Init is not expected to fail. |
- return NULL; |
- } |
- return new_host.release(); |
-} |
- |
PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess( |
int render_process_id, |
const base::FilePath& plugin_path, |
@@ -388,29 +191,6 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( |
return PpapiPluginProcessHost::CreateBrokerHost(*info); |
} |
-void PluginServiceImpl::OpenChannelToNpapiPlugin( |
- int render_process_id, |
- int render_frame_id, |
- const GURL& url, |
- const GURL& page_url, |
- const std::string& mime_type, |
- PluginProcessHost::Client* client) { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- DCHECK(!ContainsKey(pending_plugin_clients_, client)); |
- pending_plugin_clients_.insert(client); |
- |
- // Make sure plugins are loaded if necessary. |
- PluginServiceFilterParams params = { |
- render_process_id, |
- render_frame_id, |
- page_url, |
- client->GetResourceContext() |
- }; |
- GetPlugins(base::Bind( |
- &PluginServiceImpl::ForwardGetAllowedPluginForOpenChannelToPlugin, |
- base::Unretained(this), params, url, mime_type, client)); |
-} |
- |
void PluginServiceImpl::OpenChannelToPpapiPlugin( |
int render_process_id, |
const base::FilePath& plugin_path, |
@@ -440,78 +220,6 @@ void PluginServiceImpl::OpenChannelToPpapiBroker( |
} |
} |
-void PluginServiceImpl::CancelOpenChannelToNpapiPlugin( |
- PluginProcessHost::Client* client) { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- DCHECK(ContainsKey(pending_plugin_clients_, client)); |
- pending_plugin_clients_.erase(client); |
-} |
- |
-void PluginServiceImpl::ForwardGetAllowedPluginForOpenChannelToPlugin( |
- const PluginServiceFilterParams& params, |
- const GURL& url, |
- const std::string& mime_type, |
- PluginProcessHost::Client* client, |
- const std::vector<WebPluginInfo>&) { |
- GetAllowedPluginForOpenChannelToPlugin( |
- params.render_process_id, params.render_frame_id, url, params.page_url, |
- mime_type, client, params.resource_context); |
-} |
- |
-void PluginServiceImpl::GetAllowedPluginForOpenChannelToPlugin( |
- int render_process_id, |
- int render_frame_id, |
- const GURL& url, |
- const GURL& page_url, |
- const std::string& mime_type, |
- PluginProcessHost::Client* client, |
- ResourceContext* resource_context) { |
- WebPluginInfo info; |
- bool allow_wildcard = true; |
- bool found = GetPluginInfo( |
- render_process_id, render_frame_id, resource_context, |
- url, page_url, mime_type, allow_wildcard, |
- NULL, &info, NULL); |
- base::FilePath plugin_path; |
- if (found) |
- plugin_path = info.path; |
- |
- // Now we jump back to the IO thread to finish opening the channel. |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::Bind(&PluginServiceImpl::FinishOpenChannelToPlugin, |
- base::Unretained(this), |
- render_process_id, |
- plugin_path, |
- client)); |
- if (filter_) { |
- DCHECK_EQ(WebPluginInfo::PLUGIN_TYPE_NPAPI, info.type); |
- filter_->NPAPIPluginLoaded(render_process_id, render_frame_id, mime_type, |
- info); |
- } |
-} |
- |
-void PluginServiceImpl::FinishOpenChannelToPlugin( |
- int render_process_id, |
- const base::FilePath& plugin_path, |
- PluginProcessHost::Client* client) { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- |
- // Make sure it hasn't been canceled yet. |
- if (!ContainsKey(pending_plugin_clients_, client)) |
- return; |
- pending_plugin_clients_.erase(client); |
- |
- PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess( |
- render_process_id, plugin_path); |
- if (plugin_host) { |
- client->OnFoundPluginProcessHost(plugin_host); |
- plugin_host->OpenChannelToPlugin(client); |
- } else { |
- client->OnError(); |
- } |
-} |
- |
bool PluginServiceImpl::GetPluginInfoArray( |
const GURL& url, |
const std::string& mime_type, |
@@ -520,8 +228,7 @@ bool PluginServiceImpl::GetPluginInfoArray( |
std::vector<std::string>* actual_mime_types) { |
bool use_stale = false; |
PluginList::Singleton()->GetPluginInfoArray( |
- url, mime_type, allow_wildcard, &use_stale, NPAPIPluginsSupported(), |
- plugins, actual_mime_types); |
+ url, mime_type, allow_wildcard, &use_stale, plugins, actual_mime_types); |
return use_stale; |
} |
@@ -598,25 +305,11 @@ void PluginServiceImpl::GetPlugins(const GetPluginsCallback& callback) { |
scoped_refptr<base::SingleThreadTaskRunner> target_task_runner( |
base::ThreadTaskRunnerHandle::Get()); |
- if (LoadPluginListInProcess()) { |
- BrowserThread::GetBlockingPool() |
- ->PostSequencedWorkerTaskWithShutdownBehavior( |
- plugin_list_token_, FROM_HERE, |
- base::Bind(&PluginServiceImpl::GetPluginsInternal, |
- base::Unretained(this), |
- base::RetainedRef(target_task_runner), callback), |
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
- return; |
- } |
-#if defined(OS_POSIX) |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::Bind(&PluginServiceImpl::GetPluginsOnIOThread, |
- base::Unretained(this), base::RetainedRef(target_task_runner), |
- callback)); |
-#else |
- NOTREACHED(); |
-#endif |
+ BrowserThread::GetBlockingPool()->PostSequencedWorkerTaskWithShutdownBehavior( |
+ plugin_list_token_, FROM_HERE, |
+ base::Bind(&PluginServiceImpl::GetPluginsInternal, base::Unretained(this), |
+ base::RetainedRef(target_task_runner), callback), |
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
} |
void PluginServiceImpl::GetPluginsInternal( |
@@ -626,39 +319,11 @@ void PluginServiceImpl::GetPluginsInternal( |
plugin_list_token_)); |
std::vector<WebPluginInfo> plugins; |
- PluginList::Singleton()->GetPlugins(&plugins, NPAPIPluginsSupported()); |
+ PluginList::Singleton()->GetPlugins(&plugins); |
target_task_runner->PostTask(FROM_HERE, base::Bind(callback, plugins)); |
} |
-#if defined(OS_POSIX) |
-void PluginServiceImpl::GetPluginsOnIOThread( |
- base::SingleThreadTaskRunner* target_task_runner, |
- const GetPluginsCallback& callback) { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- |
- // If we switch back to loading plugins in process, then we need to make |
- // sure g_thread_init() gets called since plugins may call glib at load. |
- |
- if (!plugin_loader_.get()) |
- plugin_loader_ = new PluginLoaderPosix; |
- |
- plugin_loader_->GetPlugins(base::Bind( |
- &ForwardCallback, base::RetainedRef(target_task_runner), callback)); |
-} |
-#endif |
- |
-#if defined(OS_WIN) |
-void PluginServiceImpl::OnKeyChanged(base::win::RegKey* key) { |
- key->StartWatching(base::Bind(&PluginServiceImpl::OnKeyChanged, |
- base::Unretained(this), |
- base::Unretained(key))); |
- |
- PluginList::Singleton()->RefreshPlugins(); |
- PurgePluginListCache(NULL, false); |
-} |
-#endif // defined(OS_WIN) |
- |
void PluginServiceImpl::RegisterPepperPlugins() { |
ComputePepperPluginList(&ppapi_plugins_); |
for (size_t i = 0; i < ppapi_plugins_.size(); ++i) { |
@@ -693,16 +358,6 @@ PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo( |
return &ppapi_plugins_[ppapi_plugins_.size() - 1]; |
} |
-#if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
-// static |
-void PluginServiceImpl::RegisterFilePathWatcher(FilePathWatcher* watcher, |
- const base::FilePath& path) { |
- bool result = watcher->Watch(path, false, |
- base::Bind(&NotifyPluginDirChanged)); |
- DCHECK(result); |
-} |
-#endif |
- |
void PluginServiceImpl::SetFilter(PluginServiceFilter* filter) { |
filter_ = filter; |
} |
@@ -711,20 +366,6 @@ PluginServiceFilter* PluginServiceImpl::GetFilter() { |
return filter_; |
} |
-void PluginServiceImpl::ForcePluginShutdown(const base::FilePath& plugin_path) { |
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::Bind(&PluginServiceImpl::ForcePluginShutdown, |
- base::Unretained(this), plugin_path)); |
- return; |
- } |
- |
- PluginProcessHost* plugin = FindNpapiPluginProcess(plugin_path); |
- if (plugin) |
- plugin->ForceShutdown(); |
-} |
- |
static const unsigned int kMaxCrashesPerInterval = 3; |
static const unsigned int kCrashesInterval = 120; |
@@ -761,33 +402,9 @@ void PluginServiceImpl::RefreshPlugins() { |
PluginList::Singleton()->RefreshPlugins(); |
} |
-void PluginServiceImpl::AddExtraPluginPath(const base::FilePath& path) { |
- if (!NPAPIPluginsSupported()) { |
- // TODO(jam): remove and just have CHECK once we're sure this doesn't get |
- // triggered. |
- DVLOG(0) << "NPAPI plugins not supported"; |
- return; |
- } |
- PluginList::Singleton()->AddExtraPluginPath(path); |
-} |
- |
-void PluginServiceImpl::RemoveExtraPluginPath(const base::FilePath& path) { |
- PluginList::Singleton()->RemoveExtraPluginPath(path); |
-} |
- |
-void PluginServiceImpl::AddExtraPluginDir(const base::FilePath& path) { |
- PluginList::Singleton()->AddExtraPluginDir(path); |
-} |
- |
void PluginServiceImpl::RegisterInternalPlugin( |
const WebPluginInfo& info, |
bool add_at_beginning) { |
- // Internal plugins should never be NPAPI. |
- CHECK_NE(info.type, WebPluginInfo::PLUGIN_TYPE_NPAPI); |
- if (info.type == WebPluginInfo::PLUGIN_TYPE_NPAPI) { |
- DVLOG(0) << "Don't register NPAPI plugins when they're not supported"; |
- return; |
- } |
PluginList::Singleton()->RegisterInternalPlugin(info, add_at_beginning); |
} |
@@ -800,36 +417,6 @@ void PluginServiceImpl::GetInternalPlugins( |
PluginList::Singleton()->GetInternalPlugins(plugins); |
} |
-bool PluginServiceImpl::NPAPIPluginsSupported() { |
-#if defined(OS_WIN) || defined(OS_MACOSX) |
- npapi_plugins_enabled_ = GetContentClient()->browser()->IsNPAPIEnabled(); |
-#if defined(OS_WIN) |
- // NPAPI plugins don't play well with Win32k renderer lockdown. |
- if (npapi_plugins_enabled_) |
- DisableWin32kRendererLockdown(); |
-#endif |
- NPAPIPluginStatus status = |
- npapi_plugins_enabled_ ? NPAPI_STATUS_ENABLED : NPAPI_STATUS_DISABLED; |
-#else |
- NPAPIPluginStatus status = NPAPI_STATUS_UNSUPPORTED; |
-#endif |
- UMA_HISTOGRAM_ENUMERATION("Plugin.NPAPIStatus", status, |
- NPAPI_STATUS_ENUM_COUNT); |
- |
- return npapi_plugins_enabled_; |
-} |
- |
-void PluginServiceImpl::DisablePluginsDiscoveryForTesting() { |
- PluginList::Singleton()->DisablePluginsDiscovery(); |
-} |
- |
-#if defined(OS_MACOSX) |
-void PluginServiceImpl::AppActivated() { |
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
- base::Bind(&NotifyPluginsOfActivation)); |
-} |
-#endif |
- |
bool PluginServiceImpl::PpapiDevChannelSupported( |
BrowserContext* browser_context, |
const GURL& document_url) { |