Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: content/common/pepper_plugin_registry.cc

Issue 7978009: Split ppapi::PluginList from PepperPluginRegistry so that DRT could load pepper plugins. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/pepper_plugin_registry.h" 5 #include "content/common/pepper_plugin_registry.h"
6 6
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/native_library.h"
10 #include "base/string_split.h"
11 #include "base/string_util.h"
12 #include "base/utf_string_conversions.h"
13 #include "content/common/content_client.h"
14 #include "content/common/content_switches.h"
15 #include "webkit/plugins/npapi/plugin_list.h"
16
17 namespace {
18
19 // Appends any plugins from the command line to the given vector.
20 void ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) {
21 bool out_of_process =
22 CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess);
23 const std::string value =
24 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
25 switches::kRegisterPepperPlugins);
26 if (value.empty())
27 return;
28
29 // FORMAT:
30 // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
31 // plugin-entry =
32 // <file-path> +
33 // ["#" + <name> + ["#" + <description> + ["#" + <version>]]] +
34 // *1( LWS + ";" + LWS + <mime-type> )
35 std::vector<std::string> modules;
36 base::SplitString(value, ',', &modules);
37 for (size_t i = 0; i < modules.size(); ++i) {
38 std::vector<std::string> parts;
39 base::SplitString(modules[i], ';', &parts);
40 if (parts.size() < 2) {
41 DLOG(ERROR) << "Required mime-type not found";
42 continue;
43 }
44
45 std::vector<std::string> name_parts;
46 base::SplitString(parts[0], '#', &name_parts);
47
48 PepperPluginInfo plugin;
49 plugin.is_out_of_process = out_of_process;
50 #if defined(OS_WIN)
51 // This means we can't provide plugins from non-ASCII paths, but
52 // since this switch is only for development I don't think that's
53 // too awful.
54 plugin.path = FilePath(ASCIIToUTF16(name_parts[0]));
55 #else
56 plugin.path = FilePath(name_parts[0]);
57 #endif
58 if (name_parts.size() > 1)
59 plugin.name = name_parts[1];
60 if (name_parts.size() > 2)
61 plugin.description = name_parts[2];
62 if (name_parts.size() > 3)
63 plugin.version = name_parts[3];
64 for (size_t j = 1; j < parts.size(); ++j) {
65 webkit::WebPluginMimeType mime_type(parts[j],
66 std::string(),
67 plugin.description);
68 plugin.mime_types.push_back(mime_type);
69 }
70
71 plugins->push_back(plugin);
72 }
73 }
74
75 } // namespace
76
77 webkit::WebPluginInfo PepperPluginInfo::ToWebPluginInfo() const {
78 webkit::WebPluginInfo info;
79
80 info.type = is_out_of_process ?
81 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS :
82 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS;
83
84 info.name = name.empty() ?
85 path.BaseName().LossyDisplayName() : UTF8ToUTF16(name);
86 info.path = path;
87 info.version = ASCIIToUTF16(version);
88 info.desc = ASCIIToUTF16(description);
89 info.mime_types = mime_types;
90
91 return info;
92 }
93
94 PepperPluginInfo::PepperPluginInfo()
95 : is_internal(false),
96 is_out_of_process(false) {
97 }
98
99 PepperPluginInfo::~PepperPluginInfo() {
100 }
101
102 bool MakePepperPluginInfo(const webkit::WebPluginInfo& webplugin_info,
103 PepperPluginInfo* pepper_info) {
104 if (!webkit::IsPepperPlugin(webplugin_info))
105 return false;
106
107 pepper_info->is_out_of_process =
108 webplugin_info.type ==
109 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS;
110
111 pepper_info->path = FilePath(webplugin_info.path);
112 pepper_info->name = UTF16ToASCII(webplugin_info.name);
113 pepper_info->description = UTF16ToASCII(webplugin_info.desc);
114 pepper_info->version = UTF16ToASCII(webplugin_info.version);
115 pepper_info->mime_types = webplugin_info.mime_types;
116 return true;
117 }
118
119 // static 7 // static
120 PepperPluginRegistry* PepperPluginRegistry::GetInstance() { 8 PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
121 static PepperPluginRegistry* registry = NULL; 9 return Singleton<PepperPluginRegistry>::get();
122 // This object leaks. It is a temporary hack to work around a crash.
123 // http://code.google.com/p/chromium/issues/detail?id=63234
124 if (!registry)
125 registry = new PepperPluginRegistry;
126 return registry;
127 } 10 }
128
129 // static
130 void PepperPluginRegistry::ComputeList(std::vector<PepperPluginInfo>* plugins) {
131 content::GetContentClient()->AddPepperPlugins(plugins);
132 ComputePluginsFromCommandLine(plugins);
133 }
134
135 // static
136 void PepperPluginRegistry::PreloadModules() {
137 std::vector<PepperPluginInfo> plugins;
138 ComputeList(&plugins);
139 for (size_t i = 0; i < plugins.size(); ++i) {
140 if (!plugins[i].is_internal) {
141 std::string error;
142 base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path,
143 &error);
144 LOG_IF(WARNING, !library) << "Unable to load plugin "
145 << plugins[i].path.value() << " "
146 << error;
147 }
148 }
149 }
150
151 const PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin(
152 const webkit::WebPluginInfo& info) {
153 for (size_t i = 0; i < plugin_list_.size(); ++i) {
154 if (info.path == plugin_list_[i].path)
155 return &plugin_list_[i];
156 }
157 // We did not find the plugin in our list. But wait! the plugin can also
158 // be a latecomer, as it happens with pepper flash. This information
159 // is actually in |info| and we can use it to construct it and add it to
160 // the list. This same deal needs to be done in the browser side in
161 // PluginService.
162 PepperPluginInfo plugin;
163 if (!MakePepperPluginInfo(info, &plugin))
164 return NULL;
165
166 plugin_list_.push_back(plugin);
167 return &plugin_list_[plugin_list_.size() - 1];
168 }
169
170 webkit::ppapi::PluginModule* PepperPluginRegistry::GetLiveModule(
171 const FilePath& path) {
172 NonOwningModuleMap::iterator it = live_modules_.find(path);
173 if (it == live_modules_.end())
174 return NULL;
175 return it->second;
176 }
177
178 void PepperPluginRegistry::AddLiveModule(const FilePath& path,
179 webkit::ppapi::PluginModule* module) {
180 DCHECK(live_modules_.find(path) == live_modules_.end());
181 live_modules_[path] = module;
182 }
183
184 void PepperPluginRegistry::PluginModuleDead(
185 webkit::ppapi::PluginModule* dead_module) {
186 // DANGER: Don't dereference the dead_module pointer! It may be in the
187 // process of being deleted.
188
189 // Modules aren't destroyed very often and there are normally at most a
190 // couple of them. So for now we just do a brute-force search.
191 for (NonOwningModuleMap::iterator i = live_modules_.begin();
192 i != live_modules_.end(); ++i) {
193 if (i->second == dead_module) {
194 live_modules_.erase(i);
195 return;
196 }
197 }
198 NOTREACHED(); // Should have always found the module above.
199 }
200
201 PepperPluginRegistry::~PepperPluginRegistry() {
202 // Explicitly clear all preloaded modules first. This will cause callbacks
203 // to erase these modules from the live_modules_ list, and we don't want
204 // that to happen implicitly out-of-order.
205 preloaded_modules_.clear();
206
207 DCHECK(live_modules_.empty());
208 }
209
210 PepperPluginRegistry::PepperPluginRegistry() {
211 ComputeList(&plugin_list_);
212
213 // Note that in each case, AddLiveModule must be called before completing
214 // initialization. If we bail out (in the continue clauses) before saving
215 // the initialized module, it will still try to unregister itself in its
216 // destructor.
217 for (size_t i = 0; i < plugin_list_.size(); i++) {
218 const PepperPluginInfo& current = plugin_list_[i];
219 if (current.is_out_of_process)
220 continue; // Out of process plugins need no special pre-initialization.
221
222 scoped_refptr<webkit::ppapi::PluginModule> module =
223 new webkit::ppapi::PluginModule(current.name, current.path, this);
224 AddLiveModule(current.path, module);
225 if (current.is_internal) {
226 if (!module->InitAsInternalPlugin(current.internal_entry_points)) {
227 DLOG(ERROR) << "Failed to load pepper module: " << current.path.value();
228 continue;
229 }
230 } else {
231 // Preload all external plugins we're not running out of process.
232 if (!module->InitAsLibrary(current.path)) {
233 DLOG(ERROR) << "Failed to load pepper module: " << current.path.value();
234 continue;
235 }
236 }
237 preloaded_modules_[current.path] = module;
238 }
239 }
240
OLDNEW
« no previous file with comments | « content/common/pepper_plugin_registry.h ('k') | content/renderer/pepper_plugin_delegate_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698