1bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// found in the LICENSE file. 4bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/pepper_plugin_registry.h" 6bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 7bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/logging.h" 8bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/common/pepper_plugin_list.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/renderer/pepper/pepper_plugin_instance_impl.h" 10bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/plugin_module.h" 11bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "ppapi/shared_impl/ppapi_permissions.h" 12bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 13bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochnamespace content { 14bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 15bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// static 16bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochPepperPluginRegistry* PepperPluginRegistry::GetInstance() { 17bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch static PepperPluginRegistry* registry = NULL; 18bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // This object leaks. It is a temporary hack to work around a crash. 19bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // http://code.google.com/p/chromium/issues/detail?id=63234 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!registry) { 21bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch registry = new PepperPluginRegistry; 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) registry->Initialize(); 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 24bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return registry; 25bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 26bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 27bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochconst PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin( 28bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const WebPluginInfo& info) { 29bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch for (size_t i = 0; i < plugin_list_.size(); ++i) { 30bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (info.path == plugin_list_[i].path) 31bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return &plugin_list_[i]; 32bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 33bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // We did not find the plugin in our list. But wait! the plugin can also 34bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // be a latecomer, as it happens with pepper flash. This information 35bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // is actually in |info| and we can use it to construct it and add it to 36bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // the list. This same deal needs to be done in the browser side in 37bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // PluginService. 38bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch PepperPluginInfo plugin; 39bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!MakePepperPluginInfo(info, &plugin)) 40bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return NULL; 41bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 42bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch plugin_list_.push_back(plugin); 43bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return &plugin_list_[plugin_list_.size() - 1]; 44bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 45bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 4658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochPluginModule* PepperPluginRegistry::GetLiveModule(const base::FilePath& path) { 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NonOwningModuleMap::iterator module_iter = live_modules_.find(path); 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (module_iter == live_modules_.end()) 49bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return NULL; 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Check the instances for the module to see if they've all been Delete()d. 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We don't want to return a PluginModule in that case, since the plugin may 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // have exited already. 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const PluginModule::PluginInstanceSet& instance_set = 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) module_iter->second->GetAllInstances(); 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If instance_set is empty, InstanceCreated() hasn't been called yet, so 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // it's safe to return the PluginModule. 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (instance_set.empty()) 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return module_iter->second; 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PluginModule::PluginInstanceSet::const_iterator instance_iter = 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) instance_set.begin(); 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) while (instance_iter != instance_set.end()) { 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!(*instance_iter)->is_deleted()) 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return module_iter->second; 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++instance_iter; 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 70bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 71bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 72bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid PepperPluginRegistry::AddLiveModule(const base::FilePath& path, 7358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch PluginModule* module) { 74bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(live_modules_.find(path) == live_modules_.end()); 75bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch live_modules_[path] = module; 76bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 77bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 7858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochvoid PepperPluginRegistry::PluginModuleDead(PluginModule* dead_module) { 79bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // DANGER: Don't dereference the dead_module pointer! It may be in the 80bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // process of being deleted. 81bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 82bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Modules aren't destroyed very often and there are normally at most a 83bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // couple of them. So for now we just do a brute-force search. 84bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch for (NonOwningModuleMap::iterator i = live_modules_.begin(); 85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch i != live_modules_.end(); 86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ++i) { 87bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (i->second == dead_module) { 88bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch live_modules_.erase(i); 89bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return; 90bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 91bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 92bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Can occur in tests. 93bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 94bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 95bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochPepperPluginRegistry::~PepperPluginRegistry() { 96bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Explicitly clear all preloaded modules first. This will cause callbacks 97bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // to erase these modules from the live_modules_ list, and we don't want 98bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // that to happen implicitly out-of-order. 99bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch preloaded_modules_.clear(); 100bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 101bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(live_modules_.empty()); 102bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 103bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 104a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperPluginRegistry::PepperPluginRegistry() {} 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PepperPluginRegistry::Initialize() { 107bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ComputePepperPluginList(&plugin_list_); 108bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 109bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Note that in each case, AddLiveModule must be called before completing 110bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // initialization. If we bail out (in the continue clauses) before saving 111bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // the initialized module, it will still try to unregister itself in its 112bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // destructor. 113bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch for (size_t i = 0; i < plugin_list_.size(); i++) { 114bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const PepperPluginInfo& current = plugin_list_[i]; 115bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (current.is_out_of_process) 116bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch continue; // Out of process plugins need no special pre-initialization. 117bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch scoped_refptr<PluginModule> module = 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new PluginModule(current.name, 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) current.version, 121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch current.path, 122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ppapi::PpapiPermissions(current.permissions)); 123bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch AddLiveModule(current.path, module.get()); 124bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (current.is_internal) { 125bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!module->InitAsInternalPlugin(current.internal_entry_points)) { 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DVLOG(1) << "Failed to load pepper module: " << current.path.value(); 127bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch continue; 128bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 129bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } else { 130bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Preload all external plugins we're not running out of process. 131bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!module->InitAsLibrary(current.path)) { 132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DVLOG(1) << "Failed to load pepper module: " << current.path.value(); 133bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch continue; 134bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 135bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 136bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch preloaded_modules_[current.path] = module; 137bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 138bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 139bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 140bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} // namespace content 141