This source file includes following definitions.
- GetFactoryInstance
- Observe
- RegisterNaClModule
- UnregisterNaClModule
- UpdatePluginListWithNaClModules
- FindNaClModule
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/plugin_manager.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/api/plugins/plugins_handler.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/common/pepper_plugin_info.h"
#include "extensions/common/extension.h"
#include "url/gurl.h"
using content::PluginService;
static const char* kNaClPluginMimeType = "application/x-nacl";
namespace extensions {
PluginManager::PluginManager(content::BrowserContext* context)
: profile_(Profile::FromBrowserContext(context)) {
registrar_.Add(this,
chrome::NOTIFICATION_EXTENSION_LOADED,
content::Source<Profile>(profile_));
registrar_.Add(this,
chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
content::Source<Profile>(profile_));
}
PluginManager::~PluginManager() {
}
static base::LazyInstance<BrowserContextKeyedAPIFactory<PluginManager> >
g_factory = LAZY_INSTANCE_INITIALIZER;
BrowserContextKeyedAPIFactory<PluginManager>*
PluginManager::GetFactoryInstance() {
return g_factory.Pointer();
}
void PluginManager::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
const Extension* extension =
content::Details<const Extension>(details).ptr();
bool plugins_or_nacl_changed = false;
if (PluginInfo::HasPlugins(extension)) {
const PluginInfo::PluginVector* plugins =
PluginInfo::GetPlugins(extension);
CHECK(plugins);
plugins_or_nacl_changed = true;
for (PluginInfo::PluginVector::const_iterator plugin = plugins->begin();
plugin != plugins->end(); ++plugin) {
PluginService::GetInstance()->RefreshPlugins();
PluginService::GetInstance()->AddExtraPluginPath(plugin->path);
ChromePluginServiceFilter* filter =
ChromePluginServiceFilter::GetInstance();
if (plugin->is_public) {
filter->RestrictPluginToProfileAndOrigin(
plugin->path, profile_, GURL());
} else {
filter->RestrictPluginToProfileAndOrigin(
plugin->path, profile_, extension->url());
}
}
}
const NaClModuleInfo::List* nacl_modules =
NaClModuleInfo::GetNaClModules(extension);
if (nacl_modules) {
plugins_or_nacl_changed = true;
for (NaClModuleInfo::List::const_iterator module = nacl_modules->begin();
module != nacl_modules->end(); ++module) {
RegisterNaClModule(*module);
}
UpdatePluginListWithNaClModules();
}
if (plugins_or_nacl_changed)
PluginService::GetInstance()->PurgePluginListCache(profile_, false);
} else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED) {
const Extension* extension =
content::Details<UnloadedExtensionInfo>(details)->extension;
bool plugins_or_nacl_changed = false;
if (PluginInfo::HasPlugins(extension)) {
const PluginInfo::PluginVector* plugins =
PluginInfo::GetPlugins(extension);
plugins_or_nacl_changed = true;
for (PluginInfo::PluginVector::const_iterator plugin = plugins->begin();
plugin != plugins->end(); ++plugin) {
PluginService::GetInstance()->ForcePluginShutdown(plugin->path);
PluginService::GetInstance()->RefreshPlugins();
PluginService::GetInstance()->RemoveExtraPluginPath(plugin->path);
ChromePluginServiceFilter::GetInstance()->UnrestrictPlugin(
plugin->path);
}
}
const NaClModuleInfo::List* nacl_modules =
NaClModuleInfo::GetNaClModules(extension);
if (nacl_modules) {
plugins_or_nacl_changed = true;
for (NaClModuleInfo::List::const_iterator module = nacl_modules->begin();
module != nacl_modules->end(); ++module) {
UnregisterNaClModule(*module);
}
UpdatePluginListWithNaClModules();
}
if (plugins_or_nacl_changed)
PluginService::GetInstance()->PurgePluginListCache(profile_, false);
} else {
NOTREACHED();
}
}
void PluginManager::RegisterNaClModule(const NaClModuleInfo& info) {
DCHECK(FindNaClModule(info.url) == nacl_module_list_.end());
nacl_module_list_.push_front(info);
}
void PluginManager::UnregisterNaClModule(const NaClModuleInfo& info) {
NaClModuleInfo::List::iterator iter = FindNaClModule(info.url);
DCHECK(iter != nacl_module_list_.end());
nacl_module_list_.erase(iter);
}
void PluginManager::UpdatePluginListWithNaClModules() {
base::FilePath path;
if (!PathService::Get(chrome::FILE_NACL_PLUGIN, &path))
return;
const content::PepperPluginInfo* pepper_info =
PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(path);
if (!pepper_info)
return;
std::vector<content::WebPluginMimeType>::const_iterator mime_iter;
for (mime_iter = pepper_info->mime_types.begin();
mime_iter != pepper_info->mime_types.end(); ++mime_iter) {
if (mime_iter->mime_type == kNaClPluginMimeType) {
PluginService::GetInstance()->UnregisterInternalPlugin(pepper_info->path);
content::WebPluginInfo info = pepper_info->ToWebPluginInfo();
for (NaClModuleInfo::List::const_iterator iter =
nacl_module_list_.begin();
iter != nacl_module_list_.end(); ++iter) {
content::WebPluginMimeType mime_type_info;
mime_type_info.mime_type = iter->mime_type;
mime_type_info.additional_param_names.push_back(
base::UTF8ToUTF16("nacl"));
mime_type_info.additional_param_values.push_back(
base::UTF8ToUTF16(iter->url.spec()));
info.mime_types.push_back(mime_type_info);
}
PluginService::GetInstance()->RefreshPlugins();
PluginService::GetInstance()->RegisterInternalPlugin(info, true);
break;
}
}
}
NaClModuleInfo::List::iterator PluginManager::FindNaClModule(const GURL& url) {
for (NaClModuleInfo::List::iterator iter = nacl_module_list_.begin();
iter != nacl_module_list_.end(); ++iter) {
if (iter->url == url)
return iter;
}
return nacl_module_list_.end();
}
}