| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 #include "content/public/browser/render_process_host.h" | 53 #include "content/public/browser/render_process_host.h" |
| 54 #include "content/public/browser/storage_partition.h" | 54 #include "content/public/browser/storage_partition.h" |
| 55 #include "extensions/browser/event_router.h" | 55 #include "extensions/browser/event_router.h" |
| 56 #include "extensions/browser/extension_host.h" | 56 #include "extensions/browser/extension_host.h" |
| 57 #include "extensions/browser/extension_prefs.h" | 57 #include "extensions/browser/extension_prefs.h" |
| 58 #include "extensions/browser/extension_registry.h" | 58 #include "extensions/browser/extension_registry.h" |
| 59 #include "extensions/browser/extension_system.h" | 59 #include "extensions/browser/extension_system.h" |
| 60 #include "extensions/browser/install_flag.h" | 60 #include "extensions/browser/install_flag.h" |
| 61 #include "extensions/browser/pref_names.h" | 61 #include "extensions/browser/pref_names.h" |
| 62 #include "extensions/browser/runtime_data.h" | 62 #include "extensions/browser/runtime_data.h" |
| 63 #include "extensions/browser/uninstall_reason.h" |
| 63 #include "extensions/browser/update_observer.h" | 64 #include "extensions/browser/update_observer.h" |
| 64 #include "extensions/common/extension_messages.h" | 65 #include "extensions/common/extension_messages.h" |
| 65 #include "extensions/common/feature_switch.h" | 66 #include "extensions/common/feature_switch.h" |
| 66 #include "extensions/common/file_util.h" | 67 #include "extensions/common/file_util.h" |
| 67 #include "extensions/common/manifest_constants.h" | 68 #include "extensions/common/manifest_constants.h" |
| 68 #include "extensions/common/manifest_handlers/background_info.h" | 69 #include "extensions/common/manifest_handlers/background_info.h" |
| 69 #include "extensions/common/one_shot_event.h" | 70 #include "extensions/common/one_shot_event.h" |
| 70 #include "extensions/common/permissions/permission_message_provider.h" | 71 #include "extensions/common/permissions/permission_message_provider.h" |
| 71 #include "extensions/common/permissions/permissions_data.h" | 72 #include "extensions/common/permissions/permissions_data.h" |
| 72 | 73 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 // For example, an extension that requires experimental permissions | 134 // For example, an extension that requires experimental permissions |
| 134 // will not be loaded if the experimental command line flag is not used. | 135 // will not be loaded if the experimental command line flag is not used. |
| 135 // In this case, do not uninstall. | 136 // In this case, do not uninstall. |
| 136 if (!GetInstalledExtension(id)) { | 137 if (!GetInstalledExtension(id)) { |
| 137 // We can't call UninstallExtension with an unloaded/invalid | 138 // We can't call UninstallExtension with an unloaded/invalid |
| 138 // extension ID. | 139 // extension ID. |
| 139 LOG(WARNING) << "Attempted uninstallation of unloaded/invalid extension " | 140 LOG(WARNING) << "Attempted uninstallation of unloaded/invalid extension " |
| 140 << "with id: " << id; | 141 << "with id: " << id; |
| 141 return; | 142 return; |
| 142 } | 143 } |
| 143 UninstallExtension(id, UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION, NULL); | 144 UninstallExtension( |
| 145 id, extensions::UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION, NULL); |
| 144 } | 146 } |
| 145 | 147 |
| 146 void ExtensionService::SetFileTaskRunnerForTesting( | 148 void ExtensionService::SetFileTaskRunnerForTesting( |
| 147 base::SequencedTaskRunner* task_runner) { | 149 base::SequencedTaskRunner* task_runner) { |
| 148 file_task_runner_ = task_runner; | 150 file_task_runner_ = task_runner; |
| 149 } | 151 } |
| 150 | 152 |
| 151 void ExtensionService::ClearProvidersForTesting() { | 153 void ExtensionService::ClearProvidersForTesting() { |
| 152 external_extension_providers_.clear(); | 154 external_extension_providers_.clear(); |
| 153 } | 155 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 return true; | 204 return true; |
| 203 } | 205 } |
| 204 | 206 |
| 205 // static | 207 // static |
| 206 // This function is used to uninstall an extension via sync. The LOG statements | 208 // This function is used to uninstall an extension via sync. The LOG statements |
| 207 // within this function are used to inform the user if the uninstall cannot be | 209 // within this function are used to inform the user if the uninstall cannot be |
| 208 // done. | 210 // done. |
| 209 bool ExtensionService::UninstallExtensionHelper( | 211 bool ExtensionService::UninstallExtensionHelper( |
| 210 ExtensionService* extensions_service, | 212 ExtensionService* extensions_service, |
| 211 const std::string& extension_id, | 213 const std::string& extension_id, |
| 212 UninstallReason reason) { | 214 extensions::UninstallReason reason) { |
| 213 // We can't call UninstallExtension with an invalid extension ID. | 215 // We can't call UninstallExtension with an invalid extension ID. |
| 214 if (!extensions_service->GetInstalledExtension(extension_id)) { | 216 if (!extensions_service->GetInstalledExtension(extension_id)) { |
| 215 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " | 217 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " |
| 216 << "id: " << extension_id; | 218 << "id: " << extension_id; |
| 217 return false; | 219 return false; |
| 218 } | 220 } |
| 219 | 221 |
| 220 // The following call to UninstallExtension will not allow an uninstall of a | 222 // The following call to UninstallExtension will not allow an uninstall of a |
| 221 // policy-controlled extension. | 223 // policy-controlled extension. |
| 222 base::string16 error; | 224 base::string16 error; |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 | 672 |
| 671 void ExtensionService::ReloadExtensionWithQuietFailure( | 673 void ExtensionService::ReloadExtensionWithQuietFailure( |
| 672 const std::string& extension_id) { | 674 const std::string& extension_id) { |
| 673 ReloadExtensionImpl(extension_id, false); // be_noisy | 675 ReloadExtensionImpl(extension_id, false); // be_noisy |
| 674 } | 676 } |
| 675 | 677 |
| 676 bool ExtensionService::UninstallExtension( | 678 bool ExtensionService::UninstallExtension( |
| 677 // "transient" because the process of uninstalling may cause the reference | 679 // "transient" because the process of uninstalling may cause the reference |
| 678 // to become invalid. Instead, use |extenson->id()|. | 680 // to become invalid. Instead, use |extenson->id()|. |
| 679 const std::string& transient_extension_id, | 681 const std::string& transient_extension_id, |
| 680 UninstallReason reason, | 682 extensions::UninstallReason reason, |
| 681 base::string16* error) { | 683 base::string16* error) { |
| 682 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 684 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 683 | 685 |
| 684 scoped_refptr<const Extension> extension = | 686 scoped_refptr<const Extension> extension = |
| 685 GetInstalledExtension(transient_extension_id); | 687 GetInstalledExtension(transient_extension_id); |
| 686 | 688 |
| 687 // Callers should not send us nonexistent extensions. | 689 // Callers should not send us nonexistent extensions. |
| 688 CHECK(extension.get()); | 690 CHECK(extension.get()); |
| 689 | 691 |
| 690 // Policy change which triggers an uninstall will always set | 692 // Policy change which triggers an uninstall will always set |
| 691 // |external_uninstall| to true so this is the only way to uninstall | 693 // |external_uninstall| to true so this is the only way to uninstall |
| 692 // managed extensions. | 694 // managed extensions. |
| 693 // Shared modules being uninstalled will also set |external_uninstall| to true | 695 // Shared modules being uninstalled will also set |external_uninstall| to true |
| 694 // so that we can guarantee users don't uninstall a shared module. | 696 // so that we can guarantee users don't uninstall a shared module. |
| 695 // (crbug.com/273300) | 697 // (crbug.com/273300) |
| 696 // TODO(rdevlin.cronin): This is probably not right. We should do something | 698 // TODO(rdevlin.cronin): This is probably not right. We should do something |
| 697 // else, like include an enum IS_INTERNAL_UNINSTALL or IS_USER_UNINSTALL so | 699 // else, like include an enum IS_INTERNAL_UNINSTALL or IS_USER_UNINSTALL so |
| 698 // we don't do this. | 700 // we don't do this. |
| 699 bool external_uninstall = | 701 bool external_uninstall = |
| 700 (reason == UNINSTALL_REASON_INTERNAL_MANAGEMENT) || | 702 (reason == extensions::UNINSTALL_REASON_INTERNAL_MANAGEMENT) || |
| 701 (reason == UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION) || | 703 (reason == extensions::UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION) || |
| 702 (reason == UNINSTALL_REASON_ORPHANED_SHARED_MODULE); | 704 (reason == extensions::UNINSTALL_REASON_ORPHANED_SHARED_MODULE); |
| 703 if (!external_uninstall && | 705 if (!external_uninstall && |
| 704 !system_->management_policy()->UserMayModifySettings( | 706 !system_->management_policy()->UserMayModifySettings( |
| 705 extension.get(), error)) { | 707 extension.get(), error)) { |
| 706 content::NotificationService::current()->Notify( | 708 content::NotificationService::current()->Notify( |
| 707 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, | 709 chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, |
| 708 content::Source<Profile>(profile_), | 710 content::Source<Profile>(profile_), |
| 709 content::Details<const Extension>(extension.get())); | 711 content::Details<const Extension>(extension.get())); |
| 710 return false; | 712 return false; |
| 711 } | 713 } |
| 712 | 714 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 741 | 743 |
| 742 extensions::DataDeleter::StartDeleting(profile_, extension.get()); | 744 extensions::DataDeleter::StartDeleting(profile_, extension.get()); |
| 743 | 745 |
| 744 UntrackTerminatedExtension(extension->id()); | 746 UntrackTerminatedExtension(extension->id()); |
| 745 | 747 |
| 746 // Notify interested parties that we've uninstalled this extension. | 748 // Notify interested parties that we've uninstalled this extension. |
| 747 content::NotificationService::current()->Notify( | 749 content::NotificationService::current()->Notify( |
| 748 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, | 750 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, |
| 749 content::Source<Profile>(profile_), | 751 content::Source<Profile>(profile_), |
| 750 content::Details<const Extension>(extension.get())); | 752 content::Details<const Extension>(extension.get())); |
| 751 ExtensionRegistry::Get(profile_)->TriggerOnUninstalled(extension.get()); | 753 ExtensionRegistry::Get(profile_) |
| 754 ->TriggerOnUninstalled(extension.get(), reason); |
| 752 | 755 |
| 753 if (extension_sync_service_) { | 756 if (extension_sync_service_) { |
| 754 extension_sync_service_->ProcessSyncUninstallExtension(extension->id(), | 757 extension_sync_service_->ProcessSyncUninstallExtension(extension->id(), |
| 755 sync_change); | 758 sync_change); |
| 756 } | 759 } |
| 757 | 760 |
| 758 delayed_installs_.Remove(extension->id()); | 761 delayed_installs_.Remove(extension->id()); |
| 759 | 762 |
| 760 extension_prefs_->OnExtensionUninstalled( | 763 extension_prefs_->OnExtensionUninstalled( |
| 761 extension->id(), extension->location(), external_uninstall); | 764 extension->id(), extension->location(), external_uninstall); |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1283 void ExtensionService::RemoveComponentExtension( | 1286 void ExtensionService::RemoveComponentExtension( |
| 1284 const std::string& extension_id) { | 1287 const std::string& extension_id) { |
| 1285 scoped_refptr<const Extension> extension( | 1288 scoped_refptr<const Extension> extension( |
| 1286 GetExtensionById(extension_id, false)); | 1289 GetExtensionById(extension_id, false)); |
| 1287 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL); | 1290 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL); |
| 1288 if (extension.get()) { | 1291 if (extension.get()) { |
| 1289 content::NotificationService::current()->Notify( | 1292 content::NotificationService::current()->Notify( |
| 1290 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, | 1293 chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, |
| 1291 content::Source<Profile>(profile_), | 1294 content::Source<Profile>(profile_), |
| 1292 content::Details<const Extension>(extension.get())); | 1295 content::Details<const Extension>(extension.get())); |
| 1293 ExtensionRegistry::Get(profile_)->TriggerOnUninstalled(extension.get()); | 1296 ExtensionRegistry::Get(profile_)->TriggerOnUninstalled( |
| 1297 extension.get(), extensions::UNINSTALL_REASON_INTERNAL_MANAGEMENT); |
| 1294 } | 1298 } |
| 1295 } | 1299 } |
| 1296 | 1300 |
| 1297 void ExtensionService::UnloadAllExtensionsForTest() { | 1301 void ExtensionService::UnloadAllExtensionsForTest() { |
| 1298 UnloadAllExtensionsInternal(); | 1302 UnloadAllExtensionsInternal(); |
| 1299 } | 1303 } |
| 1300 | 1304 |
| 1301 void ExtensionService::ReloadExtensionsForTest() { | 1305 void ExtensionService::ReloadExtensionsForTest() { |
| 1302 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit | 1306 // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit |
| 1303 // warning about calling test code in production. | 1307 // warning about calling test code in production. |
| (...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2330 } | 2334 } |
| 2331 | 2335 |
| 2332 void ExtensionService::OnProfileDestructionStarted() { | 2336 void ExtensionService::OnProfileDestructionStarted() { |
| 2333 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); | 2337 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); |
| 2334 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); | 2338 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); |
| 2335 it != ids_to_unload.end(); | 2339 it != ids_to_unload.end(); |
| 2336 ++it) { | 2340 ++it) { |
| 2337 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); | 2341 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); |
| 2338 } | 2342 } |
| 2339 } | 2343 } |
| OLD | NEW |