Chromium Code Reviews| 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/extensions/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/file_util.h" | 14 #include "base/file_util.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/metrics/field_trial.h" | 16 #include "base/metrics/field_trial.h" |
| 17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 18 #include "base/path_service.h" | 18 #include "base/path_service.h" |
| 19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 20 #include "base/string16.h" | |
| 21 #include "base/string_number_conversions.h" | 20 #include "base/string_number_conversions.h" |
| 22 #include "base/string_util.h" | 21 #include "base/string_util.h" |
| 23 #include "base/stringprintf.h" | 22 #include "base/stringprintf.h" |
| 24 #include "base/threading/thread_restrictions.h" | 23 #include "base/threading/thread_restrictions.h" |
| 25 #include "base/time.h" | 24 #include "base/time.h" |
| 26 #include "base/utf_string_conversions.h" | 25 #include "base/utf_string_conversions.h" |
| 27 #include "base/values.h" | 26 #include "base/values.h" |
| 28 #include "base/version.h" | 27 #include "base/version.h" |
| 29 #include "chrome/browser/accessibility/accessibility_extension_api.h" | 28 #include "chrome/browser/accessibility/accessibility_extension_api.h" |
| 30 #include "chrome/browser/bookmarks/bookmark_extension_api.h" | 29 #include "chrome/browser/bookmarks/bookmark_extension_api.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 #include "chrome/common/url_constants.h" | 97 #include "chrome/common/url_constants.h" |
| 99 #include "content/public/browser/browser_thread.h" | 98 #include "content/public/browser/browser_thread.h" |
| 100 #include "content/public/browser/devtools_agent_host_registry.h" | 99 #include "content/public/browser/devtools_agent_host_registry.h" |
| 101 #include "content/public/browser/devtools_manager.h" | 100 #include "content/public/browser/devtools_manager.h" |
| 102 #include "content/public/browser/notification_service.h" | 101 #include "content/public/browser/notification_service.h" |
| 103 #include "content/public/browser/notification_types.h" | 102 #include "content/public/browser/notification_types.h" |
| 104 #include "content/public/browser/plugin_service.h" | 103 #include "content/public/browser/plugin_service.h" |
| 105 #include "content/public/browser/render_process_host.h" | 104 #include "content/public/browser/render_process_host.h" |
| 106 #include "content/public/common/pepper_plugin_info.h" | 105 #include "content/public/common/pepper_plugin_info.h" |
| 107 #include "googleurl/src/gurl.h" | 106 #include "googleurl/src/gurl.h" |
| 107 #include "grit/generated_resources.h" | |
| 108 #include "net/base/registry_controlled_domain.h" | 108 #include "net/base/registry_controlled_domain.h" |
| 109 #include "sync/api/sync_change.h" | 109 #include "sync/api/sync_change.h" |
| 110 #include "sync/api/sync_error_factory.h" | 110 #include "sync/api/sync_error_factory.h" |
| 111 #include "ui/base/l10n/l10n_util.h" | |
| 111 #include "webkit/database/database_tracker.h" | 112 #include "webkit/database/database_tracker.h" |
| 112 #include "webkit/database/database_util.h" | 113 #include "webkit/database/database_util.h" |
| 113 | 114 |
| 114 #if defined(OS_CHROMEOS) | 115 #if defined(OS_CHROMEOS) |
| 115 #include "chrome/browser/chromeos/cros/cros_library.h" | 116 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 116 #include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" | 117 #include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" |
| 117 #include "chrome/browser/chromeos/extensions/file_browser_event_router.h" | 118 #include "chrome/browser/chromeos/extensions/file_browser_event_router.h" |
| 118 #include "chrome/browser/chromeos/extensions/input_method_event_router.h" | 119 #include "chrome/browser/chromeos/extensions/input_method_event_router.h" |
| 119 #include "chrome/browser/chromeos/extensions/media_player_event_router.h" | 120 #include "chrome/browser/chromeos/extensions/media_player_event_router.h" |
| 120 #include "chrome/browser/chromeos/input_method/input_method_manager.h" | 121 #include "chrome/browser/chromeos/input_method/input_method_manager.h" |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 297 | 298 |
| 298 // We can't call UninstallExtension with an invalid extension ID. | 299 // We can't call UninstallExtension with an invalid extension ID. |
| 299 if (!extension) { | 300 if (!extension) { |
| 300 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " | 301 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " |
| 301 << "id: " << extension_id; | 302 << "id: " << extension_id; |
| 302 return false; | 303 return false; |
| 303 } | 304 } |
| 304 | 305 |
| 305 // The following call to UninstallExtension will not allow an uninstall of a | 306 // The following call to UninstallExtension will not allow an uninstall of a |
| 306 // policy-controlled extension. | 307 // policy-controlled extension. |
| 307 std::string error; | 308 string16 error; |
| 308 if (!extensions_service->UninstallExtension(extension_id, false, &error)) { | 309 if (!extensions_service->UninstallExtension(extension_id, false, &error)) { |
| 309 LOG(WARNING) << "Cannot uninstall extension with id " << extension_id | 310 LOG(WARNING) << "Cannot uninstall extension with id " << extension_id |
| 310 << ": " << error; | 311 << ": " << error; |
| 311 return false; | 312 return false; |
| 312 } | 313 } |
| 313 | 314 |
| 314 return true; | 315 return true; |
| 315 } | 316 } |
| 316 | 317 |
| 317 ExtensionService::ExtensionService(Profile* profile, | 318 ExtensionService::ExtensionService(Profile* profile, |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 680 // We should always be able to remember the extension's path. If it's not in | 681 // We should always be able to remember the extension's path. If it's not in |
| 681 // the map, someone failed to update |unloaded_extension_paths_|. | 682 // the map, someone failed to update |unloaded_extension_paths_|. |
| 682 CHECK(!path.empty()); | 683 CHECK(!path.empty()); |
| 683 extensions::UnpackedInstaller::Create(this)->Load(path); | 684 extensions::UnpackedInstaller::Create(this)->Load(path); |
| 684 } | 685 } |
| 685 } | 686 } |
| 686 | 687 |
| 687 bool ExtensionService::UninstallExtension( | 688 bool ExtensionService::UninstallExtension( |
| 688 std::string extension_id, | 689 std::string extension_id, |
| 689 bool external_uninstall, | 690 bool external_uninstall, |
| 690 std::string* error) { | 691 string16* error) { |
| 691 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 692 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 692 | 693 |
| 693 scoped_refptr<const Extension> extension(GetInstalledExtension(extension_id)); | 694 scoped_refptr<const Extension> extension(GetInstalledExtension(extension_id)); |
| 694 | 695 |
| 695 // Callers should not send us nonexistent extensions. | 696 // Callers should not send us nonexistent extensions. |
| 696 CHECK(extension); | 697 CHECK(extension); |
| 697 | 698 |
| 698 // Policy change which triggers an uninstall will always set | 699 // Policy change which triggers an uninstall will always set |
| 699 // |external_uninstall| to true so this is the only way to uninstall | 700 // |external_uninstall| to true so this is the only way to uninstall |
| 700 // managed extensions. | 701 // managed extensions. |
| 701 if (!Extension::UserMayDisable(extension->location()) && | 702 if (!external_uninstall && |
| 702 !external_uninstall) { | 703 !system_->management_policy()->UserMayModifyStatus( |
| 704 extension.get(), error)) { | |
| 703 content::NotificationService::current()->Notify( | 705 content::NotificationService::current()->Notify( |
| 704 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, | 706 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, |
| 705 content::Source<Profile>(profile_), | 707 content::Source<Profile>(profile_), |
| 706 content::Details<const Extension>(extension)); | 708 content::Details<const Extension>(extension)); |
| 707 if (error != NULL) { | |
| 708 *error = errors::kCannotUninstallManagedExtension; | |
| 709 } | |
| 710 return false; | 709 return false; |
| 711 } | 710 } |
| 712 | 711 |
| 713 // Extract the data we need for sync now, but don't actually sync until we've | 712 // Extract the data we need for sync now, but don't actually sync until we've |
| 714 // completed the uninstallation. | 713 // completed the uninstallation. |
| 715 SyncChange sync_change; | 714 SyncChange sync_change; |
| 716 if (app_sync_bundle_.HandlesApp(*extension)) { | 715 if (app_sync_bundle_.HandlesApp(*extension)) { |
| 717 sync_change = app_sync_bundle_.CreateSyncChangeToDelete(extension); | 716 sync_change = app_sync_bundle_.CreateSyncChangeToDelete(extension); |
| 718 } else if (extension_sync_bundle_.HandlesExtension(*extension)) { | 717 } else if (extension_sync_bundle_.HandlesExtension(*extension)) { |
| 719 sync_change = extension_sync_bundle_.CreateSyncChangeToDelete(extension); | 718 sync_change = extension_sync_bundle_.CreateSyncChangeToDelete(extension); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 810 // enabled unless otherwise noted. | 809 // enabled unless otherwise noted. |
| 811 return !extension_prefs_->IsExtensionDisabled(extension_id) && | 810 return !extension_prefs_->IsExtensionDisabled(extension_id) && |
| 812 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 811 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
| 813 } | 812 } |
| 814 | 813 |
| 815 bool ExtensionService::IsExternalExtensionUninstalled( | 814 bool ExtensionService::IsExternalExtensionUninstalled( |
| 816 const std::string& extension_id) const { | 815 const std::string& extension_id) const { |
| 817 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 816 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
| 818 } | 817 } |
| 819 | 818 |
| 819 std::string ExtensionService::PolicyProviderName() const { | |
| 820 return "admin policy forcelist, via the ExtensionService"; | |
| 821 } | |
| 822 | |
| 823 bool ExtensionService::UserMayModifyStatus(const Extension* extension, | |
| 824 string16* error) const { | |
| 825 return ManagementPolicyImpl(extension, error, true); | |
| 826 } | |
| 827 | |
| 828 bool ExtensionService::MustRemainEnabled(const Extension* extension, | |
| 829 string16* error) const { | |
| 830 return ManagementPolicyImpl(extension, error, false); | |
| 831 } | |
| 832 | |
| 833 bool ExtensionService::ManagementPolicyImpl(const Extension* extension, | |
| 834 string16* error, bool modifiable_value) const { | |
| 835 // An extension that is required (by admin policy, for example) cannot be | |
| 836 // modified. | |
| 837 bool modifiable = !Extension::IsRequired(extension->location()); | |
|
Aaron Boodman
2012/05/22 15:56:11
It seems like if ManagementPolicy did this check i
Pam (message me for reviews)
2012/05/23 15:00:58
True, but the ManagementPolicy class is pretty abs
Aaron Boodman
2012/05/24 08:11:23
I can see that. I just want to get this interface
| |
| 838 // Some callers equate "no restriction" to true, others to false. | |
| 839 if (modifiable) | |
| 840 return modifiable_value; | |
| 841 | |
| 842 if (error) { | |
| 843 *error = l10n_util::GetStringFUTF16( | |
| 844 IDS_EXTENSION_CANT_MODIFY_POLICY_REQUIRED, | |
| 845 UTF8ToUTF16(extension->name())); | |
| 846 } | |
| 847 return !modifiable_value; | |
| 848 } | |
| 849 | |
| 820 void ExtensionService::EnableExtension(const std::string& extension_id) { | 850 void ExtensionService::EnableExtension(const std::string& extension_id) { |
| 821 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 851 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 822 | 852 |
| 823 if (IsExtensionEnabled(extension_id)) | 853 if (IsExtensionEnabled(extension_id)) |
| 824 return; | 854 return; |
| 825 | 855 |
| 826 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); | 856 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); |
| 827 extension_prefs_->RemoveDisableReason(extension_id); | 857 extension_prefs_->RemoveDisableReason(extension_id); |
| 828 | 858 |
| 829 const Extension* extension = | 859 const Extension* extension = |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 850 Extension::DisableReason disable_reason) { | 880 Extension::DisableReason disable_reason) { |
| 851 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 881 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 852 | 882 |
| 853 // The extension may have been disabled already. | 883 // The extension may have been disabled already. |
| 854 if (!IsExtensionEnabled(extension_id)) | 884 if (!IsExtensionEnabled(extension_id)) |
| 855 return; | 885 return; |
| 856 | 886 |
| 857 const Extension* extension = GetInstalledExtension(extension_id); | 887 const Extension* extension = GetInstalledExtension(extension_id); |
| 858 // |extension| can be NULL if sync disables an extension that is not | 888 // |extension| can be NULL if sync disables an extension that is not |
| 859 // installed yet. | 889 // installed yet. |
| 860 if (extension && !Extension::UserMayDisable(extension->location())) | 890 if (extension && |
| 891 !system_->management_policy()->UserMayModifyStatus(extension, NULL)) { | |
| 861 return; | 892 return; |
| 893 } | |
| 862 | 894 |
| 863 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); | 895 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); |
| 864 extension_prefs_->SetDisableReason(extension_id, disable_reason); | 896 extension_prefs_->SetDisableReason(extension_id, disable_reason); |
| 865 | 897 |
| 866 extension = GetExtensionByIdInternal(extension_id, true, false, true); | 898 extension = GetExtensionByIdInternal(extension_id, true, false, true); |
| 867 if (!extension) | 899 if (!extension) |
| 868 return; | 900 return; |
| 869 | 901 |
| 870 // Move it over to the disabled list. | 902 // Move it over to the disabled list. |
| 871 disabled_extensions_.Insert(make_scoped_refptr(extension)); | 903 disabled_extensions_.Insert(make_scoped_refptr(extension)); |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1156 extensions::ExtensionUpdater* ExtensionService::updater() { | 1188 extensions::ExtensionUpdater* ExtensionService::updater() { |
| 1157 return updater_.get(); | 1189 return updater_.get(); |
| 1158 } | 1190 } |
| 1159 | 1191 |
| 1160 void ExtensionService::CheckAdminBlacklist() { | 1192 void ExtensionService::CheckAdminBlacklist() { |
| 1161 std::vector<std::string> to_be_removed; | 1193 std::vector<std::string> to_be_removed; |
| 1162 // Loop through extensions list, unload installed extensions. | 1194 // Loop through extensions list, unload installed extensions. |
| 1163 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 1195 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
| 1164 iter != extensions_.end(); ++iter) { | 1196 iter != extensions_.end(); ++iter) { |
| 1165 const Extension* extension = (*iter); | 1197 const Extension* extension = (*iter); |
| 1166 if (!extension_prefs_->IsExtensionAllowedByPolicy(extension->id(), | 1198 if (!system_->management_policy()->UserMayLoad(extension, |
| 1167 extension->location())) { | 1199 extension->location(), |
| 1200 NULL)) { | |
| 1168 to_be_removed.push_back(extension->id()); | 1201 to_be_removed.push_back(extension->id()); |
| 1169 } | 1202 } |
| 1170 } | 1203 } |
| 1171 | 1204 |
| 1172 // UnloadExtension will change the extensions_ list. So, we should | 1205 // UnloadExtension will change the extensions_ list. So, we should |
| 1173 // call it outside the iterator loop. | 1206 // call it outside the iterator loop. |
| 1174 for (unsigned int i = 0; i < to_be_removed.size(); ++i) | 1207 for (unsigned int i = 0; i < to_be_removed.size(); ++i) |
| 1175 UnloadExtension(to_be_removed[i], extension_misc::UNLOAD_REASON_DISABLE); | 1208 UnloadExtension(to_be_removed[i], extension_misc::UNLOAD_REASON_DISABLE); |
| 1176 } | 1209 } |
| 1177 | 1210 |
| (...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2099 const StringOrdinal& page_ordinal) { | 2132 const StringOrdinal& page_ordinal) { |
| 2100 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2133 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2101 | 2134 |
| 2102 // Ensure extension is deleted unless we transfer ownership. | 2135 // Ensure extension is deleted unless we transfer ownership. |
| 2103 scoped_refptr<const Extension> scoped_extension(extension); | 2136 scoped_refptr<const Extension> scoped_extension(extension); |
| 2104 const std::string& id = extension->id(); | 2137 const std::string& id = extension->id(); |
| 2105 // Extensions installed by policy can't be disabled. So even if a previous | 2138 // Extensions installed by policy can't be disabled. So even if a previous |
| 2106 // installation disabled the extension, make sure it is now enabled. | 2139 // installation disabled the extension, make sure it is now enabled. |
| 2107 bool initial_enable = | 2140 bool initial_enable = |
| 2108 !extension_prefs_->IsExtensionDisabled(id) || | 2141 !extension_prefs_->IsExtensionDisabled(id) || |
| 2109 !Extension::UserMayDisable(extension->location()); | 2142 system_->management_policy()->MustRemainEnabled(extension, NULL); |
| 2110 PendingExtensionInfo pending_extension_info; | 2143 PendingExtensionInfo pending_extension_info; |
| 2111 if (pending_extension_manager()->GetById(id, &pending_extension_info)) { | 2144 if (pending_extension_manager()->GetById(id, &pending_extension_info)) { |
| 2112 pending_extension_manager()->Remove(id); | 2145 pending_extension_manager()->Remove(id); |
| 2113 | 2146 |
| 2114 if (!pending_extension_info.ShouldAllowInstall(*extension)) { | 2147 if (!pending_extension_info.ShouldAllowInstall(*extension)) { |
| 2115 LOG(WARNING) | 2148 LOG(WARNING) |
| 2116 << "ShouldAllowInstall() returned false for " | 2149 << "ShouldAllowInstall() returned false for " |
| 2117 << id << " of type " << extension->GetType() | 2150 << id << " of type " << extension->GetType() |
| 2118 << " and update URL " << extension->update_url().spec() | 2151 << " and update URL " << extension->update_url().spec() |
| 2119 << "; not installing"; | 2152 << "; not installing"; |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2557 // To coexist with certain unit tests that don't have an IO thread message | 2590 // To coexist with certain unit tests that don't have an IO thread message |
| 2558 // loop available at ExtensionService shutdown, we lazy-initialize this | 2591 // loop available at ExtensionService shutdown, we lazy-initialize this |
| 2559 // object so that those cases neither create nor destroy an | 2592 // object so that those cases neither create nor destroy an |
| 2560 // APIResourceController. | 2593 // APIResourceController. |
| 2561 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 2594 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 2562 if (!api_resource_controller_) { | 2595 if (!api_resource_controller_) { |
| 2563 api_resource_controller_ = new extensions::APIResourceController(); | 2596 api_resource_controller_ = new extensions::APIResourceController(); |
| 2564 } | 2597 } |
| 2565 return api_resource_controller_; | 2598 return api_resource_controller_; |
| 2566 } | 2599 } |
| OLD | NEW |