Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 <iterator> | 8 #include <iterator> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 using extensions::ExtensionSet; | 96 using extensions::ExtensionSet; |
| 97 using extensions::FeatureSwitch; | 97 using extensions::FeatureSwitch; |
| 98 using extensions::InstallVerifier; | 98 using extensions::InstallVerifier; |
| 99 using extensions::ManagementPolicy; | 99 using extensions::ManagementPolicy; |
| 100 using extensions::Manifest; | 100 using extensions::Manifest; |
| 101 using extensions::PermissionMessage; | 101 using extensions::PermissionMessage; |
| 102 using extensions::PermissionMessages; | 102 using extensions::PermissionMessages; |
| 103 using extensions::PermissionSet; | 103 using extensions::PermissionSet; |
| 104 using extensions::SharedModuleInfo; | 104 using extensions::SharedModuleInfo; |
| 105 using extensions::SharedModuleService; | 105 using extensions::SharedModuleService; |
| 106 using extensions::UninstalledExtensionInfo; | |
| 106 using extensions::UnloadedExtensionInfo; | 107 using extensions::UnloadedExtensionInfo; |
| 107 | 108 |
| 108 namespace errors = extensions::manifest_errors; | 109 namespace errors = extensions::manifest_errors; |
| 109 | 110 |
| 110 namespace { | 111 namespace { |
| 111 | 112 |
| 112 // Wait this many seconds after an extensions becomes idle before updating it. | 113 // Wait this many seconds after an extensions becomes idle before updating it. |
| 113 const int kUpdateIdleDelay = 5; | 114 const int kUpdateIdleDelay = 5; |
| 114 | 115 |
| 115 bool IsCWSSharedModule(const Extension* extension) { | 116 bool IsCWSSharedModule(const Extension* extension) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 // For example, an extension that requires experimental permissions | 162 // For example, an extension that requires experimental permissions |
| 162 // will not be loaded if the experimental command line flag is not used. | 163 // will not be loaded if the experimental command line flag is not used. |
| 163 // In this case, do not uninstall. | 164 // In this case, do not uninstall. |
| 164 if (!GetInstalledExtension(id)) { | 165 if (!GetInstalledExtension(id)) { |
| 165 // We can't call UninstallExtension with an unloaded/invalid | 166 // We can't call UninstallExtension with an unloaded/invalid |
| 166 // extension ID. | 167 // extension ID. |
| 167 LOG(WARNING) << "Attempted uninstallation of unloaded/invalid extension " | 168 LOG(WARNING) << "Attempted uninstallation of unloaded/invalid extension " |
| 168 << "with id: " << id; | 169 << "with id: " << id; |
| 169 return; | 170 return; |
| 170 } | 171 } |
| 171 UninstallExtension(id, UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION, NULL); | 172 UninstallExtension( |
| 173 id, UninstalledExtensionInfo::REASON_ORPHANED_EXTERNAL_EXTENSION, NULL); | |
| 172 } | 174 } |
| 173 | 175 |
| 174 void ExtensionService::SetFileTaskRunnerForTesting( | 176 void ExtensionService::SetFileTaskRunnerForTesting( |
| 175 base::SequencedTaskRunner* task_runner) { | 177 base::SequencedTaskRunner* task_runner) { |
| 176 file_task_runner_ = task_runner; | 178 file_task_runner_ = task_runner; |
| 177 } | 179 } |
| 178 | 180 |
| 179 void ExtensionService::ClearProvidersForTesting() { | 181 void ExtensionService::ClearProvidersForTesting() { |
| 180 external_extension_providers_.clear(); | 182 external_extension_providers_.clear(); |
| 181 } | 183 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 return true; | 232 return true; |
| 231 } | 233 } |
| 232 | 234 |
| 233 // static | 235 // static |
| 234 // This function is used to uninstall an extension via sync. The LOG statements | 236 // This function is used to uninstall an extension via sync. The LOG statements |
| 235 // within this function are used to inform the user if the uninstall cannot be | 237 // within this function are used to inform the user if the uninstall cannot be |
| 236 // done. | 238 // done. |
| 237 bool ExtensionService::UninstallExtensionHelper( | 239 bool ExtensionService::UninstallExtensionHelper( |
| 238 ExtensionService* extensions_service, | 240 ExtensionService* extensions_service, |
| 239 const std::string& extension_id, | 241 const std::string& extension_id, |
| 240 UninstallReason reason) { | 242 UninstalledExtensionInfo::Reason reason) { |
| 241 // We can't call UninstallExtension with an invalid extension ID. | 243 // We can't call UninstallExtension with an invalid extension ID. |
| 242 if (!extensions_service->GetInstalledExtension(extension_id)) { | 244 if (!extensions_service->GetInstalledExtension(extension_id)) { |
| 243 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " | 245 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " |
| 244 << "id: " << extension_id; | 246 << "id: " << extension_id; |
| 245 return false; | 247 return false; |
| 246 } | 248 } |
| 247 | 249 |
| 248 // The following call to UninstallExtension will not allow an uninstall of a | 250 // The following call to UninstallExtension will not allow an uninstall of a |
| 249 // policy-controlled extension. | 251 // policy-controlled extension. |
| 250 base::string16 error; | 252 base::string16 error; |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 687 } | 689 } |
| 688 // When reloading is done, mark this extension as done reloading. | 690 // When reloading is done, mark this extension as done reloading. |
| 689 SetBeingReloaded(extension_id, false); | 691 SetBeingReloaded(extension_id, false); |
| 690 #endif // defined(ENABLE_EXTENSIONS) | 692 #endif // defined(ENABLE_EXTENSIONS) |
| 691 } | 693 } |
| 692 | 694 |
| 693 bool ExtensionService::UninstallExtension( | 695 bool ExtensionService::UninstallExtension( |
| 694 // "transient" because the process of uninstalling may cause the reference | 696 // "transient" because the process of uninstalling may cause the reference |
| 695 // to become invalid. Instead, use |extenson->id()|. | 697 // to become invalid. Instead, use |extenson->id()|. |
| 696 const std::string& transient_extension_id, | 698 const std::string& transient_extension_id, |
| 697 UninstallReason reason, | 699 UninstalledExtensionInfo::Reason reason, |
| 698 base::string16* error) { | 700 base::string16* error) { |
| 699 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 701 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 700 | 702 |
| 701 scoped_refptr<const Extension> extension = | 703 scoped_refptr<const Extension> extension = |
| 702 GetInstalledExtension(transient_extension_id); | 704 GetInstalledExtension(transient_extension_id); |
| 703 | 705 |
| 704 // Callers should not send us nonexistent extensions. | 706 // Callers should not send us nonexistent extensions. |
| 705 CHECK(extension.get()); | 707 CHECK(extension.get()); |
| 706 | 708 |
| 707 // Policy change which triggers an uninstall will always set | 709 // Policy change which triggers an uninstall will always set |
| 708 // |external_uninstall| to true so this is the only way to uninstall | 710 // |external_uninstall| to true so this is the only way to uninstall |
| 709 // managed extensions. | 711 // managed extensions. |
| 710 // Shared modules being uninstalled will also set |external_uninstall| to true | 712 // Shared modules being uninstalled will also set |external_uninstall| to true |
| 711 // so that we can guarantee users don't uninstall a shared module. | 713 // so that we can guarantee users don't uninstall a shared module. |
| 712 // (crbug.com/273300) | 714 // (crbug.com/273300) |
| 713 // TODO(rdevlin.cronin): This is probably not right. We should do something | 715 // TODO(rdevlin.cronin): This is probably not right. We should do something |
| 714 // else, like include an enum IS_INTERNAL_UNINSTALL or IS_USER_UNINSTALL so | 716 // else, like include an enum IS_INTERNAL_UNINSTALL or IS_USER_UNINSTALL so |
| 715 // we don't do this. | 717 // we don't do this. |
| 716 bool external_uninstall = | 718 bool external_uninstall = |
| 717 (reason == UNINSTALL_REASON_INTERNAL_MANAGEMENT) || | 719 (reason == UninstalledExtensionInfo::REASON_INTERNAL_MANAGEMENT) || |
| 718 (reason == UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION) || | 720 (reason == |
| 719 (reason == UNINSTALL_REASON_ORPHANED_SHARED_MODULE); | 721 UninstalledExtensionInfo::REASON_ORPHANED_EXTERNAL_EXTENSION) || |
|
Devlin
2014/07/16 20:05:43
nit: please extra-indent this line.
rpaquay
2014/07/16 21:16:45
Done.
| |
| 722 (reason == UninstalledExtensionInfo::REASON_ORPHANED_SHARED_MODULE); | |
| 720 if (!external_uninstall && | 723 if (!external_uninstall && |
| 721 !system_->management_policy()->UserMayModifySettings( | 724 !system_->management_policy()->UserMayModifySettings( |
| 722 extension.get(), error)) { | 725 extension.get(), error)) { |
| 723 content::NotificationService::current()->Notify( | 726 content::NotificationService::current()->Notify( |
| 724 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, | 727 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, |
| 725 content::Source<Profile>(profile_), | 728 content::Source<Profile>(profile_), |
| 726 content::Details<const Extension>(extension.get())); | 729 content::Details<const Extension>(extension.get())); |
| 727 return false; | 730 return false; |
| 728 } | 731 } |
| 729 | 732 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 754 install_directory_, | 757 install_directory_, |
| 755 extension->path()))) | 758 extension->path()))) |
| 756 NOTREACHED(); | 759 NOTREACHED(); |
| 757 } | 760 } |
| 758 | 761 |
| 759 extensions::DataDeleter::StartDeleting(profile_, extension.get()); | 762 extensions::DataDeleter::StartDeleting(profile_, extension.get()); |
| 760 | 763 |
| 761 UntrackTerminatedExtension(extension->id()); | 764 UntrackTerminatedExtension(extension->id()); |
| 762 | 765 |
| 763 // Notify interested parties that we've uninstalled this extension. | 766 // Notify interested parties that we've uninstalled this extension. |
| 767 UninstalledExtensionInfo details(extension, reason); | |
| 764 content::NotificationService::current()->Notify( | 768 content::NotificationService::current()->Notify( |
| 765 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, | 769 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, |
| 766 content::Source<Profile>(profile_), | 770 content::Source<Profile>(profile_), |
| 767 content::Details<const Extension>(extension.get())); | 771 content::Details<UninstalledExtensionInfo>(&details)); |
| 768 ExtensionRegistry::Get(profile_)->TriggerOnUninstalled(extension.get()); | 772 ExtensionRegistry::Get(profile_)->TriggerOnUninstalled(extension.get()); |
| 769 | 773 |
| 770 if (extension_sync_service_) { | 774 if (extension_sync_service_) { |
| 771 extension_sync_service_->ProcessSyncUninstallExtension(extension->id(), | 775 extension_sync_service_->ProcessSyncUninstallExtension(extension->id(), |
| 772 sync_change); | 776 sync_change); |
| 773 } | 777 } |
| 774 | 778 |
| 775 delayed_installs_.Remove(extension->id()); | 779 delayed_installs_.Remove(extension->id()); |
| 776 | 780 |
| 777 extension_prefs_->OnExtensionUninstalled( | 781 extension_prefs_->OnExtensionUninstalled( |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1296 content::Source<Profile>(profile_), | 1300 content::Source<Profile>(profile_), |
| 1297 content::Details<const Extension>(extension.get())); | 1301 content::Details<const Extension>(extension.get())); |
| 1298 } | 1302 } |
| 1299 | 1303 |
| 1300 void ExtensionService::RemoveComponentExtension( | 1304 void ExtensionService::RemoveComponentExtension( |
| 1301 const std::string& extension_id) { | 1305 const std::string& extension_id) { |
| 1302 scoped_refptr<const Extension> extension( | 1306 scoped_refptr<const Extension> extension( |
| 1303 GetExtensionById(extension_id, false)); | 1307 GetExtensionById(extension_id, false)); |
| 1304 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL); | 1308 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL); |
| 1305 if (extension.get()) { | 1309 if (extension.get()) { |
| 1310 UninstalledExtensionInfo details( | |
| 1311 extension, UninstalledExtensionInfo::REASON_INTERNAL_MANAGEMENT); | |
| 1306 content::NotificationService::current()->Notify( | 1312 content::NotificationService::current()->Notify( |
| 1307 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, | 1313 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, |
| 1308 content::Source<Profile>(profile_), | 1314 content::Source<Profile>(profile_), |
| 1309 content::Details<const Extension>(extension.get())); | 1315 content::Details<UninstalledExtensionInfo>(&details)); |
| 1310 ExtensionRegistry::Get(profile_)->TriggerOnUninstalled(extension.get()); | 1316 ExtensionRegistry::Get(profile_)->TriggerOnUninstalled(extension.get()); |
| 1311 } | 1317 } |
| 1312 } | 1318 } |
| 1313 | 1319 |
| 1314 void ExtensionService::UnloadAllExtensionsForTest() { | 1320 void ExtensionService::UnloadAllExtensionsForTest() { |
| 1315 UnloadAllExtensionsInternal(); | 1321 UnloadAllExtensionsInternal(); |
| 1316 } | 1322 } |
| 1317 | 1323 |
| 1318 void ExtensionService::ReloadExtensionsForTest() { | 1324 void ExtensionService::ReloadExtensionsForTest() { |
| 1319 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit | 1325 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit |
| (...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2346 } | 2352 } |
| 2347 | 2353 |
| 2348 void ExtensionService::OnProfileDestructionStarted() { | 2354 void ExtensionService::OnProfileDestructionStarted() { |
| 2349 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); | 2355 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); |
| 2350 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); | 2356 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); |
| 2351 it != ids_to_unload.end(); | 2357 it != ids_to_unload.end(); |
| 2352 ++it) { | 2358 ++it) { |
| 2353 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); | 2359 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); |
| 2354 } | 2360 } |
| 2355 } | 2361 } |
| OLD | NEW |