OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/extensions/extensions_service.h" | 5 #include "chrome/browser/extensions/extensions_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/histogram.h" | 12 #include "base/histogram.h" |
13 #include "base/stl_util-inl.h" | 13 #include "base/stl_util-inl.h" |
14 #include "base/string16.h" | 14 #include "base/string16.h" |
15 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
17 #include "base/stringprintf.h" | 17 #include "base/stringprintf.h" |
18 #include "base/time.h" | 18 #include "base/time.h" |
19 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
20 #include "base/values.h" | 20 #include "base/values.h" |
21 #include "base/version.h" | 21 #include "base/version.h" |
22 #include "chrome/browser/browser_process.h" | 22 #include "chrome/browser/browser_process.h" |
23 #include "chrome/browser/chrome_thread.h" | 23 #include "chrome/browser/chrome_thread.h" |
24 #include "chrome/browser/debugger/devtools_manager.h" | 24 #include "chrome/browser/debugger/devtools_manager.h" |
25 #include "chrome/browser/extensions/crx_installer.h" | 25 #include "chrome/browser/extensions/crx_installer.h" |
| 26 #include "chrome/browser/extensions/default_apps.h" |
26 #include "chrome/browser/extensions/extension_accessibility_api.h" | 27 #include "chrome/browser/extensions/extension_accessibility_api.h" |
27 #include "chrome/browser/extensions/extension_bookmarks_module.h" | 28 #include "chrome/browser/extensions/extension_bookmarks_module.h" |
28 #include "chrome/browser/extensions/extension_browser_event_router.h" | 29 #include "chrome/browser/extensions/extension_browser_event_router.h" |
29 #include "chrome/browser/extensions/extension_cookies_api.h" | 30 #include "chrome/browser/extensions/extension_cookies_api.h" |
30 #include "chrome/browser/extensions/extension_data_deleter.h" | 31 #include "chrome/browser/extensions/extension_data_deleter.h" |
31 #include "chrome/browser/extensions/extension_dom_ui.h" | 32 #include "chrome/browser/extensions/extension_dom_ui.h" |
32 #include "chrome/browser/extensions/extension_error_reporter.h" | 33 #include "chrome/browser/extensions/extension_error_reporter.h" |
33 #include "chrome/browser/extensions/extension_history_api.h" | 34 #include "chrome/browser/extensions/extension_history_api.h" |
34 #include "chrome/browser/extensions/extension_host.h" | 35 #include "chrome/browser/extensions/extension_host.h" |
35 #include "chrome/browser/extensions/extension_management_api.h" | 36 #include "chrome/browser/extensions/extension_management_api.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 } | 123 } |
123 | 124 |
124 } // namespace | 125 } // namespace |
125 | 126 |
126 PendingExtensionInfo::PendingExtensionInfo( | 127 PendingExtensionInfo::PendingExtensionInfo( |
127 const GURL& update_url, | 128 const GURL& update_url, |
128 PendingExtensionInfo::ExpectedCrxType expected_crx_type, | 129 PendingExtensionInfo::ExpectedCrxType expected_crx_type, |
129 bool is_from_sync, | 130 bool is_from_sync, |
130 bool install_silently, | 131 bool install_silently, |
131 bool enable_on_install, | 132 bool enable_on_install, |
132 bool enable_incognito_on_install) | 133 bool enable_incognito_on_install, |
| 134 Extension::Location location) |
133 : update_url(update_url), | 135 : update_url(update_url), |
134 expected_crx_type(expected_crx_type), | 136 expected_crx_type(expected_crx_type), |
135 is_from_sync(is_from_sync), | 137 is_from_sync(is_from_sync), |
136 install_silently(install_silently), | 138 install_silently(install_silently), |
137 enable_on_install(enable_on_install), | 139 enable_on_install(enable_on_install), |
138 enable_incognito_on_install(enable_incognito_on_install) {} | 140 enable_incognito_on_install(enable_incognito_on_install), |
| 141 install_source(location) {} |
139 | 142 |
140 PendingExtensionInfo::PendingExtensionInfo() | 143 PendingExtensionInfo::PendingExtensionInfo() |
141 : update_url(), | 144 : update_url(), |
142 expected_crx_type(PendingExtensionInfo::UNKNOWN), | 145 expected_crx_type(PendingExtensionInfo::UNKNOWN), |
143 is_from_sync(true), | 146 is_from_sync(true), |
144 install_silently(false), | 147 install_silently(false), |
145 enable_on_install(false), | 148 enable_on_install(false), |
146 enable_incognito_on_install(false) {} | 149 enable_incognito_on_install(false), |
| 150 install_source(Extension::INVALID) {} |
147 | 151 |
148 // ExtensionsService. | 152 // ExtensionsService. |
149 | 153 |
150 const char* ExtensionsService::kInstallDirectoryName = "Extensions"; | 154 const char* ExtensionsService::kInstallDirectoryName = "Extensions"; |
151 const char* ExtensionsService::kCurrentVersionFileName = "Current Version"; | 155 const char* ExtensionsService::kCurrentVersionFileName = "Current Version"; |
152 | 156 |
153 // Implements IO for the ExtensionsService. | 157 // Implements IO for the ExtensionsService. |
154 | 158 |
155 class ExtensionsServiceBackend | 159 class ExtensionsServiceBackend |
156 : public base::RefCountedThreadSafe<ExtensionsServiceBackend>, | 160 : public base::RefCountedThreadSafe<ExtensionsServiceBackend>, |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 const CommandLine* command_line, | 558 const CommandLine* command_line, |
555 const FilePath& install_directory, | 559 const FilePath& install_directory, |
556 bool autoupdate_enabled) | 560 bool autoupdate_enabled) |
557 : profile_(profile), | 561 : profile_(profile), |
558 extension_prefs_(new ExtensionPrefs(profile->GetPrefs(), | 562 extension_prefs_(new ExtensionPrefs(profile->GetPrefs(), |
559 install_directory)), | 563 install_directory)), |
560 install_directory_(install_directory), | 564 install_directory_(install_directory), |
561 extensions_enabled_(true), | 565 extensions_enabled_(true), |
562 show_extensions_prompts_(true), | 566 show_extensions_prompts_(true), |
563 ready_(false), | 567 ready_(false), |
564 ALLOW_THIS_IN_INITIALIZER_LIST(toolbar_model_(this)) { | 568 ALLOW_THIS_IN_INITIALIZER_LIST(toolbar_model_(this)), |
| 569 default_apps_(profile->GetPrefs()) { |
565 // Figure out if extension installation should be enabled. | 570 // Figure out if extension installation should be enabled. |
566 if (command_line->HasSwitch(switches::kDisableExtensions)) { | 571 if (command_line->HasSwitch(switches::kDisableExtensions)) { |
567 extensions_enabled_ = false; | 572 extensions_enabled_ = false; |
568 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { | 573 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { |
569 extensions_enabled_ = false; | 574 extensions_enabled_ = false; |
570 } | 575 } |
571 | 576 |
572 registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED, | 577 registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED, |
573 NotificationService::AllSources()); | 578 NotificationService::AllSources()); |
574 pref_change_registrar_.Init(profile->GetPrefs()); | 579 pref_change_registrar_.Init(profile->GetPrefs()); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 // pending extensions that have install_silently set. | 680 // pending extensions that have install_silently set. |
676 ExtensionInstallUI* client = | 681 ExtensionInstallUI* client = |
677 (!is_pending_extension || it->second.install_silently) ? | 682 (!is_pending_extension || it->second.install_silently) ? |
678 NULL : new ExtensionInstallUI(profile_); | 683 NULL : new ExtensionInstallUI(profile_); |
679 | 684 |
680 scoped_refptr<CrxInstaller> installer( | 685 scoped_refptr<CrxInstaller> installer( |
681 new CrxInstaller(install_directory_, | 686 new CrxInstaller(install_directory_, |
682 this, // frontend | 687 this, // frontend |
683 client)); | 688 client)); |
684 installer->set_expected_id(id); | 689 installer->set_expected_id(id); |
685 if (is_pending_extension && !it->second.is_from_sync) | 690 installer->set_install_source(it->second.install_source); |
686 installer->set_install_source(Extension::EXTERNAL_PREF_DOWNLOAD); | |
687 installer->set_delete_source(true); | 691 installer->set_delete_source(true); |
688 installer->set_original_url(download_url); | 692 installer->set_original_url(download_url); |
689 installer->InstallCrx(extension_path); | 693 installer->InstallCrx(extension_path); |
690 } | 694 } |
691 | 695 |
692 void ExtensionsService::AddPendingExtensionFromSync( | 696 void ExtensionsService::AddPendingExtensionFromSync( |
693 const std::string& id, const GURL& update_url, | 697 const std::string& id, const GURL& update_url, |
694 PendingExtensionInfo::ExpectedCrxType expected_crx_type, | 698 PendingExtensionInfo::ExpectedCrxType expected_crx_type, |
695 bool install_silently, bool enable_on_install, | 699 bool install_silently, bool enable_on_install, |
696 bool enable_incognito_on_install) { | 700 bool enable_incognito_on_install) { |
697 if (GetExtensionByIdInternal(id, true, true)) { | 701 if (GetExtensionByIdInternal(id, true, true)) { |
698 LOG(DFATAL) << "Trying to add pending extension " << id | 702 LOG(DFATAL) << "Trying to add pending extension " << id |
699 << " which already exists"; | 703 << " which already exists"; |
700 return; | 704 return; |
701 } | 705 } |
702 AddPendingExtensionInternal( | 706 |
703 id, update_url, expected_crx_type, true, install_silently, | 707 AddPendingExtensionInternal(id, update_url, expected_crx_type, true, |
704 enable_on_install, enable_incognito_on_install); | 708 install_silently, enable_on_install, |
| 709 enable_incognito_on_install, |
| 710 Extension::INTERNAL); |
705 } | 711 } |
706 | 712 |
707 void ExtensionsService::AddPendingExtensionFromExternalUpdateUrl( | 713 void ExtensionsService::AddPendingExtensionFromExternalUpdateUrl( |
708 const std::string& id, const GURL& update_url) { | 714 const std::string& id, const GURL& update_url) { |
709 // Add the extension to this list of extensions to update. | 715 // Add the extension to this list of extensions to update. |
710 // We do not know if the id refers to a theme, so make is_theme unknown. | |
711 const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType = | 716 const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType = |
712 PendingExtensionInfo::UNKNOWN; | 717 PendingExtensionInfo::UNKNOWN; |
713 const bool kIsFromSync = false; | 718 const bool kIsFromSync = false; |
714 const bool kInstallSilently = true; | 719 const bool kInstallSilently = true; |
715 const bool kEnableOnInstall = true; | 720 const bool kEnableOnInstall = true; |
716 const bool kEnableIncognitoOnInstall = false; | 721 const bool kEnableIncognitoOnInstall = false; |
717 | 722 |
718 if (GetExtensionByIdInternal(id, true, true)) { | 723 if (GetExtensionByIdInternal(id, true, true)) { |
719 LOG(DFATAL) << "Trying to add extension " << id | 724 LOG(DFATAL) << "Trying to add extension " << id |
720 << " by external update, but it is already installed."; | 725 << " by external update, but it is already installed."; |
721 return; | 726 return; |
722 } | 727 } |
723 | 728 |
724 AddPendingExtensionInternal(id, update_url, kExpectedCrxType, kIsFromSync, | 729 AddPendingExtensionInternal(id, update_url, kExpectedCrxType, kIsFromSync, |
725 kInstallSilently, kEnableOnInstall, | 730 kInstallSilently, kEnableOnInstall, |
726 kEnableIncognitoOnInstall); | 731 kEnableIncognitoOnInstall, |
| 732 Extension::EXTERNAL_PREF_DOWNLOAD); |
| 733 } |
| 734 |
| 735 void ExtensionsService::AddPendingExtensionFromDefaultAppList( |
| 736 const std::string& id) { |
| 737 // Add the extension to this list of extensions to update. |
| 738 const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType = |
| 739 PendingExtensionInfo::APP; |
| 740 const bool kIsFromSync = false; |
| 741 const bool kInstallSilently = true; |
| 742 const bool kEnableOnInstall = true; |
| 743 const bool kEnableIncognitoOnInstall = true; |
| 744 |
| 745 // This can legitimately happen if the user manually installed one of the |
| 746 // default apps before this code ran. |
| 747 if (GetExtensionByIdInternal(id, true, true)) |
| 748 return; |
| 749 |
| 750 AddPendingExtensionInternal(id, GURL(), kExpectedCrxType, kIsFromSync, |
| 751 kInstallSilently, kEnableOnInstall, |
| 752 kEnableIncognitoOnInstall, |
| 753 Extension::INTERNAL); |
727 } | 754 } |
728 | 755 |
729 void ExtensionsService::AddPendingExtensionInternal( | 756 void ExtensionsService::AddPendingExtensionInternal( |
730 const std::string& id, const GURL& update_url, | 757 const std::string& id, const GURL& update_url, |
731 PendingExtensionInfo::ExpectedCrxType expected_crx_type, | 758 PendingExtensionInfo::ExpectedCrxType expected_crx_type, |
732 bool is_from_sync, bool install_silently, | 759 bool is_from_sync, bool install_silently, |
733 bool enable_on_install, bool enable_incognito_on_install) { | 760 bool enable_on_install, bool enable_incognito_on_install, |
| 761 Extension::Location install_source) { |
734 pending_extensions_[id] = | 762 pending_extensions_[id] = |
735 PendingExtensionInfo(update_url, expected_crx_type, is_from_sync, | 763 PendingExtensionInfo(update_url, expected_crx_type, is_from_sync, |
736 install_silently, enable_on_install, | 764 install_silently, enable_on_install, |
737 enable_incognito_on_install); | 765 enable_incognito_on_install, install_source); |
738 } | 766 } |
739 | 767 |
740 void ExtensionsService::ReloadExtension(const std::string& extension_id) { | 768 void ExtensionsService::ReloadExtension(const std::string& extension_id) { |
741 FilePath path; | 769 FilePath path; |
742 Extension* current_extension = GetExtensionById(extension_id, false); | 770 Extension* current_extension = GetExtensionById(extension_id, false); |
743 | 771 |
744 // Disable the extension if it's loaded. It might not be loaded if it crashed. | 772 // Disable the extension if it's loaded. It might not be loaded if it crashed. |
745 if (current_extension) { | 773 if (current_extension) { |
746 // If the extension has an inspector open for its background page, detach | 774 // If the extension has an inspector open for its background page, detach |
747 // the inspector and hang onto a cookie for it, so that we can reattach | 775 // the inspector and hang onto a cookie for it, so that we can reattach |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1474 if (it != pending_extensions_.end()) { | 1502 if (it != pending_extensions_.end()) { |
1475 PendingExtensionInfo pending_extension_info = it->second; | 1503 PendingExtensionInfo pending_extension_info = it->second; |
1476 PendingExtensionInfo::ExpectedCrxType expected_crx_type = | 1504 PendingExtensionInfo::ExpectedCrxType expected_crx_type = |
1477 pending_extension_info.expected_crx_type; | 1505 pending_extension_info.expected_crx_type; |
1478 bool is_from_sync = pending_extension_info.is_from_sync; | 1506 bool is_from_sync = pending_extension_info.is_from_sync; |
1479 pending_extensions_.erase(it); | 1507 pending_extensions_.erase(it); |
1480 it = pending_extensions_.end(); | 1508 it = pending_extensions_.end(); |
1481 | 1509 |
1482 // Set initial state from pending extension data. | 1510 // Set initial state from pending extension data. |
1483 PendingExtensionInfo::ExpectedCrxType actual_crx_type = | 1511 PendingExtensionInfo::ExpectedCrxType actual_crx_type = |
1484 (extension->is_theme() ? PendingExtensionInfo::THEME | 1512 PendingExtensionInfo::EXTENSION; |
1485 : PendingExtensionInfo::EXTENSION); | 1513 if (extension->is_app()) |
| 1514 actual_crx_type = PendingExtensionInfo::APP; |
| 1515 else if (extension->is_theme()) |
| 1516 actual_crx_type = PendingExtensionInfo::THEME; |
1486 | 1517 |
1487 if (expected_crx_type != PendingExtensionInfo::UNKNOWN && | 1518 if (expected_crx_type != PendingExtensionInfo::UNKNOWN && |
1488 expected_crx_type != actual_crx_type) { | 1519 expected_crx_type != actual_crx_type) { |
1489 LOG(WARNING) | 1520 LOG(WARNING) |
1490 << "Not installing pending extension " << extension->id() | 1521 << "Not installing pending extension " << extension->id() |
1491 << " with is_theme = " << extension->is_theme(); | 1522 << " with is_theme = " << extension->is_theme(); |
1492 // Delete the extension directory since we're not going to | 1523 // Delete the extension directory since we're not going to |
1493 // load it. | 1524 // load it. |
1494 ChromeThread::PostTask( | 1525 ChromeThread::PostTask( |
1495 ChromeThread::FILE, FROM_HERE, | 1526 ChromeThread::FILE, FROM_HERE, |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1584 NotificationType::THEME_INSTALLED, | 1615 NotificationType::THEME_INSTALLED, |
1585 Source<Profile>(profile_), | 1616 Source<Profile>(profile_), |
1586 Details<Extension>(extension)); | 1617 Details<Extension>(extension)); |
1587 } else { | 1618 } else { |
1588 NotificationService::current()->Notify( | 1619 NotificationService::current()->Notify( |
1589 NotificationType::EXTENSION_INSTALLED, | 1620 NotificationType::EXTENSION_INSTALLED, |
1590 Source<Profile>(profile_), | 1621 Source<Profile>(profile_), |
1591 Details<Extension>(extension)); | 1622 Details<Extension>(extension)); |
1592 } | 1623 } |
1593 | 1624 |
| 1625 if (extension->is_app()) { |
| 1626 ExtensionIdSet installed_ids = GetAppIds(); |
| 1627 installed_ids.insert(extension->id()); |
| 1628 default_apps_.DidInstallApp(installed_ids); |
| 1629 } |
| 1630 |
1594 // Transfer ownership of |extension| to OnExtensionLoaded. | 1631 // Transfer ownership of |extension| to OnExtensionLoaded. |
1595 OnExtensionLoaded(scoped_extension.release(), allow_privilege_increase); | 1632 OnExtensionLoaded(scoped_extension.release(), allow_privilege_increase); |
1596 } | 1633 } |
1597 | 1634 |
1598 Extension* ExtensionsService::GetExtensionByIdInternal(const std::string& id, | 1635 Extension* ExtensionsService::GetExtensionByIdInternal(const std::string& id, |
1599 bool include_enabled, | 1636 bool include_enabled, |
1600 bool include_disabled) { | 1637 bool include_disabled) { |
1601 std::string lowercase_id = StringToLowerASCII(id); | 1638 std::string lowercase_id = StringToLowerASCII(id); |
1602 if (include_enabled) { | 1639 if (include_enabled) { |
1603 for (ExtensionList::const_iterator iter = extensions_.begin(); | 1640 for (ExtensionList::const_iterator iter = extensions_.begin(); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1783 *pref_name == prefs::kExtensionInstallDenyList); | 1820 *pref_name == prefs::kExtensionInstallDenyList); |
1784 CheckAdminBlacklist(); | 1821 CheckAdminBlacklist(); |
1785 break; | 1822 break; |
1786 } | 1823 } |
1787 | 1824 |
1788 default: | 1825 default: |
1789 NOTREACHED() << "Unexpected notification type."; | 1826 NOTREACHED() << "Unexpected notification type."; |
1790 } | 1827 } |
1791 } | 1828 } |
1792 | 1829 |
1793 bool ExtensionsService::HasApps() { | 1830 bool ExtensionsService::HasApps() const { |
1794 if (!extensions_enabled_) | 1831 return !GetAppIds().empty(); |
1795 return false; | 1832 } |
1796 | 1833 |
| 1834 ExtensionIdSet ExtensionsService::GetAppIds() const { |
| 1835 ExtensionIdSet result; |
1797 for (ExtensionList::const_iterator it = extensions_.begin(); | 1836 for (ExtensionList::const_iterator it = extensions_.begin(); |
1798 it != extensions_.end(); ++it) { | 1837 it != extensions_.end(); ++it) { |
1799 if ((*it)->is_app()) | 1838 if ((*it)->is_app() && (*it)->location() != Extension::COMPONENT) |
1800 return true; | 1839 result.insert((*it)->id()); |
1801 } | 1840 } |
1802 | 1841 |
1803 return false; | 1842 return result; |
1804 } | 1843 } |
OLD | NEW |