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

Side by Side Diff: webkit/glue/plugins/plugin_list.cc

Issue 164305: Ensure we don't load plugins on the IO thread (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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
« no previous file with comments | « webkit/glue/plugins/plugin_list.h ('k') | webkit/glue/plugins/plugin_list_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "webkit/glue/plugins/plugin_list.h" 5 #include "webkit/glue/plugins/plugin_list.h"
6 6
7 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "net/base/mime_util.h" 11 #include "net/base/mime_util.h"
12 #include "webkit/default_plugin/plugin_main.h" 12 #include "webkit/default_plugin/plugin_main.h"
13 #include "webkit/glue/plugins/plugin_lib.h" 13 #include "webkit/glue/plugins/plugin_lib.h"
14 #include "webkit/glue/webkit_glue.h" 14 #include "webkit/glue/webkit_glue.h"
15 #include "googleurl/src/gurl.h" 15 #include "googleurl/src/gurl.h"
16 16
17 #if defined(OS_WIN) 17 #if defined(OS_WIN)
18 #include "webkit/activex_shim/activex_shared.h" 18 #include "webkit/activex_shim/activex_shared.h"
19 #include "webkit/glue/plugins/plugin_constants_win.h" 19 #include "webkit/glue/plugins/plugin_constants_win.h"
20 #endif 20 #endif
21 21
22 namespace NPAPI { 22 namespace NPAPI {
23 23
24 base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED); 24 base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED);
25 25
26 // static 26 // static
27 PluginList* PluginList::Singleton() { 27 PluginList* PluginList::Singleton() {
28 PluginList* singleton = g_singleton.Pointer(); 28 return g_singleton.Pointer();
29 if (!singleton->plugins_loaded_) {
30 singleton->LoadPlugins(false);
31 DCHECK(singleton->plugins_loaded_);
32 }
33 return singleton;
34 } 29 }
35 30
36 // static 31 bool PluginList::PluginsLoaded() {
37 void PluginList::ResetPluginsLoaded() { 32 AutoLock lock(lock_);
38 // We access the singleton directly, and not through Singleton(), since 33 return plugins_loaded_;
39 // we don't want LoadPlugins() to be called.
40 g_singleton.Pointer()->plugins_loaded_ = false;
41 } 34 }
42 35
43 // static 36 void PluginList::ResetPluginsLoaded() {
44 void PluginList::AddExtraPluginPath(const FilePath& plugin_path) { 37 AutoLock lock(lock_);
45 DCHECK(!g_singleton.Pointer()->plugins_loaded_); 38 plugins_loaded_ = false;
46 g_singleton.Pointer()->extra_plugin_paths_.push_back(plugin_path);
47 } 39 }
48 40
49 // static 41 void PluginList::AddExtraPluginPath(const FilePath& plugin_path) {
42 AutoLock lock(lock_);
43 extra_plugin_paths_.push_back(plugin_path);
44 }
45
50 void PluginList::AddExtraPluginDir(const FilePath& plugin_dir) { 46 void PluginList::AddExtraPluginDir(const FilePath& plugin_dir) {
51 DCHECK(!g_singleton.Pointer()->plugins_loaded_); 47 AutoLock lock(lock_);
52 g_singleton.Pointer()->extra_plugin_dirs_.push_back(plugin_dir); 48 extra_plugin_dirs_.push_back(plugin_dir);
53 } 49 }
54 50
55 void PluginList::RegisterInternalPlugin(const PluginVersionInfo& info) { 51 void PluginList::RegisterInternalPlugin(const PluginVersionInfo& info) {
56 DCHECK(!g_singleton.Pointer()->plugins_loaded_); 52 AutoLock lock(lock_);
57 g_singleton.Pointer()->internal_plugins_.push_back(info); 53 internal_plugins_.push_back(info);
58 } 54 }
59 55
60 bool PluginList::ReadPluginInfo(const FilePath &filename, 56 bool PluginList::ReadPluginInfo(const FilePath &filename,
61 WebPluginInfo* info, 57 WebPluginInfo* info,
62 const PluginEntryPoints** entry_points) { 58 const PluginEntryPoints** entry_points) {
63 // We access the singleton directly, and not through Singleton(), since 59 {
64 // we might be in a LoadPlugins call and don't want to call it recursively! 60 AutoLock lock(lock_);
65 const std::vector<PluginVersionInfo>& internal_plugins = 61 for (size_t i = 0; i < internal_plugins_.size(); ++i) {
66 g_singleton.Pointer()->internal_plugins_; 62 if (filename == internal_plugins_[i].path) {
67 for (size_t i = 0; i < internal_plugins.size(); ++i) { 63 *entry_points = &internal_plugins_[i].entry_points;
68 if (filename == internal_plugins[i].path) { 64 return CreateWebPluginInfo(internal_plugins_[i], info);
69 *entry_points = &internal_plugins[i].entry_points; 65 }
70 return CreateWebPluginInfo(internal_plugins[i], info);
71 } 66 }
72 } 67 }
73 68
74 // Not an internal plugin. 69 // Not an internal plugin.
75 *entry_points = NULL; 70 *entry_points = NULL;
76 71
77 return PluginLib::ReadWebPluginInfo(filename, info); 72 return PluginLib::ReadWebPluginInfo(filename, info);
78 } 73 }
79 74
80 bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi, 75 bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 default_plugin::NP_Initialize, 134 default_plugin::NP_Initialize,
140 default_plugin::NP_Shutdown 135 default_plugin::NP_Shutdown
141 } 136 }
142 }; 137 };
143 138
144 internal_plugins_.push_back(default_plugin); 139 internal_plugins_.push_back(default_plugin);
145 #endif 140 #endif
146 } 141 }
147 142
148 void PluginList::LoadPlugins(bool refresh) { 143 void PluginList::LoadPlugins(bool refresh) {
149 if (plugins_loaded_ && !refresh) 144 // Don't want to hold the lock while loading new plugins, so we don't block
150 return; 145 // other methods if they're called on other threads.
146 std::vector<FilePath> extra_plugin_paths;
147 std::vector<FilePath> extra_plugin_dirs;
148 {
149 AutoLock lock(lock_);
150 if (plugins_loaded_ && !refresh)
151 return;
151 152
152 plugins_.clear(); 153 extra_plugin_paths = extra_plugin_paths_;
153 plugins_loaded_ = true; 154 extra_plugin_dirs = extra_plugin_dirs_;
155 }
154 156
155 base::TimeTicks start_time = base::TimeTicks::Now(); 157 base::TimeTicks start_time = base::TimeTicks::Now();
156 158
159 std::vector<WebPluginInfo> new_plugins;
160
157 std::vector<FilePath> directories_to_scan; 161 std::vector<FilePath> directories_to_scan;
158 GetPluginDirectories(&directories_to_scan); 162 GetPluginDirectories(&directories_to_scan);
159 163
160 for (size_t i = 0; i < extra_plugin_paths_.size(); ++i) 164 for (size_t i = 0; i < extra_plugin_paths.size(); ++i)
161 LoadPlugin(extra_plugin_paths_[i]); 165 LoadPlugin(extra_plugin_paths[i], &new_plugins);
162 166
163 for (size_t i = 0; i < extra_plugin_dirs_.size(); ++i) { 167 for (size_t i = 0; i < extra_plugin_dirs.size(); ++i) {
164 LoadPluginsFromDir(extra_plugin_dirs_[i]); 168 LoadPluginsFromDir(extra_plugin_dirs[i], &new_plugins);
165 } 169 }
166 170
167 for (size_t i = 0; i < directories_to_scan.size(); ++i) { 171 for (size_t i = 0; i < directories_to_scan.size(); ++i) {
168 LoadPluginsFromDir(directories_to_scan[i]); 172 LoadPluginsFromDir(directories_to_scan[i], &new_plugins);
169 } 173 }
170 174
171 LoadInternalPlugins(); 175 LoadInternalPlugins(&new_plugins);
172 176
173 if (webkit_glue::IsDefaultPluginEnabled()) 177 if (webkit_glue::IsDefaultPluginEnabled())
174 LoadPlugin(FilePath(kDefaultPluginLibraryName)); 178 LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins);
175 179
176 base::TimeTicks end_time = base::TimeTicks::Now(); 180 base::TimeTicks end_time = base::TimeTicks::Now();
177 base::TimeDelta elapsed = end_time - start_time; 181 base::TimeDelta elapsed = end_time - start_time;
178 DLOG(INFO) << "Loaded plugin list in " << elapsed.InMilliseconds() << " ms."; 182 DLOG(INFO) << "Loaded plugin list in " << elapsed.InMilliseconds() << " ms.";
183
184 AutoLock lock(lock_);
185 plugins_ = new_plugins;
186 plugins_loaded_ = true;
179 } 187 }
180 188
181 void PluginList::LoadPlugin(const FilePath &path) { 189 void PluginList::LoadPlugin(const FilePath &path,
190 std::vector<WebPluginInfo>* plugins) {
182 WebPluginInfo plugin_info; 191 WebPluginInfo plugin_info;
183 const PluginEntryPoints* entry_points; 192 const PluginEntryPoints* entry_points;
184 193
185 if (!ReadPluginInfo(path, &plugin_info, &entry_points)) 194 if (!ReadPluginInfo(path, &plugin_info, &entry_points))
186 return; 195 return;
187 196
188 if (!ShouldLoadPlugin(plugin_info)) 197 if (!ShouldLoadPlugin(plugin_info, plugins))
189 return; 198 return;
190 199
191 if (path.value() != kDefaultPluginLibraryName 200 if (path.value() != kDefaultPluginLibraryName
192 #if defined(OS_WIN) && !defined(NDEBUG) 201 #if defined(OS_WIN) && !defined(NDEBUG)
193 && path.BaseName().value() != L"npspy.dll" // Make an exception for NPSPY 202 && path.BaseName().value() != L"npspy.dll" // Make an exception for NPSPY
194 #endif 203 #endif
195 ) { 204 ) {
196 for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) { 205 for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) {
197 // TODO: don't load global handlers for now. 206 // TODO: don't load global handlers for now.
198 // WebKit hands to the Plugin before it tries 207 // WebKit hands to the Plugin before it tries
199 // to handle mimeTypes on its own. 208 // to handle mimeTypes on its own.
200 const std::string &mime_type = plugin_info.mime_types[i].mime_type; 209 const std::string &mime_type = plugin_info.mime_types[i].mime_type;
201 if (mime_type == "*" ) 210 if (mime_type == "*" )
202 return; 211 return;
203 } 212 }
204 } 213 }
205 214
206 plugins_.push_back(plugin_info); 215 plugins->push_back(plugin_info);
207 } 216 }
208 217
209 bool PluginList::FindPlugin(const std::string& mime_type, 218 bool PluginList::FindPlugin(const std::string& mime_type,
210 const std::string& clsid, 219 const std::string& clsid,
211 bool allow_wildcard, 220 bool allow_wildcard,
212 WebPluginInfo* info) { 221 WebPluginInfo* info) {
213 DCHECK(mime_type == StringToLowerASCII(mime_type)); 222 DCHECK(mime_type == StringToLowerASCII(mime_type));
214 223
224 LoadPlugins(false);
225 AutoLock lock(lock_);
215 for (size_t i = 0; i < plugins_.size(); ++i) { 226 for (size_t i = 0; i < plugins_.size(); ++i) {
216 if (SupportsType(plugins_[i], mime_type, allow_wildcard)) { 227 if (SupportsType(plugins_[i], mime_type, allow_wildcard)) {
217 #if defined(OS_WIN) 228 #if defined(OS_WIN)
218 if (!clsid.empty() && plugins_[i].path.value() == kActiveXShimFileName) { 229 if (!clsid.empty() && plugins_[i].path.value() == kActiveXShimFileName) {
219 // Special handling for ActiveX shim. If ActiveX is not installed, we 230 // Special handling for ActiveX shim. If ActiveX is not installed, we
220 // should use the default plugin to show the installation UI. 231 // should use the default plugin to show the installation UI.
221 if (!activex_shim::IsActiveXInstalled(clsid)) 232 if (!activex_shim::IsActiveXInstalled(clsid))
222 continue; 233 continue;
223 } 234 }
224 #endif 235 #endif
225 *info = plugins_[i]; 236 *info = plugins_[i];
226 return true; 237 return true;
227 } 238 }
228 } 239 }
229 240
230 return false; 241 return false;
231 } 242 }
232 243
233 bool PluginList::FindPlugin(const GURL &url, std::string* actual_mime_type, 244 bool PluginList::FindPlugin(const GURL &url, std::string* actual_mime_type,
234 WebPluginInfo* info) { 245 WebPluginInfo* info) {
246 LoadPlugins(false);
247 AutoLock lock(lock_);
235 std::string path = url.path(); 248 std::string path = url.path();
236 std::string::size_type last_dot = path.rfind('.'); 249 std::string::size_type last_dot = path.rfind('.');
237 if (last_dot == std::string::npos) 250 if (last_dot == std::string::npos)
238 return false; 251 return false;
239 252
240 std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); 253 std::string extension = StringToLowerASCII(std::string(path, last_dot+1));
241 254
242 for (size_t i = 0; i < plugins_.size(); ++i) { 255 for (size_t i = 0; i < plugins_.size(); ++i) {
243 if (SupportsExtension(plugins_[i], extension, actual_mime_type)) { 256 if (SupportsExtension(plugins_[i], extension, actual_mime_type)) {
244 *info = plugins_[i]; 257 *info = plugins_[i];
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 *actual_mime_type = mime_type.mime_type; 292 *actual_mime_type = mime_type.mime_type;
280 return true; 293 return true;
281 } 294 }
282 } 295 }
283 } 296 }
284 297
285 return false; 298 return false;
286 } 299 }
287 300
288 301
289 bool PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { 302 void PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
290 if (refresh) 303 LoadPlugins(refresh);
291 LoadPlugins(true);
292 304
305 AutoLock lock(lock_);
293 *plugins = plugins_; 306 *plugins = plugins_;
294
295 return true;
296 } 307 }
297 308
298 bool PluginList::GetPluginInfo(const GURL& url, 309 bool PluginList::GetPluginInfo(const GURL& url,
299 const std::string& mime_type, 310 const std::string& mime_type,
300 const std::string& clsid, 311 const std::string& clsid,
301 bool allow_wildcard, 312 bool allow_wildcard,
302 WebPluginInfo* info, 313 WebPluginInfo* info,
303 std::string* actual_mime_type) { 314 std::string* actual_mime_type) {
304 bool found = FindPlugin(mime_type, 315 bool found = FindPlugin(mime_type,
305 clsid, 316 clsid,
306 allow_wildcard, info); 317 allow_wildcard, info);
307 if (!found 318 if (!found
308 || (info->path.value() == kDefaultPluginLibraryName 319 || (info->path.value() == kDefaultPluginLibraryName
309 #if defined(OS_WIN) 320 #if defined(OS_WIN)
310 && clsid.empty() 321 && clsid.empty()
311 #endif 322 #endif
312 )) { 323 )) {
313 WebPluginInfo info2; 324 WebPluginInfo info2;
314 if (FindPlugin(url, actual_mime_type, &info2)) { 325 if (FindPlugin(url, actual_mime_type, &info2)) {
315 found = true; 326 found = true;
316 *info = info2; 327 *info = info2;
317 } 328 }
318 } 329 }
319 330
320 return found; 331 return found;
321 } 332 }
322 333
323 bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, 334 bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path,
324 WebPluginInfo* info) { 335 WebPluginInfo* info) {
336 LoadPlugins(false);
337 AutoLock lock(lock_);
325 for (size_t i = 0; i < plugins_.size(); ++i) { 338 for (size_t i = 0; i < plugins_.size(); ++i) {
326 if (plugins_[i].path == plugin_path) { 339 if (plugins_[i].path == plugin_path) {
327 *info = plugins_[i]; 340 *info = plugins_[i];
328 return true; 341 return true;
329 } 342 }
330 } 343 }
331 344
332 return false; 345 return false;
333 } 346 }
334 347
335 void PluginList::Shutdown() { 348 void PluginList::Shutdown() {
336 // TODO 349 // TODO
337 } 350 }
338 351
339 } // namespace NPAPI 352 } // namespace NPAPI
OLDNEW
« no previous file with comments | « webkit/glue/plugins/plugin_list.h ('k') | webkit/glue/plugins/plugin_list_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698