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 |