OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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" | 7 #include "base/command_line.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/native_library.h" | 9 #include "base/native_library.h" |
10 #include "base/string_split.h" | 10 #include "base/string_split.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "content/public/common/content_client.h" | 13 #include "content/public/common/content_client.h" |
14 #include "content/public/common/content_switches.h" | 14 #include "content/public/common/content_switches.h" |
15 #include "ppapi/shared_impl/ppapi_permissions.h" | 15 #include "ppapi/shared_impl/ppapi_permissions.h" |
16 #include "webkit/plugins/npapi/plugin_list.h" | 16 #include "webkit/plugins/npapi/plugin_list.h" |
17 | 17 |
| 18 namespace content { |
18 namespace { | 19 namespace { |
19 | 20 |
20 // Appends any plugins from the command line to the given vector. | 21 // Appends any plugins from the command line to the given vector. |
21 void ComputePluginsFromCommandLine( | 22 void ComputePluginsFromCommandLine(std::vector<PepperPluginInfo>* plugins) { |
22 std::vector<content::PepperPluginInfo>* plugins) { | |
23 bool out_of_process = | 23 bool out_of_process = |
24 CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess); | 24 CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess); |
25 const std::string value = | 25 const std::string value = |
26 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 26 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
27 switches::kRegisterPepperPlugins); | 27 switches::kRegisterPepperPlugins); |
28 if (value.empty()) | 28 if (value.empty()) |
29 return; | 29 return; |
30 | 30 |
31 // FORMAT: | 31 // FORMAT: |
32 // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> ) | 32 // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> ) |
33 // plugin-entry = | 33 // plugin-entry = |
34 // <file-path> + | 34 // <file-path> + |
35 // ["#" + <name> + ["#" + <description> + ["#" + <version>]]] + | 35 // ["#" + <name> + ["#" + <description> + ["#" + <version>]]] + |
36 // *1( LWS + ";" + LWS + <mime-type> ) | 36 // *1( LWS + ";" + LWS + <mime-type> ) |
37 std::vector<std::string> modules; | 37 std::vector<std::string> modules; |
38 base::SplitString(value, ',', &modules); | 38 base::SplitString(value, ',', &modules); |
39 for (size_t i = 0; i < modules.size(); ++i) { | 39 for (size_t i = 0; i < modules.size(); ++i) { |
40 std::vector<std::string> parts; | 40 std::vector<std::string> parts; |
41 base::SplitString(modules[i], ';', &parts); | 41 base::SplitString(modules[i], ';', &parts); |
42 if (parts.size() < 2) { | 42 if (parts.size() < 2) { |
43 DLOG(ERROR) << "Required mime-type not found"; | 43 DLOG(ERROR) << "Required mime-type not found"; |
44 continue; | 44 continue; |
45 } | 45 } |
46 | 46 |
47 std::vector<std::string> name_parts; | 47 std::vector<std::string> name_parts; |
48 base::SplitString(parts[0], '#', &name_parts); | 48 base::SplitString(parts[0], '#', &name_parts); |
49 | 49 |
50 content::PepperPluginInfo plugin; | 50 PepperPluginInfo plugin; |
51 plugin.is_out_of_process = out_of_process; | 51 plugin.is_out_of_process = out_of_process; |
52 #if defined(OS_WIN) | 52 #if defined(OS_WIN) |
53 // This means we can't provide plugins from non-ASCII paths, but | 53 // This means we can't provide plugins from non-ASCII paths, but |
54 // since this switch is only for development I don't think that's | 54 // since this switch is only for development I don't think that's |
55 // too awful. | 55 // too awful. |
56 plugin.path = FilePath(ASCIIToUTF16(name_parts[0])); | 56 plugin.path = FilePath(ASCIIToUTF16(name_parts[0])); |
57 #else | 57 #else |
58 plugin.path = FilePath(name_parts[0]); | 58 plugin.path = FilePath(name_parts[0]); |
59 #endif | 59 #endif |
60 if (name_parts.size() > 1) | 60 if (name_parts.size() > 1) |
(...skipping 11 matching lines...) Expand all Loading... |
72 | 72 |
73 // Command-line plugins get full permissions. | 73 // Command-line plugins get full permissions. |
74 plugin.permissions = ppapi::PERMISSION_ALL_BITS; | 74 plugin.permissions = ppapi::PERMISSION_ALL_BITS; |
75 | 75 |
76 plugins->push_back(plugin); | 76 plugins->push_back(plugin); |
77 } | 77 } |
78 } | 78 } |
79 | 79 |
80 } // namespace | 80 } // namespace |
81 | 81 |
82 webkit::WebPluginInfo content::PepperPluginInfo::ToWebPluginInfo() const { | 82 webkit::WebPluginInfo PepperPluginInfo::ToWebPluginInfo() const { |
83 webkit::WebPluginInfo info; | 83 webkit::WebPluginInfo info; |
84 | 84 |
85 info.type = is_out_of_process ? | 85 info.type = is_out_of_process ? |
86 (is_sandboxed ? | 86 (is_sandboxed ? |
87 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS : | 87 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS : |
88 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED) : | 88 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED) : |
89 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS; | 89 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS; |
90 | 90 |
91 info.name = name.empty() ? | 91 info.name = name.empty() ? |
92 path.BaseName().LossyDisplayName() : UTF8ToUTF16(name); | 92 path.BaseName().LossyDisplayName() : UTF8ToUTF16(name); |
93 info.path = path; | 93 info.path = path; |
94 info.version = ASCIIToUTF16(version); | 94 info.version = ASCIIToUTF16(version); |
95 info.desc = ASCIIToUTF16(description); | 95 info.desc = ASCIIToUTF16(description); |
96 info.mime_types = mime_types; | 96 info.mime_types = mime_types; |
97 info.pepper_permissions = permissions; | 97 info.pepper_permissions = permissions; |
98 | 98 |
99 return info; | 99 return info; |
100 } | 100 } |
101 | 101 |
102 bool MakePepperPluginInfo(const webkit::WebPluginInfo& webplugin_info, | 102 bool MakePepperPluginInfo(const webkit::WebPluginInfo& webplugin_info, |
103 content::PepperPluginInfo* pepper_info) { | 103 PepperPluginInfo* pepper_info) { |
104 if (!webkit::IsPepperPlugin(webplugin_info)) | 104 if (!webkit::IsPepperPlugin(webplugin_info)) |
105 return false; | 105 return false; |
106 | 106 |
107 pepper_info->is_out_of_process = webkit::IsOutOfProcessPlugin(webplugin_info); | 107 pepper_info->is_out_of_process = webkit::IsOutOfProcessPlugin(webplugin_info); |
108 pepper_info->is_sandboxed = webplugin_info.type != | 108 pepper_info->is_sandboxed = webplugin_info.type != |
109 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED; | 109 webkit::WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED; |
110 | 110 |
111 pepper_info->path = FilePath(webplugin_info.path); | 111 pepper_info->path = FilePath(webplugin_info.path); |
112 pepper_info->name = UTF16ToASCII(webplugin_info.name); | 112 pepper_info->name = UTF16ToASCII(webplugin_info.name); |
113 pepper_info->description = UTF16ToASCII(webplugin_info.desc); | 113 pepper_info->description = UTF16ToASCII(webplugin_info.desc); |
114 pepper_info->version = UTF16ToASCII(webplugin_info.version); | 114 pepper_info->version = UTF16ToASCII(webplugin_info.version); |
115 pepper_info->mime_types = webplugin_info.mime_types; | 115 pepper_info->mime_types = webplugin_info.mime_types; |
116 pepper_info->permissions = webplugin_info.pepper_permissions; | 116 pepper_info->permissions = webplugin_info.pepper_permissions; |
117 | 117 |
118 return true; | 118 return true; |
119 } | 119 } |
120 | 120 |
121 // static | 121 // static |
122 PepperPluginRegistry* PepperPluginRegistry::GetInstance() { | 122 PepperPluginRegistry* PepperPluginRegistry::GetInstance() { |
123 static PepperPluginRegistry* registry = NULL; | 123 static PepperPluginRegistry* registry = NULL; |
124 // This object leaks. It is a temporary hack to work around a crash. | 124 // This object leaks. It is a temporary hack to work around a crash. |
125 // http://code.google.com/p/chromium/issues/detail?id=63234 | 125 // http://code.google.com/p/chromium/issues/detail?id=63234 |
126 if (!registry) | 126 if (!registry) |
127 registry = new PepperPluginRegistry; | 127 registry = new PepperPluginRegistry; |
128 return registry; | 128 return registry; |
129 } | 129 } |
130 | 130 |
131 // static | 131 // static |
132 void PepperPluginRegistry::ComputeList( | 132 void PepperPluginRegistry::ComputeList(std::vector<PepperPluginInfo>* plugins) { |
133 std::vector<content::PepperPluginInfo>* plugins) { | 133 GetContentClient()->AddPepperPlugins(plugins); |
134 content::GetContentClient()->AddPepperPlugins(plugins); | |
135 ComputePluginsFromCommandLine(plugins); | 134 ComputePluginsFromCommandLine(plugins); |
136 } | 135 } |
137 | 136 |
138 // static | 137 // static |
139 void PepperPluginRegistry::PreloadModules() { | 138 void PepperPluginRegistry::PreloadModules() { |
140 std::vector<content::PepperPluginInfo> plugins; | 139 std::vector<PepperPluginInfo> plugins; |
141 ComputeList(&plugins); | 140 ComputeList(&plugins); |
142 for (size_t i = 0; i < plugins.size(); ++i) { | 141 for (size_t i = 0; i < plugins.size(); ++i) { |
143 if (!plugins[i].is_internal && plugins[i].is_sandboxed) { | 142 if (!plugins[i].is_internal && plugins[i].is_sandboxed) { |
144 std::string error; | 143 std::string error; |
145 base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path, | 144 base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path, |
146 &error); | 145 &error); |
147 DLOG_IF(WARNING, !library) << "Unable to load plugin " | 146 DLOG_IF(WARNING, !library) << "Unable to load plugin " |
148 << plugins[i].path.value() << " " | 147 << plugins[i].path.value() << " " |
149 << error; | 148 << error; |
150 (void)library; // Prevent release-mode warning. | 149 (void)library; // Prevent release-mode warning. |
151 } | 150 } |
152 } | 151 } |
153 } | 152 } |
154 | 153 |
155 const content::PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin( | 154 const PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin( |
156 const webkit::WebPluginInfo& info) { | 155 const webkit::WebPluginInfo& info) { |
157 for (size_t i = 0; i < plugin_list_.size(); ++i) { | 156 for (size_t i = 0; i < plugin_list_.size(); ++i) { |
158 if (info.path == plugin_list_[i].path) | 157 if (info.path == plugin_list_[i].path) |
159 return &plugin_list_[i]; | 158 return &plugin_list_[i]; |
160 } | 159 } |
161 // We did not find the plugin in our list. But wait! the plugin can also | 160 // We did not find the plugin in our list. But wait! the plugin can also |
162 // be a latecomer, as it happens with pepper flash. This information | 161 // be a latecomer, as it happens with pepper flash. This information |
163 // is actually in |info| and we can use it to construct it and add it to | 162 // is actually in |info| and we can use it to construct it and add it to |
164 // the list. This same deal needs to be done in the browser side in | 163 // the list. This same deal needs to be done in the browser side in |
165 // PluginService. | 164 // PluginService. |
166 content::PepperPluginInfo plugin; | 165 PepperPluginInfo plugin; |
167 if (!MakePepperPluginInfo(info, &plugin)) | 166 if (!MakePepperPluginInfo(info, &plugin)) |
168 return NULL; | 167 return NULL; |
169 | 168 |
170 plugin_list_.push_back(plugin); | 169 plugin_list_.push_back(plugin); |
171 return &plugin_list_[plugin_list_.size() - 1]; | 170 return &plugin_list_[plugin_list_.size() - 1]; |
172 } | 171 } |
173 | 172 |
174 webkit::ppapi::PluginModule* PepperPluginRegistry::GetLiveModule( | 173 webkit::ppapi::PluginModule* PepperPluginRegistry::GetLiveModule( |
175 const FilePath& path) { | 174 const FilePath& path) { |
176 NonOwningModuleMap::iterator it = live_modules_.find(path); | 175 NonOwningModuleMap::iterator it = live_modules_.find(path); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 } | 211 } |
213 | 212 |
214 PepperPluginRegistry::PepperPluginRegistry() { | 213 PepperPluginRegistry::PepperPluginRegistry() { |
215 ComputeList(&plugin_list_); | 214 ComputeList(&plugin_list_); |
216 | 215 |
217 // Note that in each case, AddLiveModule must be called before completing | 216 // Note that in each case, AddLiveModule must be called before completing |
218 // initialization. If we bail out (in the continue clauses) before saving | 217 // initialization. If we bail out (in the continue clauses) before saving |
219 // the initialized module, it will still try to unregister itself in its | 218 // the initialized module, it will still try to unregister itself in its |
220 // destructor. | 219 // destructor. |
221 for (size_t i = 0; i < plugin_list_.size(); i++) { | 220 for (size_t i = 0; i < plugin_list_.size(); i++) { |
222 const content::PepperPluginInfo& current = plugin_list_[i]; | 221 const PepperPluginInfo& current = plugin_list_[i]; |
223 if (current.is_out_of_process) | 222 if (current.is_out_of_process) |
224 continue; // Out of process plugins need no special pre-initialization. | 223 continue; // Out of process plugins need no special pre-initialization. |
225 | 224 |
226 scoped_refptr<webkit::ppapi::PluginModule> module = | 225 scoped_refptr<webkit::ppapi::PluginModule> module = |
227 new webkit::ppapi::PluginModule(current.name, current.path, this, | 226 new webkit::ppapi::PluginModule(current.name, current.path, this, |
228 ppapi::PpapiPermissions(current.permissions)); | 227 ppapi::PpapiPermissions(current.permissions)); |
229 AddLiveModule(current.path, module); | 228 AddLiveModule(current.path, module); |
230 if (current.is_internal) { | 229 if (current.is_internal) { |
231 if (!module->InitAsInternalPlugin(current.internal_entry_points)) { | 230 if (!module->InitAsInternalPlugin(current.internal_entry_points)) { |
232 DLOG(ERROR) << "Failed to load pepper module: " << current.path.value(); | 231 DLOG(ERROR) << "Failed to load pepper module: " << current.path.value(); |
233 continue; | 232 continue; |
234 } | 233 } |
235 } else { | 234 } else { |
236 // Preload all external plugins we're not running out of process. | 235 // Preload all external plugins we're not running out of process. |
237 if (!module->InitAsLibrary(current.path)) { | 236 if (!module->InitAsLibrary(current.path)) { |
238 DLOG(ERROR) << "Failed to load pepper module: " << current.path.value(); | 237 DLOG(ERROR) << "Failed to load pepper module: " << current.path.value(); |
239 continue; | 238 continue; |
240 } | 239 } |
241 } | 240 } |
242 preloaded_modules_[current.path] = module; | 241 preloaded_modules_[current.path] = module; |
243 } | 242 } |
244 } | 243 } |
245 | 244 |
| 245 } // namespace content |
OLD | NEW |