| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 | 52 |
| 53 namespace errors = extension_manifest_errors; | 53 namespace errors = extension_manifest_errors; |
| 54 | 54 |
| 55 namespace { | 55 namespace { |
| 56 | 56 |
| 57 // Helper class to collect the IDs of every extension listed in the prefs. | 57 // Helper class to collect the IDs of every extension listed in the prefs. |
| 58 class InstalledExtensionSet { | 58 class InstalledExtensionSet { |
| 59 public: | 59 public: |
| 60 explicit InstalledExtensionSet(ExtensionPrefs* prefs) { | 60 explicit InstalledExtensionSet(ExtensionPrefs* prefs) { |
| 61 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info( | 61 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info( |
| 62 ExtensionPrefs::CollectExtensionsInfo(prefs)); | 62 prefs->GetInstalledExtensionsInfo()); |
| 63 | 63 |
| 64 for (size_t i = 0; i < info->size(); ++i) { | 64 for (size_t i = 0; i < info->size(); ++i) { |
| 65 std::string version; | 65 std::string version; |
| 66 const DictionaryValue* manifest = info->at(i)->extension_manifest.get(); | 66 const DictionaryValue* manifest = info->at(i)->extension_manifest.get(); |
| 67 if (!manifest || | 67 if (!manifest || |
| 68 !manifest->GetString(extension_manifest_keys::kVersion, &version)) { | 68 !manifest->GetString(extension_manifest_keys::kVersion, &version)) { |
| 69 // Without a version, the extension is invalid. Ignoring it here will | 69 // Without a version, the extension is invalid. Ignoring it here will |
| 70 // cause it to get garbage collected. | 70 // cause it to get garbage collected. |
| 71 continue; | 71 continue; |
| 72 } | 72 } |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 if (devtools_cookie >= 0) | 240 if (devtools_cookie >= 0) |
| 241 orphaned_dev_tools_[extension_id] = devtools_cookie; | 241 orphaned_dev_tools_[extension_id] = devtools_cookie; |
| 242 } | 242 } |
| 243 | 243 |
| 244 path = current_extension->path(); | 244 path = current_extension->path(); |
| 245 UnloadExtension(extension_id); | 245 UnloadExtension(extension_id); |
| 246 } else { | 246 } else { |
| 247 path = unloaded_extension_paths_[extension_id]; | 247 path = unloaded_extension_paths_[extension_id]; |
| 248 } | 248 } |
| 249 | 249 |
| 250 // We should always be able to remember the extension's path. If it's not in | 250 // Check the installed extensions to see if what we're reloading was already |
| 251 // the map, someone failed to update |unloaded_extension_paths_|. | 251 // installed. |
| 252 CHECK(!path.empty()); | 252 scoped_ptr<ExtensionInfo> installed_extension( |
| 253 | 253 extension_prefs_->GetInstalledExtensionInfo(extension_id)); |
| 254 LoadExtension(path); | 254 if (installed_extension.get() && |
| 255 installed_extension->extension_manifest.get()) { |
| 256 LoadInstalledExtension(*installed_extension, false); |
| 257 } else { |
| 258 // We should always be able to remember the extension's path. If it's not in |
| 259 // the map, someone failed to update |unloaded_extension_paths_|. |
| 260 CHECK(!path.empty()); |
| 261 LoadExtension(path); |
| 262 } |
| 255 } | 263 } |
| 256 | 264 |
| 257 void ExtensionsService::UninstallExtension(const std::string& extension_id, | 265 void ExtensionsService::UninstallExtension(const std::string& extension_id, |
| 258 bool external_uninstall) { | 266 bool external_uninstall) { |
| 259 Extension* extension = GetExtensionByIdInternal(extension_id, true, true); | 267 Extension* extension = GetExtensionByIdInternal(extension_id, true, true); |
| 260 | 268 |
| 261 // Callers should not send us nonexistant extensions. | 269 // Callers should not send us nonexistant extensions. |
| 262 DCHECK(extension); | 270 DCHECK(extension); |
| 263 | 271 |
| 264 extension_prefs_->OnExtensionUninstalled(extension, external_uninstall); | 272 extension_prefs_->OnExtensionUninstalled(extension, external_uninstall); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 } | 369 } |
| 362 | 370 |
| 363 void ExtensionsService::LoadAllExtensions() { | 371 void ExtensionsService::LoadAllExtensions() { |
| 364 base::TimeTicks start_time = base::TimeTicks::Now(); | 372 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 365 | 373 |
| 366 // Load any component extensions. | 374 // Load any component extensions. |
| 367 LoadComponentExtensions(); | 375 LoadComponentExtensions(); |
| 368 | 376 |
| 369 // Load the previously installed extensions. | 377 // Load the previously installed extensions. |
| 370 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info( | 378 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info( |
| 371 ExtensionPrefs::CollectExtensionsInfo(extension_prefs_.get())); | 379 extension_prefs_->GetInstalledExtensionsInfo()); |
| 372 | 380 |
| 373 // If any extensions need localization, we bounce them all to the file thread | 381 // If any extensions need localization, we bounce them all to the file thread |
| 374 // for re-reading and localization. | 382 // for re-reading and localization. |
| 375 for (size_t i = 0; i < info->size(); ++i) { | 383 for (size_t i = 0; i < info->size(); ++i) { |
| 376 if (ShouldReloadExtensionManifest(*info->at(i))) { | 384 if (ShouldReloadExtensionManifest(*info->at(i))) { |
| 377 ChromeThread::PostTask( | 385 ChromeThread::PostTask( |
| 378 ChromeThread::FILE, FROM_HERE, NewRunnableMethod( | 386 ChromeThread::FILE, FROM_HERE, NewRunnableMethod( |
| 379 backend_.get(), | 387 backend_.get(), |
| 380 &ExtensionsServiceBackend::ReloadExtensionManifests, | 388 &ExtensionsServiceBackend::ReloadExtensionManifests, |
| 381 info.release(), // Callee takes ownership of the memory. | 389 info.release(), // Callee takes ownership of the memory. |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 | 739 |
| 732 // To upgrade an extension in place, unload the old one and | 740 // To upgrade an extension in place, unload the old one and |
| 733 // then load the new one. | 741 // then load the new one. |
| 734 UnloadExtension(old->id()); | 742 UnloadExtension(old->id()); |
| 735 old = NULL; | 743 old = NULL; |
| 736 | 744 |
| 737 if (!allow_silent_upgrade) { | 745 if (!allow_silent_upgrade) { |
| 738 // Extension has changed permissions significantly. Disable it. We | 746 // Extension has changed permissions significantly. Disable it. We |
| 739 // send a notification below. | 747 // send a notification below. |
| 740 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); | 748 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); |
| 741 extension_prefs_->SetShowInstallWarningOnEnable(extension, true); | 749 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); |
| 742 } | 750 } |
| 743 } else { | 751 } else { |
| 744 // We already have the extension of the same or older version. | 752 // We already have the extension of the same or older version. |
| 745 std::string error_message("Duplicate extension load attempt: "); | 753 std::string error_message("Duplicate extension load attempt: "); |
| 746 error_message += extension->id(); | 754 error_message += extension->id(); |
| 747 LOG(WARNING) << error_message; | 755 LOG(WARNING) << error_message; |
| 748 ReportExtensionLoadError(extension->path(), | 756 ReportExtensionLoadError(extension->path(), |
| 749 error_message, | 757 error_message, |
| 750 NotificationType::EXTENSION_OVERINSTALL_ERROR, | 758 NotificationType::EXTENSION_OVERINSTALL_ERROR, |
| 751 false); | 759 false); |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1141 // Finish installing on UI thread. | 1149 // Finish installing on UI thread. |
| 1142 ChromeThread::PostTask( | 1150 ChromeThread::PostTask( |
| 1143 ChromeThread::UI, FROM_HERE, | 1151 ChromeThread::UI, FROM_HERE, |
| 1144 NewRunnableMethod( | 1152 NewRunnableMethod( |
| 1145 frontend_, | 1153 frontend_, |
| 1146 &ExtensionsService::ContinueLoadAllExtensions, | 1154 &ExtensionsService::ContinueLoadAllExtensions, |
| 1147 extensions_to_reload, | 1155 extensions_to_reload, |
| 1148 start_time, | 1156 start_time, |
| 1149 true)); | 1157 true)); |
| 1150 } | 1158 } |
| OLD | NEW |