Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: chrome/browser/extensions/extension_service.cc

Issue 10382149: Refactor the various ways to control what users can do to extensions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698