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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 #include "extensions/browser/updater/extension_cache.h" | 74 #include "extensions/browser/updater/extension_cache.h" |
| 75 #include "extensions/browser/updater/extension_downloader.h" | 75 #include "extensions/browser/updater/extension_downloader.h" |
| 76 #include "extensions/common/extension_messages.h" | 76 #include "extensions/common/extension_messages.h" |
| 77 #include "extensions/common/extension_urls.h" | 77 #include "extensions/common/extension_urls.h" |
| 78 #include "extensions/common/feature_switch.h" | 78 #include "extensions/common/feature_switch.h" |
| 79 #include "extensions/common/file_util.h" | 79 #include "extensions/common/file_util.h" |
| 80 #include "extensions/common/manifest_constants.h" | 80 #include "extensions/common/manifest_constants.h" |
| 81 #include "extensions/common/manifest_handlers/background_info.h" | 81 #include "extensions/common/manifest_handlers/background_info.h" |
| 82 #include "extensions/common/manifest_url_handlers.h" | 82 #include "extensions/common/manifest_url_handlers.h" |
| 83 #include "extensions/common/one_shot_event.h" | 83 #include "extensions/common/one_shot_event.h" |
| 84 #include "extensions/common/permissions/api_permission.h" | |
| 84 #include "extensions/common/permissions/permission_message_provider.h" | 85 #include "extensions/common/permissions/permission_message_provider.h" |
| 85 #include "extensions/common/permissions/permissions_data.h" | 86 #include "extensions/common/permissions/permissions_data.h" |
| 86 | 87 |
| 87 #if defined(ENABLE_SUPERVISED_USERS) | 88 #if defined(ENABLE_SUPERVISED_USERS) |
| 88 #include "chrome/browser/supervised_user/supervised_user_service.h" | 89 #include "chrome/browser/supervised_user/supervised_user_service.h" |
| 89 #include "chrome/browser/supervised_user/supervised_user_service_factory.h" | 90 #include "chrome/browser/supervised_user/supervised_user_service_factory.h" |
| 90 #endif | 91 #endif |
| 91 | 92 |
| 92 #if defined(OS_CHROMEOS) | 93 #if defined(OS_CHROMEOS) |
| 93 #include "chrome/browser/chromeos/extensions/install_limiter.h" | 94 #include "chrome/browser/chromeos/extensions/install_limiter.h" |
| 94 #include "storage/browser/fileapi/file_system_backend.h" | 95 #include "storage/browser/fileapi/file_system_backend.h" |
| 95 #include "storage/browser/fileapi/file_system_context.h" | 96 #include "storage/browser/fileapi/file_system_context.h" |
| 96 #endif | 97 #endif |
| 97 | 98 |
| 98 using content::BrowserContext; | 99 using content::BrowserContext; |
| 99 using content::BrowserThread; | 100 using content::BrowserThread; |
| 100 using content::DevToolsAgentHost; | 101 using content::DevToolsAgentHost; |
| 102 using extensions::APIPermission; | |
| 101 using extensions::CrxInstaller; | 103 using extensions::CrxInstaller; |
| 102 using extensions::Extension; | 104 using extensions::Extension; |
| 103 using extensions::ExtensionIdSet; | 105 using extensions::ExtensionIdSet; |
| 104 using extensions::ExtensionInfo; | 106 using extensions::ExtensionInfo; |
| 105 using extensions::ExtensionRegistry; | 107 using extensions::ExtensionRegistry; |
| 106 using extensions::ExtensionSet; | 108 using extensions::ExtensionSet; |
| 107 using extensions::FeatureSwitch; | 109 using extensions::FeatureSwitch; |
| 108 using extensions::InstallVerifier; | 110 using extensions::InstallVerifier; |
| 109 using extensions::ManagementPolicy; | 111 using extensions::ManagementPolicy; |
| 110 using extensions::Manifest; | 112 using extensions::Manifest; |
| 113 using extensions::PermissionID; | |
| 114 using extensions::PermissionIDSet; | |
| 111 using extensions::PermissionMessage; | 115 using extensions::PermissionMessage; |
| 112 using extensions::PermissionMessageIDs; | 116 using extensions::PermissionMessageIDs; |
| 113 using extensions::PermissionSet; | 117 using extensions::PermissionSet; |
| 114 using extensions::SharedModuleInfo; | 118 using extensions::SharedModuleInfo; |
| 115 using extensions::SharedModuleService; | 119 using extensions::SharedModuleService; |
| 116 using extensions::UnloadedExtensionInfo; | 120 using extensions::UnloadedExtensionInfo; |
| 117 | 121 |
| 118 namespace { | 122 namespace { |
| 119 | 123 |
| 120 // Wait this many seconds after an extensions becomes idle before updating it. | 124 // Wait this many seconds after an extensions becomes idle before updating it. |
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 733 if (extension_sync_service_ && | 737 if (extension_sync_service_ && |
| 734 reason != extensions::UNINSTALL_REASON_REINSTALL) { | 738 reason != extensions::UNINSTALL_REASON_REINSTALL) { |
| 735 sync_change = extension_sync_service_->PrepareToSyncUninstallExtension( | 739 sync_change = extension_sync_service_->PrepareToSyncUninstallExtension( |
| 736 extension.get(), is_ready()); | 740 extension.get(), is_ready()); |
| 737 } | 741 } |
| 738 | 742 |
| 739 system_->install_verifier()->Remove(extension->id()); | 743 system_->install_verifier()->Remove(extension->id()); |
| 740 | 744 |
| 741 UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType", | 745 UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType", |
| 742 extension->GetType(), 100); | 746 extension->GetType(), 100); |
| 743 RecordPermissionMessagesHistogram(extension.get(), | 747 RecordPermissionMessagesHistogram(extension.get(), "Uninstall"); |
| 744 "Extensions.Permissions_Uninstall2"); | |
| 745 | 748 |
| 746 // Unload before doing more cleanup to ensure that nothing is hanging on to | 749 // Unload before doing more cleanup to ensure that nothing is hanging on to |
| 747 // any of these resources. | 750 // any of these resources. |
| 748 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UNINSTALL); | 751 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UNINSTALL); |
| 749 | 752 |
| 750 // Tell the backend to start deleting installed extensions on the file thread. | 753 // Tell the backend to start deleting installed extensions on the file thread. |
| 751 if (!Manifest::IsUnpackedLocation(extension->location())) { | 754 if (!Manifest::IsUnpackedLocation(extension->location())) { |
| 752 if (!GetFileTaskRunner()->PostTask( | 755 if (!GetFileTaskRunner()->PostTask( |
| 753 FROM_HERE, | 756 FROM_HERE, |
| 754 base::Bind(&ExtensionService::UninstallExtensionOnFileThread, | 757 base::Bind(&ExtensionService::UninstallExtensionOnFileThread, |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 987 | 990 |
| 988 for (const scoped_refptr<const Extension>& extension : *to_unblock) { | 991 for (const scoped_refptr<const Extension>& extension : *to_unblock) { |
| 989 registry_->RemoveBlocked(extension->id()); | 992 registry_->RemoveBlocked(extension->id()); |
| 990 AddExtension(extension.get()); | 993 AddExtension(extension.get()); |
| 991 } | 994 } |
| 992 } | 995 } |
| 993 | 996 |
| 994 void ExtensionService::GrantPermissionsAndEnableExtension( | 997 void ExtensionService::GrantPermissionsAndEnableExtension( |
| 995 const Extension* extension) { | 998 const Extension* extension) { |
| 996 GrantPermissions(extension); | 999 GrantPermissions(extension); |
| 997 RecordPermissionMessagesHistogram(extension, | 1000 RecordPermissionMessagesHistogram(extension, "ReEnable"); |
| 998 "Extensions.Permissions_ReEnable2"); | |
| 999 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); | 1001 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); |
| 1000 EnableExtension(extension->id()); | 1002 EnableExtension(extension->id()); |
| 1001 } | 1003 } |
| 1002 | 1004 |
| 1003 void ExtensionService::GrantPermissions(const Extension* extension) { | 1005 void ExtensionService::GrantPermissions(const Extension* extension) { |
| 1004 CHECK(extension); | 1006 CHECK(extension); |
| 1005 extensions::PermissionsUpdater(profile()).GrantActivePermissions(extension); | 1007 extensions::PermissionsUpdater(profile()).GrantActivePermissions(extension); |
| 1006 } | 1008 } |
| 1007 | 1009 |
| 1008 // static | 1010 // static |
| 1009 void ExtensionService::RecordPermissionMessagesHistogram( | 1011 void ExtensionService::RecordPermissionMessagesHistogram( |
| 1010 const Extension* extension, const char* histogram) { | 1012 const Extension* extension, const char* histogram) { |
| 1011 // Since this is called from multiple sources, and since the histogram macros | 1013 // Since this is called from multiple sources, and since the histogram macros |
| 1012 // use statics, we need to manually lookup the histogram ourselves. | 1014 // use statics, we need to manually lookup the histogram ourselves. |
| 1013 base::HistogramBase* counter = base::LinearHistogram::FactoryGet( | 1015 std::string histogram_name_base = |
|
Devlin
2015/04/27 17:58:03
Is there a reason to record both 2 and 3? (It doe
Marc Treib
2015/04/28 12:31:32
I just didn't want to break the existing ones unti
Devlin
2015/04/28 16:16:36
Yeah, I understand the motivation, but I'm not sur
Marc Treib
2015/04/29 11:24:02
What do you mean by "pollute"? The old histograms
Devlin
2015/04/29 15:42:24
Ah, misread part of this. Nevermind; should be fi
| |
| 1014 histogram, | 1016 std::string("Extensions.Permissions_") + histogram; |
|
Devlin
2015/04/27 17:58:03
nit: + string concatenation is pretty slow - let's
Marc Treib
2015/04/28 12:31:32
Okay, done. Is "+"-style concatenation really that
Devlin
2015/04/28 16:16:36
Depends on whom you ask. ;) It's tremendously wor
| |
| 1017 base::HistogramBase* legacy_counter = base::LinearHistogram::FactoryGet( | |
| 1018 histogram_name_base + "2", | |
| 1015 1, | 1019 1, |
| 1016 PermissionMessage::kEnumBoundary, | 1020 PermissionMessage::kEnumBoundary, |
| 1017 PermissionMessage::kEnumBoundary + 1, | 1021 PermissionMessage::kEnumBoundary + 1, |
| 1018 base::HistogramBase::kUmaTargetedHistogramFlag); | 1022 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 1019 | 1023 |
| 1020 PermissionMessageIDs permissions = | 1024 PermissionMessageIDs legacy_permissions = |
| 1021 extension->permissions_data()->GetLegacyPermissionMessageIDs(); | 1025 extension->permissions_data()->GetLegacyPermissionMessageIDs(); |
| 1026 if (legacy_permissions.empty()) { | |
| 1027 legacy_counter->Add(PermissionMessage::kNone); | |
| 1028 } else { | |
| 1029 for (PermissionMessage::ID id : legacy_permissions) | |
| 1030 legacy_counter->Add(id); | |
| 1031 } | |
| 1032 | |
| 1033 base::HistogramBase* counter = base::LinearHistogram::FactoryGet( | |
| 1034 histogram_name_base + "3", | |
| 1035 1, | |
| 1036 APIPermission::kEnumBoundary, | |
| 1037 APIPermission::kEnumBoundary + 1, | |
| 1038 base::HistogramBase::kUmaTargetedHistogramFlag); | |
| 1039 | |
| 1040 PermissionIDSet permissions = | |
| 1041 extensions::PermissionMessageProvider::Get()->GetAllPermissionIDs( | |
| 1042 extension->permissions_data()->active_permissions().get(), | |
| 1043 extension->GetType()); | |
| 1022 if (permissions.empty()) { | 1044 if (permissions.empty()) { |
| 1023 counter->Add(PermissionMessage::kNone); | 1045 counter->Add(APIPermission::kNone); |
| 1024 } else { | 1046 } else { |
| 1025 for (PermissionMessage::ID id : permissions) | 1047 for (const PermissionID& id : permissions) |
| 1026 counter->Add(id); | 1048 counter->Add(id.id()); |
| 1027 } | 1049 } |
| 1028 } | 1050 } |
| 1029 | 1051 |
| 1030 void ExtensionService::NotifyExtensionLoaded(const Extension* extension) { | 1052 void ExtensionService::NotifyExtensionLoaded(const Extension* extension) { |
| 1031 // The URLRequestContexts need to be first to know that the extension | 1053 // The URLRequestContexts need to be first to know that the extension |
| 1032 // was loaded, otherwise a race can arise where a renderer that is created | 1054 // was loaded, otherwise a race can arise where a renderer that is created |
| 1033 // for the extension may try to load an extension URL with an extension id | 1055 // for the extension may try to load an extension URL with an extension id |
| 1034 // that the request context doesn't yet know about. The profile is responsible | 1056 // that the request context doesn't yet know about. The profile is responsible |
| 1035 // for ensuring its URLRequestContexts appropriately discover the loaded | 1057 // for ensuring its URLRequestContexts appropriately discover the loaded |
| 1036 // extension. | 1058 // extension. |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1658 // Extension has changed permissions significantly. Disable it. A | 1680 // Extension has changed permissions significantly. Disable it. A |
| 1659 // notification should be sent by the caller. If the extension is already | 1681 // notification should be sent by the caller. If the extension is already |
| 1660 // disabled because it was installed remotely, don't add another disable | 1682 // disabled because it was installed remotely, don't add another disable |
| 1661 // reason, but instead always set the "did escalate permissions" flag, to | 1683 // reason, but instead always set the "did escalate permissions" flag, to |
| 1662 // ensure enabling it will always show a warning. | 1684 // ensure enabling it will always show a warning. |
| 1663 if (disable_reasons == Extension::DISABLE_REMOTE_INSTALL) { | 1685 if (disable_reasons == Extension::DISABLE_REMOTE_INSTALL) { |
| 1664 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); | 1686 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); |
| 1665 } else if (is_privilege_increase) { | 1687 } else if (is_privilege_increase) { |
| 1666 disable_reasons |= Extension::DISABLE_PERMISSIONS_INCREASE; | 1688 disable_reasons |= Extension::DISABLE_PERMISSIONS_INCREASE; |
| 1667 if (!extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { | 1689 if (!extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { |
| 1668 RecordPermissionMessagesHistogram(extension, | 1690 RecordPermissionMessagesHistogram(extension, "AutoDisable"); |
| 1669 "Extensions.Permissions_AutoDisable2"); | |
| 1670 } | 1691 } |
| 1671 extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED); | 1692 extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED); |
| 1672 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); | 1693 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); |
| 1673 | 1694 |
| 1674 #if defined(ENABLE_SUPERVISED_USERS) | 1695 #if defined(ENABLE_SUPERVISED_USERS) |
| 1675 // If a custodian-installed extension is disabled for a supervised user due | 1696 // If a custodian-installed extension is disabled for a supervised user due |
| 1676 // to a permissions increase, send a request to the custodian, since the | 1697 // to a permissions increase, send a request to the custodian, since the |
| 1677 // supervised user themselves can't re-enable the extension. | 1698 // supervised user themselves can't re-enable the extension. |
| 1678 if (extensions::util::IsExtensionSupervised(extension, profile_)) { | 1699 if (extensions::util::IsExtensionSupervised(extension, profile_)) { |
| 1679 SupervisedUserService* supervised_user_service = | 1700 SupervisedUserService* supervised_user_service = |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1782 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall", | 1803 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall", |
| 1783 extension->location(), | 1804 extension->location(), |
| 1784 Manifest::NUM_LOCATIONS); | 1805 Manifest::NUM_LOCATIONS); |
| 1785 } | 1806 } |
| 1786 | 1807 |
| 1787 if (!GetInstalledExtension(extension->id())) { | 1808 if (!GetInstalledExtension(extension->id())) { |
| 1788 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", | 1809 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", |
| 1789 extension->GetType(), 100); | 1810 extension->GetType(), 100); |
| 1790 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", | 1811 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", |
| 1791 extension->location(), Manifest::NUM_LOCATIONS); | 1812 extension->location(), Manifest::NUM_LOCATIONS); |
| 1792 RecordPermissionMessagesHistogram(extension, | 1813 RecordPermissionMessagesHistogram(extension, "Install"); |
| 1793 "Extensions.Permissions_Install2"); | |
| 1794 } else { | 1814 } else { |
| 1795 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", | 1815 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", |
| 1796 extension->GetType(), 100); | 1816 extension->GetType(), 100); |
| 1797 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", | 1817 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", |
| 1798 extension->location(), Manifest::NUM_LOCATIONS); | 1818 extension->location(), Manifest::NUM_LOCATIONS); |
| 1799 | 1819 |
| 1800 // A fully installed app cannot be demoted to an ephemeral app. | 1820 // A fully installed app cannot be demoted to an ephemeral app. |
| 1801 if ((install_flags & extensions::kInstallFlagIsEphemeral) && | 1821 if ((install_flags & extensions::kInstallFlagIsEphemeral) && |
| 1802 !extension_prefs_->IsEphemeralApp(id)) { | 1822 !extension_prefs_->IsEphemeralApp(id)) { |
| 1803 install_flags &= ~static_cast<int>(extensions::kInstallFlagIsEphemeral); | 1823 install_flags &= ~static_cast<int>(extensions::kInstallFlagIsEphemeral); |
| (...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2582 } | 2602 } |
| 2583 | 2603 |
| 2584 void ExtensionService::OnProfileDestructionStarted() { | 2604 void ExtensionService::OnProfileDestructionStarted() { |
| 2585 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); | 2605 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); |
| 2586 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); | 2606 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); |
| 2587 it != ids_to_unload.end(); | 2607 it != ids_to_unload.end(); |
| 2588 ++it) { | 2608 ++it) { |
| 2589 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); | 2609 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); |
| 2590 } | 2610 } |
| 2591 } | 2611 } |
| OLD | NEW |