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

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

Issue 1862513003: Remove NPAPI from browser and utility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 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
OLDNEW
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/plugin_list.h" 5 #include "content/common/plugin_list.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
15 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
16 #include "base/strings/sys_string_conversions.h" 16 #include "base/strings/sys_string_conversions.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "build/build_config.h" 18 #include "build/build_config.h"
19 #include "content/public/common/content_switches.h" 19 #include "content/public/common/content_switches.h"
20 #include "net/base/mime_util.h" 20 #include "net/base/mime_util.h"
21 #include "url/gurl.h" 21 #include "url/gurl.h"
22 22
23 #if defined(OS_WIN)
24 #include "content/common/plugin_constants_win.h"
25 #endif
26
27 namespace content { 23 namespace content {
28 24
29 namespace { 25 namespace {
30 26
31 base::LazyInstance<PluginList> g_singleton = LAZY_INSTANCE_INITIALIZER; 27 base::LazyInstance<PluginList> g_singleton = LAZY_INSTANCE_INITIALIZER;
32 28
33 } // namespace 29 } // namespace
34 30
35 // static 31 // static
36 PluginList* PluginList::Singleton() { 32 PluginList* PluginList::Singleton() {
37 return g_singleton.Pointer(); 33 return g_singleton.Pointer();
38 } 34 }
39 35
40 // static
41 bool PluginList::DebugPluginLoading() {
42 return base::CommandLine::ForCurrentProcess()->HasSwitch(
43 switches::kDebugPluginLoading);
44 }
45
46 void PluginList::DisablePluginsDiscovery() {
47 plugins_discovery_disabled_ = true;
48 }
49
50 void PluginList::RefreshPlugins() { 36 void PluginList::RefreshPlugins() {
51 base::AutoLock lock(lock_); 37 base::AutoLock lock(lock_);
52 loading_state_ = LOADING_STATE_NEEDS_REFRESH; 38 loading_state_ = LOADING_STATE_NEEDS_REFRESH;
53 } 39 }
54 40
55 void PluginList::AddExtraPluginPath(const base::FilePath& plugin_path) {
56 // Chrome OS only loads plugins from /opt/google/chrome/plugins.
57 #if !defined(OS_CHROMEOS)
58 base::AutoLock lock(lock_);
59 extra_plugin_paths_.push_back(plugin_path);
60 #endif
61 }
62
63 void PluginList::RemoveExtraPluginPath(const base::FilePath& plugin_path) {
64 base::AutoLock lock(lock_);
65 RemoveExtraPluginPathLocked(plugin_path);
66 }
67
68 void PluginList::AddExtraPluginDir(const base::FilePath& plugin_dir) {
69 // Chrome OS only loads plugins from /opt/google/chrome/plugins.
70 #if !defined(OS_CHROMEOS)
71 base::AutoLock lock(lock_);
72 extra_plugin_dirs_.push_back(plugin_dir);
73 #endif
74 }
75
76 void PluginList::RegisterInternalPlugin(const WebPluginInfo& info, 41 void PluginList::RegisterInternalPlugin(const WebPluginInfo& info,
77 bool add_at_beginning) { 42 bool add_at_beginning) {
78 base::AutoLock lock(lock_); 43 base::AutoLock lock(lock_);
79 44
80 internal_plugins_.push_back(info); 45 internal_plugins_.push_back(info);
81 if (add_at_beginning) { 46 if (add_at_beginning) {
82 // Newer registrations go earlier in the list so they can override the MIME 47 // Newer registrations go earlier in the list so they can override the MIME
83 // types of older registrations. 48 // types of older registrations.
84 extra_plugin_paths_.insert(extra_plugin_paths_.begin(), info.path); 49 extra_plugin_paths_.insert(extra_plugin_paths_.begin(), info.path);
85 } else { 50 } else {
(...skipping 21 matching lines...) Expand all
107 72
108 for (std::vector<WebPluginInfo>::iterator it = internal_plugins_.begin(); 73 for (std::vector<WebPluginInfo>::iterator it = internal_plugins_.begin();
109 it != internal_plugins_.end(); 74 it != internal_plugins_.end();
110 ++it) { 75 ++it) {
111 internal_plugins->push_back(*it); 76 internal_plugins->push_back(*it);
112 } 77 }
113 } 78 }
114 79
115 bool PluginList::ReadPluginInfo(const base::FilePath& filename, 80 bool PluginList::ReadPluginInfo(const base::FilePath& filename,
116 WebPluginInfo* info) { 81 WebPluginInfo* info) {
117 { 82 base::AutoLock lock(lock_);
118 base::AutoLock lock(lock_); 83 for (const auto& plugin : internal_plugins_) {
119 for (size_t i = 0; i < internal_plugins_.size(); ++i) { 84 if (filename == plugin.path) {
120 if (filename == internal_plugins_[i].path) { 85 *info = plugin;
121 *info = internal_plugins_[i]; 86 return true;
122 return true;
123 }
124 } 87 }
125 } 88 }
126 89 return false;
127 return PluginList::ReadWebPluginInfo(filename, info);
128 }
129
130 // static
131 bool PluginList::ParseMimeTypes(
132 const std::string& mime_types_str,
133 const std::string& file_extensions_str,
134 const base::string16& mime_type_descriptions_str,
135 std::vector<WebPluginMimeType>* parsed_mime_types) {
136 std::vector<std::string> mime_types = base::SplitString(
137 mime_types_str, "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
138 std::vector<std::string> file_extensions = base::SplitString(
139 file_extensions_str, "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
140 std::vector<base::string16> descriptions = base::SplitString(
141 mime_type_descriptions_str, base::string16(1, '|'), base::TRIM_WHITESPACE,
142 base::SPLIT_WANT_ALL);
143
144 parsed_mime_types->clear();
145
146 if (mime_types.empty())
147 return false;
148
149 for (size_t i = 0; i < mime_types.size(); ++i) {
150 WebPluginMimeType mime_type;
151 mime_type.mime_type = base::ToLowerASCII(mime_types[i]);
152 if (file_extensions.size() > i) {
153 mime_type.file_extensions = base::SplitString(
154 file_extensions[i], ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
155 }
156
157 if (descriptions.size() > i) {
158 mime_type.description = descriptions[i];
159
160 // On Windows, the description likely has a list of file extensions
161 // embedded in it (e.g. "SurfWriter file (*.swr)"). Remove an extension
162 // list from the description if it is present.
163 size_t ext = mime_type.description.find(base::ASCIIToUTF16("(*"));
164 if (ext != base::string16::npos) {
165 if (ext > 1 && mime_type.description[ext - 1] == ' ')
166 ext--;
167
168 mime_type.description.erase(ext);
169 }
170 }
171
172 parsed_mime_types->push_back(mime_type);
173 }
174
175 return true;
176 } 90 }
177 91
178 PluginList::PluginList() 92 PluginList::PluginList()
179 : loading_state_(LOADING_STATE_NEEDS_REFRESH), 93 : loading_state_(LOADING_STATE_NEEDS_REFRESH) {
180 plugins_discovery_disabled_(false) {
181 } 94 }
182 95
183 bool PluginList::PrepareForPluginLoading() { 96 bool PluginList::PrepareForPluginLoading() {
184 base::AutoLock lock(lock_); 97 base::AutoLock lock(lock_);
185 if (loading_state_ == LOADING_STATE_UP_TO_DATE) 98 if (loading_state_ == LOADING_STATE_UP_TO_DATE)
186 return false; 99 return false;
187 100
188 loading_state_ = LOADING_STATE_REFRESHING; 101 loading_state_ = LOADING_STATE_REFRESHING;
189 return true; 102 return true;
190 } 103 }
191 104
192 void PluginList::LoadPlugins(bool include_npapi) { 105 void PluginList::LoadPlugins() {
193 if (!PrepareForPluginLoading()) 106 if (!PrepareForPluginLoading())
194 return; 107 return;
195 108
196 std::vector<WebPluginInfo> new_plugins; 109 std::vector<WebPluginInfo> new_plugins;
197 base::Closure will_load_callback; 110 base::Closure will_load_callback;
198 { 111 {
199 base::AutoLock lock(lock_); 112 base::AutoLock lock(lock_);
200 will_load_callback = will_load_plugins_callback_; 113 will_load_callback = will_load_plugins_callback_;
201 } 114 }
202 if (!will_load_callback.is_null()) 115 if (!will_load_callback.is_null())
203 will_load_callback.Run(); 116 will_load_callback.Run();
204 117
205 std::vector<base::FilePath> plugin_paths; 118 std::vector<base::FilePath> plugin_paths;
206 GetPluginPathsToLoad(&plugin_paths, include_npapi); 119 GetPluginPathsToLoad(&plugin_paths);
207 120
208 for (std::vector<base::FilePath>::const_iterator it = plugin_paths.begin(); 121 for (std::vector<base::FilePath>::const_iterator it = plugin_paths.begin();
209 it != plugin_paths.end(); 122 it != plugin_paths.end();
210 ++it) { 123 ++it) {
211 WebPluginInfo plugin_info; 124 WebPluginInfo plugin_info;
212 LoadPluginIntoPluginList(*it, &new_plugins, &plugin_info); 125 LoadPluginIntoPluginList(*it, &new_plugins, &plugin_info);
213 } 126 }
214 127
215 SetPlugins(new_plugins); 128 SetPlugins(new_plugins);
piman 2016/04/05 06:00:48 At this point this is pretty much just a roundabou
216 } 129 }
217 130
218 bool PluginList::LoadPluginIntoPluginList( 131 bool PluginList::LoadPluginIntoPluginList(
219 const base::FilePath& path, 132 const base::FilePath& path,
220 std::vector<WebPluginInfo>* plugins, 133 std::vector<WebPluginInfo>* plugins,
221 WebPluginInfo* plugin_info) { 134 WebPluginInfo* plugin_info) {
222 LOG_IF(ERROR, PluginList::DebugPluginLoading())
223 << "Loading plugin " << path.value();
224 if (!ReadPluginInfo(path, plugin_info)) 135 if (!ReadPluginInfo(path, plugin_info))
225 return false; 136 return false;
226 137
227 if (!ShouldLoadPluginUsingPluginList(*plugin_info, plugins)) 138 // TODO(piman): Do we still need this after NPAPI removal?
228 return false; 139 for (size_t i = 0; i < plugin_info->mime_types.size(); ++i) {
229 140 // TODO: don't load global handlers for now.
230 #if defined(OS_WIN) && !defined(NDEBUG) 141 // WebKit hands to the Plugin before it tries
231 if (path.BaseName().value() != L"npspy.dll") // Make an exception for NPSPY 142 // to handle mimeTypes on its own.
232 #endif 143 const std::string &mime_type = plugin_info->mime_types[i].mime_type;
233 { 144 if (mime_type == "*")
234 for (size_t i = 0; i < plugin_info->mime_types.size(); ++i) { 145 return false;
235 // TODO: don't load global handlers for now.
236 // WebKit hands to the Plugin before it tries
237 // to handle mimeTypes on its own.
238 const std::string &mime_type = plugin_info->mime_types[i].mime_type;
239 if (mime_type == "*")
240 return false;
241 }
242 } 146 }
243 plugins->push_back(*plugin_info); 147 plugins->push_back(*plugin_info);
244 return true; 148 return true;
245 } 149 }
246 150
247 void PluginList::GetPluginPathsToLoad(std::vector<base::FilePath>* plugin_paths, 151 void PluginList::GetPluginPathsToLoad(
248 bool include_npapi) { 152 std::vector<base::FilePath>* plugin_paths) {
249 // Don't want to hold the lock while loading new plugins, so we don't block 153 // Don't want to hold the lock while loading new plugins, so we don't block
250 // other methods if they're called on other threads. 154 // other methods if they're called on other threads.
251 std::vector<base::FilePath> extra_plugin_paths; 155 std::vector<base::FilePath> extra_plugin_paths;
252 std::vector<base::FilePath> extra_plugin_dirs;
253 { 156 {
254 base::AutoLock lock(lock_); 157 base::AutoLock lock(lock_);
255 extra_plugin_paths = extra_plugin_paths_; 158 extra_plugin_paths = extra_plugin_paths_;
256 extra_plugin_dirs = extra_plugin_dirs_;
257 } 159 }
258 160
259 for (size_t i = 0; i < extra_plugin_paths.size(); ++i) { 161 for (size_t i = 0; i < extra_plugin_paths.size(); ++i) {
260 const base::FilePath& path = extra_plugin_paths[i]; 162 const base::FilePath& path = extra_plugin_paths[i];
261 if (std::find(plugin_paths->begin(), plugin_paths->end(), path) != 163 if (std::find(plugin_paths->begin(), plugin_paths->end(), path) !=
262 plugin_paths->end()) { 164 plugin_paths->end()) {
263 continue; 165 continue;
264 } 166 }
265 plugin_paths->push_back(path); 167 plugin_paths->push_back(path);
266 } 168 }
267
268 if (include_npapi) {
269 // A bit confusingly, this function is used to load Pepper plugins as well.
270 // Those are all internal plugins so we have to use extra_plugin_paths.
271 for (size_t i = 0; i < extra_plugin_dirs.size(); ++i)
272 GetPluginsInDir(extra_plugin_dirs[i], plugin_paths);
273
274 std::vector<base::FilePath> directories_to_scan;
275 GetPluginDirectories(&directories_to_scan);
276 for (size_t i = 0; i < directories_to_scan.size(); ++i)
277 GetPluginsInDir(directories_to_scan[i], plugin_paths);
278
279 #if defined(OS_WIN)
280 GetPluginPathsFromRegistry(plugin_paths);
281 #endif
282 }
283 } 169 }
284 170
285 void PluginList::SetPlugins(const std::vector<WebPluginInfo>& plugins) { 171 void PluginList::SetPlugins(const std::vector<WebPluginInfo>& plugins) {
286 base::AutoLock lock(lock_); 172 base::AutoLock lock(lock_);
287 173
288 // If we haven't been invalidated in the mean time, mark the plugin list as 174 // If we haven't been invalidated in the mean time, mark the plugin list as
289 // up-to-date. 175 // up-to-date.
290 if (loading_state_ != LOADING_STATE_NEEDS_REFRESH) 176 if (loading_state_ != LOADING_STATE_NEEDS_REFRESH)
291 loading_state_ = LOADING_STATE_UP_TO_DATE; 177 loading_state_ = LOADING_STATE_UP_TO_DATE;
292 178
293 plugins_list_ = plugins; 179 plugins_list_ = plugins;
294 } 180 }
295 181
296 void PluginList::set_will_load_plugins_callback(const base::Closure& callback) { 182 void PluginList::set_will_load_plugins_callback(const base::Closure& callback) {
297 base::AutoLock lock(lock_); 183 base::AutoLock lock(lock_);
298 will_load_plugins_callback_ = callback; 184 will_load_plugins_callback_ = callback;
299 } 185 }
300 186
301 void PluginList::GetPlugins(std::vector<WebPluginInfo>* plugins, 187 void PluginList::GetPlugins(std::vector<WebPluginInfo>* plugins) {
302 bool include_npapi) { 188 LoadPlugins();
303 LoadPlugins(include_npapi);
304 base::AutoLock lock(lock_); 189 base::AutoLock lock(lock_);
305 plugins->insert(plugins->end(), plugins_list_.begin(), plugins_list_.end()); 190 plugins->insert(plugins->end(), plugins_list_.begin(), plugins_list_.end());
306 } 191 }
307 192
308 bool PluginList::GetPluginsNoRefresh(std::vector<WebPluginInfo>* plugins) { 193 bool PluginList::GetPluginsNoRefresh(std::vector<WebPluginInfo>* plugins) {
309 base::AutoLock lock(lock_); 194 base::AutoLock lock(lock_);
310 plugins->insert(plugins->end(), plugins_list_.begin(), plugins_list_.end()); 195 plugins->insert(plugins->end(), plugins_list_.begin(), plugins_list_.end());
311 196
312 return loading_state_ == LOADING_STATE_UP_TO_DATE; 197 return loading_state_ == LOADING_STATE_UP_TO_DATE;
313 } 198 }
314 199
315 void PluginList::GetPluginInfoArray( 200 void PluginList::GetPluginInfoArray(
316 const GURL& url, 201 const GURL& url,
317 const std::string& mime_type, 202 const std::string& mime_type,
318 bool allow_wildcard, 203 bool allow_wildcard,
319 bool* use_stale, 204 bool* use_stale,
320 bool include_npapi,
321 std::vector<WebPluginInfo>* info, 205 std::vector<WebPluginInfo>* info,
322 std::vector<std::string>* actual_mime_types) { 206 std::vector<std::string>* actual_mime_types) {
323 DCHECK(mime_type == base::ToLowerASCII(mime_type)); 207 DCHECK(mime_type == base::ToLowerASCII(mime_type));
324 DCHECK(info); 208 DCHECK(info);
325 209
326 if (!use_stale) 210 if (!use_stale)
327 LoadPlugins(include_npapi); 211 LoadPlugins();
328 base::AutoLock lock(lock_); 212 base::AutoLock lock(lock_);
329 if (use_stale) 213 if (use_stale)
330 *use_stale = (loading_state_ != LOADING_STATE_UP_TO_DATE); 214 *use_stale = (loading_state_ != LOADING_STATE_UP_TO_DATE);
331 info->clear(); 215 info->clear();
332 if (actual_mime_types) 216 if (actual_mime_types)
333 actual_mime_types->clear(); 217 actual_mime_types->clear();
334 218
335 std::set<base::FilePath> visited_plugins; 219 std::set<base::FilePath> visited_plugins;
336 220
337 // Add in plugins by mime type. 221 // Add in plugins by mime type.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 plugin_path); 297 plugin_path);
414 if (it != extra_plugin_paths_.end()) 298 if (it != extra_plugin_paths_.end())
415 extra_plugin_paths_.erase(it); 299 extra_plugin_paths_.erase(it);
416 } 300 }
417 301
418 PluginList::~PluginList() { 302 PluginList::~PluginList() {
419 } 303 }
420 304
421 305
422 } // namespace content 306 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698