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 "chrome/browser/plugins/plugin_prefs.h" | 5 #include "chrome/browser/plugins/plugin_prefs.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
25 #include "chrome/common/chrome_constants.h" | 25 #include "chrome/common/chrome_constants.h" |
26 #include "chrome/common/chrome_content_client.h" | 26 #include "chrome/common/chrome_content_client.h" |
27 #include "chrome/common/chrome_paths.h" | 27 #include "chrome/common/chrome_paths.h" |
28 #include "chrome/common/chrome_switches.h" | 28 #include "chrome/common/chrome_switches.h" |
29 #include "chrome/common/pref_names.h" | 29 #include "chrome/common/pref_names.h" |
30 #include "components/browser_context_keyed_service/browser_context_keyed_service
.h" | 30 #include "components/browser_context_keyed_service/browser_context_keyed_service
.h" |
31 #include "content/public/browser/browser_thread.h" | 31 #include "content/public/browser/browser_thread.h" |
32 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
33 #include "content/public/browser/plugin_service.h" | 33 #include "content/public/browser/plugin_service.h" |
34 #include "webkit/plugins/npapi/plugin_list.h" | |
35 #include "webkit/plugins/webplugininfo.h" | 34 #include "webkit/plugins/webplugininfo.h" |
36 | 35 |
37 using content::BrowserThread; | 36 using content::BrowserThread; |
38 using content::PluginService; | 37 using content::PluginService; |
39 | 38 |
40 namespace { | 39 namespace { |
41 | 40 |
42 // How long to wait to save the plugin enabled information, which might need to | |
43 // go to disk. | |
44 const int64 kPluginUpdateDelayMs = 60 * 1000; | |
45 | |
46 bool IsComponentUpdatedPepperFlash(const base::FilePath& plugin) { | 41 bool IsComponentUpdatedPepperFlash(const base::FilePath& plugin) { |
47 if (plugin.BaseName().value() == chrome::kPepperFlashPluginFilename) { | 42 if (plugin.BaseName().value() == chrome::kPepperFlashPluginFilename) { |
48 base::FilePath component_updated_pepper_flash_dir; | 43 base::FilePath component_updated_pepper_flash_dir; |
49 if (PathService::Get(chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, | 44 if (PathService::Get(chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, |
50 &component_updated_pepper_flash_dir) && | 45 &component_updated_pepper_flash_dir) && |
51 component_updated_pepper_flash_dir.IsParent(plugin)) { | 46 component_updated_pepper_flash_dir.IsParent(plugin)) { |
52 return true; | 47 return true; |
53 } | 48 } |
54 } | 49 } |
55 | 50 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 } | 94 } |
100 | 95 |
101 // static | 96 // static |
102 scoped_refptr<PluginPrefs> PluginPrefs::GetForTestingProfile( | 97 scoped_refptr<PluginPrefs> PluginPrefs::GetForTestingProfile( |
103 Profile* profile) { | 98 Profile* profile) { |
104 return static_cast<PluginPrefs*>( | 99 return static_cast<PluginPrefs*>( |
105 PluginPrefsFactory::GetInstance()->SetTestingFactoryAndUse( | 100 PluginPrefsFactory::GetInstance()->SetTestingFactoryAndUse( |
106 profile, &PluginPrefsFactory::CreateForTestingProfile).get()); | 101 profile, &PluginPrefsFactory::CreateForTestingProfile).get()); |
107 } | 102 } |
108 | 103 |
109 void PluginPrefs::SetPluginListForTesting( | |
110 webkit::npapi::PluginList* plugin_list) { | |
111 plugin_list_ = plugin_list; | |
112 } | |
113 | |
114 void PluginPrefs::EnablePluginGroup(bool enabled, const string16& group_name) { | 104 void PluginPrefs::EnablePluginGroup(bool enabled, const string16& group_name) { |
115 PluginService::GetInstance()->GetPlugins( | 105 PluginService::GetInstance()->GetPlugins( |
116 base::Bind(&PluginPrefs::EnablePluginGroupInternal, | 106 base::Bind(&PluginPrefs::EnablePluginGroupInternal, |
117 this, enabled, group_name)); | 107 this, enabled, group_name)); |
118 } | 108 } |
119 | 109 |
120 void PluginPrefs::EnablePluginGroupInternal( | 110 void PluginPrefs::EnablePluginGroupInternal( |
121 bool enabled, | 111 bool enabled, |
122 const string16& group_name, | 112 const string16& group_name, |
123 const std::vector<webkit::WebPluginInfo>& plugins) { | 113 const std::vector<webkit::WebPluginInfo>& plugins) { |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 base::FilePath last_internal_dir = | 309 base::FilePath last_internal_dir = |
320 prefs_->GetFilePath(prefs::kPluginsLastInternalDirectory); | 310 prefs_->GetFilePath(prefs::kPluginsLastInternalDirectory); |
321 base::FilePath cur_internal_dir; | 311 base::FilePath cur_internal_dir; |
322 if (PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &cur_internal_dir) && | 312 if (PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &cur_internal_dir) && |
323 cur_internal_dir != last_internal_dir) { | 313 cur_internal_dir != last_internal_dir) { |
324 update_internal_dir = true; | 314 update_internal_dir = true; |
325 prefs_->SetFilePath( | 315 prefs_->SetFilePath( |
326 prefs::kPluginsLastInternalDirectory, cur_internal_dir); | 316 prefs::kPluginsLastInternalDirectory, cur_internal_dir); |
327 } | 317 } |
328 | 318 |
329 bool force_enable_nacl = false; | |
330 string16 nacl_group_name = | |
331 ASCIIToUTF16(chrome::ChromeContentClient::kNaClPluginName); | |
332 // Since the NaCl Plugin changed names between Chrome 13 and 14, we need to | |
333 // check for both because either could be stored as the plugin group name. | |
334 string16 old_nacl_group_name = | |
335 ASCIIToUTF16(chrome::ChromeContentClient::kNaClOldPluginName); | |
336 base::FilePath nacl_path; | |
337 PathService::Get(chrome::FILE_NACL_PLUGIN, &nacl_path); | |
338 base::FilePath::StringType nacl_path_str = nacl_path.value(); | |
339 if (!prefs_->GetBoolean(prefs::kPluginsEnabledNaCl)) { | |
340 // We switched to the nacl plugin being on by default, and so we need to | |
341 // force it to be enabled. We only want to do it this once though, i.e. | |
342 // we don't want to enable it again if the user disables it afterwards. | |
343 prefs_->SetBoolean(prefs::kPluginsEnabledNaCl, true); | |
344 force_enable_nacl = true; | |
345 } | |
346 | |
347 bool migrate_to_pepper_flash = false; | 319 bool migrate_to_pepper_flash = false; |
348 #if defined(OS_WIN) || defined(OS_MACOSX) | 320 #if defined(OS_WIN) || defined(OS_MACOSX) |
349 // If bundled NPAPI Flash is enabled while Pepper Flash is disabled, we | 321 // If bundled NPAPI Flash is enabled while Pepper Flash is disabled, we |
350 // would like to turn Pepper Flash on. And we only want to do it once. | 322 // would like to turn Pepper Flash on. And we only want to do it once. |
351 // TODO(yzshen): Remove all |migrate_to_pepper_flash|-related code after it | 323 // TODO(yzshen): Remove all |migrate_to_pepper_flash|-related code after it |
352 // has been run once by most users. (Maybe Chrome 24 or Chrome 25.) | 324 // has been run once by most users. (Maybe Chrome 24 or Chrome 25.) |
353 // NOTE(shess): Keep in mind that Mac is on a different schedule. | 325 // NOTE(shess): Keep in mind that Mac is on a different schedule. |
354 if (!prefs_->GetBoolean(prefs::kPluginsMigratedToPepperFlash)) { | 326 if (!prefs_->GetBoolean(prefs::kPluginsMigratedToPepperFlash)) { |
355 prefs_->SetBoolean(prefs::kPluginsMigratedToPepperFlash, true); | 327 prefs_->SetBoolean(prefs::kPluginsMigratedToPepperFlash, true); |
356 migrate_to_pepper_flash = true; | 328 migrate_to_pepper_flash = true; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 | 414 |
443 // If |relative_path| is empty, |plugin_path| is not within | 415 // If |relative_path| is empty, |plugin_path| is not within |
444 // |last_internal_dir|. We don't need to update it. | 416 // |last_internal_dir|. We don't need to update it. |
445 if (!relative_path.empty()) { | 417 if (!relative_path.empty()) { |
446 plugin_path = cur_internal_dir.Append(relative_path); | 418 plugin_path = cur_internal_dir.Append(relative_path); |
447 path = plugin_path.value(); | 419 path = plugin_path.value(); |
448 plugin->SetString("path", path); | 420 plugin->SetString("path", path); |
449 } | 421 } |
450 } | 422 } |
451 | 423 |
452 if (base::FilePath::CompareIgnoreCase(path, nacl_path_str) == 0) { | 424 if (migrate_to_pepper_flash && |
453 if (!enabled && force_enable_nacl) { | |
454 enabled = true; | |
455 plugin->SetBoolean("enabled", true); | |
456 } | |
457 } else if (migrate_to_pepper_flash && | |
458 base::FilePath::CompareEqualIgnoreCase( | 425 base::FilePath::CompareEqualIgnoreCase( |
459 path, npapi_flash.value())) { | 426 path, npapi_flash.value())) { |
460 npapi_flash_enabled = enabled; | 427 npapi_flash_enabled = enabled; |
461 } else if (migrate_to_pepper_flash && | 428 } else if (migrate_to_pepper_flash && |
462 base::FilePath::CompareEqualIgnoreCase( | 429 base::FilePath::CompareEqualIgnoreCase( |
463 path, pepper_flash.value())) { | 430 path, pepper_flash.value())) { |
464 if (!enabled) | 431 if (!enabled) |
465 pepper_flash_node = plugin; | 432 pepper_flash_node = plugin; |
466 } else if (remove_component_pepper_flash_settings && | 433 } else if (remove_component_pepper_flash_settings && |
467 IsComponentUpdatedPepperFlash(plugin_path)) { | 434 IsComponentUpdatedPepperFlash(plugin_path)) { |
468 if (!enabled) { | 435 if (!enabled) { |
469 component_pepper_flash_node = it; | 436 component_pepper_flash_node = it; |
470 // Skip setting |enabled| into |plugin_state_|. | 437 // Skip setting |enabled| into |plugin_state_|. |
471 continue; | 438 continue; |
472 } | 439 } |
473 } | 440 } |
474 | 441 |
475 plugin_state_.Set(plugin_path, enabled); | 442 plugin_state_.Set(plugin_path, enabled); |
476 } else if (!enabled && plugin->GetString("name", &group_name)) { | 443 } else if (!enabled && plugin->GetString("name", &group_name)) { |
477 // Don't disable this group if it's for the nacl plugin and we just | |
478 // forced it on. | |
479 if (force_enable_nacl && (nacl_group_name == group_name || | |
480 old_nacl_group_name == group_name)) | |
481 continue; | |
482 | |
483 // Otherwise this is a list of groups. | 444 // Otherwise this is a list of groups. |
484 plugin_group_state_[group_name] = false; | 445 plugin_group_state_[group_name] = false; |
485 } | 446 } |
486 } | 447 } |
487 | 448 |
488 if (npapi_flash_enabled && pepper_flash_node) { | 449 if (npapi_flash_enabled && pepper_flash_node) { |
489 DCHECK(migrate_to_pepper_flash); | 450 DCHECK(migrate_to_pepper_flash); |
490 pepper_flash_node->SetBoolean("enabled", true); | 451 pepper_flash_node->SetBoolean("enabled", true); |
491 plugin_state_.Set(pepper_flash, true); | 452 plugin_state_.Set(pepper_flash, true); |
492 } | 453 } |
493 | 454 |
494 if (component_pepper_flash_node != saved_plugins_list->end()) { | 455 if (component_pepper_flash_node != saved_plugins_list->end()) { |
495 DCHECK(remove_component_pepper_flash_settings); | 456 DCHECK(remove_component_pepper_flash_settings); |
496 saved_plugins_list->Erase(component_pepper_flash_node, NULL); | 457 saved_plugins_list->Erase(component_pepper_flash_node, NULL); |
497 } | 458 } |
498 } else { | 459 } else { |
499 // If the saved plugin list is empty, then the call to UpdatePreferences() | 460 // If the saved plugin list is empty, then the call to UpdatePreferences() |
500 // below failed in an earlier run, possibly because the user closed the | 461 // below failed in an earlier run, possibly because the user closed the |
501 // browser too quickly. Try to force enable the internal nacl plugin | 462 // browser too quickly. |
502 // again. | |
503 force_enable_nacl = true; | |
504 | 463 |
505 // Only want one PDF plugin enabled at a time. See http://crbug.com/50105 | 464 // Only want one PDF plugin enabled at a time. See http://crbug.com/50105 |
506 // for background. | 465 // for background. |
507 plugin_group_state_[ASCIIToUTF16( | 466 plugin_group_state_[ASCIIToUTF16( |
508 PluginMetadata::kAdobeReaderGroupName)] = false; | 467 PluginMetadata::kAdobeReaderGroupName)] = false; |
509 } | 468 } |
510 } // Scoped update of prefs::kPluginsPluginsList. | 469 } // Scoped update of prefs::kPluginsPluginsList. |
511 | 470 |
512 // Build the set of policy enabled/disabled plugin patterns once and cache it. | 471 // Build the set of policy enabled/disabled plugin patterns once and cache it. |
513 // Don't do this in the constructor, there's no profile available there. | 472 // Don't do this in the constructor, there's no profile available there. |
(...skipping 17 matching lines...) Expand all Loading... |
531 &policy_disabled_plugin_patterns_)); | 490 &policy_disabled_plugin_patterns_)); |
532 registrar_.Add(prefs::kPluginsDisabledPluginsExceptions, | 491 registrar_.Add(prefs::kPluginsDisabledPluginsExceptions, |
533 base::Bind(&PluginPrefs::UpdatePatternsAndNotify, | 492 base::Bind(&PluginPrefs::UpdatePatternsAndNotify, |
534 base::Unretained(this), | 493 base::Unretained(this), |
535 &policy_disabled_plugin_exception_patterns_)); | 494 &policy_disabled_plugin_exception_patterns_)); |
536 registrar_.Add(prefs::kPluginsEnabledPlugins, | 495 registrar_.Add(prefs::kPluginsEnabledPlugins, |
537 base::Bind(&PluginPrefs::UpdatePatternsAndNotify, | 496 base::Bind(&PluginPrefs::UpdatePatternsAndNotify, |
538 base::Unretained(this), | 497 base::Unretained(this), |
539 &policy_enabled_plugin_patterns_)); | 498 &policy_enabled_plugin_patterns_)); |
540 | 499 |
541 if (force_enable_nacl) { | |
542 // We want to save this, but doing so requires loading the list of plugins, | |
543 // so do it after a minute as to not impact startup performance. Note that | |
544 // plugins are loaded after 30s by the metrics service. | |
545 BrowserThread::PostDelayedTask( | |
546 BrowserThread::FILE, | |
547 FROM_HERE, | |
548 base::Bind(&PluginPrefs::GetPreferencesDataOnFileThread, this), | |
549 base::TimeDelta::FromMilliseconds(kPluginUpdateDelayMs)); | |
550 } | |
551 | |
552 NotifyPluginStatusChanged(); | 500 NotifyPluginStatusChanged(); |
553 } | 501 } |
554 | 502 |
555 void PluginPrefs::ShutdownOnUIThread() { | 503 void PluginPrefs::ShutdownOnUIThread() { |
556 prefs_ = NULL; | 504 prefs_ = NULL; |
557 registrar_.RemoveAll(); | 505 registrar_.RemoveAll(); |
558 } | 506 } |
559 | 507 |
560 PluginPrefs::PluginPrefs() : profile_(NULL), | 508 PluginPrefs::PluginPrefs() : profile_(NULL), |
561 prefs_(NULL), | 509 prefs_(NULL) { |
562 plugin_list_(NULL) { | |
563 } | 510 } |
564 | 511 |
565 PluginPrefs::~PluginPrefs() { | 512 PluginPrefs::~PluginPrefs() { |
566 } | 513 } |
567 | 514 |
568 void PluginPrefs::SetPolicyEnforcedPluginPatterns( | 515 void PluginPrefs::SetPolicyEnforcedPluginPatterns( |
569 const std::set<string16>& disabled_patterns, | 516 const std::set<string16>& disabled_patterns, |
570 const std::set<string16>& disabled_exception_patterns, | 517 const std::set<string16>& disabled_exception_patterns, |
571 const std::set<string16>& enabled_patterns) { | 518 const std::set<string16>& enabled_patterns) { |
572 policy_disabled_plugin_patterns_ = disabled_patterns; | 519 policy_disabled_plugin_patterns_ = disabled_patterns; |
573 policy_disabled_plugin_exception_patterns_ = disabled_exception_patterns; | 520 policy_disabled_plugin_exception_patterns_ = disabled_exception_patterns; |
574 policy_enabled_plugin_patterns_ = enabled_patterns; | 521 policy_enabled_plugin_patterns_ = enabled_patterns; |
575 } | 522 } |
576 | 523 |
577 webkit::npapi::PluginList* PluginPrefs::GetPluginList() const { | |
578 if (plugin_list_) | |
579 return plugin_list_; | |
580 return PluginService::GetInstance()->GetPluginList(); | |
581 } | |
582 | |
583 void PluginPrefs::GetPreferencesDataOnFileThread() { | |
584 std::vector<webkit::WebPluginInfo> plugins; | |
585 webkit::npapi::PluginList* plugin_list = GetPluginList(); | |
586 plugin_list->GetPluginsNoRefresh(&plugins); | |
587 | |
588 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
589 base::Bind(&PluginPrefs::OnUpdatePreferences, this, plugins)); | |
590 } | |
591 | |
592 void PluginPrefs::OnUpdatePreferences( | 524 void PluginPrefs::OnUpdatePreferences( |
593 const std::vector<webkit::WebPluginInfo>& plugins) { | 525 const std::vector<webkit::WebPluginInfo>& plugins) { |
594 if (!prefs_) | 526 if (!prefs_) |
595 return; | 527 return; |
596 | 528 |
597 PluginFinder* finder = PluginFinder::GetInstance(); | 529 PluginFinder* finder = PluginFinder::GetInstance(); |
598 ListPrefUpdate update(prefs_, prefs::kPluginsPluginsList); | 530 ListPrefUpdate update(prefs_, prefs::kPluginsPluginsList); |
599 ListValue* plugins_list = update.Get(); | 531 ListValue* plugins_list = update.Get(); |
600 plugins_list->Clear(); | 532 plugins_list->Clear(); |
601 | 533 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 } | 570 } |
639 } | 571 } |
640 | 572 |
641 void PluginPrefs::NotifyPluginStatusChanged() { | 573 void PluginPrefs::NotifyPluginStatusChanged() { |
642 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 574 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
643 content::NotificationService::current()->Notify( | 575 content::NotificationService::current()->Notify( |
644 chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, | 576 chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED, |
645 content::Source<Profile>(profile_), | 577 content::Source<Profile>(profile_), |
646 content::NotificationService::NoDetails()); | 578 content::NotificationService::NoDetails()); |
647 } | 579 } |
OLD | NEW |