| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/extensions_service.h" | 5 #include "chrome/browser/extensions/extensions_service.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/histogram.h" | 10 #include "base/histogram.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 if (info.extension_location == Extension::LOAD) | 66 if (info.extension_location == Extension::LOAD) |
| 67 return true; | 67 return true; |
| 68 | 68 |
| 69 // Otherwise, reload the manifest it needs to be relocalized. | 69 // Otherwise, reload the manifest it needs to be relocalized. |
| 70 return extension_l10n_util::ShouldRelocalizeManifest(info); | 70 return extension_l10n_util::ShouldRelocalizeManifest(info); |
| 71 } | 71 } |
| 72 | 72 |
| 73 } // namespace | 73 } // namespace |
| 74 | 74 |
| 75 PendingExtensionInfo::PendingExtensionInfo(const GURL& update_url, | 75 PendingExtensionInfo::PendingExtensionInfo(const GURL& update_url, |
| 76 const Version& version, | |
| 77 bool is_theme, | 76 bool is_theme, |
| 78 bool install_silently) | 77 bool install_silently, |
| 78 bool enable_on_install, |
| 79 bool enable_incognito_on_install) |
| 79 : update_url(update_url), | 80 : update_url(update_url), |
| 80 version(version), | |
| 81 is_theme(is_theme), | 81 is_theme(is_theme), |
| 82 install_silently(install_silently) {} | 82 install_silently(install_silently), |
| 83 enable_on_install(enable_on_install), |
| 84 enable_incognito_on_install(enable_incognito_on_install) {} |
| 83 | 85 |
| 84 PendingExtensionInfo::PendingExtensionInfo() | 86 PendingExtensionInfo::PendingExtensionInfo() |
| 85 : update_url(), | 87 : update_url(), |
| 86 version(), | |
| 87 is_theme(false), | 88 is_theme(false), |
| 88 install_silently(false) {} | 89 install_silently(false), |
| 90 enable_on_install(false), |
| 91 enable_incognito_on_install(false) {} |
| 89 | 92 |
| 90 // ExtensionsService. | 93 // ExtensionsService. |
| 91 | 94 |
| 92 const char* ExtensionsService::kInstallDirectoryName = "Extensions"; | 95 const char* ExtensionsService::kInstallDirectoryName = "Extensions"; |
| 93 const char* ExtensionsService::kCurrentVersionFileName = "Current Version"; | 96 const char* ExtensionsService::kCurrentVersionFileName = "Current Version"; |
| 94 | 97 |
| 95 // static | 98 // static |
| 96 bool ExtensionsService::IsDownloadFromGallery(const GURL& download_url, | 99 bool ExtensionsService::IsDownloadFromGallery(const GURL& download_url, |
| 97 const GURL& referrer_url) { | 100 const GURL& referrer_url) { |
| 98 if (StartsWithASCII(download_url.spec(), | 101 if (StartsWithASCII(download_url.spec(), |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 client)); | 250 client)); |
| 248 installer->set_expected_id(id); | 251 installer->set_expected_id(id); |
| 249 installer->set_delete_source(true); | 252 installer->set_delete_source(true); |
| 250 installer->set_force_web_origin_to_download_url(true); | 253 installer->set_force_web_origin_to_download_url(true); |
| 251 installer->set_original_url(download_url); | 254 installer->set_original_url(download_url); |
| 252 installer->InstallCrx(extension_path); | 255 installer->InstallCrx(extension_path); |
| 253 } | 256 } |
| 254 | 257 |
| 255 void ExtensionsService::AddPendingExtension( | 258 void ExtensionsService::AddPendingExtension( |
| 256 const std::string& id, const GURL& update_url, | 259 const std::string& id, const GURL& update_url, |
| 257 const Version& version, bool is_theme, bool install_silently) { | 260 bool is_theme, bool install_silently, |
| 261 bool enable_on_install, bool enable_incognito_on_install) { |
| 258 if (GetExtensionByIdInternal(id, true, true)) { | 262 if (GetExtensionByIdInternal(id, true, true)) { |
| 259 LOG(DFATAL) << "Trying to add pending extension " << id | 263 LOG(DFATAL) << "Trying to add pending extension " << id |
| 260 << " which already exists"; | 264 << " which already exists"; |
| 261 return; | 265 return; |
| 262 } | 266 } |
| 263 AddPendingExtensionInternal(id, update_url, version, | 267 AddPendingExtensionInternal( |
| 264 is_theme, install_silently); | 268 id, update_url, is_theme, install_silently, |
| 269 enable_on_install, enable_incognito_on_install); |
| 265 } | 270 } |
| 266 | 271 |
| 267 void ExtensionsService::AddPendingExtensionInternal( | 272 void ExtensionsService::AddPendingExtensionInternal( |
| 268 const std::string& id, const GURL& update_url, | 273 const std::string& id, const GURL& update_url, |
| 269 const Version& version, bool is_theme, bool install_silently) { | 274 bool is_theme, bool install_silently, |
| 275 bool enable_on_install, bool enable_incognito_on_install) { |
| 270 pending_extensions_[id] = | 276 pending_extensions_[id] = |
| 271 PendingExtensionInfo(update_url, version, is_theme, install_silently); | 277 PendingExtensionInfo(update_url, is_theme, install_silently, |
| 278 enable_on_install, enable_incognito_on_install); |
| 272 } | 279 } |
| 273 | 280 |
| 274 void ExtensionsService::ReloadExtension(const std::string& extension_id) { | 281 void ExtensionsService::ReloadExtension(const std::string& extension_id) { |
| 275 FilePath path; | 282 FilePath path; |
| 276 Extension* current_extension = GetExtensionById(extension_id, false); | 283 Extension* current_extension = GetExtensionById(extension_id, false); |
| 277 | 284 |
| 278 // Unload the extension if it's loaded. It might not be loaded if it crashed. | 285 // Unload the extension if it's loaded. It might not be loaded if it crashed. |
| 279 if (current_extension) { | 286 if (current_extension) { |
| 280 // If the extension has an inspector open for its background page, detach | 287 // If the extension has an inspector open for its background page, detach |
| 281 // the inspector and hang onto a cookie for it, so that we can reattach | 288 // the inspector and hang onto a cookie for it, so that we can reattach |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 bool enabled) { | 678 bool enabled) { |
| 672 extension_prefs_->SetIsIncognitoEnabled(extension->id(), enabled); | 679 extension_prefs_->SetIsIncognitoEnabled(extension->id(), enabled); |
| 673 | 680 |
| 674 // Broadcast unloaded and loaded events to update browser state. | 681 // Broadcast unloaded and loaded events to update browser state. |
| 675 NotifyExtensionUnloaded(extension); | 682 NotifyExtensionUnloaded(extension); |
| 676 NotifyExtensionLoaded(extension); | 683 NotifyExtensionLoaded(extension); |
| 677 } | 684 } |
| 678 | 685 |
| 679 bool ExtensionsService::AllowFileAccess(const Extension* extension) { | 686 bool ExtensionsService::AllowFileAccess(const Extension* extension) { |
| 680 return (CommandLine::ForCurrentProcess()->HasSwitch( | 687 return (CommandLine::ForCurrentProcess()->HasSwitch( |
| 681 switches::kDisableExtensionsFileAccessCheck) || | 688 switches::kDisableExtensionsFileAccessCheck) || |
| 682 extension_prefs_->AllowFileAccess(extension->id())); | 689 extension_prefs_->AllowFileAccess(extension->id())); |
| 683 } | 690 } |
| 684 | 691 |
| 685 void ExtensionsService::SetAllowFileAccess(Extension* extension, bool allow) { | 692 void ExtensionsService::SetAllowFileAccess(Extension* extension, bool allow) { |
| 686 extension_prefs_->SetAllowFileAccess(extension->id(), allow); | 693 extension_prefs_->SetAllowFileAccess(extension->id(), allow); |
| 687 NotificationService::current()->Notify( | 694 NotificationService::current()->Notify( |
| 688 NotificationType::EXTENSION_USER_SCRIPTS_UPDATED, | 695 NotificationType::EXTENSION_USER_SCRIPTS_UPDATED, |
| 689 Source<Profile>(profile_), | 696 Source<Profile>(profile_), |
| 690 Details<Extension>(extension)); | 697 Details<Extension>(extension)); |
| 691 } | 698 } |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 for (size_t i = 0; i < extensions_.size(); ++i) { | 888 for (size_t i = 0; i < extensions_.size(); ++i) { |
| 882 if (!extensions_[i]->is_theme()) | 889 if (!extensions_[i]->is_theme()) |
| 883 extension_ids.insert(extensions_[i]->id()); | 890 extension_ids.insert(extensions_[i]->id()); |
| 884 } | 891 } |
| 885 | 892 |
| 886 child_process_logging::SetActiveExtensions(extension_ids); | 893 child_process_logging::SetActiveExtensions(extension_ids); |
| 887 } | 894 } |
| 888 | 895 |
| 889 void ExtensionsService::OnExtensionInstalled(Extension* extension, | 896 void ExtensionsService::OnExtensionInstalled(Extension* extension, |
| 890 bool allow_privilege_increase) { | 897 bool allow_privilege_increase) { |
| 898 // Ensure extension is deleted unless we transfer ownership. |
| 899 scoped_ptr<Extension> scoped_extension(extension); |
| 900 Extension::State initial_state = Extension::DISABLED; |
| 901 bool initial_enable_incognito = false; |
| 891 PendingExtensionMap::iterator it = | 902 PendingExtensionMap::iterator it = |
| 892 pending_extensions_.find(extension->id()); | 903 pending_extensions_.find(extension->id()); |
| 893 if (it != pending_extensions_.end() && | 904 if (it != pending_extensions_.end()) { |
| 894 (it->second.is_theme != extension->is_theme())) { | 905 // Set initial state from pending extension data. |
| 895 LOG(WARNING) << "Not installing pending extension " << extension->id() | 906 if (it->second.is_theme != extension->is_theme()) { |
| 896 << " with is_theme = " << extension->is_theme() | 907 LOG(WARNING) |
| 897 << "; expected is_theme = " << it->second.is_theme; | 908 << "Not installing pending extension " << extension->id() |
| 898 // Delete the extension directory since we're not going to load | 909 << " with is_theme = " << extension->is_theme() |
| 899 // it. | 910 << "; expected is_theme = " << it->second.is_theme; |
| 900 ChromeThread::PostTask( | 911 // Delete the extension directory since we're not going to |
| 901 ChromeThread::FILE, FROM_HERE, | 912 // load it. |
| 902 NewRunnableFunction(&DeleteFileHelper, extension->path(), true)); | 913 ChromeThread::PostTask( |
| 903 delete extension; | 914 ChromeThread::FILE, FROM_HERE, |
| 904 return; | 915 NewRunnableFunction(&DeleteFileHelper, extension->path(), true)); |
| 916 return; |
| 917 } |
| 918 if (it->second.is_theme) { |
| 919 DCHECK(it->second.enable_on_install); |
| 920 initial_state = Extension::ENABLED; |
| 921 DCHECK(!it->second.enable_incognito_on_install); |
| 922 initial_enable_incognito = false; |
| 923 } else { |
| 924 initial_state = |
| 925 it->second.enable_on_install ? |
| 926 Extension::ENABLED : Extension::DISABLED; |
| 927 initial_enable_incognito = |
| 928 it->second.enable_incognito_on_install; |
| 929 } |
| 930 |
| 931 pending_extensions_.erase(it); |
| 932 } else { |
| 933 // Make sure we don't enable a disabled extension. |
| 934 Extension::State existing_state = |
| 935 extension_prefs_->GetExtensionState(extension->id()); |
| 936 initial_state = |
| 937 (existing_state == Extension::DISABLED) ? |
| 938 Extension::DISABLED : Extension::ENABLED; |
| 939 initial_enable_incognito = false; |
| 905 } | 940 } |
| 906 | 941 |
| 907 extension_prefs_->OnExtensionInstalled(extension); | 942 extension_prefs_->OnExtensionInstalled( |
| 943 extension, initial_state, initial_enable_incognito); |
| 908 | 944 |
| 909 // If the extension is a theme, tell the profile (and therefore ThemeProvider) | 945 // If the extension is a theme, tell the profile (and therefore ThemeProvider) |
| 910 // to apply it. | 946 // to apply it. |
| 911 if (extension->is_theme()) { | 947 if (extension->is_theme()) { |
| 912 NotificationService::current()->Notify( | 948 NotificationService::current()->Notify( |
| 913 NotificationType::THEME_INSTALLED, | 949 NotificationType::THEME_INSTALLED, |
| 914 Source<Profile>(profile_), | 950 Source<Profile>(profile_), |
| 915 Details<Extension>(extension)); | 951 Details<Extension>(extension)); |
| 916 } else { | 952 } else { |
| 917 NotificationService::current()->Notify( | 953 NotificationService::current()->Notify( |
| 918 NotificationType::EXTENSION_INSTALLED, | 954 NotificationType::EXTENSION_INSTALLED, |
| 919 Source<Profile>(profile_), | 955 Source<Profile>(profile_), |
| 920 Details<Extension>(extension)); | 956 Details<Extension>(extension)); |
| 921 } | 957 } |
| 922 | 958 |
| 923 // Also load the extension. | |
| 924 OnExtensionLoaded(extension, allow_privilege_increase); | |
| 925 | |
| 926 // Erase any pending extension. | |
| 927 if (it != pending_extensions_.end()) { | |
| 928 pending_extensions_.erase(it); | |
| 929 } | |
| 930 | |
| 931 if (profile_->GetTemplateURLModel()) | 959 if (profile_->GetTemplateURLModel()) |
| 932 profile_->GetTemplateURLModel()->RegisterExtensionKeyword(extension); | 960 profile_->GetTemplateURLModel()->RegisterExtensionKeyword(extension); |
| 961 |
| 962 // Transfer ownership of |extension| to OnExtensionLoaded. |
| 963 OnExtensionLoaded(scoped_extension.release(), allow_privilege_increase); |
| 933 } | 964 } |
| 934 | 965 |
| 935 Extension* ExtensionsService::GetExtensionByIdInternal(const std::string& id, | 966 Extension* ExtensionsService::GetExtensionByIdInternal(const std::string& id, |
| 936 bool include_enabled, | 967 bool include_enabled, |
| 937 bool include_disabled) { | 968 bool include_disabled) { |
| 938 std::string lowercase_id = StringToLowerASCII(id); | 969 std::string lowercase_id = StringToLowerASCII(id); |
| 939 if (include_enabled) { | 970 if (include_enabled) { |
| 940 for (ExtensionList::const_iterator iter = extensions_.begin(); | 971 for (ExtensionList::const_iterator iter = extensions_.begin(); |
| 941 iter != extensions_.end(); ++iter) { | 972 iter != extensions_.end(); ++iter) { |
| 942 if ((*iter)->id() == lowercase_id) | 973 if ((*iter)->id() == lowercase_id) |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 // Finish installing on UI thread. | 1289 // Finish installing on UI thread. |
| 1259 ChromeThread::PostTask( | 1290 ChromeThread::PostTask( |
| 1260 ChromeThread::UI, FROM_HERE, | 1291 ChromeThread::UI, FROM_HERE, |
| 1261 NewRunnableMethod( | 1292 NewRunnableMethod( |
| 1262 frontend_, | 1293 frontend_, |
| 1263 &ExtensionsService::ContinueLoadAllExtensions, | 1294 &ExtensionsService::ContinueLoadAllExtensions, |
| 1264 extensions_to_reload, | 1295 extensions_to_reload, |
| 1265 start_time, | 1296 start_time, |
| 1266 true)); | 1297 true)); |
| 1267 } | 1298 } |
| OLD | NEW |