| 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 |