| OLD | NEW |
| 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" |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 DevToolsAgentHost* agent = | 713 DevToolsAgentHost* agent = |
| 714 DevToolsAgentHostRegistry::GetDevToolsAgentHost( | 714 DevToolsAgentHostRegistry::GetDevToolsAgentHost( |
| 715 host->render_view_host()); | 715 host->render_view_host()); |
| 716 int devtools_cookie = | 716 int devtools_cookie = |
| 717 content::DevToolsManager::GetInstance()->DetachClientHost(agent); | 717 content::DevToolsManager::GetInstance()->DetachClientHost(agent); |
| 718 if (devtools_cookie >= 0) | 718 if (devtools_cookie >= 0) |
| 719 orphaned_dev_tools_[extension_id] = devtools_cookie; | 719 orphaned_dev_tools_[extension_id] = devtools_cookie; |
| 720 } | 720 } |
| 721 | 721 |
| 722 path = current_extension->path(); | 722 path = current_extension->path(); |
| 723 DisableExtension(extension_id); | 723 DisableExtension(extension_id, Extension::DISABLE_RELOAD); |
| 724 disabled_extension_paths_[extension_id] = path; | 724 disabled_extension_paths_[extension_id] = path; |
| 725 } else { | 725 } else { |
| 726 path = unloaded_extension_paths_[extension_id]; | 726 path = unloaded_extension_paths_[extension_id]; |
| 727 } | 727 } |
| 728 | 728 |
| 729 // If we're reloading a component extension, use the component extension | 729 // If we're reloading a component extension, use the component extension |
| 730 // loader's reloader. | 730 // loader's reloader. |
| 731 if (component_loader_->Exists(extension_id)) { | 731 if (component_loader_->Exists(extension_id)) { |
| 732 component_loader_->Reload(extension_id); | 732 component_loader_->Reload(extension_id); |
| 733 return; | 733 return; |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 891 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
| 892 } | 892 } |
| 893 | 893 |
| 894 void ExtensionService::EnableExtension(const std::string& extension_id) { | 894 void ExtensionService::EnableExtension(const std::string& extension_id) { |
| 895 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 895 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 896 | 896 |
| 897 if (IsExtensionEnabled(extension_id)) | 897 if (IsExtensionEnabled(extension_id)) |
| 898 return; | 898 return; |
| 899 | 899 |
| 900 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); | 900 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); |
| 901 extension_prefs_->RemoveDisableReason(extension_id); |
| 901 | 902 |
| 902 const Extension* extension = | 903 const Extension* extension = |
| 903 GetExtensionByIdInternal(extension_id, false, true, false); | 904 GetExtensionByIdInternal(extension_id, false, true, false); |
| 904 // This can happen if sync enables an extension that is not | 905 // This can happen if sync enables an extension that is not |
| 905 // installed yet. | 906 // installed yet. |
| 906 if (!extension) | 907 if (!extension) |
| 907 return; | 908 return; |
| 908 | 909 |
| 909 // Move it over to the enabled list. | 910 // Move it over to the enabled list. |
| 910 extensions_.Insert(make_scoped_refptr(extension)); | 911 extensions_.Insert(make_scoped_refptr(extension)); |
| 911 disabled_extensions_.Remove(extension->id()); | 912 disabled_extensions_.Remove(extension->id()); |
| 912 | 913 |
| 913 // Make sure any browser action contained within it is not hidden. | 914 // Make sure any browser action contained within it is not hidden. |
| 914 extension_prefs_->SetBrowserActionVisibility(extension, true); | 915 extension_prefs_->SetBrowserActionVisibility(extension, true); |
| 915 | 916 |
| 916 NotifyExtensionLoaded(extension); | 917 NotifyExtensionLoaded(extension); |
| 917 | 918 |
| 918 SyncExtensionChangeIfNeeded(*extension); | 919 SyncExtensionChangeIfNeeded(*extension); |
| 919 } | 920 } |
| 920 | 921 |
| 921 void ExtensionService::DisableExtension(const std::string& extension_id) { | 922 void ExtensionService::DisableExtension( |
| 923 const std::string& extension_id, |
| 924 Extension::DisableReason disable_reason) { |
| 922 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 925 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 923 | 926 |
| 924 // The extension may have been disabled already. | 927 // The extension may have been disabled already. |
| 925 if (!IsExtensionEnabled(extension_id)) | 928 if (!IsExtensionEnabled(extension_id)) |
| 926 return; | 929 return; |
| 927 | 930 |
| 928 const Extension* extension = GetInstalledExtension(extension_id); | 931 const Extension* extension = GetInstalledExtension(extension_id); |
| 929 // |extension| can be NULL if sync disables an extension that is not | 932 // |extension| can be NULL if sync disables an extension that is not |
| 930 // installed yet. | 933 // installed yet. |
| 931 if (extension && !Extension::UserMayDisable(extension->location())) | 934 if (extension && !Extension::UserMayDisable(extension->location())) |
| 932 return; | 935 return; |
| 933 | 936 |
| 934 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); | 937 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); |
| 938 extension_prefs_->SetDisableReason(extension_id, disable_reason); |
| 935 | 939 |
| 936 extension = GetExtensionByIdInternal(extension_id, true, false, true); | 940 extension = GetExtensionByIdInternal(extension_id, true, false, true); |
| 937 if (!extension) | 941 if (!extension) |
| 938 return; | 942 return; |
| 939 | 943 |
| 940 // Move it over to the disabled list. | 944 // Move it over to the disabled list. |
| 941 disabled_extensions_.Insert(make_scoped_refptr(extension)); | 945 disabled_extensions_.Insert(make_scoped_refptr(extension)); |
| 942 if (extensions_.Contains(extension->id())) | 946 if (extensions_.Contains(extension->id())) |
| 943 extensions_.Remove(extension->id()); | 947 extensions_.Remove(extension->id()); |
| 944 else | 948 else |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1500 LOG(WARNING) << "Could not uninstall extension " << id | 1504 LOG(WARNING) << "Could not uninstall extension " << id |
| 1501 << " for sync"; | 1505 << " for sync"; |
| 1502 } | 1506 } |
| 1503 return; | 1507 return; |
| 1504 } | 1508 } |
| 1505 | 1509 |
| 1506 // Set user settings. | 1510 // Set user settings. |
| 1507 if (extension_sync_data.enabled()) { | 1511 if (extension_sync_data.enabled()) { |
| 1508 EnableExtension(id); | 1512 EnableExtension(id); |
| 1509 } else { | 1513 } else { |
| 1510 DisableExtension(id); | 1514 DisableExtension(id, Extension::DISABLE_USER_ACTION); |
| 1511 } | 1515 } |
| 1512 | 1516 |
| 1513 // We need to cache some version information here because setting the | 1517 // We need to cache some version information here because setting the |
| 1514 // incognito flag invalidates the |extension| pointer (it reloads the | 1518 // incognito flag invalidates the |extension| pointer (it reloads the |
| 1515 // extension). | 1519 // extension). |
| 1516 bool extension_installed = (extension != NULL); | 1520 bool extension_installed = (extension != NULL); |
| 1517 int result = extension ? | 1521 int result = extension ? |
| 1518 extension->version()->CompareTo(extension_sync_data.version()) : 0; | 1522 extension->version()->CompareTo(extension_sync_data.version()) : 0; |
| 1519 SetIsIncognitoEnabled(id, extension_sync_data.incognito_enabled()); | 1523 SetIsIncognitoEnabled(id, extension_sync_data.incognito_enabled()); |
| 1520 extension = NULL; // No longer safe to use. | 1524 extension = NULL; // No longer safe to use. |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2028 EnableExtension(extension->id()); | 2032 EnableExtension(extension->id()); |
| 2029 | 2033 |
| 2030 // Check if the extension's privileges have changed and disable the | 2034 // Check if the extension's privileges have changed and disable the |
| 2031 // extension if necessary. | 2035 // extension if necessary. |
| 2032 InitializePermissions(extension); | 2036 InitializePermissions(extension); |
| 2033 | 2037 |
| 2034 bool disabled = extension_prefs_->IsExtensionDisabled(extension->id()); | 2038 bool disabled = extension_prefs_->IsExtensionDisabled(extension->id()); |
| 2035 if (disabled) { | 2039 if (disabled) { |
| 2036 disabled_extensions_.Insert(scoped_extension); | 2040 disabled_extensions_.Insert(scoped_extension); |
| 2037 SyncExtensionChangeIfNeeded(*extension); | 2041 SyncExtensionChangeIfNeeded(*extension); |
| 2042 content::NotificationService::current()->Notify( |
| 2043 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
| 2044 content::Source<Profile>(profile_), |
| 2045 content::Details<const Extension>(extension)); |
| 2038 | 2046 |
| 2039 if (extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { | 2047 if (extension_prefs_->GetDisableReason(extension->id()) == |
| 2040 content::NotificationService::current()->Notify( | 2048 Extension::DISABLE_PERMISSIONS_INCREASE) { |
| 2041 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | |
| 2042 content::Source<Profile>(profile_), | |
| 2043 content::Details<const Extension>(extension)); | |
| 2044 extensions::AddExtensionDisabledError(this, extension); | 2049 extensions::AddExtensionDisabledError(this, extension); |
| 2045 } | 2050 } |
| 2046 // Although the extension is disabled, we technically did succeed in adding | 2051 // Although the extension is disabled, we technically did succeed in adding |
| 2047 // it to the list of installed extensions. | 2052 // it to the list of installed extensions. |
| 2048 return true; | 2053 return true; |
| 2049 } | 2054 } |
| 2050 | 2055 |
| 2051 // All apps that are displayed in the launcher are ordered by their ordinals | 2056 // All apps that are displayed in the launcher are ordered by their ordinals |
| 2052 // so we must ensure they have valid ordinals. | 2057 // so we must ensure they have valid ordinals. |
| 2053 if (extension->ShouldDisplayInLauncher()) | 2058 if (extension->ShouldDisplayInLauncher()) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2108 // will disable the extension and prompt the user to approve the increase | 2113 // will disable the extension and prompt the user to approve the increase |
| 2109 // in privileges. The extension could then release a new version that | 2114 // in privileges. The extension could then release a new version that |
| 2110 // removes the "omnibox" permission. When the user upgrades, Chrome will | 2115 // removes the "omnibox" permission. When the user upgrades, Chrome will |
| 2111 // still remember that "omnibox" had been granted, so that if the | 2116 // still remember that "omnibox" had been granted, so that if the |
| 2112 // extension once again includes "omnibox" in an upgrade, the extension | 2117 // extension once again includes "omnibox" in an upgrade, the extension |
| 2113 // can upgrade without requiring this user's approval. | 2118 // can upgrade without requiring this user's approval. |
| 2114 const Extension* old = GetExtensionByIdInternal(extension->id(), | 2119 const Extension* old = GetExtensionByIdInternal(extension->id(), |
| 2115 true, true, false); | 2120 true, true, false); |
| 2116 bool is_extension_upgrade = old != NULL; | 2121 bool is_extension_upgrade = old != NULL; |
| 2117 bool is_privilege_increase = false; | 2122 bool is_privilege_increase = false; |
| 2123 bool previously_disabled = false; |
| 2124 Extension::DisableReason disable_reason = |
| 2125 extension_prefs_->GetDisableReason(extension->id()); |
| 2118 | 2126 |
| 2119 // We only need to compare the granted permissions to the current permissions | 2127 // We only need to compare the granted permissions to the current permissions |
| 2120 // if the extension is not allowed to silently increase its permissions. | 2128 // if the extension is not allowed to silently increase its permissions. |
| 2121 if (!extension->CanSilentlyIncreasePermissions()) { | 2129 if (!extension->CanSilentlyIncreasePermissions()) { |
| 2122 // Add all the recognized permissions if the granted permissions list | 2130 // Add all the recognized permissions if the granted permissions list |
| 2123 // hasn't been initialized yet. | 2131 // hasn't been initialized yet. |
| 2124 scoped_refptr<ExtensionPermissionSet> granted_permissions = | 2132 scoped_refptr<ExtensionPermissionSet> granted_permissions = |
| 2125 extension_prefs_->GetGrantedPermissions(extension->id()); | 2133 extension_prefs_->GetGrantedPermissions(extension->id()); |
| 2126 CHECK(granted_permissions.get()); | 2134 CHECK(granted_permissions.get()); |
| 2127 | 2135 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2140 if (extension->location() != Extension::LOAD) | 2148 if (extension->location() != Extension::LOAD) |
| 2141 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); | 2149 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); |
| 2142 | 2150 |
| 2143 // Extensions get upgraded if the privileges are allowed to increase or | 2151 // Extensions get upgraded if the privileges are allowed to increase or |
| 2144 // the privileges haven't increased. | 2152 // the privileges haven't increased. |
| 2145 if (!is_privilege_increase) { | 2153 if (!is_privilege_increase) { |
| 2146 SetBeingUpgraded(old, true); | 2154 SetBeingUpgraded(old, true); |
| 2147 SetBeingUpgraded(extension, true); | 2155 SetBeingUpgraded(extension, true); |
| 2148 } | 2156 } |
| 2149 | 2157 |
| 2158 // If the extension was already disabled, suppress any alerts for becoming |
| 2159 // disabled on permissions increase. |
| 2160 previously_disabled = extension_prefs_->IsExtensionDisabled(old->id()); |
| 2161 if (previously_disabled) { |
| 2162 Extension::DisableReason reason = extension_prefs_->GetDisableReason( |
| 2163 old->id()); |
| 2164 if (reason == Extension::DISABLE_UNKNOWN) { |
| 2165 // Initialize the reason for legacy disabled extensions from whether the |
| 2166 // extension already exceeded granted permissions. |
| 2167 if (extension_prefs_->DidExtensionEscalatePermissions(old->id())) |
| 2168 disable_reason = Extension::DISABLE_PERMISSIONS_INCREASE; |
| 2169 else |
| 2170 disable_reason = Extension::DISABLE_USER_ACTION; |
| 2171 } |
| 2172 } else { |
| 2173 disable_reason = Extension::DISABLE_PERMISSIONS_INCREASE; |
| 2174 } |
| 2175 |
| 2150 // To upgrade an extension in place, unload the old one and | 2176 // To upgrade an extension in place, unload the old one and |
| 2151 // then load the new one. | 2177 // then load the new one. |
| 2152 UnloadExtension(old->id(), extension_misc::UNLOAD_REASON_UPDATE); | 2178 UnloadExtension(old->id(), extension_misc::UNLOAD_REASON_UPDATE); |
| 2153 old = NULL; | 2179 old = NULL; |
| 2154 } | 2180 } |
| 2155 | 2181 |
| 2156 // Extension has changed permissions significantly. Disable it. A | 2182 // Extension has changed permissions significantly. Disable it. A |
| 2157 // notification should be sent by the caller. | 2183 // notification should be sent by the caller. |
| 2158 if (is_privilege_increase) { | 2184 if (is_privilege_increase) { |
| 2159 if (!extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { | 2185 if (!extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { |
| 2160 RecordPermissionMessagesHistogram( | 2186 RecordPermissionMessagesHistogram( |
| 2161 extension, "Extensions.Permissions_AutoDisable"); | 2187 extension, "Extensions.Permissions_AutoDisable"); |
| 2162 } | 2188 } |
| 2163 extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED); | 2189 extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED); |
| 2164 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); | 2190 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); |
| 2191 extension_prefs_->SetDisableReason(extension->id(), disable_reason); |
| 2165 } | 2192 } |
| 2166 } | 2193 } |
| 2167 | 2194 |
| 2168 void ExtensionService::UpdateActiveExtensionsInCrashReporter() { | 2195 void ExtensionService::UpdateActiveExtensionsInCrashReporter() { |
| 2169 std::set<std::string> extension_ids; | 2196 std::set<std::string> extension_ids; |
| 2170 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 2197 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
| 2171 iter != extensions_.end(); ++iter) { | 2198 iter != extensions_.end(); ++iter) { |
| 2172 const Extension* extension = *iter; | 2199 const Extension* extension = *iter; |
| 2173 if (!extension->is_theme() && extension->location() != Extension::COMPONENT) | 2200 if (!extension->is_theme() && extension->location() != Extension::COMPONENT) |
| 2174 extension_ids.insert(extension->id()); | 2201 extension_ids.insert(extension->id()); |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2639 // To coexist with certain unit tests that don't have an IO thread message | 2666 // To coexist with certain unit tests that don't have an IO thread message |
| 2640 // loop available at ExtensionService shutdown, we lazy-initialize this | 2667 // loop available at ExtensionService shutdown, we lazy-initialize this |
| 2641 // object so that those cases neither create nor destroy an | 2668 // object so that those cases neither create nor destroy an |
| 2642 // APIResourceController. | 2669 // APIResourceController. |
| 2643 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 2670 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 2644 if (!api_resource_controller_) { | 2671 if (!api_resource_controller_) { |
| 2645 api_resource_controller_ = new extensions::APIResourceController(); | 2672 api_resource_controller_ = new extensions::APIResourceController(); |
| 2646 } | 2673 } |
| 2647 return api_resource_controller_; | 2674 return api_resource_controller_; |
| 2648 } | 2675 } |
| OLD | NEW |