summaryrefslogtreecommitdiff
path: root/chromium/content/browser/plugin_service_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/plugin_service_impl.cc')
-rw-r--r--chromium/content/browser/plugin_service_impl.cc473
1 files changed, 11 insertions, 462 deletions
diff --git a/chromium/content/browser/plugin_service_impl.cc b/chromium/content/browser/plugin_service_impl.cc
index 700d30428c7..c81e19b6b23 100644
--- a/chromium/content/browser/plugin_service_impl.cc
+++ b/chromium/content/browser/plugin_service_impl.cc
@@ -34,108 +34,27 @@
#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.";
- }
+ CHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
+ token));
}
-#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));
-}
-#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
// static
@@ -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,23 +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), 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), 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(
@@ -624,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, make_scoped_refptr(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) {
@@ -691,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;
}
@@ -709,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;
@@ -759,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);
}
@@ -798,76 +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));
-}
-#elif defined(OS_WIN)
-
-bool GetPluginPropertyFromWindow(
- HWND window, const wchar_t* plugin_atom_property,
- base::string16* plugin_property) {
- ATOM plugin_atom = static_cast<ATOM>(
- reinterpret_cast<uintptr_t>(GetPropW(window, plugin_atom_property)));
- if (plugin_atom != 0) {
- WCHAR plugin_property_local[MAX_PATH] = {0};
- GlobalGetAtomNameW(plugin_atom,
- plugin_property_local,
- ARRAYSIZE(plugin_property_local));
- *plugin_property = plugin_property_local;
- return true;
- }
- return false;
-}
-
-bool PluginServiceImpl::GetPluginInfoFromWindow(
- HWND window,
- base::string16* plugin_name,
- base::string16* plugin_version) {
- if (!IsPluginWindow(window))
- return false;
-
-
- DWORD process_id = 0;
- GetWindowThreadProcessId(window, &process_id);
- WebPluginInfo info;
- if (!PluginProcessHost::GetWebPluginInfoFromPluginPid(process_id, &info))
- return false;
-
- *plugin_name = info.name;
- *plugin_version = info.version;
- return true;
-}
-
-bool PluginServiceImpl::IsPluginWindow(HWND window) {
- return gfx::GetClassName(window) == base::string16(kNativeWindowClassName);
-}
-#endif
-
bool PluginServiceImpl::PpapiDevChannelSupported(
BrowserContext* browser_context,
const GURL& document_url) {