OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/plugin_service.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/command_line.h" | |
10 #include "base/path_service.h" | |
11 #include "base/string_util.h" | |
12 #include "base/threading/thread.h" | |
13 #include "base/utf_string_conversions.h" | |
14 #include "base/values.h" | |
15 #include "base/synchronization/waitable_event.h" | |
16 #include "chrome/browser/browser_process.h" | |
17 #include "chrome/browser/browser_thread.h" | |
18 #include "chrome/browser/chrome_plugin_host.h" | |
19 #include "chrome/browser/extensions/extension_service.h" | |
20 #include "chrome/browser/plugin_updater.h" | |
21 #include "chrome/browser/ppapi_plugin_process_host.h" | |
22 #include "chrome/browser/profiles/profile.h" | |
23 #include "chrome/browser/renderer_host/render_process_host.h" | |
24 #include "chrome/browser/renderer_host/render_view_host.h" | |
25 #include "chrome/common/chrome_plugin_lib.h" | |
26 #include "chrome/common/chrome_paths.h" | |
27 #include "chrome/common/chrome_switches.h" | |
28 #include "chrome/common/default_plugin.h" | |
29 #include "chrome/common/extensions/extension.h" | |
30 #include "chrome/common/gpu_plugin.h" | |
31 #include "chrome/common/logging_chrome.h" | |
32 #include "chrome/common/notification_type.h" | |
33 #include "chrome/common/notification_service.h" | |
34 #include "chrome/common/pepper_plugin_registry.h" | |
35 #include "chrome/common/plugin_messages.h" | |
36 #include "chrome/common/render_messages.h" | |
37 #include "webkit/plugins/npapi/plugin_constants_win.h" | |
38 #include "webkit/plugins/npapi/plugin_list.h" | |
39 #include "webkit/plugins/npapi/webplugininfo.h" | |
40 | |
41 #if defined(OS_CHROMEOS) | |
42 #include "chrome/browser/chromeos/plugin_selection_policy.h" | |
43 #endif | |
44 | |
45 #if defined(OS_MACOSX) | |
46 static void NotifyPluginsOfActivation() { | |
47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
48 | |
49 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS); | |
50 !iter.Done(); ++iter) { | |
51 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); | |
52 plugin->OnAppActivation(); | |
53 } | |
54 } | |
55 #endif | |
56 | |
57 static void PurgePluginListCache(bool reload_pages) { | |
58 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator(); | |
59 !it.IsAtEnd(); it.Advance()) { | |
60 it.GetCurrentValue()->Send(new ViewMsg_PurgePluginListCache(reload_pages)); | |
61 } | |
62 } | |
63 | |
64 #if defined(OS_LINUX) | |
65 // Delegate class for monitoring directories. | |
66 class PluginDirWatcherDelegate : public FilePathWatcher::Delegate { | |
67 virtual void OnFilePathChanged(const FilePath& path) { | |
68 VLOG(1) << "Watched path changed: " << path.value(); | |
69 // Make the plugin list update itself | |
70 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); | |
71 } | |
72 virtual void OnError() { | |
73 // TODO(pastarmovj): Add some sensible error handling. Maybe silently | |
74 // stopping the watcher would be enough. Or possibly restart it. | |
75 NOTREACHED(); | |
76 } | |
77 }; | |
78 #endif | |
79 | |
80 // static | |
81 bool PluginService::enable_chrome_plugins_ = true; | |
82 | |
83 // static | |
84 void PluginService::InitGlobalInstance(Profile* profile) { | |
85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
86 | |
87 // We first group the plugins and then figure out which groups to disable. | |
88 PluginUpdater::GetInstance()->DisablePluginGroupsFromPrefs(profile); | |
89 | |
90 // Have Chrome plugins write their data to the profile directory. | |
91 GetInstance()->SetChromePluginDataDir(profile->GetPath()); | |
92 } | |
93 | |
94 // static | |
95 PluginService* PluginService::GetInstance() { | |
96 return Singleton<PluginService>::get(); | |
97 } | |
98 | |
99 // static | |
100 void PluginService::EnableChromePlugins(bool enable) { | |
101 enable_chrome_plugins_ = enable; | |
102 } | |
103 | |
104 PluginService::PluginService() | |
105 : main_message_loop_(MessageLoop::current()), | |
106 resource_dispatcher_host_(NULL), | |
107 ui_locale_(g_browser_process->GetApplicationLocale()) { | |
108 RegisterPepperPlugins(); | |
109 | |
110 // Have the NPAPI plugin list search for Chrome plugins as well. | |
111 ChromePluginLib::RegisterPluginsWithNPAPI(); | |
112 | |
113 // Load any specified on the command line as well. | |
114 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
115 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin); | |
116 if (!path.empty()) | |
117 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path); | |
118 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir); | |
119 if (!path.empty()) | |
120 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(path); | |
121 | |
122 chrome::RegisterInternalDefaultPlugin(); | |
123 | |
124 // Register the internal Flash and PDF, if available. | |
125 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
126 switches::kDisableInternalFlash) && | |
127 PathService::Get(chrome::FILE_FLASH_PLUGIN, &path)) { | |
128 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path); | |
129 } | |
130 | |
131 #if defined(OS_CHROMEOS) | |
132 plugin_selection_policy_ = new chromeos::PluginSelectionPolicy; | |
133 plugin_selection_policy_->StartInit(); | |
134 #endif | |
135 | |
136 chrome::RegisterInternalGPUPlugin(); | |
137 | |
138 // Start watching for changes in the plugin list. This means watching | |
139 // for changes in the Windows registry keys and on both Windows and POSIX | |
140 // watch for changes in the paths that are expected to contain plugins. | |
141 #if defined(OS_WIN) | |
142 hkcu_key_.Create( | |
143 HKEY_CURRENT_USER, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY); | |
144 hklm_key_.Create( | |
145 HKEY_LOCAL_MACHINE, webkit::npapi::kRegistryMozillaPlugins, KEY_NOTIFY); | |
146 if (hkcu_key_.StartWatching() == ERROR_SUCCESS) { | |
147 hkcu_event_.reset(new base::WaitableEvent(hkcu_key_.watch_event())); | |
148 hkcu_watcher_.StartWatching(hkcu_event_.get(), this); | |
149 } | |
150 | |
151 if (hklm_key_.StartWatching() == ERROR_SUCCESS) { | |
152 hklm_event_.reset(new base::WaitableEvent(hklm_key_.watch_event())); | |
153 hklm_watcher_.StartWatching(hklm_event_.get(), this); | |
154 } | |
155 #elif defined(OS_POSIX) && !defined(OS_MACOSX) | |
156 // Also find plugins in a user-specific plugins dir, | |
157 // e.g. ~/.config/chromium/Plugins. | |
158 FilePath user_data_dir; | |
159 if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { | |
160 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir( | |
161 user_data_dir.Append("Plugins")); | |
162 } | |
163 #endif | |
164 // The FilePathWatcher produces too many false positives on MacOS (access time | |
165 // updates?) which will lead to enforcing updates of the plugins way too often. | |
166 // On ChromeOS the user can't install plugins anyway and on Windows all | |
167 // important plugins register themselves in the registry so no need to do that. | |
168 #if defined(OS_LINUX) | |
169 file_watcher_delegate_ = new PluginDirWatcherDelegate(); | |
170 // Get the list of all paths for registering the FilePathWatchers | |
171 // that will track and if needed reload the list of plugins on runtime. | |
172 std::vector<FilePath> plugin_dirs; | |
173 webkit::npapi::PluginList::Singleton()->GetPluginDirectories( | |
174 &plugin_dirs); | |
175 | |
176 for (size_t i = 0; i < plugin_dirs.size(); ++i) { | |
177 FilePathWatcher* watcher = new FilePathWatcher(); | |
178 // FilePathWatcher can not handle non-absolute paths under windows. | |
179 // We don't watch for file changes in windows now but if this should ever | |
180 // be extended to Windows these lines might save some time of debugging. | |
181 #if defined(OS_WIN) | |
182 if (!plugin_dirs[i].IsAbsolute()) | |
183 continue; | |
184 #endif | |
185 VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value(); | |
186 BrowserThread::PostTask( | |
187 BrowserThread::FILE, FROM_HERE, | |
188 NewRunnableFunction( | |
189 &PluginService::RegisterFilePathWatcher, | |
190 watcher, plugin_dirs[i], file_watcher_delegate_)); | |
191 file_watchers_.push_back(watcher); | |
192 } | |
193 #endif | |
194 registrar_.Add(this, NotificationType::EXTENSION_LOADED, | |
195 NotificationService::AllSources()); | |
196 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, | |
197 NotificationService::AllSources()); | |
198 #if defined(OS_MACOSX) | |
199 // We need to know when the browser comes forward so we can bring modal plugin | |
200 // windows forward too. | |
201 registrar_.Add(this, NotificationType::APP_ACTIVATED, | |
202 NotificationService::AllSources()); | |
203 #endif | |
204 registrar_.Add(this, NotificationType::PLUGIN_ENABLE_STATUS_CHANGED, | |
205 NotificationService::AllSources()); | |
206 registrar_.Add(this, | |
207 NotificationType::RENDERER_PROCESS_CLOSED, | |
208 NotificationService::AllSources()); | |
209 } | |
210 | |
211 PluginService::~PluginService() { | |
212 #if defined(OS_WIN) | |
213 // Release the events since they're owned by RegKey, not WaitableEvent. | |
214 hkcu_watcher_.StopWatching(); | |
215 hklm_watcher_.StopWatching(); | |
216 if (hkcu_event_.get()) | |
217 hkcu_event_->Release(); | |
218 if (hklm_event_.get()) | |
219 hklm_event_->Release(); | |
220 #endif | |
221 } | |
222 | |
223 void PluginService::LoadChromePlugins( | |
224 ResourceDispatcherHost* resource_dispatcher_host) { | |
225 if (!enable_chrome_plugins_) | |
226 return; | |
227 | |
228 resource_dispatcher_host_ = resource_dispatcher_host; | |
229 ChromePluginLib::LoadChromePlugins(GetCPBrowserFuncsForBrowser()); | |
230 } | |
231 | |
232 void PluginService::SetChromePluginDataDir(const FilePath& data_dir) { | |
233 chrome_plugin_data_dir_ = data_dir; | |
234 } | |
235 | |
236 const FilePath& PluginService::GetChromePluginDataDir() { | |
237 return chrome_plugin_data_dir_; | |
238 } | |
239 | |
240 const std::string& PluginService::GetUILocale() { | |
241 return ui_locale_; | |
242 } | |
243 | |
244 PluginProcessHost* PluginService::FindNpapiPluginProcess( | |
245 const FilePath& plugin_path) { | |
246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
247 | |
248 for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS); | |
249 !iter.Done(); ++iter) { | |
250 PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); | |
251 if (plugin->info().path == plugin_path) | |
252 return plugin; | |
253 } | |
254 | |
255 return NULL; | |
256 } | |
257 | |
258 PpapiPluginProcessHost* PluginService::FindPpapiPluginProcess( | |
259 const FilePath& plugin_path) { | |
260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
261 | |
262 for (BrowserChildProcessHost::Iterator iter( | |
263 ChildProcessInfo::PPAPI_PLUGIN_PROCESS); | |
264 !iter.Done(); ++iter) { | |
265 PpapiPluginProcessHost* plugin = | |
266 static_cast<PpapiPluginProcessHost*>(*iter); | |
267 if (plugin->plugin_path() == plugin_path) | |
268 return plugin; | |
269 } | |
270 | |
271 return NULL; | |
272 } | |
273 | |
274 PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess( | |
275 const FilePath& plugin_path) { | |
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
277 | |
278 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); | |
279 if (plugin_host) | |
280 return plugin_host; | |
281 | |
282 webkit::npapi::WebPluginInfo info; | |
283 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( | |
284 plugin_path, &info)) { | |
285 return NULL; | |
286 } | |
287 | |
288 // This plugin isn't loaded by any plugin process, so create a new process. | |
289 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); | |
290 if (!new_host->Init(info, ui_locale_)) { | |
291 NOTREACHED(); // Init is not expected to fail. | |
292 return NULL; | |
293 } | |
294 return new_host.release(); | |
295 } | |
296 | |
297 PpapiPluginProcessHost* PluginService::FindOrStartPpapiPluginProcess( | |
298 const FilePath& plugin_path) { | |
299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
300 | |
301 PpapiPluginProcessHost* plugin_host = FindPpapiPluginProcess(plugin_path); | |
302 if (plugin_host) | |
303 return plugin_host; | |
304 | |
305 // Validate that the plugin is actually registered. There should generally | |
306 // be very few plugins so a brute-force search is fine. | |
307 PepperPluginInfo* info = NULL; | |
308 for (size_t i = 0; i < ppapi_plugins_.size(); i++) { | |
309 if (ppapi_plugins_[i].path == plugin_path) { | |
310 info = &ppapi_plugins_[i]; | |
311 break; | |
312 } | |
313 } | |
314 if (!info) | |
315 return NULL; | |
316 | |
317 // This plugin isn't loaded by any plugin process, so create a new process. | |
318 scoped_ptr<PpapiPluginProcessHost> new_host(new PpapiPluginProcessHost); | |
319 if (!new_host->Init(plugin_path)) { | |
320 NOTREACHED(); // Init is not expected to fail. | |
321 return NULL; | |
322 } | |
323 return new_host.release(); | |
324 } | |
325 | |
326 void PluginService::OpenChannelToNpapiPlugin( | |
327 int render_process_id, | |
328 int render_view_id, | |
329 const GURL& url, | |
330 const std::string& mime_type, | |
331 PluginProcessHost::Client* client) { | |
332 // The PluginList::GetFirstAllowedPluginInfo may need to load the | |
333 // plugins. Don't do it on the IO thread. | |
334 BrowserThread::PostTask( | |
335 BrowserThread::FILE, FROM_HERE, | |
336 NewRunnableMethod( | |
337 this, &PluginService::GetAllowedPluginForOpenChannelToPlugin, | |
338 render_process_id, render_view_id, url, mime_type, client)); | |
339 } | |
340 | |
341 void PluginService::OpenChannelToPpapiPlugin( | |
342 const FilePath& path, | |
343 PpapiPluginProcessHost::Client* client) { | |
344 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess(path); | |
345 if (plugin_host) | |
346 plugin_host->OpenChannelToPlugin(client); | |
347 else // Send error. | |
348 client->OnChannelOpened(base::kNullProcessHandle, IPC::ChannelHandle()); | |
349 } | |
350 | |
351 void PluginService::GetAllowedPluginForOpenChannelToPlugin( | |
352 int render_process_id, | |
353 int render_view_id, | |
354 const GURL& url, | |
355 const std::string& mime_type, | |
356 PluginProcessHost::Client* client) { | |
357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
358 webkit::npapi::WebPluginInfo info; | |
359 bool found = GetFirstAllowedPluginInfo( | |
360 render_process_id, render_view_id, url, mime_type, &info, NULL); | |
361 FilePath plugin_path; | |
362 if (found && webkit::npapi::IsPluginEnabled(info)) | |
363 plugin_path = FilePath(info.path); | |
364 | |
365 // Now we jump back to the IO thread to finish opening the channel. | |
366 BrowserThread::PostTask( | |
367 BrowserThread::IO, FROM_HERE, | |
368 NewRunnableMethod( | |
369 this, &PluginService::FinishOpenChannelToPlugin, | |
370 plugin_path, client)); | |
371 } | |
372 | |
373 void PluginService::FinishOpenChannelToPlugin( | |
374 const FilePath& plugin_path, | |
375 PluginProcessHost::Client* client) { | |
376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
377 | |
378 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess(plugin_path); | |
379 if (plugin_host) | |
380 plugin_host->OpenChannelToPlugin(client); | |
381 else | |
382 client->OnError(); | |
383 } | |
384 | |
385 bool PluginService::GetFirstAllowedPluginInfo( | |
386 int render_process_id, | |
387 int render_view_id, | |
388 const GURL& url, | |
389 const std::string& mime_type, | |
390 webkit::npapi::WebPluginInfo* info, | |
391 std::string* actual_mime_type) { | |
392 // GetPluginInfoArray may need to load the plugins, so we need to be | |
393 // on the FILE thread. | |
394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
395 bool allow_wildcard = true; | |
396 #if defined(OS_CHROMEOS) | |
397 std::vector<webkit::npapi::WebPluginInfo> info_array; | |
398 std::vector<std::string> actual_mime_types; | |
399 webkit::npapi::PluginList::Singleton()->GetPluginInfoArray( | |
400 url, mime_type, allow_wildcard, &info_array, &actual_mime_types); | |
401 | |
402 // Now we filter by the plugin selection policy. | |
403 int allowed_index = plugin_selection_policy_->FindFirstAllowed(url, | |
404 info_array); | |
405 if (!info_array.empty() && allowed_index >= 0) { | |
406 *info = info_array[allowed_index]; | |
407 if (actual_mime_type) | |
408 *actual_mime_type = actual_mime_types[allowed_index]; | |
409 return true; | |
410 } | |
411 return false; | |
412 #else | |
413 { | |
414 base::AutoLock auto_lock(overridden_plugins_lock_); | |
415 for (size_t i = 0; i < overridden_plugins_.size(); ++i) { | |
416 if (overridden_plugins_[i].render_process_id == render_process_id && | |
417 overridden_plugins_[i].render_view_id == render_view_id && | |
418 overridden_plugins_[i].url == url) { | |
419 if (actual_mime_type) | |
420 *actual_mime_type = mime_type; | |
421 *info = overridden_plugins_[i].plugin; | |
422 return true; | |
423 } | |
424 } | |
425 } | |
426 return webkit::npapi::PluginList::Singleton()->GetPluginInfo( | |
427 url, mime_type, allow_wildcard, info, actual_mime_type); | |
428 #endif | |
429 } | |
430 | |
431 void PluginService::OnWaitableEventSignaled( | |
432 base::WaitableEvent* waitable_event) { | |
433 #if defined(OS_WIN) | |
434 if (waitable_event == hkcu_event_.get()) { | |
435 hkcu_key_.StartWatching(); | |
436 } else { | |
437 hklm_key_.StartWatching(); | |
438 } | |
439 | |
440 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); | |
441 PurgePluginListCache(true); | |
442 #else | |
443 // This event should only get signaled on a Windows machine. | |
444 NOTREACHED(); | |
445 #endif // defined(OS_WIN) | |
446 } | |
447 | |
448 static void ForceShutdownPlugin(const FilePath& plugin_path) { | |
449 PluginProcessHost* plugin = | |
450 PluginService::GetInstance()->FindNpapiPluginProcess(plugin_path); | |
451 if (plugin) | |
452 plugin->ForceShutdown(); | |
453 } | |
454 | |
455 void PluginService::Observe(NotificationType type, | |
456 const NotificationSource& source, | |
457 const NotificationDetails& details) { | |
458 switch (type.value) { | |
459 case NotificationType::EXTENSION_LOADED: { | |
460 const Extension* extension = Details<const Extension>(details).ptr(); | |
461 bool plugins_changed = false; | |
462 for (size_t i = 0; i < extension->plugins().size(); ++i) { | |
463 const Extension::PluginInfo& plugin = extension->plugins()[i]; | |
464 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); | |
465 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(plugin.path); | |
466 plugins_changed = true; | |
467 if (!plugin.is_public) | |
468 private_plugins_[plugin.path] = extension->url(); | |
469 } | |
470 if (plugins_changed) | |
471 PurgePluginListCache(false); | |
472 break; | |
473 } | |
474 | |
475 case NotificationType::EXTENSION_UNLOADED: { | |
476 const Extension* extension = | |
477 Details<UnloadedExtensionInfo>(details)->extension; | |
478 bool plugins_changed = false; | |
479 for (size_t i = 0; i < extension->plugins().size(); ++i) { | |
480 const Extension::PluginInfo& plugin = extension->plugins()[i]; | |
481 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
482 NewRunnableFunction(&ForceShutdownPlugin, | |
483 plugin.path)); | |
484 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); | |
485 webkit::npapi::PluginList::Singleton()->RemoveExtraPluginPath( | |
486 plugin.path); | |
487 plugins_changed = true; | |
488 if (!plugin.is_public) | |
489 private_plugins_.erase(plugin.path); | |
490 } | |
491 if (plugins_changed) | |
492 PurgePluginListCache(false); | |
493 break; | |
494 } | |
495 | |
496 #if defined(OS_MACOSX) | |
497 case NotificationType::APP_ACTIVATED: { | |
498 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
499 NewRunnableFunction(&NotifyPluginsOfActivation)); | |
500 break; | |
501 } | |
502 #endif | |
503 | |
504 case NotificationType::PLUGIN_ENABLE_STATUS_CHANGED: { | |
505 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); | |
506 PurgePluginListCache(false); | |
507 break; | |
508 } | |
509 case NotificationType::RENDERER_PROCESS_CLOSED: { | |
510 int render_process_id = Source<RenderProcessHost>(source).ptr()->id(); | |
511 | |
512 base::AutoLock auto_lock(overridden_plugins_lock_); | |
513 for (size_t i = 0; i < overridden_plugins_.size(); ++i) { | |
514 if (overridden_plugins_[i].render_process_id == render_process_id) { | |
515 overridden_plugins_.erase(overridden_plugins_.begin() + i); | |
516 break; | |
517 } | |
518 } | |
519 break; | |
520 } | |
521 default: | |
522 NOTREACHED(); | |
523 } | |
524 } | |
525 | |
526 bool PluginService::PrivatePluginAllowedForURL(const FilePath& plugin_path, | |
527 const GURL& url) { | |
528 if (url.is_empty()) | |
529 return true; // Caller wants all plugins. | |
530 | |
531 PrivatePluginMap::iterator it = private_plugins_.find(plugin_path); | |
532 if (it == private_plugins_.end()) | |
533 return true; // This plugin is not private, so it's allowed everywhere. | |
534 | |
535 // We do a dumb compare of scheme and host, rather than using the domain | |
536 // service, since we only care about this for extensions. | |
537 const GURL& required_url = it->second; | |
538 return (url.scheme() == required_url.scheme() && | |
539 url.host() == required_url.host()); | |
540 } | |
541 | |
542 void PluginService::OverridePluginForTab(OverriddenPlugin plugin) { | |
543 base::AutoLock auto_lock(overridden_plugins_lock_); | |
544 overridden_plugins_.push_back(plugin); | |
545 } | |
546 | |
547 void PluginService::RegisterPepperPlugins() { | |
548 PepperPluginRegistry::ComputeList(&ppapi_plugins_); | |
549 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) { | |
550 webkit::npapi::WebPluginInfo info; | |
551 info.path = ppapi_plugins_[i].path; | |
552 info.name = ppapi_plugins_[i].name.empty() ? | |
553 ppapi_plugins_[i].path.BaseName().LossyDisplayName() : | |
554 ASCIIToUTF16(ppapi_plugins_[i].name); | |
555 info.desc = ASCIIToUTF16(ppapi_plugins_[i].description); | |
556 info.version = ASCIIToUTF16(ppapi_plugins_[i].version); | |
557 info.enabled = webkit::npapi::WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED; | |
558 | |
559 // TODO(evan): Pepper shouldn't require us to parse strings to get | |
560 // the list of mime types out. | |
561 if (!webkit::npapi::PluginList::ParseMimeTypes( | |
562 JoinString(ppapi_plugins_[i].mime_types, '|'), | |
563 ppapi_plugins_[i].file_extensions, | |
564 ASCIIToUTF16(ppapi_plugins_[i].type_descriptions), | |
565 &info.mime_types)) { | |
566 LOG(ERROR) << "Error parsing mime types for " | |
567 << ppapi_plugins_[i].path.LossyDisplayName(); | |
568 return; | |
569 } | |
570 | |
571 webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(info); | |
572 } | |
573 } | |
574 | |
575 #if defined(OS_LINUX) | |
576 // static | |
577 void PluginService::RegisterFilePathWatcher( | |
578 FilePathWatcher *watcher, | |
579 const FilePath& path, | |
580 FilePathWatcher::Delegate* delegate) { | |
581 bool result = watcher->Watch(path, delegate); | |
582 DCHECK(result); | |
583 } | |
584 #endif | |
OLD | NEW |