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