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

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

Issue 9694038: OBSOLETE REVIEW. See http://codereview.chromium.org/10382149/ (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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 #include "chrome/common/url_constants.h" 98 #include "chrome/common/url_constants.h"
100 #include "content/public/browser/browser_thread.h" 99 #include "content/public/browser/browser_thread.h"
101 #include "content/public/browser/devtools_agent_host_registry.h" 100 #include "content/public/browser/devtools_agent_host_registry.h"
102 #include "content/public/browser/devtools_manager.h" 101 #include "content/public/browser/devtools_manager.h"
103 #include "content/public/browser/notification_service.h" 102 #include "content/public/browser/notification_service.h"
104 #include "content/public/browser/notification_types.h" 103 #include "content/public/browser/notification_types.h"
105 #include "content/public/browser/plugin_service.h" 104 #include "content/public/browser/plugin_service.h"
106 #include "content/public/browser/render_process_host.h" 105 #include "content/public/browser/render_process_host.h"
107 #include "content/public/common/pepper_plugin_info.h" 106 #include "content/public/common/pepper_plugin_info.h"
108 #include "googleurl/src/gurl.h" 107 #include "googleurl/src/gurl.h"
108 #include "grit/generated_resources.h"
109 #include "net/base/registry_controlled_domain.h" 109 #include "net/base/registry_controlled_domain.h"
110 #include "webkit/database/database_tracker.h" 110 #include "webkit/database/database_tracker.h"
111 #include "webkit/database/database_util.h" 111 #include "webkit/database/database_util.h"
112 #include "ui/base/l10n/l10n_util.h"
112 113
113 #if defined(OS_CHROMEOS) 114 #if defined(OS_CHROMEOS)
114 #include "chrome/browser/chromeos/cros/cros_library.h" 115 #include "chrome/browser/chromeos/cros/cros_library.h"
115 #include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" 116 #include "chrome/browser/chromeos/extensions/bluetooth_event_router.h"
116 #include "chrome/browser/chromeos/extensions/file_browser_event_router.h" 117 #include "chrome/browser/chromeos/extensions/file_browser_event_router.h"
117 #include "chrome/browser/chromeos/extensions/input_method_event_router.h" 118 #include "chrome/browser/chromeos/extensions/input_method_event_router.h"
118 #include "chrome/browser/chromeos/extensions/media_player_event_router.h" 119 #include "chrome/browser/chromeos/extensions/media_player_event_router.h"
119 #include "chrome/browser/chromeos/input_method/input_method_manager.h" 120 #include "chrome/browser/chromeos/input_method/input_method_manager.h"
120 #include "chrome/browser/extensions/extension_input_ime_api.h" 121 #include "chrome/browser/extensions/extension_input_ime_api.h"
121 #include "webkit/fileapi/file_system_context.h" 122 #include "webkit/fileapi/file_system_context.h"
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 359
359 // We can't call UninstallExtension with an invalid extension ID. 360 // We can't call UninstallExtension with an invalid extension ID.
360 if (!extension) { 361 if (!extension) {
361 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " 362 LOG(WARNING) << "Attempted uninstallation of non-existent extension with "
362 << "id: " << extension_id; 363 << "id: " << extension_id;
363 return false; 364 return false;
364 } 365 }
365 366
366 // The following call to UninstallExtension will not allow an uninstall of a 367 // The following call to UninstallExtension will not allow an uninstall of a
367 // policy-controlled extension. 368 // policy-controlled extension.
368 std::string error; 369 string16 error;
369 if (!extensions_service->UninstallExtension(extension_id, false, &error)) { 370 if (!extensions_service->UninstallExtension(extension_id, false, &error)) {
370 LOG(WARNING) << "Cannot uninstall extension with id " << extension_id 371 LOG(WARNING) << "Cannot uninstall extension with id " << extension_id
371 << ": " << error; 372 << ": " << error;
372 return false; 373 return false;
373 } 374 }
374 375
375 return true; 376 return true;
376 } 377 }
377 378
378 ExtensionService::ExtensionService(Profile* profile, 379 ExtensionService::ExtensionService(Profile* profile,
(...skipping 24 matching lines...) Expand all
403 app_shortcut_manager_(profile) { 404 app_shortcut_manager_(profile) {
404 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 405 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
405 406
406 // Figure out if extension installation should be enabled. 407 // Figure out if extension installation should be enabled.
407 if (command_line->HasSwitch(switches::kDisableExtensions)) { 408 if (command_line->HasSwitch(switches::kDisableExtensions)) {
408 extensions_enabled_ = false; 409 extensions_enabled_ = false;
409 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { 410 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) {
410 extensions_enabled_ = false; 411 extensions_enabled_ = false;
411 } 412 }
412 413
414 extension_management_policy_.RegisterDelegate(this);
415
416 // Normally each delegate should register itself, but the ExtensionPrefs are
417 // created before the ExtensionService.
418 extension_management_policy_.RegisterDelegate(extension_prefs_);
419
413 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, 420 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
414 content::NotificationService::AllBrowserContextsAndSources()); 421 content::NotificationService::AllBrowserContextsAndSources());
415 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, 422 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
416 content::NotificationService::AllBrowserContextsAndSources()); 423 content::NotificationService::AllBrowserContextsAndSources());
417 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 424 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
418 content::NotificationService::AllBrowserContextsAndSources()); 425 content::NotificationService::AllBrowserContextsAndSources());
419 pref_change_registrar_.Init(profile->GetPrefs()); 426 pref_change_registrar_.Init(profile->GetPrefs());
420 pref_change_registrar_.Add(prefs::kExtensionInstallAllowList, this); 427 pref_change_registrar_.Add(prefs::kExtensionInstallAllowList, this);
421 pref_change_registrar_.Add(prefs::kExtensionInstallDenyList, this); 428 pref_change_registrar_.Add(prefs::kExtensionInstallDenyList, this);
422 429
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 installed_extensions->InsertAll(extensions_); 489 installed_extensions->InsertAll(extensions_);
483 installed_extensions->InsertAll(disabled_extensions_); 490 installed_extensions->InsertAll(disabled_extensions_);
484 installed_extensions->InsertAll(terminated_extensions_); 491 installed_extensions->InsertAll(terminated_extensions_);
485 return installed_extensions; 492 return installed_extensions;
486 } 493 }
487 494
488 PendingExtensionManager* ExtensionService::pending_extension_manager() { 495 PendingExtensionManager* ExtensionService::pending_extension_manager() {
489 return &pending_extension_manager_; 496 return &pending_extension_manager_;
490 } 497 }
491 498
499 ExtensionManagementPolicy* ExtensionService::extension_management_policy() {
500 return &extension_management_policy_;
501 }
502
492 ExtensionService::~ExtensionService() { 503 ExtensionService::~ExtensionService() {
493 // No need to unload extensions here because they are profile-scoped, and the 504 // No need to unload extensions here because they are profile-scoped, and the
494 // profile is in the process of being deleted. 505 // profile is in the process of being deleted.
495 506
496 ProviderCollection::const_iterator i; 507 ProviderCollection::const_iterator i;
497 for (i = external_extension_providers_.begin(); 508 for (i = external_extension_providers_.begin();
498 i != external_extension_providers_.end(); ++i) { 509 i != external_extension_providers_.end(); ++i) {
499 ExternalExtensionProviderInterface* provider = i->get(); 510 ExternalExtensionProviderInterface* provider = i->get();
500 provider->ServiceShutdown(); 511 provider->ServiceShutdown();
501 } 512 }
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 // We should always be able to remember the extension's path. If it's not in 753 // We should always be able to remember the extension's path. If it's not in
743 // the map, someone failed to update |unloaded_extension_paths_|. 754 // the map, someone failed to update |unloaded_extension_paths_|.
744 CHECK(!path.empty()); 755 CHECK(!path.empty());
745 extensions::UnpackedInstaller::Create(this)->Load(path); 756 extensions::UnpackedInstaller::Create(this)->Load(path);
746 } 757 }
747 } 758 }
748 759
749 bool ExtensionService::UninstallExtension( 760 bool ExtensionService::UninstallExtension(
750 std::string extension_id, 761 std::string extension_id,
751 bool external_uninstall, 762 bool external_uninstall,
752 std::string* error) { 763 string16* error) {
753 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 764 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
754 765
755 scoped_refptr<const Extension> extension(GetInstalledExtension(extension_id)); 766 scoped_refptr<const Extension> extension(GetInstalledExtension(extension_id));
756 767
757 // Callers should not send us nonexistent extensions. 768 // Callers should not send us nonexistent extensions.
758 CHECK(extension); 769 CHECK(extension);
759 770
760 // Policy change which triggers an uninstall will always set 771 // Policy change which triggers an uninstall will always set
761 // |external_uninstall| to true so this is the only way to uninstall 772 // |external_uninstall| to true so this is the only way to uninstall
762 // managed extensions. 773 // managed extensions.
763 if (!Extension::UserMayDisable(extension->location()) && 774 if (!external_uninstall &&
764 !external_uninstall) { 775 !extension_management_policy_.
776 UserMayModifyStatus(extension.get(), error)) {
765 content::NotificationService::current()->Notify( 777 content::NotificationService::current()->Notify(
766 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, 778 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED,
767 content::Source<Profile>(profile_), 779 content::Source<Profile>(profile_),
768 content::Details<const Extension>(extension)); 780 content::Details<const Extension>(extension));
769 if (error != NULL) {
770 *error = errors::kCannotUninstallManagedExtension;
771 }
772 return false; 781 return false;
773 } 782 }
774 783
775 // Extract the data we need for sync now, but don't actually sync until we've 784 // Extract the data we need for sync now, but don't actually sync until we've
776 // completed the uninstallation. 785 // completed the uninstallation.
777 SyncChange sync_change; 786 SyncChange sync_change;
778 if (app_sync_bundle_.HandlesApp(*extension)) { 787 if (app_sync_bundle_.HandlesApp(*extension)) {
779 sync_change = app_sync_bundle_.CreateSyncChangeToDelete(extension); 788 sync_change = app_sync_bundle_.CreateSyncChangeToDelete(extension);
780 } else if (extension_sync_bundle_.HandlesExtension(*extension)) { 789 } else if (extension_sync_bundle_.HandlesExtension(*extension)) {
781 sync_change = extension_sync_bundle_.CreateSyncChangeToDelete(extension); 790 sync_change = extension_sync_bundle_.CreateSyncChangeToDelete(extension);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 // enabled unless otherwise noted. 881 // enabled unless otherwise noted.
873 return !extension_prefs_->IsExtensionDisabled(extension_id) && 882 return !extension_prefs_->IsExtensionDisabled(extension_id) &&
874 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); 883 !extension_prefs_->IsExternalExtensionUninstalled(extension_id);
875 } 884 }
876 885
877 bool ExtensionService::IsExternalExtensionUninstalled( 886 bool ExtensionService::IsExternalExtensionUninstalled(
878 const std::string& extension_id) const { 887 const std::string& extension_id) const {
879 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); 888 return extension_prefs_->IsExternalExtensionUninstalled(extension_id);
880 } 889 }
881 890
891 bool ExtensionService::UserMayModifyStatus(const Extension* extension,
892 string16* error) const {
893 return ExtensionManagementPolicyImpl(extension, error, true);
894 }
895
896 bool ExtensionService::UserMayModifyUsage(const Extension* extension,
897 string16* error) const {
898 return ExtensionManagementPolicyImpl(extension, error, true);
899 }
900
901 bool ExtensionService::MustRemainEnabled(const Extension* extension,
902 string16* error) const {
903 return ExtensionManagementPolicyImpl(extension, error, false);
904 }
905
906 bool ExtensionService::ExtensionManagementPolicyImpl(const Extension* extension,
907 string16* error, bool modifiable_value) const {
908 // An extension that is required (by admin policy, for example) cannot be
909 // modified.
910 bool modifiable = !Extension::IsRequired(extension->location());
911 if (modifiable)
912 return modifiable_value;
913
914 if (error) {
915 *error = l10n_util::GetStringFUTF16(
916 IDS_EXTENSION_CANT_MODIFY_POLICY_REQUIRED,
917 UTF8ToUTF16(extension->name()),
918 UTF8ToUTF16(extension->id()));
919 }
920 return !modifiable_value;
921 }
922
882 void ExtensionService::EnableExtension(const std::string& extension_id) { 923 void ExtensionService::EnableExtension(const std::string& extension_id) {
883 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 924 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
884 925
885 if (IsExtensionEnabled(extension_id)) 926 if (IsExtensionEnabled(extension_id))
886 return; 927 return;
887 928
888 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); 929 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED);
889 extension_prefs_->RemoveDisableReason(extension_id); 930 extension_prefs_->RemoveDisableReason(extension_id);
890 931
891 const Extension* extension = 932 const Extension* extension =
(...skipping 20 matching lines...) Expand all
912 Extension::DisableReason disable_reason) { 953 Extension::DisableReason disable_reason) {
913 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 954 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
914 955
915 // The extension may have been disabled already. 956 // The extension may have been disabled already.
916 if (!IsExtensionEnabled(extension_id)) 957 if (!IsExtensionEnabled(extension_id))
917 return; 958 return;
918 959
919 const Extension* extension = GetInstalledExtension(extension_id); 960 const Extension* extension = GetInstalledExtension(extension_id);
920 // |extension| can be NULL if sync disables an extension that is not 961 // |extension| can be NULL if sync disables an extension that is not
921 // installed yet. 962 // installed yet.
922 if (extension && !Extension::UserMayDisable(extension->location())) 963 if (extension &&
964 !extension_management_policy_.UserMayModifyStatus(extension, NULL)) {
923 return; 965 return;
966 }
924 967
925 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); 968 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED);
926 extension_prefs_->SetDisableReason(extension_id, disable_reason); 969 extension_prefs_->SetDisableReason(extension_id, disable_reason);
927 970
928 extension = GetExtensionByIdInternal(extension_id, true, false, true); 971 extension = GetExtensionByIdInternal(extension_id, true, false, true);
929 if (!extension) 972 if (!extension)
930 return; 973 return;
931 974
932 // Move it over to the disabled list. 975 // Move it over to the disabled list.
933 disabled_extensions_.Insert(make_scoped_refptr(extension)); 976 disabled_extensions_.Insert(make_scoped_refptr(extension));
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 extensions::ExtensionUpdater* ExtensionService::updater() { 1276 extensions::ExtensionUpdater* ExtensionService::updater() {
1234 return updater_.get(); 1277 return updater_.get();
1235 } 1278 }
1236 1279
1237 void ExtensionService::CheckAdminBlacklist() { 1280 void ExtensionService::CheckAdminBlacklist() {
1238 std::vector<std::string> to_be_removed; 1281 std::vector<std::string> to_be_removed;
1239 // Loop through extensions list, unload installed extensions. 1282 // Loop through extensions list, unload installed extensions.
1240 for (ExtensionSet::const_iterator iter = extensions_.begin(); 1283 for (ExtensionSet::const_iterator iter = extensions_.begin();
1241 iter != extensions_.end(); ++iter) { 1284 iter != extensions_.end(); ++iter) {
1242 const Extension* extension = (*iter); 1285 const Extension* extension = (*iter);
1243 if (!extension_prefs_->IsExtensionAllowedByPolicy(extension->id(), 1286 if (!extension_management_policy_.UserMayInstall(extension->id(),
1244 extension->location())) { 1287 extension->location(),
1288 std::string(),
1289 NULL)) {
1245 to_be_removed.push_back(extension->id()); 1290 to_be_removed.push_back(extension->id());
1246 } 1291 }
1247 } 1292 }
1248 1293
1249 // UnloadExtension will change the extensions_ list. So, we should 1294 // UnloadExtension will change the extensions_ list. So, we should
1250 // call it outside the iterator loop. 1295 // call it outside the iterator loop.
1251 for (unsigned int i = 0; i < to_be_removed.size(); ++i) 1296 for (unsigned int i = 0; i < to_be_removed.size(); ++i)
1252 UnloadExtension(to_be_removed[i], extension_misc::UNLOAD_REASON_DISABLE); 1297 UnloadExtension(to_be_removed[i], extension_misc::UNLOAD_REASON_DISABLE);
1253 } 1298 }
1254 1299
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after
2185 const StringOrdinal& page_ordinal) { 2230 const StringOrdinal& page_ordinal) {
2186 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2231 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2187 2232
2188 // Ensure extension is deleted unless we transfer ownership. 2233 // Ensure extension is deleted unless we transfer ownership.
2189 scoped_refptr<const Extension> scoped_extension(extension); 2234 scoped_refptr<const Extension> scoped_extension(extension);
2190 const std::string& id = extension->id(); 2235 const std::string& id = extension->id();
2191 // Extensions installed by policy can't be disabled. So even if a previous 2236 // Extensions installed by policy can't be disabled. So even if a previous
2192 // installation disabled the extension, make sure it is now enabled. 2237 // installation disabled the extension, make sure it is now enabled.
2193 bool initial_enable = 2238 bool initial_enable =
2194 !extension_prefs_->IsExtensionDisabled(id) || 2239 !extension_prefs_->IsExtensionDisabled(id) ||
2195 !Extension::UserMayDisable(extension->location()); 2240 extension_management_policy_.MustRemainEnabled(extension, NULL);
2196 PendingExtensionInfo pending_extension_info; 2241 PendingExtensionInfo pending_extension_info;
2197 if (pending_extension_manager()->GetById(id, &pending_extension_info)) { 2242 if (pending_extension_manager()->GetById(id, &pending_extension_info)) {
2198 pending_extension_manager()->Remove(id); 2243 pending_extension_manager()->Remove(id);
2199 2244
2200 if (!pending_extension_info.ShouldAllowInstall(*extension)) { 2245 if (!pending_extension_info.ShouldAllowInstall(*extension)) {
2201 LOG(WARNING) 2246 LOG(WARNING)
2202 << "ShouldAllowInstall() returned false for " 2247 << "ShouldAllowInstall() returned false for "
2203 << id << " of type " << extension->GetType() 2248 << id << " of type " << extension->GetType()
2204 << " and update URL " << extension->update_url().spec() 2249 << " and update URL " << extension->update_url().spec()
2205 << "; not installing"; 2250 << "; not installing";
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
2643 // To coexist with certain unit tests that don't have an IO thread message 2688 // To coexist with certain unit tests that don't have an IO thread message
2644 // loop available at ExtensionService shutdown, we lazy-initialize this 2689 // loop available at ExtensionService shutdown, we lazy-initialize this
2645 // object so that those cases neither create nor destroy an 2690 // object so that those cases neither create nor destroy an
2646 // APIResourceController. 2691 // APIResourceController.
2647 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 2692 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2648 if (!api_resource_controller_) { 2693 if (!api_resource_controller_) {
2649 api_resource_controller_ = new extensions::APIResourceController(); 2694 api_resource_controller_ = new extensions::APIResourceController();
2650 } 2695 }
2651 return api_resource_controller_; 2696 return api_resource_controller_;
2652 } 2697 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698