plugin_manager.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_path.h" 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/lazy_instance.h" 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/path_service.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/plugin_manager.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/plugins/chrome_plugin_service_filter.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/api/plugins/plugins_handler.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/plugin_service.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/common/pepper_plugin_info.h" 160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "extensions/browser/extension_registry.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using content::PluginService; 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstatic const char kNaClPluginMimeType[] = "application/x-nacl"; 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace extensions { 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PluginManager::PluginManager(content::BrowserContext* context) 270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : profile_(Profile::FromBrowserContext(context)), 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch extension_registry_observer_(this) { 290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PluginManager::~PluginManager() { 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<PluginManager> > 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) g_factory = LAZY_INSTANCE_INITIALIZER; 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<PluginManager>* 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PluginManager::GetFactoryInstance() { 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_factory.Pointer(); 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid PluginManager::OnExtensionLoaded(content::BrowserContext* browser_context, 450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const Extension* extension) { 460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool plugins_or_nacl_changed = false; 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (PluginInfo::HasPlugins(extension)) { 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const PluginInfo::PluginVector* plugins = PluginInfo::GetPlugins(extension); 490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CHECK(plugins); 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugins_or_nacl_changed = true; 510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (PluginInfo::PluginVector::const_iterator plugin = plugins->begin(); 520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugin != plugins->end(); 530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ++plugin) { 540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PluginService::GetInstance()->RefreshPlugins(); 550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PluginService::GetInstance()->AddExtraPluginPath(plugin->path); 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ChromePluginServiceFilter* filter = 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ChromePluginServiceFilter::GetInstance(); 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (plugin->is_public) { 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch filter->RestrictPluginToProfileAndOrigin( 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugin->path, profile_, GURL()); 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else { 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch filter->RestrictPluginToProfileAndOrigin( 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugin->path, profile_, extension->url()); 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const NaClModuleInfo::List* nacl_modules = 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NaClModuleInfo::GetNaClModules(extension); 700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (nacl_modules) { 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugins_or_nacl_changed = true; 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (NaClModuleInfo::List::const_iterator module = nacl_modules->begin(); 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch module != nacl_modules->end(); 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ++module) { 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RegisterNaClModule(*module); 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch UpdatePluginListWithNaClModules(); 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (plugins_or_nacl_changed) 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PluginService::GetInstance()->PurgePluginListCache(profile_, false); 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid PluginManager::OnExtensionUnloaded( 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::BrowserContext* browser_context, 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const Extension* extension, 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch UnloadedExtensionInfo::Reason reason) { 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool plugins_or_nacl_changed = false; 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (PluginInfo::HasPlugins(extension)) { 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const PluginInfo::PluginVector* plugins = PluginInfo::GetPlugins(extension); 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugins_or_nacl_changed = true; 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (PluginInfo::PluginVector::const_iterator plugin = plugins->begin(); 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugin != plugins->end(); 940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ++plugin) { 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PluginService::GetInstance()->ForcePluginShutdown(plugin->path); 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PluginService::GetInstance()->RefreshPlugins(); 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PluginService::GetInstance()->RemoveExtraPluginPath(plugin->path); 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ChromePluginServiceFilter::GetInstance()->UnrestrictPlugin(plugin->path); 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const NaClModuleInfo::List* nacl_modules = 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NaClModuleInfo::GetNaClModules(extension); 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (nacl_modules) { 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch plugins_or_nacl_changed = true; 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (NaClModuleInfo::List::const_iterator module = nacl_modules->begin(); 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch module != nacl_modules->end(); 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ++module) { 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch UnregisterNaClModule(*module); 1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch UpdatePluginListWithNaClModules(); 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (plugins_or_nacl_changed) 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PluginService::GetInstance()->PurgePluginListCache(profile_, false); 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PluginManager::RegisterNaClModule(const NaClModuleInfo& info) { 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(FindNaClModule(info.url) == nacl_module_list_.end()); 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) nacl_module_list_.push_front(info); 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PluginManager::UnregisterNaClModule(const NaClModuleInfo& info) { 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NaClModuleInfo::List::iterator iter = FindNaClModule(info.url); 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(iter != nacl_module_list_.end()); 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) nacl_module_list_.erase(iter); 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PluginManager::UpdatePluginListWithNaClModules() { 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // An extension has been added which has a nacl_module component, which means 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // there is a MIME type that module wants to handle, so we need to add that 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // MIME type to plugins which handle NaCl modules in order to allow the 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // individual modules to handle these types. 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath path; 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const content::PepperPluginInfo* pepper_info = 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(path); 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!pepper_info) 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::vector<content::WebPluginMimeType>::const_iterator mime_iter; 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Check each MIME type the plugins handle for the NaCl MIME type. 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (mime_iter = pepper_info->mime_types.begin(); 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mime_iter != pepper_info->mime_types.end(); ++mime_iter) { 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (mime_iter->mime_type == kNaClPluginMimeType) { 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This plugin handles "application/x-nacl". 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PluginService::GetInstance()->UnregisterInternalPlugin(pepper_info->path); 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 151ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch content::WebPluginInfo info = pepper_info->ToWebPluginInfo(); 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (NaClModuleInfo::List::const_iterator iter = 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) nacl_module_list_.begin(); 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) iter != nacl_module_list_.end(); ++iter) { 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Add the MIME type specified in the extension to this NaCl plugin, 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // With an extra "nacl" argument to specify the location of the NaCl 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // manifest file. 159ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch content::WebPluginMimeType mime_type_info; 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mime_type_info.mime_type = iter->mime_type; 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mime_type_info.additional_param_names.push_back( 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16("nacl")); 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mime_type_info.additional_param_values.push_back( 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16(iter->url.spec())); 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) info.mime_types.push_back(mime_type_info); 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PluginService::GetInstance()->RefreshPlugins(); 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PluginService::GetInstance()->RegisterInternalPlugin(info, true); 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This plugin has been modified, no need to check the rest of its 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // types, but continue checking other plugins. 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)NaClModuleInfo::List::iterator PluginManager::FindNaClModule(const GURL& url) { 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (NaClModuleInfo::List::iterator iter = nacl_module_list_.begin(); 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) iter != nacl_module_list_.end(); ++iter) { 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (iter->url == url) 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return iter; 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return nacl_module_list_.end(); 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace extensions 187